From ce51256c91e566d339c6a670af11bab519f98349 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Thu, 9 Jul 2026 21:49:15 +0200 Subject: Get rid of windows.h --- src/disasm.c | 70 ++++++++- src/events.c | 389 ++++++++++++++++++++++++++++++++++++++++++++++-- src/hashmap.c | 70 ++++++++- src/main.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/parser.c | 440 +++++++++++++++++++++++++++++++++++++++++++++++++++++- src/pdb.c | 227 ++++++++++++++++++++++++++-- src/stack_walk.c | 283 ++++++++++++++++++++++++++++++++++- src/utils.c | 56 ++++++- 8 files changed, 1925 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/disasm.c b/src/disasm.c index 2f59dfe..6e425fb 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -1,8 +1,74 @@ -#include - #include "disasm.h" #include "utils.h" +// ======================= +// ====== windows.h ====== +// ======================= + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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 ====== +// ======================== + const u8 MAX_LEGACY_PREFIXES = 4U; const u8 legacy_prefixes[] = { // Operand-size override diff --git a/src/events.c b/src/events.c index a1dd6ce..1886617 100644 --- a/src/events.c +++ b/src/events.c @@ -1,8 +1,367 @@ -#include - #include "utils.h" #include "pdb.h" +// ======================= +// ====== windows.h ====== +// ======================= + +// +// Debug APIs +// +#define EXCEPTION_DEBUG_EVENT 1 +#define CREATE_THREAD_DEBUG_EVENT 2 +#define CREATE_PROCESS_DEBUG_EVENT 3 +#define EXIT_THREAD_DEBUG_EVENT 4 +#define EXIT_PROCESS_DEBUG_EVENT 5 +#define LOAD_DLL_DEBUG_EVENT 6 +#define UNLOAD_DLL_DEBUG_EVENT 7 +#define OUTPUT_DEBUG_STRING_EVENT 8 +#define RIP_EVENT 9 + +typedef u32 (*PTHREAD_START_ROUTINE)(void* lpThreadParameter); +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 + +#define STATUS_WAIT_0 ((u32 )0x00000000L) +#define STATUS_ABANDONED_WAIT_0 ((u32 )0x00000080L) +#define STATUS_USER_APC ((u32 )0x000000C0L) +#define STATUS_TIMEOUT ((u32 )0x00000102L) +#define STATUS_PENDING ((u32 )0x00000103L) +#define DBG_EXCEPTION_HANDLED ((u32 )0x00010001L) +#define DBG_CONTINUE ((u32 )0x00010002L) +#define STATUS_SEGMENT_NOTIFICATION ((u32 )0x40000005L) +#define STATUS_FATAL_APP_EXIT ((u32 )0x40000015L) +#define DBG_REPLY_LATER ((u32 )0x40010001L) +#define DBG_TERMINATE_THREAD ((u32 )0x40010003L) +#define DBG_TERMINATE_PROCESS ((u32 )0x40010004L) +#define DBG_CONTROL_C ((u32 )0x40010005L) +#define DBG_PRINTEXCEPTION_C ((u32 )0x40010006L) +#define DBG_RIPEXCEPTION ((u32 )0x40010007L) +#define DBG_CONTROL_BREAK ((u32 )0x40010008L) +#define DBG_COMMAND_EXCEPTION ((u32 )0x40010009L) +#define DBG_PRINTEXCEPTION_WIDE_C ((u32 )0x4001000AL) +#define STATUS_GUARD_PAGE_VIOLATION ((u32 )0x80000001L) +#define STATUS_DATATYPE_MISALIGNMENT ((u32 )0x80000002L) +#define STATUS_BREAKPOINT ((u32 )0x80000003L) +#define STATUS_SINGLE_STEP ((u32 )0x80000004L) +#define STATUS_LONGJUMP ((u32 )0x80000026L) +#define STATUS_UNWIND_CONSOLIDATE ((u32 )0x80000029L) +#define DBG_EXCEPTION_NOT_HANDLED ((u32 )0x80010001L) +#define STATUS_ACCESS_VIOLATION ((u32 )0xC0000005L) +#define STATUS_IN_PAGE_ERROR ((u32 )0xC0000006L) +#define STATUS_INVALID_HANDLE ((u32 )0xC0000008L) +#define STATUS_INVALID_PARAMETER ((u32 )0xC000000DL) +#define STATUS_NO_MEMORY ((u32 )0xC0000017L) +#define STATUS_ILLEGAL_INSTRUCTION ((u32 )0xC000001DL) +#define STATUS_NONCONTINUABLE_EXCEPTION ((u32 )0xC0000025L) +#define STATUS_INVALID_DISPOSITION ((u32 )0xC0000026L) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((u32 )0xC000008CL) +#define STATUS_FLOAT_DENORMAL_OPERAND ((u32 )0xC000008DL) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((u32 )0xC000008EL) +#define STATUS_FLOAT_INEXACT_RESULT ((u32 )0xC000008FL) +#define STATUS_FLOAT_INVALID_OPERATION ((u32 )0xC0000090L) +#define STATUS_FLOAT_OVERFLOW ((u32 )0xC0000091L) +#define STATUS_FLOAT_STACK_CHECK ((u32 )0xC0000092L) +#define STATUS_FLOAT_UNDERFLOW ((u32 )0xC0000093L) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((u32 )0xC0000094L) +#define STATUS_INTEGER_OVERFLOW ((u32 )0xC0000095L) +#define STATUS_PRIVILEGED_INSTRUCTION ((u32 )0xC0000096L) +#define STATUS_STACK_OVERFLOW ((u32 )0xC00000FDL) +#define STATUS_DLL_NOT_FOUND ((u32 )0xC0000135L) +#define STATUS_ORDINAL_NOT_FOUND ((u32 )0xC0000138L) +#define STATUS_ENTRYPOINT_NOT_FOUND ((u32 )0xC0000139L) +#define STATUS_CONTROL_C_EXIT ((u32 )0xC000013AL) +#define STATUS_DLL_INIT_FAILED ((u32 )0xC0000142L) +#define STATUS_CONTROL_STACK_VIOLATION ((u32 )0xC00001B2L) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((u32 )0xC00002B4L) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((u32 )0xC00002B5L) +#define STATUS_REG_NAT_CONSUMPTION ((u32 )0xC00002C9L) +#define STATUS_HEAP_CORRUPTION ((u32 )0xC0000374L) +#define STATUS_STACK_BUFFER_OVERRUN ((u32 )0xC0000409L) +#define STATUS_INVALID_CRUNTIME_PARAMETER ((u32 )0xC0000417L) +#define STATUS_ASSERTION_FAILURE ((u32 )0xC0000420L) +#define STATUS_ENCLAVE_VIOLATION ((u32 )0xC00004A2L) +#define STATUS_INTERRUPTED ((u32 )0xC0000515L) +#define STATUS_THREAD_NOT_RUNNING ((u32 )0xC0000516L) +#define STATUS_ALREADY_REGISTERED ((u32 )0xC0000718L) + +/* compatibility macros */ +#define STILL_ACTIVE STATUS_PENDING +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION +#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT +#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT +#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP +#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED +#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND +#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO +#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT +#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION +#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW +#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK +#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW +#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO +#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW +#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION +#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR +#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION +#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION +#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW +#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION +#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION +#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE +#define EXCEPTION_POSSIBLE_DEADLOCK STATUS_POSSIBLE_DEADLOCK +#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT + +typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY { + u32 BeginAddress; + u32 EndAddress; + union { + u32 UnwindInfoAddress; + u32 UnwindData; + }; +} _IMAGE_RUNTIME_FUNCTION_ENTRY, *_PIMAGE_RUNTIME_FUNCTION_ENTRY; + +typedef struct _IMAGE_EXPORT_DIRECTORY { + u32 Characteristics; + u32 TimeDateStamp; + u16 MajorVersion; + u16 MinorVersion; + u32 Name; + u32 Base; + u32 NumberOfFunctions; + u32 NumberOfNames; + u32 AddressOfFunctions; // RVA from base of image + u32 AddressOfNames; // RVA from base of image + u32 AddressOfNameOrdinals; // RVA from base of image +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +typedef struct _IMAGE_DEBUG_DIRECTORY { + u32 Characteristics; + u32 TimeDateStamp; + u16 MajorVersion; + u16 MinorVersion; + u32 Type; + u32 SizeOfData; + u32 AddressOfRawData; + u32 PointerToRawData; +} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; + +#define IMAGE_DEBUG_TYPE_UNKNOWN 0 +#define IMAGE_DEBUG_TYPE_COFF 1 +#define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#define IMAGE_DEBUG_TYPE_FPO 3 +#define IMAGE_DEBUG_TYPE_MISC 4 +#define IMAGE_DEBUG_TYPE_EXCEPTION 5 +#define IMAGE_DEBUG_TYPE_FIXUP 6 +#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 +#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 +#define IMAGE_DEBUG_TYPE_BORLAND 9 +#define IMAGE_DEBUG_TYPE_RESERVED10 10 +#define IMAGE_DEBUG_TYPE_BBT IMAGE_DEBUG_TYPE_RESERVED10 +#define IMAGE_DEBUG_TYPE_CLSID 11 +#define IMAGE_DEBUG_TYPE_VC_FEATURE 12 +#define IMAGE_DEBUG_TYPE_POGO 13 +#define IMAGE_DEBUG_TYPE_ILTCG 14 +#define IMAGE_DEBUG_TYPE_MPX 15 +#define IMAGE_DEBUG_TYPE_REPRO 16 +#define IMAGE_DEBUG_TYPE_SPGO 18 +#define IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 + +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) +// +#define CP_ACP 0 // default to ANSI code page +#define CP_OEMCP 1 // default to OEM code page +#define CP_MACCP 2 // default to MAC code page +#define CP_THREAD_ACP 3 // current thread's ANSI code page +#define CP_SYMBOL 42 // SYMBOL translations + +#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, const 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 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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) +#define PROCESS_VM_OPERATION (0x0008) +#define PROCESS_VM_READ (0x0010) +#define PROCESS_VM_WRITE (0x0020) +#define PROCESS_DUP_HANDLE (0x0040) +#define PROCESS_CREATE_PROCESS (0x0080) +#define PROCESS_SET_QUOTA (0x0100) +#define PROCESS_SET_INFORMATION (0x0200) +#define PROCESS_QUERY_INFORMATION (0x0400) +#define PROCESS_SUSPEND_RESUME (0x0800) +#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 ====== +// ======================== + u8 expect_single_step = FALSE; extern DEBUG_EVENT dbg_event; @@ -11,14 +370,14 @@ extern u8* string_stack_current; const char* dummy_name = "Function_dummy_name"; -void read_name_uni(const void* name_addr, const char* name, size_t name_size) { +void read_name_uni(const void* name_addr, i8* name, size_t name_size) { u8* addr = NULL; if (!read_memory(name_addr, (void*)&addr, 8U)) { print("%s %u\n", "Loading DLL : error reading dll name : ", GetLastError()); return; } - wchar_t name_uni[256U] = { 0U }; + u16 name_uni[256U] = { 0U }; if (!read_memory((const void*)addr, name_uni, sizeof(name_uni))) { print("Cannot read dll name from proc memory %u\n", GetLastError()); return; @@ -29,7 +388,7 @@ void read_name_uni(const void* name_addr, const char* name, size_t name_size) { 0, name_uni, -1, - (char*)name, + name, (int)name_size, NULL, NULL @@ -220,7 +579,7 @@ void load_symbols(const void* base_addr, struct module* module) { u32 signature; u32 guid[4U]; u32 age; - char path; + i8 path; } header = { 0U }; if (!read_memory((const void*)((u64)base_addr + (u64)debug_entries[i].AddressOfRawData), (void*)&header, debug_entries[i].SizeOfData)) { print("Cannot read code view header for module %s at address %x\n", (char*)module->name, base_addr); @@ -353,8 +712,8 @@ void handle_create_process() { CREATE_PROCESS_DEBUG_INFO proc_dbg_info = dbg_event.u.CreateProcessInfo; - HANDLE hproc = OpenProcess(PROCESS_VM_READ, FALSE, dbg_event.dwProcessId); - hproc; + void* hproc = OpenProcess(PROCESS_VM_READ, FALSE, dbg_event.dwProcessId); + (void)hproc; struct module* module = &modules[add_module()]; // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-create_process_debug_info @@ -363,7 +722,7 @@ void handle_create_process() { // module->base_addr = proc_dbg_info.lpBaseOfImage; // read_name_uni(proc_dbg_info.lpImageName, (const char*)module->name, sizeof(module->name)); module->base_addr = proc_dbg_info.lpBaseOfImage; - GetFinalPathNameByHandleA(proc_dbg_info.hFile, (LPSTR)module->name, sizeof(module->name), FILE_NAME_NORMALIZED); + GetFinalPathNameByHandleA(proc_dbg_info.hFile, module->name, sizeof(module->name), FILE_NAME_NORMALIZED); print("%s%s\n", "Loading Process : ", (char*)module->name); load_symbols((const void*)proc_dbg_info.lpBaseOfImage, module); @@ -374,7 +733,7 @@ void handle_create_thread() { } void handle_exception() { - extern DWORD continue_status; + extern u32 continue_status; print("%s : ", "ExceptionDebugEvent"); @@ -410,7 +769,7 @@ void handle_load_dll() { struct module* module = &modules[add_module()]; module->base_addr = dll_base_addr; - read_name_uni(dll_name_addr, (const char*)module->name, sizeof(module->name)); + read_name_uni(dll_name_addr, module->name, sizeof(module->name)); print("%s%s\n", "Loading DLL : ", (char*)module->name); @@ -426,19 +785,19 @@ void handle_output_debug_string() { char* str_addr = dbg_str_event.lpDebugStringData; size_t str_size = (size_t)dbg_str_event.nDebugStringLength; // assert(str_size > 1024U); - u8 dbg_str[1024U] = { 0U }; + u16 dbg_str[1024U] = { 0U }; if (!read_memory(str_addr, dbg_str, str_size)) { print("%s %u\n", "OutputDebugStringDebugEvent : error reading debug string : ", GetLastError()); return; } if (dbg_str_event.fUnicode) { - u8 ansi_str[1024U] = { 0U }; + i8 ansi_str[1024U] = { 0U }; WideCharToMultiByte( CP_ACP, 0, - (wchar_t*)dbg_str, + dbg_str, -1, - (char*)ansi_str, + ansi_str, sizeof(ansi_str), NULL, NULL diff --git a/src/hashmap.c b/src/hashmap.c index 4a59e15..a218f26 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -1,9 +1,75 @@ #include "hashmap.h" -#include - #include "utils.h" +// ======================= +// ====== windows.h ====== +// ======================= + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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 ====== +// ======================== + static const u32 initial_size = 4096U * 100U; static const u32 empty_psl = (u32)-1; static const float max_load_factor = 0.75f; diff --git a/src/main.c b/src/main.c index 3ec9631..dd84cea 100644 --- a/src/main.c +++ b/src/main.c @@ -1,21 +1,439 @@ -#include - #include "types.h" #include "utils.h" #include "events.h" #include "parser.h" +// ======================= +// ====== windows.h ====== +// ======================= + +#define STATUS_WAIT_0 ((u32 )0x00000000L) +#define STATUS_ABANDONED_WAIT_0 ((u32 )0x00000080L) +#define STATUS_USER_APC ((u32 )0x000000C0L) +#define STATUS_TIMEOUT ((u32 )0x00000102L) +#define STATUS_PENDING ((u32 )0x00000103L) +#define DBG_EXCEPTION_HANDLED ((u32 )0x00010001L) +#define DBG_CONTINUE ((u32 )0x00010002L) +#define STATUS_SEGMENT_NOTIFICATION ((u32 )0x40000005L) +#define STATUS_FATAL_APP_EXIT ((u32 )0x40000015L) +#define DBG_REPLY_LATER ((u32 )0x40010001L) +#define DBG_TERMINATE_THREAD ((u32 )0x40010003L) +#define DBG_TERMINATE_PROCESS ((u32 )0x40010004L) +#define DBG_CONTROL_C ((u32 )0x40010005L) +#define DBG_PRINTEXCEPTION_C ((u32 )0x40010006L) +#define DBG_RIPEXCEPTION ((u32 )0x40010007L) +#define DBG_CONTROL_BREAK ((u32 )0x40010008L) +#define DBG_COMMAND_EXCEPTION ((u32 )0x40010009L) +#define DBG_PRINTEXCEPTION_WIDE_C ((u32 )0x4001000AL) +#define STATUS_GUARD_PAGE_VIOLATION ((u32 )0x80000001L) +#define STATUS_DATATYPE_MISALIGNMENT ((u32 )0x80000002L) +#define STATUS_BREAKPOINT ((u32 )0x80000003L) +#define STATUS_SINGLE_STEP ((u32 )0x80000004L) +#define STATUS_LONGJUMP ((u32 )0x80000026L) +#define STATUS_UNWIND_CONSOLIDATE ((u32 )0x80000029L) +#define DBG_EXCEPTION_NOT_HANDLED ((u32 )0x80010001L) +#define STATUS_ACCESS_VIOLATION ((u32 )0xC0000005L) +#define STATUS_IN_PAGE_ERROR ((u32 )0xC0000006L) +#define STATUS_INVALID_HANDLE ((u32 )0xC0000008L) +#define STATUS_INVALID_PARAMETER ((u32 )0xC000000DL) +#define STATUS_NO_MEMORY ((u32 )0xC0000017L) +#define STATUS_ILLEGAL_INSTRUCTION ((u32 )0xC000001DL) +#define STATUS_NONCONTINUABLE_EXCEPTION ((u32 )0xC0000025L) +#define STATUS_INVALID_DISPOSITION ((u32 )0xC0000026L) +#define STATUS_ARRAY_BOUNDS_EXCEEDED ((u32 )0xC000008CL) +#define STATUS_FLOAT_DENORMAL_OPERAND ((u32 )0xC000008DL) +#define STATUS_FLOAT_DIVIDE_BY_ZERO ((u32 )0xC000008EL) +#define STATUS_FLOAT_INEXACT_RESULT ((u32 )0xC000008FL) +#define STATUS_FLOAT_INVALID_OPERATION ((u32 )0xC0000090L) +#define STATUS_FLOAT_OVERFLOW ((u32 )0xC0000091L) +#define STATUS_FLOAT_STACK_CHECK ((u32 )0xC0000092L) +#define STATUS_FLOAT_UNDERFLOW ((u32 )0xC0000093L) +#define STATUS_INTEGER_DIVIDE_BY_ZERO ((u32 )0xC0000094L) +#define STATUS_INTEGER_OVERFLOW ((u32 )0xC0000095L) +#define STATUS_PRIVILEGED_INSTRUCTION ((u32 )0xC0000096L) +#define STATUS_STACK_OVERFLOW ((u32 )0xC00000FDL) +#define STATUS_DLL_NOT_FOUND ((u32 )0xC0000135L) +#define STATUS_ORDINAL_NOT_FOUND ((u32 )0xC0000138L) +#define STATUS_ENTRYPOINT_NOT_FOUND ((u32 )0xC0000139L) +#define STATUS_CONTROL_C_EXIT ((u32 )0xC000013AL) +#define STATUS_DLL_INIT_FAILED ((u32 )0xC0000142L) +#define STATUS_CONTROL_STACK_VIOLATION ((u32 )0xC00001B2L) +#define STATUS_FLOAT_MULTIPLE_FAULTS ((u32 )0xC00002B4L) +#define STATUS_FLOAT_MULTIPLE_TRAPS ((u32 )0xC00002B5L) +#define STATUS_REG_NAT_CONSUMPTION ((u32 )0xC00002C9L) +#define STATUS_HEAP_CORRUPTION ((u32 )0xC0000374L) +#define STATUS_STACK_BUFFER_OVERRUN ((u32 )0xC0000409L) +#define STATUS_INVALID_CRUNTIME_PARAMETER ((u32 )0xC0000417L) +#define STATUS_ASSERTION_FAILURE ((u32 )0xC0000420L) +#define STATUS_ENCLAVE_VIOLATION ((u32 )0xC00004A2L) +#define STATUS_INTERRUPTED ((u32 )0xC0000515L) +#define STATUS_THREAD_NOT_RUNNING ((u32 )0xC0000516L) +#define STATUS_ALREADY_REGISTERED ((u32 )0xC0000718L) + +/* compatibility macros */ +#define STILL_ACTIVE STATUS_PENDING +#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION +#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT +#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT +#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP +#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED +#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND +#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO +#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT +#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION +#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW +#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK +#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW +#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO +#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW +#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION +#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR +#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION +#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION +#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW +#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION +#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION +#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE +#define EXCEPTION_POSSIBLE_DEADLOCK STATUS_POSSIBLE_DEADLOCK +#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT + +// +// Debug APIs +// +#define EXCEPTION_DEBUG_EVENT 1 +#define CREATE_THREAD_DEBUG_EVENT 2 +#define CREATE_PROCESS_DEBUG_EVENT 3 +#define EXIT_THREAD_DEBUG_EVENT 4 +#define EXIT_PROCESS_DEBUG_EVENT 5 +#define LOAD_DLL_DEBUG_EVENT 6 +#define UNLOAD_DLL_DEBUG_EVENT 7 +#define OUTPUT_DEBUG_STRING_EVENT 8 +#define RIP_EVENT 9 + +typedef u32 (*PTHREAD_START_ROUTINE)(void* lpThreadParameter); +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 WaitForDebugEventEx(LPDEBUG_EVENT lpDebugEvent, u32 dwMilliseconds); + +typedef struct _PROCESS_INFORMATION { + void* hProcess; + void* hThread; + u32 dwProcessId; + u32 dwThreadId; +} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + +#define PAGE_NOACCESS 0x01 +#define PAGE_READONLY 0x02 +#define PAGE_READWRITE 0x04 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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 STD_INPUT_HANDLE ((u32)-10) +#define STD_OUTPUT_HANDLE ((u32)-11) +#define STD_ERROR_HANDLE ((u32)-12) + +extern void* GetStdHandle(u32 nStdHandle); + +typedef struct _STARTUPINFOA { + u32 cb; + i8* lpReserved; + i8* lpDesktop; + i8* lpTitle; + u32 dwX; + u32 dwY; + u32 dwXSize; + u32 dwYSize; + u32 dwXCountChars; + u32 dwYCountChars; + u32 dwFillAttribute; + u32 dwFlags; + u16 wShowWindow; + u16 cbReserved2; + u8* lpReserved2; + void* hStdInput; + void* hStdOutput; + void* hStdError; +} STARTUPINFOA, *LPSTARTUPINFOA; + +typedef struct _SECURITY_ATTRIBUTES { + u32 nLength; + void* lpSecurityDescriptor; + i32 bInheritHandle; +} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + +// +// Process dwCreationFlag values +// + +#define DEBUG_PROCESS 0x00000001 +#define DEBUG_ONLY_THIS_PROCESS 0x00000002 +#define CREATE_SUSPENDED 0x00000004 +#define DETACHED_PROCESS 0x00000008 + +#define CREATE_NEW_CONSOLE 0x00000010 +#define NORMAL_PRIORITY_CLASS 0x00000020 +#define IDLE_PRIORITY_CLASS 0x00000040 +#define HIGH_PRIORITY_CLASS 0x00000080 + +#define REALTIME_PRIORITY_CLASS 0x00000100 +#define CREATE_NEW_PROCESS_GROUP 0x00000200 +#define CREATE_UNICODE_ENVIRONMENT 0x00000400 +#define CREATE_SEPARATE_WOW_VDM 0x00000800 + +#define CREATE_SHARED_WOW_VDM 0x00001000 +#define CREATE_FORCEDOS 0x00002000 +#define BELOW_NORMAL_PRIORITY_CLASS 0x00004000 +#define ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 + +#define INHERIT_PARENT_AFFINITY 0x00010000 +#define INHERIT_CALLER_PRIORITY 0x00020000 // Deprecated +#define CREATE_PROTECTED_PROCESS 0x00040000 +#define EXTENDED_STARTUPINFO_PRESENT 0x00080000 + +#define PROCESS_MODE_BACKGROUND_BEGIN 0x00100000 +#define PROCESS_MODE_BACKGROUND_END 0x00200000 +#define CREATE_SECURE_PROCESS 0x00400000 + +#define CREATE_BREAKAWAY_FROM_JOB 0x01000000 +#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL 0x02000000 +#define CREATE_DEFAULT_ERROR_MODE 0x04000000 +#define CREATE_NO_WINDOW 0x08000000 + +#define PROFILE_USER 0x10000000 +#define PROFILE_KERNEL 0x20000000 +#define PROFILE_SERVER 0x40000000 +#define CREATE_IGNORE_SYSTEM_DEFAULT 0x80000000 + +// +// Thread dwCreationFlag values +// + +//#define CREATE_SUSPENDED 0x00000004 + +extern i32 CreateProcessA( + const i8* lpApplicationName, + i8* lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + i32 bInheritHandles, + u32 dwCreationFlags, + void* lpEnvironment, + const i8* lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +); + +extern i32 TerminateProcess(void* hProcess, u32 uExitCode); + +// +// Input Mode flags: +// + +#define ENABLE_PROCESSED_INPUT 0x0001 +#define ENABLE_LINE_INPUT 0x0002 +#define ENABLE_ECHO_INPUT 0x0004 +#define ENABLE_WINDOW_INPUT 0x0008 +#define ENABLE_MOUSE_INPUT 0x0010 +#define ENABLE_INSERT_MODE 0x0020 +#define ENABLE_QUICK_EDIT_MODE 0x0040 +#define ENABLE_EXTENDED_FLAGS 0x0080 +#define ENABLE_AUTO_POSITION 0x0100 +#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200 + +// +// Output Mode flags: +// + +#define ENABLE_PROCESSED_OUTPUT 0x0001 +#define ENABLE_WRAP_AT_EOL_OUTPUT 0x0002 +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#define DISABLE_NEWLINE_AUTO_RETURN 0x0008 +#define ENABLE_LVB_GRID_WORLDWIDE 0x0010 + +extern i32 SetConsoleMode(void* hConsoleHandle, u32 dwMode); + +typedef struct _CONSOLE_READCONSOLE_CONTROL { + u32 nLength; + u32 nInitialChars; + u32 dwCtrlWakeupMask; + u32 dwControlKeyState; +} CONSOLE_READCONSOLE_CONTROL, *PCONSOLE_READCONSOLE_CONTROL; + +extern i32 ReadConsoleA( + void* hConsoleInput, + void* lpBuffer, + u32 nNumberOfCharsToRead, + u32* lpNumberOfCharsRead, + PCONSOLE_READCONSOLE_CONTROL pInputControl + ); + +extern i32 WriteConsoleA( + void* hConsoleOutput, + const void* lpBuffer, + u32 nNumberOfCharsToWrite, + u32* lpNumberOfCharsWritten, + void* lpReserved + ); + +// ======================== +// ====== !windows.h ====== +// ======================== + extern u32 _fltused = TRUE; u8 is_open = TRUE; u8 process_commands = TRUE; -HANDLE h_input = NULL; -HANDLE h_output = NULL; +void* h_input = NULL; +void* h_output = NULL; DEBUG_EVENT dbg_event; PROCESS_INFORMATION proc_info = { 0 }; -DWORD continue_status = DBG_EXCEPTION_NOT_HANDLED; +u32 continue_status = DBG_EXCEPTION_NOT_HANDLED; // TODO: Perfect hashing table ? u8* string_stack_base = NULL; u8* string_stack_current = NULL; @@ -59,11 +477,11 @@ void dbg_loop() { process_commands = TRUE; while(process_commands) { const char write_buffer[] = "> "; - DWORD c_written = 0U; - WriteConsole(h_output, write_buffer, sizeof(write_buffer), &c_written, NULL); + u32 c_written = 0U; + WriteConsoleA(h_output, write_buffer, sizeof(write_buffer), &c_written, NULL); char input_buffer[64] = { 0 }; - DWORD input_size = 0U; - ReadConsole(h_input, input_buffer, sizeof(input_buffer), &input_size, NULL); + u32 input_size = 0U; + ReadConsoleA(h_input, input_buffer, sizeof(input_buffer), &input_size, NULL); interpreter(input_buffer, input_size); } @@ -77,9 +495,9 @@ int mainCRTStartup() { STARTUPINFOA startup_info = { 0 }; startup_info.cb = sizeof(startup_info); - BOOL ret = CreateProcessA( + i32 ret = CreateProcessA( NULL, - "./test.exe", + (i8*)"./test.exe", NULL, NULL, FALSE, @@ -106,7 +524,7 @@ int mainCRTStartup() { TerminateProcess(proc_info.hProcess, 1U); return 1U; } - DWORD console_mode = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; + u32 console_mode = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; SetConsoleMode(h_input, console_mode); dbg_loop(); diff --git a/src/parser.c b/src/parser.c index f6dd074..40133a7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -5,8 +5,442 @@ #include "stack_walk.h" #include "disasm.h" +// ======================= +// ====== windows.h ====== +// ======================= + +#define CONTEXT_AMD64 0x00100000L + +#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x00000001L) +#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x00000002L) +#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x00000004L) +#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x00000008L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x00000010L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | \ + CONTEXT_FLOATING_POINT) + +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | \ + CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | \ + CONTEXT_DEBUG_REGISTERS) + +#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) +#define THREAD_SET_CONTEXT (0x0010) +#define THREAD_QUERY_INFORMATION (0x0040) +#define THREAD_SET_INFORMATION (0x0020) +#define THREAD_SET_THREAD_TOKEN (0x0080) +#define THREAD_IMPERSONATE (0x0100) +#define THREAD_DIRECT_IMPERSONATION (0x0200) +#define THREAD_SET_LIMITED_INFORMATION (0x0400) // winnt +#define THREAD_QUERY_LIMITED_INFORMATION (0x0800) // winnt +#define THREAD_RESUME (0x1000) // winnt + +// +// Debug APIs +// +#define EXCEPTION_DEBUG_EVENT 1 +#define CREATE_THREAD_DEBUG_EVENT 2 +#define CREATE_PROCESS_DEBUG_EVENT 3 +#define EXIT_THREAD_DEBUG_EVENT 4 +#define EXIT_PROCESS_DEBUG_EVENT 5 +#define LOAD_DLL_DEBUG_EVENT 6 +#define UNLOAD_DLL_DEBUG_EVENT 7 +#define OUTPUT_DEBUG_STRING_EVENT 8 +#define RIP_EVENT 9 + +typedef u32 (*PTHREAD_START_ROUTINE)(void* lpThreadParameter); +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 +#define SUBLANG_SYS_DEFAULT 0x02 // system default + +#define MAKELANGID(p, s) ((((u16 )(s)) << 10) | (u16 )(p)) +#define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)) + +#define MAKELCID(lgid, srtid) ((u32)((((u32)((u16 )(srtid))) << 16) | \ + ((u32)((u16 )(lgid))))) +#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)) + +// +// Compare String Return Values. +// +#define CSTR_LESS_THAN 1 // string 1 less than string 2 +#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 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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 ====== +// ======================== + extern u8 expect_single_step; -extern DWORD continue_status; +extern u32 continue_status; enum TOKEN_TYPE { // Commands @@ -104,7 +538,7 @@ void lexer(const char* str_cmd, size_t str_cmd_len, struct token* tokens) { for(int i = 0; i < sizeof(commands) / sizeof(commands[0]); i++) { struct command cur_cmd = commands[i]; - if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, cur_cmd.start, cur_cmd.size, cur_token->lexeme, cur_token->size) == CSTR_EQUAL) { + if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, (i8*)cur_cmd.start, cur_cmd.size, (i8*)cur_token->lexeme, cur_token->size) == CSTR_EQUAL) { cur_token->type = i; cur_token++; break; @@ -221,7 +655,7 @@ void run(struct ast_node* root) { CONTEXT ctx = { .ContextFlags = CONTEXT_ALL, }; - HANDLE h_thread = OpenThread( + void* h_thread = OpenThread( THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, FALSE, dbg_event.dwThreadId diff --git a/src/pdb.c b/src/pdb.c index 955e3be..e9bb594 100644 --- a/src/pdb.c +++ b/src/pdb.c @@ -1,9 +1,214 @@ #include "pdb.h" - #include "cvinfo.h" - #include "utils.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 +// + +// +// The FILE_READ_DATA and FILE_WRITE_DATA constants are also defined in +// devioctl.h as FILE_READ_ACCESS and FILE_WRITE_ACCESS. The values for these +// constants *MUST* always be in sync. +// The values are redefined in devioctl.h because they must be available to +// both DOS and NT. +// + +#define FILE_READ_DATA ( 0x0001 ) // file & pipe +#define FILE_LIST_DIRECTORY ( 0x0001 ) // directory + +#define FILE_WRITE_DATA ( 0x0002 ) // file & pipe +#define FILE_ADD_FILE ( 0x0002 ) // directory + +#define FILE_APPEND_DATA ( 0x0004 ) // file +#define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory +#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe + + +#define FILE_READ_EA ( 0x0008 ) // file & directory + +#define FILE_WRITE_EA ( 0x0010 ) // file & directory + +#define FILE_EXECUTE ( 0x0020 ) // file +#define FILE_TRAVERSE ( 0x0020 ) // directory + +#define FILE_DELETE_CHILD ( 0x0040 ) // directory + +#define FILE_READ_ATTRIBUTES ( 0x0080 ) // all + +#define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all + +#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) + +#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ |\ + FILE_READ_DATA |\ + FILE_READ_ATTRIBUTES |\ + FILE_READ_EA |\ + SYNCHRONIZE) + + +#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\ + FILE_WRITE_DATA |\ + FILE_WRITE_ATTRIBUTES |\ + FILE_WRITE_EA |\ + FILE_APPEND_DATA |\ + SYNCHRONIZE) + + +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE |\ + FILE_READ_ATTRIBUTES |\ + FILE_EXECUTE |\ + SYNCHRONIZE) + +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 +#define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000 +#define FILE_ATTRIBUTE_VIRTUAL 0x00010000 +#define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000 +#define FILE_ATTRIBUTE_EA 0x00040000 +#define FILE_ATTRIBUTE_PINNED 0x00080000 +#define FILE_ATTRIBUTE_UNPINNED 0x00100000 +#define FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000 +#define FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000 +#define TREE_CONNECT_ATTRIBUTE_PRIVACY 0x00004000 +#define TREE_CONNECT_ATTRIBUTE_INTEGRITY 0x00008000 +#define TREE_CONNECT_ATTRIBUTE_GLOBAL 0x00000004 +#define TREE_CONNECT_ATTRIBUTE_PINNED 0x00000002 +#define FILE_ATTRIBUTE_STRICTLY_SEQUENTIAL 0x20000000 +#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 +#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 +#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004 +#define FILE_NOTIFY_CHANGE_SIZE 0x00000008 +#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010 +#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020 +#define FILE_NOTIFY_CHANGE_CREATION 0x00000040 +#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100 +#define FILE_ACTION_ADDED 0x00000001 +#define FILE_ACTION_REMOVED 0x00000002 +#define FILE_ACTION_MODIFIED 0x00000003 +#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004 +#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005 +#define MAILSLOT_NO_MESSAGE ((DWORD)-1) +#define MAILSLOT_WAIT_FOREVER ((DWORD)-1) +#define FILE_CASE_SENSITIVE_SEARCH 0x00000001 +#define FILE_CASE_PRESERVED_NAMES 0x00000002 +#define FILE_UNICODE_ON_DISK 0x00000004 +#define FILE_PERSISTENT_ACLS 0x00000008 +#define FILE_FILE_COMPRESSION 0x00000010 +#define FILE_VOLUME_QUOTAS 0x00000020 +#define FILE_SUPPORTS_SPARSE_FILES 0x00000040 +#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080 +#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100 +#define FILE_RETURNS_CLEANUP_RESULT_INFO 0x00000200 +#define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400 +#define FILE_SUPPORTS_BYPASS_IO 0x00000800 +#define FILE_SUPPORTS_STREAM_SNAPSHOTS 0x00001000 +#define FILE_SUPPORTS_CASE_SENSITIVE_DIRS 0x00002000 + +#define FILE_VOLUME_IS_COMPRESSED 0x00008000 +#define FILE_SUPPORTS_OBJECT_IDS 0x00010000 +#define FILE_SUPPORTS_ENCRYPTION 0x00020000 +#define FILE_NAMED_STREAMS 0x00040000 +#define FILE_READ_ONLY_VOLUME 0x00080000 +#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000 +#define FILE_SUPPORTS_TRANSACTIONS 0x00200000 +#define FILE_SUPPORTS_HARD_LINKS 0x00400000 +#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000 +#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000 +#define FILE_SUPPORTS_USN_JOURNAL 0x02000000 +#define FILE_SUPPORTS_INTEGRITY_STREAMS 0x04000000 +#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 +#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 +#define FILE_DAX_VOLUME 0x20000000 +#define FILE_SUPPORTS_GHOSTING 0x40000000 + +#define FILE_INVALID_FILE_ID ((LONGLONG)-1LL) + +// +// These are the generic rights. +// + +#define GENERIC_READ (0x80000000L) +#define GENERIC_WRITE (0x40000000L) +#define GENERIC_EXECUTE (0x20000000L) +#define GENERIC_ALL (0x10000000L) + +#define FILE_BEGIN 0 +#define FILE_CURRENT 1 +#define FILE_END 2 + +// +// Constants +// +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + +#define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + +// +// Constants +// +#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 ====== +// ======================== + enum STREAM_INDEX { OLD_DIRECTORY, PDB, @@ -15,8 +220,8 @@ enum STREAM_INDEX { extern u8* string_stack_base; extern u8* string_stack_current; -void open_pdb(const char* pdb_path, struct module* module) { - HANDLE pdb_file = CreateFileA(pdb_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +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); if (pdb_file == INVALID_HANDLE_VALUE) { print("Cannot open pdb file at path %s due to error %u\n", pdb_path, GetLastError()); @@ -36,12 +241,12 @@ void open_pdb(const char* pdb_path, struct module* module) { struct msf_superblock superblock = { 0U }; u8 block[4096U] = { 0U }; u32 b_read = 0U; - ReadFile(pdb_file, (void*)&superblock, sizeof(superblock), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&superblock, sizeof(superblock), &b_read, NULL); // 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, (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)block, superblock.num_directory_bytes, &b_read, NULL); // Loog through streams u32 num_streams = ((u32*)block)[0U]; @@ -79,7 +284,7 @@ void open_pdb(const char* pdb_path, struct module* module) { struct pdb_info_stream pdb_info_stream = { 0U }; SetFilePointer(pdb_file, stream_blocks_indices[PDB][0U] * sizeof(block), NULL, FILE_BEGIN); - ReadFile(pdb_file, (void*)&pdb_info_stream, sizeof(pdb_info_stream), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&pdb_info_stream, sizeof(pdb_info_stream), &b_read, NULL); // DBI Stream struct DBI_stream_header { @@ -133,7 +338,7 @@ void open_pdb(const char* pdb_path, struct module* module) { u8* obj_files_name[64U] = { 0U }; u8 DBI_block[4096U] = { 0U }; SetFilePointer(pdb_file, stream_blocks_indices[DBI][0U] * sizeof(block), NULL, FILE_BEGIN); - ReadFile(pdb_file, (void*)&DBI_block, sizeof(DBI_block), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&DBI_block, sizeof(DBI_block), &b_read, NULL); struct DBI_stream_header* DBI_stream_header = (struct DBI_stream_header*)DBI_block; // Read Module Info Substreams @@ -157,7 +362,7 @@ void open_pdb(const char* pdb_path, struct module* module) { // Read curren Module Info Stream u8 module_info_block[4096U] = { 0U }; SetFilePointer(pdb_file, stream_blocks_indices[modules_info[module_index]->ModuleSymStream][0U] * sizeof(module_info_block), NULL, FILE_BEGIN); - ReadFile(pdb_file, (void*)&module_info_block, sizeof(module_info_block), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&module_info_block, sizeof(module_info_block), &b_read, NULL); u8* symbols = &module_info_block[4U]; u8* cur_sym = symbols; @@ -231,11 +436,11 @@ void open_pdb(const char* pdb_path, struct module* module) { // Global Symbol Stream SetFilePointer(pdb_file, stream_blocks_indices[DBI_stream_header->global_stream_index][0U] * sizeof(block), NULL, FILE_BEGIN); - ReadFile(pdb_file, (void*)&block, sizeof(DBI_stream_header), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&block, sizeof(DBI_stream_header), &b_read, NULL); // Public Symbol Stream SetFilePointer(pdb_file, stream_blocks_indices[DBI_stream_header->public_stream_index][0U] * sizeof(block), NULL, FILE_BEGIN); - ReadFile(pdb_file, (void*)&block, sizeof(block), (LPDWORD)&b_read, NULL); + ReadFile(pdb_file, (void*)&block, sizeof(block), &b_read, NULL); CloseHandle(pdb_file); } diff --git a/src/stack_walk.c b/src/stack_walk.c index cc030b2..cbb6464 100644 --- a/src/stack_walk.c +++ b/src/stack_walk.c @@ -1,10 +1,289 @@ #include "stack_walk.h" -#include - #include "module.h" #include "utils.h" +// ======================= +// ====== windows.h ====== +// ======================= + +#define CONTEXT_AMD64 0x00100000L + +#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x00000001L) +#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x00000002L) +#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x00000004L) +#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x00000008L) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x00000010L) + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | \ + CONTEXT_FLOATING_POINT) + +#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | \ + CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | \ + CONTEXT_DEBUG_REGISTERS) + +#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 +#define PAGE_WRITECOPY 0x08 +#define PAGE_EXECUTE 0x10 +#define PAGE_EXECUTE_READ 0x20 +#define PAGE_EXECUTE_READWRITE 0x40 +#define PAGE_EXECUTE_WRITECOPY 0x80 +#define PAGE_GUARD 0x100 +#define PAGE_NOCACHE 0x200 +#define PAGE_WRITECOMBINE 0x400 +#define PAGE_GRAPHICS_NOACCESS 0x0800 +#define PAGE_GRAPHICS_READONLY 0x1000 +#define PAGE_GRAPHICS_READWRITE 0x2000 +#define PAGE_GRAPHICS_EXECUTE 0x4000 +#define PAGE_GRAPHICS_EXECUTE_READ 0x8000 +#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x10000 +#define PAGE_GRAPHICS_COHERENT 0x20000 +#define PAGE_GRAPHICS_NOCACHE 0x40000 +#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000 +#define PAGE_REVERT_TO_FILE_MAP 0x80000000 +#define PAGE_TARGETS_NO_UPDATE 0x40000000 +#define PAGE_TARGETS_INVALID 0x40000000 +#define PAGE_ENCLAVE_UNVALIDATED 0x20000000 +#define PAGE_ENCLAVE_MASK 0x10000000 +#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0) +#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1) +#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2) +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_REPLACE_PLACEHOLDER 0x00004000 +#define MEM_RESERVE_PLACEHOLDER 0x00040000 +#define MEM_RESET 0x00080000 +#define MEM_TOP_DOWN 0x00100000 +#define MEM_WRITE_WATCH 0x00200000 +#define MEM_PHYSICAL 0x00400000 +#define MEM_ROTATE 0x00800000 +#define MEM_DIFFERENT_IMAGE_BASE_OK 0x00800000 +#define MEM_RESET_UNDO 0x01000000 +#define MEM_LARGE_PAGES 0x20000000 +#define MEM_4MB_PAGES 0x80000000 +#define MEM_64K_PAGES (MEM_LARGE_PAGES | MEM_PHYSICAL) +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 0x00000001 +#define MEM_COALESCE_PLACEHOLDERS 0x00000001 +#define MEM_PRESERVE_PLACEHOLDER 0x00000002 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#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 ====== +// ======================== + // enum UNWIND_INFO_FLAGS { // UNW_FLAG_EHANDLER, // UNW_FLAG_UHANDLER, diff --git a/src/utils.c b/src/utils.c index 729b74d..d512238 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,52 @@ #include "utils.h" -#include +// ======================= +// ====== 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 _MSC_VER + #define va_start(ap, x) ((void)(__va_start(&ap, x))) + #define va_arg(ap, t) \ + ((sizeof(t) > sizeof(__int64) || (sizeof(t) & (sizeof(t) - 1)) != 0) \ + ? **(t**)((ap += sizeof(__int64)) - sizeof(__int64)) \ + : *(t* )((ap += sizeof(__int64)) - sizeof(__int64))) + #define va_end(ap) ((void)(ap = (va_list)0)) +#endif + +#define STD_INPUT_HANDLE ((u32)-10) +#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 ====== +// ======================== u8 is_alpha(char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); @@ -211,8 +257,8 @@ void print(const char* format, ...) { cur_char += str_len; } else if(*cur_fmt == 'b') { - u8 number = va_arg(args, u8); - u32 str_len = 8U - __lzcnt(number); + u64 number = va_arg(args, u64); + u32 str_len = 64U - __lzcnt(number); i64 relative_fill_count = fill_count - str_len; if (relative_fill_count > 1) { @@ -283,7 +329,7 @@ void print(const char* format, ...) { } va_end(args); - HANDLE standard_err = GetStdHandle(STD_ERROR_HANDLE); + void* standard_err = GetStdHandle(STD_ERROR_HANDLE); SUCCEEDED(WriteFile(standard_err, formatted_str, (u32)(cur_char - formatted_str), NULL, NULL)); } @@ -292,7 +338,7 @@ u8 read_memory(const void* addr, void* buffer, size_t size) { extern PROCESS_INFORMATION proc_info; size_t b_read = 0U; - HRESULT hr = ReadProcessMemory(proc_info.hProcess, addr, buffer, size, &b_read); + i32 hr = ReadProcessMemory(proc_info.hProcess, addr, buffer, size, &b_read); return hr > 0 && b_read == size; } -- cgit v1.3