diff options
Diffstat (limited to 'src/ntutil.h')
| -rw-r--r-- | src/ntutil.h | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/ntutil.h b/src/ntutil.h new file mode 100644 index 0000000..feca8f6 --- /dev/null +++ b/src/ntutil.h @@ -0,0 +1,251 @@ +//|_ _ _. _ ._ |_ _. _ | +//| | (/_ (_| \/ (/_ | | | | (_| (_ |< + +#pragma once +#include <Windows.h> +#include <winternl.h> +#include <vector> +#include "x86.h" +#include "winintern.h" +#include "asmutil.h" +#include "util.h" + +struct MODULE_EXPORT { + const char* name; + void* base; +}; + +struct MODULE_EXPORT64 { + STR<256> name; + U64 base; +}; + +inline void* nt_get_address() { + U32 fs_offset = (U32)&( (NT_TIB*)nullptr )->Self; + + PTEB teb = (PTEB)( __readfsdword( fs_offset ) ); + PEB* peb = teb->ProcessEnvironmentBlock; + + auto ldr_entry = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InMemoryOrderModuleList.Flink[0].Flink; + auto data_entry = ldr_entry->Reserved2[0]; + + return data_entry; +} + +inline U64 nt_get_address64() { + REG64 _ret; + + heavens_gate_enter(); + + { + db( 0x65 ) db( 0x48 ) db( 0x8b ) db( 0x04 ) db( 0x25 ) + db( 0x30 ) db( 0x00 ) db( 0x00 ) db( 0x00 ) // mov rax, qword ptr[gs:0x30] // get TEB + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x60 ) // mov rax, qword ptr[rax+0x60] // TEB->PEB + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x18 ) // mov rax, qword ptr[rax+0x18] // PEB->LDR + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x10 ) // mov rax, qword ptr[rax+0x10] // LDR->InMemList + db( 0x48 ) db( 0x8b ) db( 0x00 ) // mov rax, qword ptr[rax] // *InMemList.Flink + db( 0x48 ) db( 0x8b ) db( 0x40 ) db( 0x30 ) // mov rax, qword ptr[rax+0x30] // entry->DllBase + } + + __asm { + rex_w mov _ret.u32[0], eax + } + + heavens_gate_exit(); + + return _ret.u64; +} + +inline std::vector< MODULE_EXPORT > module_get_exports( void* module_base ) { + auto dos_header = (IMAGE_DOS_HEADER*)( module_base ); + auto nt_headers = (IMAGE_NT_HEADERS*)( (U32)module_base + dos_header->e_lfanew ); + auto data_dir = nt_headers->OptionalHeader.DataDirectory[0].VirtualAddress; + auto export_dir = (IMAGE_EXPORT_DIRECTORY*)( data_dir + (U32)module_base ); + + U32* names = (U32*)( (U32)module_base + export_dir->AddressOfNames ); + U32* funcs = (U32*)( (U32)module_base + export_dir->AddressOfFunctions ); + U16* ords = (U16*)( (U32)module_base + export_dir->AddressOfNameOrdinals ); + + std::vector< MODULE_EXPORT > ret; + for( U32 i = 0; i < export_dir->NumberOfNames; ++i ) { + const char* name = (const char*)( (U32)module_base + names[i] ); + void* func = (void*)( (U32)module_base + funcs[ords[i]] ); + + ret.push_back( { name, func } ); + } + + return ret; +}; + +extern NTSTATUS64 nt_create_thread64( + REG64* thread, + ACCESS_MASK mask, + _OBJECT_ATTRIBUTES64* object_attributes, + HANDLE process_handle, + LPTHREAD_START_ROUTINE start_routine, + void* parameter, + U32 suspended, + U32 stack_zero_bits = 0, + U32 stack_commit = 0, + U32 stack_reserve = 0 +); + +extern NTSTATUS64 nt_close64( + REG64 handle +); + +inline NTSTATUS64 nt_close64( HANDLE handle ) { + return nt_close64( (U64)handle ); +} + +extern NTSTATUS64 nt_open_process64( + HANDLE* handle, + U32 desired_access, + _OBJECT_ATTRIBUTES64* obj_attrbitues, + _CLIENT_ID_T<U64>* client_id +); + +extern NTSTATUS64 nt_write_vm64( + HANDLE handle, + U64 address, // imagine lmfao + void* value, + ULONG size, + U64* out_ret_bytes = 0 +); + +extern NTSTATUS64 nt_read_vm64( + HANDLE handle, + U64 address, + void* buffer, + ULONG size, + U64* out_ret_bytes = 0 +); + +extern NTSTATUS64 nt_query_vm64( + HANDLE handle, + U64 address, + WIN32_MEMORY_INFORMATION_CLASS information_class, + void* memory_information, + U64 memory_information_length, + U64* return_length = 0 +); + +extern NTSTATUS64 nt_allocate_vm64( + HANDLE handle, + U64* allocated_address, + ULONG zero_bits, + U64* region_size, + ULONG allocation_type, + ULONG protect +); + +extern NTSTATUS64 nt_free_vm64( + HANDLE handle, + U64* address, + U64* size, + ULONG free_type +); + +extern NTSTATUS64 nt_query_system_information64( + SYSTEM_INFORMATION_CLASS info_class, + void* system_information, + ULONG system_infromation_length, + ULONG* return_length +); + +extern NTSTATUS64 nt_query_information_process64( + HANDLE handle, + PROCESSINFOCLASS info_class, + void* process_information, + ULONG process_information_length, + ULONG* out_information_length +); + +extern NTSTATUS64 nt_delay_execution64( + BOOLEAN alterable, + LARGE_INTEGER* delay_interval +); + +extern NTSTATUS64 nt_query_object64( + HANDLE handle, + I32 info_class, + void* object_information, + ULONG object_information_length, + ULONG* return_length +); + +extern NTSTATUS64 nt_set_timer_resolution64( + ULONG desired_resolution, + BOOLEAN set_resolution, + ULONG* current_resolution +); + +inline std::vector< MODULE_EXPORT64 > module_get_exports( U32 module_base, HANDLE proc = (HANDLE)-1 ) { + std::vector< MODULE_EXPORT64 > ret; + IMAGE_DOS_HEADER dos_header; + IMAGE_NT_HEADERS nt_headers; + U32 data_dir; + IMAGE_EXPORT_DIRECTORY export_dir; + + nt_read_vm64( proc, module_base, &dos_header, sizeof( dos_header ) ); + nt_read_vm64( proc, module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + data_dir = nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress; + nt_read_vm64( proc, module_base + data_dir, &export_dir, sizeof( export_dir ) ); + + U32 names = module_base + export_dir.AddressOfNames; + U32 funcs = module_base + export_dir.AddressOfFunctions; + U32 ords = module_base + export_dir.AddressOfNameOrdinals; + + char name[256]{}; + U32 func = 0; + U16 ord; + U32 str_ptr = 0; + + for( U32 i = 0; i < export_dir.NumberOfNames; ++i ) { + nt_read_vm64( proc, names + 0x4 * i, &str_ptr, 0x4 ); + nt_read_vm64( proc, module_base + str_ptr, name, 256 ); + + nt_read_vm64( proc, ords + 0x2 * i, &ord, 0x2 ); + nt_read_vm64( proc, funcs + 0x4 * ord, &func, 0x4 ); + + name[255] = 0; + ret.push_back( { STR<256>( name ), module_base + func } ); + } + + return ret; +} + +inline std::vector< MODULE_EXPORT64 > module_get_exports64( U64 module_base, HANDLE proc = (HANDLE)-1 ) { + std::vector< MODULE_EXPORT64 > ret; + IMAGE_DOS_HEADER dos_header; + IMAGE_NT_HEADERS64 nt_headers; + U64 data_dir; + IMAGE_EXPORT_DIRECTORY export_dir; + + nt_read_vm64( proc, module_base, &dos_header, sizeof( dos_header ) ); + nt_read_vm64( proc, module_base + dos_header.e_lfanew, &nt_headers, sizeof( nt_headers ) ); + data_dir = nt_headers.OptionalHeader.DataDirectory[0].VirtualAddress; + nt_read_vm64( proc, module_base + data_dir, &export_dir, sizeof( export_dir ) ); + + U64 names = module_base + export_dir.AddressOfNames; + U64 funcs = module_base + export_dir.AddressOfFunctions; + U64 ords = module_base + export_dir.AddressOfNameOrdinals; + + char name[256]{}; + U64 func = 0; + U16 ord; + U64 str_ptr = 0; + + for( U32 i = 0; i < export_dir.NumberOfNames; ++i ) { + nt_read_vm64( proc, names + 0x4 * i, &str_ptr, 0x4 ); + nt_read_vm64( proc, module_base + str_ptr, name, 256, 0 ); + + nt_read_vm64( proc, ords + 0x2 * i, &ord, 0x2 ); + nt_read_vm64( proc, funcs + 0x4 * ord, &func, 0x4 ); + + + ret.push_back( { STR<128>( name ), module_base + func } ); + } + + return ret; +}
\ No newline at end of file |
