summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/disasm.c70
-rw-r--r--src/events.c389
-rw-r--r--src/hashmap.c70
-rw-r--r--src/main.c442
-rw-r--r--src/parser.c440
-rw-r--r--src/pdb.c227
-rw-r--r--src/stack_walk.c283
-rw-r--r--src/utils.c56
8 files changed, 1925 insertions, 52 deletions
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 <Windows.h>
-
#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 <Windows.h>
-
#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 <Windows.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 ======
+// ========================
+
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 <Windows.h>
-
#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 <Windows.h>
-
#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>
+// =======================
+// ====== 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;
}