diff options
| -rw-r--r-- | build.bat | 4 | ||||
| -rw-r--r-- | include/funcs.h | 9 | ||||
| -rw-r--r-- | include/utils.h | 2 | ||||
| -rw-r--r-- | include/win_funcs.h | 13 | ||||
| -rw-r--r-- | src/loader.c | 23 | ||||
| -rw-r--r-- | src/module.c | 3 | ||||
| -rw-r--r-- | src/pdb.c | 20 |
7 files changed, 50 insertions, 24 deletions
@@ -26,8 +26,8 @@ if EXIST %VS2022_PRO% ( :compilation REM set C_FLAGS=/DHASHMAP /nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /std:c17 /c /Tc -REM set C_FLAGS=/nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /std:clatest /c /Tc -set C_FLAGS=-fno-builtin -nostdlib -mno-stack-arg-probe --target=x86_64-pc-windows-msvc -Wall -Werror -pedantic -I include -std=c23 -Wno-msvc-not-found -Wno-microsoft-anon-tag -Wno-gnu-binary-literal -g -O0 -c +REM set C_FLAGS=/nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /DDEBUG /std:clatest /c /Tc +set C_FLAGS=-fno-builtin -nostdlib -mno-stack-arg-probe --target=x86_64-pc-windows-msvc -Wall -Werror -pedantic -I include -std=c23 -Wno-msvc-not-found -Wno-microsoft-anon-tag -Wno-gnu-binary-literal -g -O0 -c -DDEBUG REM set L_FLAGS=/WX /SUBSYSTEM:CONSOLE /NODEFAULTLIB /stack:0x100000,100000 set L_FLAGS=/WX /SUBSYSTEM:CONSOLE /NODEFAULTLIB diff --git a/include/funcs.h b/include/funcs.h index 8ed5cf1..d15cdc7 100644 --- a/include/funcs.h +++ b/include/funcs.h @@ -10,6 +10,7 @@ KERNEL32(GetThreadContext) KERNEL32(SetThreadContext) KERNEL32(CreateFileA) +KERNEL32(GetFileSizeEx) KERNEL32(ReadFile) KERNEL32(WriteFile) KERNEL32(SetFilePointer) @@ -20,10 +21,10 @@ KERNEL32(SetConsoleMode) KERNEL32(ReadConsoleA) KERNEL32(WriteConsoleA) -KERNEL32(ReadProcessMemory) -KERNEL32(OutputDebugStringA) -KERNEL32(ContinueDebugEvent) -KERNEL32(WaitForDebugEventEx) +KERNEL_BASE(ReadProcessMemory) +KERNEL_BASE(OutputDebugStringA) +KERNEL_BASE(ContinueDebugEvent) +KERNEL_BASE(WaitForDebugEventEx) KERNEL32(WideCharToMultiByte) KERNEL32(GetFinalPathNameByHandleA) diff --git a/include/utils.h b/include/utils.h index e84653f..30a5612 100644 --- a/include/utils.h +++ b/include/utils.h @@ -2,7 +2,7 @@ #include "types.h" -#if defined (_DEBUG) +#if defined (DEBUG) #define assert(x) if (!(x)) __debugbreak(); #else #define assert(x) ((void)((x) ? 1 : 0)) diff --git a/include/win_funcs.h b/include/win_funcs.h index 59f395d..3d053bb 100644 --- a/include/win_funcs.h +++ b/include/win_funcs.h @@ -347,6 +347,18 @@ typedef struct __declspec(align(16)) _CONTEXT { } CONTEXT, *PCONTEXT; typedef PCONTEXT LPCONTEXT; +typedef union _LARGE_INTEGER { + struct { + u32 LowPart; + i32 HighPart; + }; + struct { + u32 LowPart; + i32 HighPart; + } u; + i64 QuadPart; +} LARGE_INTEGER, *PLARGE_INTEGER; + // ======================= // ====== Funcs PFN ====== // ======================= @@ -362,6 +374,7 @@ typedef i32(*PFN_GetThreadContext)(void*, LPCONTEXT); typedef i32(*PFN_SetThreadContext)(void*, const CONTEXT*); typedef void*(*PFN_CreateFileA)(const i8*, u32, u32, LPSECURITY_ATTRIBUTES, u32, u32, void*); +typedef i32(*PFN_GetFileSizeEx)(void*, PLARGE_INTEGER); typedef i32(*PFN_ReadFile)(void*, void*, u32, u32*, LPOVERLAPPED); typedef u32(*PFN_SetFilePointer)(void*, i32, i32*, u32); typedef i32(*PFN_WriteFile)(void*, const void*, u32, u32*, LPOVERLAPPED); diff --git a/src/loader.c b/src/loader.c index 2e79e67..8f2ac28 100644 --- a/src/loader.c +++ b/src/loader.c @@ -133,10 +133,8 @@ size_t str_len(const char* str) { 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; - - for (u32 index = 0U; index < min_len; index++) { +i32 str_cmpn(const i8* str1, const i8* str2, size_t count) { + for (u32 index = 0U; index < count; index++) { if (str1[index] < str2[index]) { return -1; } else if (str1[index] > str2[index]) { @@ -147,10 +145,8 @@ i32 str_cmp(const i8* str1, size_t str1_len, const i8* str2, size_t str2_len) { return 0; } -i32 wstr_cmp(const u16* str1, size_t str1_len, const u16* str2, size_t str2_len) { - u32 min_len = str1_len < str2_len ? str1_len : str2_len; - - for (u32 index = 0U; index < min_len; index++) { +i32 wstr_cmpn(const u16* str1, const u16* str2, size_t count) { + for (u32 index = 0U; index < count; index++) { if (str1[index] < str2[index]) { return -1; } else if (str1[index] > str2[index]) { @@ -174,8 +170,9 @@ void* get_module(u16* name, size_t name_size) { 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(name, name_size / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { + if (BaseDllName->Buffer && ((name_size / sizeof(u16)) - 1) == (BaseDllName->Length / sizeof(u16))) { + if (wstr_cmpn(name, BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { + return table_entry->DllBase; } } @@ -183,6 +180,7 @@ void* get_module(u16* name, size_t name_size) { cur_entry = cur_entry->Flink; } while(cur_entry != first_entry); + assert(FALSE); return NULL; } @@ -198,13 +196,12 @@ 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); - - if (str_cmp((i8*)name, length, (i8*)func_name, func_name_len) == 0) { + if (str_cmpn((i8*)name, (i8*)func_name, func_name_len - 1U) == 0) { return (void*)(base_addr + addresses[ordinals[name_index]]); } } + assert(FALSE); return NULL; } diff --git a/src/module.c b/src/module.c index 25ab2ad..13f0a8d 100644 --- a/src/module.c +++ b/src/module.c @@ -5,7 +5,8 @@ extern unsigned char _BitScanForward64(unsigned long *_Index, uint64_t _Mask); struct module modules[64U] = { 0U }; -u64 modules_list = ~0ULL; +// u64 modules_list = ~0ULL; // TODO: Check if modules_list is supposed to be filled with one's ? +u64 modules_list = 0ULL; // TODO: Filled modules_list with zeroes since we assert during the first call to add_module, see comment above // u64 module_symbols @@ -181,6 +181,12 @@ // ====== !windows.h ====== // ======================== +#if defined(_MSC_VER) && !defined(__clang__) + #define alloca +#elif defined(__clang__) + #define alloca __builtin_alloca +#endif + enum STREAM_INDEX { OLD_DIRECTORY, PDB, @@ -193,13 +199,16 @@ extern u8* string_stack_base; extern u8* string_stack_current; void open_pdb(const i8* pdb_path, struct module* module) { - void* pdb_file = CreateFileA(pdb_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + void* pdb_file = CreateFileA(pdb_path, GENERIC_READ | FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (pdb_file == INVALID_HANDLE_VALUE) { + if (pdb_file == NULL || pdb_file == INVALID_HANDLE_VALUE) { print("Cannot open pdb file at path %s due to error %u\n", pdb_path, GetLastError()); return; } + LARGE_INTEGER file_size = { 0 }; + assert(SUCCEEDED(GetFileSizeEx(pdb_file, &file_size))); + // MSF superblock struct msf_superblock { u8 magic[32U]; @@ -211,14 +220,19 @@ void open_pdb(const i8* pdb_path, struct module* module) { u32 block_map_addr; }; struct msf_superblock superblock = { 0U }; - u8 block[4096U] = { 0U }; u32 b_read = 0U; ReadFile(pdb_file, (void*)&superblock, sizeof(superblock), &b_read, NULL); + + assert(b_read == sizeof(superblock)); + assert(((i64)superblock.num_blocks) * superblock.block_size == file_size.QuadPart); + u8* block = alloca(superblock.block_size); + // Stream directory u32 dir_addr = (superblock.block_map_addr - 1U) * sizeof(block); SetFilePointer(pdb_file, dir_addr, NULL, FILE_BEGIN); ReadFile(pdb_file, (void*)block, superblock.num_directory_bytes, &b_read, NULL); + assert(b_read == superblock.num_directory_bytes); // Loog through streams u32 num_streams = ((u32*)block)[0U]; |
