diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-07-12 23:26:58 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-07-12 23:26:58 +0200 |
| commit | cee4c6d1c8cbf898d6aa9ad555d8dfcece4c7d96 (patch) | |
| tree | a5c9710ca65e4bc1183d365a013d4494882e0eb3 /src | |
| parent | 7b6964eb1bcf30a0ae7ed3391adce30565b262b4 (diff) | |
Fix runtime crashes due to loaded functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/disasm.c | 5 | ||||
| -rw-r--r-- | src/events.c | 103 | ||||
| -rw-r--r-- | src/hashmap.c | 4 | ||||
| -rw-r--r-- | src/loader.c | 67 | ||||
| -rw-r--r-- | src/parser.c | 300 | ||||
| -rw-r--r-- | src/pdb.c | 38 | ||||
| -rw-r--r-- | src/stack_walk.c | 199 | ||||
| -rw-r--r-- | src/test.c | 4 | ||||
| -rw-r--r-- | src/utils.c | 54 |
9 files changed, 61 insertions, 713 deletions
diff --git a/src/disasm.c b/src/disasm.c index 6cceb53..c9b839d 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -1,5 +1,7 @@ #include "disasm.h" + #include "utils.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== @@ -62,9 +64,6 @@ #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 -extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); -extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); - // ======================== // ====== !windows.h ====== // ======================== diff --git a/src/events.c b/src/events.c index fd96966..8c0f8ad 100644 --- a/src/events.c +++ b/src/events.c @@ -1,5 +1,6 @@ #include "utils.h" #include "pdb.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== @@ -23,94 +24,6 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; #define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters -// -// Exception record definition. -// - -typedef struct _EXCEPTION_RECORD { - u32 ExceptionCode; - u32 ExceptionFlags; - struct _EXCEPTION_RECORD *ExceptionRecord; - void* ExceptionAddress; - u32 NumberParameters; - u64* ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; - } EXCEPTION_RECORD; - -typedef EXCEPTION_RECORD *PEXCEPTION_RECORD; - -typedef struct _EXCEPTION_DEBUG_INFO { - EXCEPTION_RECORD ExceptionRecord; - u32 dwFirstChance; -} EXCEPTION_DEBUG_INFO, *LPEXCEPTION_DEBUG_INFO; - -typedef struct _CREATE_THREAD_DEBUG_INFO { - void* hThread; - void* lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; -} CREATE_THREAD_DEBUG_INFO, *LPCREATE_THREAD_DEBUG_INFO; - -typedef struct _CREATE_PROCESS_DEBUG_INFO { - void* hFile; - void* hProcess; - void* hThread; - void* lpBaseOfImage; - u32 dwDebugInfoFileOffset; - u32 nDebugInfoSize; - void* lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; - void* lpImageName; - u16 fUnicode; -} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO; - -typedef struct _EXIT_THREAD_DEBUG_INFO { - u32 dwExitCode; -} EXIT_THREAD_DEBUG_INFO, *LPEXIT_THREAD_DEBUG_INFO; - -typedef struct _EXIT_PROCESS_DEBUG_INFO { - u32 dwExitCode; -} EXIT_PROCESS_DEBUG_INFO, *LPEXIT_PROCESS_DEBUG_INFO; - -typedef struct _LOAD_DLL_DEBUG_INFO { - void* hFile; - void* lpBaseOfDll; - u32 dwDebugInfoFileOffset; - u32 nDebugInfoSize; - void* lpImageName; - u16 fUnicode; -} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO; - -typedef struct _UNLOAD_DLL_DEBUG_INFO { - void* lpBaseOfDll; -} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO; - -typedef struct _OUTPUT_DEBUG_STRING_INFO { - char* lpDebugStringData; - u16 fUnicode; - u16 nDebugStringLength; -} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO; - -typedef struct _RIP_INFO { - u32 dwError; - u32 dwType; -} RIP_INFO, *LPRIP_INFO; - -typedef struct _DEBUG_EVENT { - u32 dwDebugEventCode; - u32 dwProcessId; - u32 dwThreadId; - union { - EXCEPTION_DEBUG_INFO Exception; - CREATE_THREAD_DEBUG_INFO CreateThread; - CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; - EXIT_THREAD_DEBUG_INFO ExitThread; - EXIT_PROCESS_DEBUG_INFO ExitProcess; - LOAD_DLL_DEBUG_INFO LoadDll; - UNLOAD_DLL_DEBUG_INFO UnloadDll; - OUTPUT_DEBUG_STRING_INFO DebugString; - RIP_INFO RipInfo; - } u; -} DEBUG_EVENT, *LPDEBUG_EVENT; - #define FILE_NAME_NORMALIZED 0x0 //default #define FILE_NAME_OPENED 0x8 @@ -261,8 +174,6 @@ typedef struct _IMAGE_DEBUG_DIRECTORY { typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; -extern u32 GetLastError(void); - // // Code Page Default Values. // Please Use Unicode, either UTF-16 (as in WCHAR) or UTF-8 (code page CP_ACP) @@ -276,10 +187,6 @@ extern u32 GetLastError(void); #define CP_UTF7 65000 // UTF-7 translation #define CP_UTF8 65001 // UTF-8 translation -extern i32 WideCharToMultiByte(u32 CodePage, u32 dwFlags, const u16* lpWideCharStr, i32 cchWideChar, i8* lpMultiByteStr, i32 cbMultiByte, i8* lpDefaultChar, i32* lpUsedDefaultChar); - -extern u32 GetFinalPathNameByHandleA(void* hFile, i8* lpszFilePath, u32 cchFilePath, u32 dwFlags); - #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 @@ -337,9 +244,6 @@ extern u32 GetFinalPathNameByHandleA(void* hFile, i8* lpszFilePath, u32 cchFileP #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 -extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); -extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); - #define PROCESS_TERMINATE (0x0001) #define PROCESS_CREATE_THREAD (0x0002) #define PROCESS_SET_SESSIONID (0x0004) @@ -355,9 +259,6 @@ extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); #define PROCESS_QUERY_LIMITED_INFORMATION (0x1000) #define PROCESS_SET_LIMITED_INFORMATION (0x2000) -extern void* OpenProcess(u32 dwDesiredAccess, i32 bInheritHandle, u32 dwProcessId); -extern i32 TerminateProcess(void* hProcess, u32 uExitCode); - // ======================== // ====== !windows.h ====== // ======================== @@ -496,7 +397,7 @@ void load_symbols(const void* base_addr, struct module* module) { assert(string_stack_current - 16U * 4096U < string_stack_base); void* name_address = (void*)((u64)module->base_addr + names_address[name_index]); read_memory(name_address, name, 256U); - length = str_len((const char*)name, 256U); + length = str_len((const char*)name); break; } } diff --git a/src/hashmap.c b/src/hashmap.c index 8362736..526a95b 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -1,6 +1,7 @@ #include "hashmap.h" #include "utils.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== @@ -63,9 +64,6 @@ #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 -extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); -extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); - // ======================== // ====== !windows.h ====== // ======================== diff --git a/src/loader.c b/src/loader.c index da98364..2e79e67 100644 --- a/src/loader.c +++ b/src/loader.c @@ -114,11 +114,25 @@ typedef struct _IMAGE_EXPORT_DIRECTORY { #define KERNEL_BASE(name) \ PFN_##name name = NULL; +#define NTDLL(name) \ + PFN_##name name = NULL; + #include "funcs.h" +#undef NTDLL #undef KERNEL_BASE #undef KERNEL32 +size_t str_len(const char* str) { + const char* c = str; + size_t count = 0U; + while (*c != '\0') { + c++; + count++; + } + return count; +} + i32 str_cmp(const i8* str1, size_t str1_len, const i8* str2, size_t str2_len) { u32 min_len = str1_len < str2_len ? str1_len : str2_len; @@ -151,46 +165,23 @@ PEB* get_PEB(void) { return (PEB*)__readgsqword(__builtin_offsetof(TEB, ProcessEnvironmentBlock)); } -void* get_kernel32(void) { - const u16 kernel32_str[] = L"KERNEL32.DLL"; +void* get_module(u16* name, size_t name_size) { PEB* PEB = get_PEB(); - LIST_ENTRY* last_entry = PEB->LoaderData->InMemoryOrderModuleList.Blink; - LIST_ENTRY* cur_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink; + LIST_ENTRY* first_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink; + LIST_ENTRY* cur_entry = first_entry; - while(cur_entry != last_entry) { + do { LDR_DATA_TABLE_ENTRY* table_entry = (LDR_DATA_TABLE_ENTRY*)((u8*)cur_entry - 0x10); UNICODE_STRING* BaseDllName = &table_entry->BaseDllName; if (BaseDllName->Buffer) { - if (wstr_cmp(kernel32_str, sizeof(kernel32_str) / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { + if (wstr_cmp(name, name_size / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { return table_entry->DllBase; } } cur_entry = cur_entry->Flink; - } - - return NULL; -} - -void* get_kernel_base(void) { - const u16 kernel32_str[] = L"KERNELBASE.dll"; - PEB* PEB = get_PEB(); - LIST_ENTRY* last_entry = PEB->LoaderData->InMemoryOrderModuleList.Blink; - LIST_ENTRY* cur_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink; - - while(cur_entry != last_entry) { - LDR_DATA_TABLE_ENTRY* table_entry = (LDR_DATA_TABLE_ENTRY*)((u8*)cur_entry - 0x10); - UNICODE_STRING* BaseDllName = &table_entry->BaseDllName; - - if (BaseDllName->Buffer) { - if (wstr_cmp(kernel32_str, sizeof(kernel32_str) / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { - return table_entry->DllBase; - } - } - - cur_entry = cur_entry->Flink; - } + } while(cur_entry != first_entry); return NULL; } @@ -207,7 +198,7 @@ void* load_func(u64 base_addr, const char* func_name, u32 func_name_len) { for (u32 name_index = 0U; name_index < export_dir->NumberOfNames; name_index++) { const char* name = (const char*)(base_addr + names_address[name_index]); - u32 length = str_len(name, 256U); + u32 length = str_len(name); if (str_cmp((i8*)name, length, (i8*)func_name, func_name_len) == 0) { return (void*)(base_addr + addresses[ordinals[name_index]]); @@ -218,17 +209,25 @@ void* load_func(u64 base_addr, const char* func_name, u32 func_name_len) { } void load_funcs(void) { - void* kernel32 = get_kernel32(); - void* kernel_base = get_kernel_base(); + u16 kernel32_str[] = L"KERNEL32.DLL"; + u16 kernel_base_str[] = L"KERNELBASE.dll"; + u16 ntdll_str[] = L"ntdll.dll"; + void* kernel32 = get_module(kernel32_str, sizeof(kernel32_str)); + void* kernel_base = get_module(kernel_base_str, sizeof(kernel_base_str)); + void* ntdll = get_module(ntdll_str, sizeof(ntdll_str)); -#define KERNEL32(name) \ +#define KERNEL32(name) \ name = (PFN_##name)load_func((u64)kernel32, #name, sizeof(#name)); -#define KERNEL_BASE(name) \ +#define KERNEL_BASE(name) \ name = (PFN_##name)load_func((u64)kernel_base, #name, sizeof(#name)); +#define NTDLL(name) \ + name = (PFN_##name)load_func((u64)ntdll, #name, sizeof(#name)); + #include "funcs.h" +#undef NTDLL #undef KERNEL_BASE #undef KERNEL32 diff --git a/src/parser.c b/src/parser.c index 40133a7..8dcbc76 100644 --- a/src/parser.c +++ b/src/parser.c @@ -4,6 +4,7 @@ #include "module.h" #include "stack_walk.h" #include "disasm.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== @@ -27,202 +28,6 @@ #define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x00000040L) #define CONTEXT_KERNEL_CET (CONTEXT_AMD64 | 0x00000080L) -// -// Define 128-bit 16-byte aligned xmm register type. -// - -typedef struct __declspec(align(16)) _M128A { - u64 Low; - i64 High; -} M128A, *PM128A; - -// -// Format of data for (F)XSAVE/(F)XRSTOR instruction -// - -typedef struct __declspec(align(16)) _XSAVE_FORMAT { - u16 ControlWord; - u16 StatusWord; - u8 TagWord; - u8 Reserved1; - u16 ErrorOpcode; - u32 ErrorOffset; - u16 ErrorSelector; - u16 Reserved2; - u32 DataOffset; - u16 DataSelector; - u16 Reserved3; - u32 MxCsr; - u32 MxCsr_Mask; - M128A FloatRegisters[8]; - -#if defined(_WIN64) - - M128A XmmRegisters[16]; - u8 Reserved4[96]; - -#else - - M128A XmmRegisters[8]; - BYTE Reserved4[224]; - -#endif - -} XSAVE_FORMAT, *PXSAVE_FORMAT; - -typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; - -// -// Context Frame -// -// This frame has a several purposes: 1) it is used as an argument to -// NtContinue, 2) it is used to constuct a call frame for APC delivery, -// and 3) it is used in the user level thread creation routines. -// -// -// The flags field within this record controls the contents of a CONTEXT -// record. -// -// If the context record is used as an input parameter, then for each -// portion of the context record controlled by a flag whose value is -// set, it is assumed that that portion of the context record contains -// valid context. If the context record is being used to modify a threads -// context, then only that portion of the threads context is modified. -// -// If the context record is used as an output parameter to capture the -// context of a thread, then only those portions of the thread's context -// corresponding to set flags will be returned. -// -// CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags. -// -// CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15. -// -// CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs. -// -// CONTEXT_FLOATING_POINT specifies Xmm0-Xmm15. -// -// CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7. -// - -typedef struct __declspec(align(16)) _CONTEXT { - - // - // Register parameter home addresses. - // - // N.B. These fields are for convience - they could be used to extend the - // context record in the future. - // - - u64 P1Home; - u64 P2Home; - u64 P3Home; - u64 P4Home; - u64 P5Home; - u64 P6Home; - - // - // Control flags. - // - - u32 ContextFlags; - u32 MxCsr; - - // - // Segment Registers and processor flags. - // - - u16 SegCs; - u16 SegDs; - u16 SegEs; - u16 SegFs; - u16 SegGs; - u16 SegSs; - u32 EFlags; - - // - // Debug registers - // - - u64 Dr0; - u64 Dr1; - u64 Dr2; - u64 Dr3; - u64 Dr6; - u64 Dr7; - - // - // Integer registers. - // - - u64 Rax; - u64 Rcx; - u64 Rdx; - u64 Rbx; - u64 Rsp; - u64 Rbp; - u64 Rsi; - u64 Rdi; - u64 R8; - u64 R9; - u64 R10; - u64 R11; - u64 R12; - u64 R13; - u64 R14; - u64 R15; - - // - // Program counter. - // - - u64 Rip; - - // - // Floating point state. - // - - union { - XMM_SAVE_AREA32 FltSave; - struct { - M128A Header[2]; - M128A Legacy[8]; - M128A Xmm0; - M128A Xmm1; - M128A Xmm2; - M128A Xmm3; - M128A Xmm4; - M128A Xmm5; - M128A Xmm6; - M128A Xmm7; - M128A Xmm8; - M128A Xmm9; - M128A Xmm10; - M128A Xmm11; - M128A Xmm12; - M128A Xmm13; - M128A Xmm14; - M128A Xmm15; - }; - }; - - // - // Vector registers. - // - - M128A VectorRegister[26]; - u64 VectorControl; - - // - // Special debug control registers. - // - - u64 DebugControl; - u64 LastBranchToRip; - u64 LastBranchFromRip; - u64 LastExceptionToRip; - u64 LastExceptionFromRip; -} CONTEXT, *PCONTEXT; - #define THREAD_TERMINATE (0x0001) #define THREAD_SUSPEND_RESUME (0x0002) #define THREAD_GET_CONTEXT (0x0008) @@ -254,101 +59,8 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; #define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters -// -// Exception record definition. -// - -typedef struct _EXCEPTION_RECORD { - u32 ExceptionCode; - u32 ExceptionFlags; - struct _EXCEPTION_RECORD *ExceptionRecord; - void* ExceptionAddress; - u32 NumberParameters; - u64* ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; - } EXCEPTION_RECORD; - -typedef EXCEPTION_RECORD *PEXCEPTION_RECORD; - -typedef struct _EXCEPTION_DEBUG_INFO { - EXCEPTION_RECORD ExceptionRecord; - u32 dwFirstChance; -} EXCEPTION_DEBUG_INFO, *LPEXCEPTION_DEBUG_INFO; - -typedef struct _CREATE_THREAD_DEBUG_INFO { - void* hThread; - void* lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; -} CREATE_THREAD_DEBUG_INFO, *LPCREATE_THREAD_DEBUG_INFO; - -typedef struct _CREATE_PROCESS_DEBUG_INFO { - void* hFile; - void* hProcess; - void* hThread; - void* lpBaseOfImage; - u32 dwDebugInfoFileOffset; - u32 nDebugInfoSize; - void* lpThreadLocalBase; - LPTHREAD_START_ROUTINE lpStartAddress; - void* lpImageName; - u16 fUnicode; -} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO; - -typedef struct _EXIT_THREAD_DEBUG_INFO { - u32 dwExitCode; -} EXIT_THREAD_DEBUG_INFO, *LPEXIT_THREAD_DEBUG_INFO; - -typedef struct _EXIT_PROCESS_DEBUG_INFO { - u32 dwExitCode; -} EXIT_PROCESS_DEBUG_INFO, *LPEXIT_PROCESS_DEBUG_INFO; - -typedef struct _LOAD_DLL_DEBUG_INFO { - void* hFile; - void* lpBaseOfDll; - u32 dwDebugInfoFileOffset; - u32 nDebugInfoSize; - void* lpImageName; - u16 fUnicode; -} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO; - -typedef struct _UNLOAD_DLL_DEBUG_INFO { - void* lpBaseOfDll; -} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO; - -typedef struct _OUTPUT_DEBUG_STRING_INFO { - char* lpDebugStringData; - u16 fUnicode; - u16 nDebugStringLength; -} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO; - -typedef struct _RIP_INFO { - u32 dwError; - u32 dwType; -} RIP_INFO, *LPRIP_INFO; - -typedef struct _DEBUG_EVENT { - u32 dwDebugEventCode; - u32 dwProcessId; - u32 dwThreadId; - union { - EXCEPTION_DEBUG_INFO Exception; - CREATE_THREAD_DEBUG_INFO CreateThread; - CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; - EXIT_THREAD_DEBUG_INFO ExitThread; - EXIT_PROCESS_DEBUG_INFO ExitProcess; - LOAD_DLL_DEBUG_INFO LoadDll; - UNLOAD_DLL_DEBUG_INFO UnloadDll; - OUTPUT_DEBUG_STRING_INFO DebugString; - RIP_INFO RipInfo; - } u; -} DEBUG_EVENT, *LPDEBUG_EVENT; - -extern i32 ContinueDebugEvent(u32 dwProcessId, u32 dwThreadId, u32 dwContinueStatus); - typedef PCONTEXT LPCONTEXT; -extern i32 GetThreadContext(void* hThread, LPCONTEXT lpContext); -extern i32 SetThreadContext(void* hThread, const CONTEXT* lpContext); - #define SORT_DEFAULT 0x0 // sorting default #define LANG_NEUTRAL 0x00 @@ -368,8 +80,6 @@ extern i32 SetThreadContext(void* hThread, const CONTEXT* lpContext); #define CSTR_EQUAL 2 // string 1 equal to string 2 #define CSTR_GREATER_THAN 3 // string 1 greater than string 2 -extern i32 CompareStringA(u32 Locale, u32 dwCmpFlags, const i8* lpString1, i32 cchCount1, const i8* lpString2, i32 cchCount2); - #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 @@ -427,14 +137,6 @@ extern i32 CompareStringA(u32 Locale, u32 dwCmpFlags, const i8* lpString1, i32 c #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 -extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); -extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); - -extern void* OpenThread(u32 dwDesiredAccess, i32 bInheritHandle, u32 dwThreadId); -extern i32 CloseHandle(void* hObject); - -extern u32 GetLastError(void); - // ======================== // ====== !windows.h ====== // ======================== @@ -2,33 +2,13 @@ #include "cvinfo.h" #include "utils.h" +#include "win_funcs.h" + // ======================= // ====== windows.h ====== // ======================= -extern u32 GetLastError(void); - -typedef struct _SECURITY_ATTRIBUTES { - u32 nLength; - void* lpSecurityDescriptor; - i32 bInheritHandle; -} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; - -typedef struct _OVERLAPPED { - u64* Internal; - u64* InternalHigh; - union { - struct { - u32 Offset; - u32 OffsetHigh; - }; - void* Pointer; - }; - - void* hEvent; -} OVERLAPPED, *LPOVERLAPPED; - // // Define access rights to files and directories // @@ -197,14 +177,6 @@ typedef struct _OVERLAPPED { // #define INVALID_HANDLE_VALUE ((void*)(i64*)-1) -extern void* CreateFileA(const i8* lpFileName, u32 dwDesiredAccess, u32 dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, u32 dwCreationDisposition, u32 dwFlagsAndAttributes, void* hTemplateFile); - -extern u32 SetFilePointer(void* hFile, i32 lDistanceToMove, i32* lpDistanceToMoveHigh, u32 dwMoveMethod); - -extern i32 ReadFile(void* hFile, void* lpBuffer, u32 nNumberOfBytesToRead, u32* lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); - -extern i32 CloseHandle(void* hObject); - // ======================== // ====== !windows.h ====== // ======================== @@ -349,11 +321,11 @@ void open_pdb(const i8* pdb_path, struct module* module) { print("Module symbol stream index %x\n", modules_info[module_index]->ModuleSymStream); print("Module name : %s\n", modules_name[module_index]); size_t module_name_length = 0U; - module_name_length = str_len((const char*)modules_name[module_index], 256U); + module_name_length = str_len((const char*)modules_name[module_index]); obj_files_name[module_index] = &DBI_block[byte_index + sizeof(struct mod_info) + module_name_length + 1U]; print("Obj file name : %s\n", obj_files_name[module_index]); - size_t obj_file_name_length = str_len((const char*)obj_files_name[module_index], 256U); + size_t obj_file_name_length = str_len((const char*)obj_files_name[module_index]); u32 module_info_size = sizeof(*modules_info[0U]) + (i32)module_name_length + 1 + (i32)obj_file_name_length + 1; module_info_size = ((module_info_size + 3U) / 4U) * 4U; @@ -388,7 +360,7 @@ void open_pdb(const i8* pdb_path, struct module* module) { print("PROC32 SYMBOL %s\n", proc->name); // TODO: Add string management code assert(string_stack_current - 16U * 4096U < string_stack_base); - size_t length = str_len((const char*)proc->name, 256U); + size_t length = str_len((const char*)proc->name); str_cat((char*)string_stack_current, (const char*)proc->name, length); string_stack_current[length] = '\0'; u32 start_address = proc->off + module->nt_header.OptionalHeader.BaseOfCode; diff --git a/src/stack_walk.c b/src/stack_walk.c index 066b879..1cd97e4 100644 --- a/src/stack_walk.c +++ b/src/stack_walk.c @@ -2,6 +2,7 @@ #include "module.h" #include "utils.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== @@ -25,201 +26,6 @@ #define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x00000040L) #define CONTEXT_KERNEL_CET (CONTEXT_AMD64 | 0x00000080L) -// -// Define 128-bit 16-byte aligned xmm register type. -// - -typedef struct __declspec(align(16)) _M128A { - u64 Low; - i64 High; -} M128A, *PM128A; - -// -// Format of data for (F)XSAVE/(F)XRSTOR instruction -// - -typedef struct __declspec(align(16)) _XSAVE_FORMAT { - u16 ControlWord; - u16 StatusWord; - u8 TagWord; - u8 Reserved1; - u16 ErrorOpcode; - u32 ErrorOffset; - u16 ErrorSelector; - u16 Reserved2; - u32 DataOffset; - u16 DataSelector; - u16 Reserved3; - u32 MxCsr; - u32 MxCsr_Mask; - M128A FloatRegisters[8]; - -#if defined(_WIN64) - - M128A XmmRegisters[16]; - u8 Reserved4[96]; - -#else - - M128A XmmRegisters[8]; - BYTE Reserved4[224]; - -#endif - -} XSAVE_FORMAT, *PXSAVE_FORMAT; - -typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; - -// -// Context Frame -// -// This frame has a several purposes: 1) it is used as an argument to -// NtContinue, 2) it is used to constuct a call frame for APC delivery, -// and 3) it is used in the user level thread creation routines. -// -// -// The flags field within this record controls the contents of a CONTEXT -// record. -// -// If the context record is used as an input parameter, then for each -// portion of the context record controlled by a flag whose value is -// set, it is assumed that that portion of the context record contains -// valid context. If the context record is being used to modify a threads -// context, then only that portion of the threads context is modified. -// -// If the context record is used as an output parameter to capture the -// context of a thread, then only those portions of the thread's context -// corresponding to set flags will be returned. -// -// CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags. -// -// CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15. -// -// CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs. -// -// CONTEXT_FLOATING_POINT specifies Xmm0-Xmm15. -// -// CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7. -// - -typedef struct __declspec(align(16)) _CONTEXT { - - // - // Register parameter home addresses. - // - // N.B. These fields are for convience - they could be used to extend the - // context record in the future. - // - - u64 P1Home; - u64 P2Home; - u64 P3Home; - u64 P4Home; - u64 P5Home; - u64 P6Home; - - // - // Control flags. - // - - u32 ContextFlags; - u32 MxCsr; - - // - // Segment Registers and processor flags. - // - - u16 SegCs; - u16 SegDs; - u16 SegEs; - u16 SegFs; - u16 SegGs; - u16 SegSs; - u32 EFlags; - - // - // Debug registers - // - - u64 Dr0; - u64 Dr1; - u64 Dr2; - u64 Dr3; - u64 Dr6; - u64 Dr7; - - // - // Integer registers. - // - - u64 Rax; - u64 Rcx; - u64 Rdx; - u64 Rbx; - u64 Rsp; - u64 Rbp; - u64 Rsi; - u64 Rdi; - u64 R8; - u64 R9; - u64 R10; - u64 R11; - u64 R12; - u64 R13; - u64 R14; - u64 R15; - - // - // Program counter. - // - - u64 Rip; - - // - // Floating point state. - // - - union { - XMM_SAVE_AREA32 FltSave; - struct { - M128A Header[2]; - M128A Legacy[8]; - M128A Xmm0; - M128A Xmm1; - M128A Xmm2; - M128A Xmm3; - M128A Xmm4; - M128A Xmm5; - M128A Xmm6; - M128A Xmm7; - M128A Xmm8; - M128A Xmm9; - M128A Xmm10; - M128A Xmm11; - M128A Xmm12; - M128A Xmm13; - M128A Xmm14; - M128A Xmm15; - }; - }; - - // - // Vector registers. - // - - M128A VectorRegister[26]; - u64 VectorControl; - - // - // Special debug control registers. - // - - u64 DebugControl; - u64 LastBranchToRip; - u64 LastBranchFromRip; - u64 LastExceptionToRip; - u64 LastExceptionFromRip; -} CONTEXT, *PCONTEXT; #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 @@ -277,9 +83,6 @@ typedef struct __declspec(align(16)) _CONTEXT { #define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 #define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 -extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect); -extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType); - // ======================== // ====== !windows.h ====== // ======================== @@ -1,4 +1,4 @@ -extern void OutputDebugStringA(const char* lpOutputString); +// #include "win_funcs.h" int mainCRTStartup() { __debugbreak(); @@ -7,7 +7,7 @@ int mainCRTStartup() { while (1) { __debugbreak(); - OutputDebugStringA("Hello World !"); + // OutputDebugStringA("Hello World !"); i++; } diff --git a/src/utils.c b/src/utils.c index 0b3513d..95a1d80 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,30 +1,10 @@ #include "utils.h" +#include "win_funcs.h" // ======================= // ====== windows.h ====== // ======================= -typedef struct _PROCESS_INFORMATION { - void* hProcess; - void* hThread; - u32 dwProcessId; - u32 dwThreadId; -} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; -typedef struct _OVERLAPPED { - u32* Internal; - u32* InternalHigh; - union { - struct { - u32 Offset; - u32 OffsetHigh; - } DUMMYSTRUCTNAME; - void* Pointer; - } DUMMYUNIONNAME; - - void* hEvent; -} OVERLAPPED, *LPOVERLAPPED; - -#define SUCCEEDED(hr) (((i32)(hr)) >= 0) #if defined(_MSC_VER) && !defined(__clang__) #define va_start(ap, x) ((void)(__va_start(&ap, x))) @@ -44,12 +24,6 @@ typedef struct _OVERLAPPED { #define STD_OUTPUT_HANDLE ((u32)-11) #define STD_ERROR_HANDLE ((u32)-12) -extern void* GetStdHandle(u32 nStdHandle); - -extern i32 WriteFile(void* hFile, const void* lpBuffer, u32 nNumberOfBytesToWrite, u32* lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); - -extern i32 ReadProcessMemory(void* hProcess, const void* lpBaseAddress, void* lpBuffer, size_t nSize, size_t* lpNumberOfBytesRead); - // ======================== // ====== !windows.h ====== // ======================== @@ -66,19 +40,7 @@ u8 is_hexadecimal_digit(char c) { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); } - // TODO: Improve basic functions perfs -// max_size: str allocated size -size_t str_len(const char* str, size_t max_size) { - const char* c = str; - size_t count = 0U; - while (*c != '\0' && count < max_size) { - c++; - count++; - } - return count; -} - void str_cat(char* out, const char* str, size_t c_str) { char* cur_out = out; const char* cur_str = str; @@ -91,6 +53,18 @@ void str_cat(char* out, const char* str, size_t c_str) { } } +void memcpy(void* restrict dst, const void* restrict src, size_t size) { + RtlCopyMemory(dst, src, size); +} + +void memset(void* dst, int fill, size_t count) { + if (fill == 0) { + RtlZeroMemory(dst, count); + } else { + RtlFillMemory(dst, count, fill); + } +} + void u64toa(u64 number, char* str, u32 base) { static char codes[16U] = { '0', @@ -201,7 +175,7 @@ void print(const char* format, ...) { if (*cur_fmt == 's') { const char* str = va_arg(args, const char*); if(str != NULL) { - size_t length = str_len(str, sizeof(formatted_str)); + size_t length = str_len(str); i64 relative_fill_count = fill_count - length; if (relative_fill_count > 1) { fill_chars((u8*)cur_char, ' ', (u32)relative_fill_count); |
