diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2026-07-12 00:47:54 +0200 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2026-07-12 00:47:54 +0200 |
| commit | 7b6964eb1bcf30a0ae7ed3391adce30565b262b4 (patch) | |
| tree | 3bbf89d582a1466a2319ccaaf6d4cbb734bdd66b | |
| parent | ce51256c91e566d339c6a670af11bab519f98349 (diff) | |
Load functions by hand
| -rw-r--r-- | build.bat | 27 | ||||
| -rw-r--r-- | include/cvinfo.h | 6 | ||||
| -rw-r--r-- | include/events.h | 18 | ||||
| -rw-r--r-- | include/funcs.h | 35 | ||||
| -rw-r--r-- | include/hashmap.h | 2 | ||||
| -rw-r--r-- | include/module.h | 2 | ||||
| -rw-r--r-- | include/utils.h | 3 | ||||
| -rw-r--r-- | include/win_funcs.h | 401 | ||||
| -rw-r--r-- | src/disasm.c | 86 | ||||
| -rw-r--r-- | src/events.c | 284 | ||||
| -rw-r--r-- | src/hashmap.c | 2 | ||||
| -rw-r--r-- | src/loader.c | 235 | ||||
| -rw-r--r-- | src/main.c | 320 | ||||
| -rw-r--r-- | src/module.c | 6 | ||||
| -rw-r--r-- | src/pdb.c | 8 | ||||
| -rw-r--r-- | src/stack_walk.c | 1 | ||||
| -rw-r--r-- | src/test.c | 4 | ||||
| -rw-r--r-- | src/utils.c | 12 |
18 files changed, 1073 insertions, 379 deletions
@@ -26,31 +26,36 @@ if EXIST %VS2022_PRO% ( :compilation REM set C_FLAGS=/DHASHMAP /nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /std:c17 /c /Tc -set C_FLAGS=/nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /std:clatest /c /Tc +REM set C_FLAGS=/nologo /W4 /WX /Zi /GS- /GR- /Gs1000000000 /Fo:%BUILD_DIR%\ /Iinclude /Isrc /std:clatest /c /Tc +set C_FLAGS=-fno-builtin -nostdlib -mno-stack-arg-probe --target=x86_64-pc-windows-msvc -Wall -Werror -pedantic -I include -std=c23 -Wno-msvc-not-found -Wno-microsoft-anon-tag -Wno-gnu-binary-literal -g -O0 -c REM set L_FLAGS=/WX /SUBSYSTEM:CONSOLE /NODEFAULTLIB /stack:0x100000,100000 -set L_FLAGS=/WX /SUBSYSTEM:CONSOLE /NODEFAULTLIB +set L_FLAGS=/WX /SUBSYSTEM:CONSOLE /NODEFAULTLIB /DEBUG -if "%release%"=="0" ( - set C_FLAGS=/Od %C_FLAGS% - set L_FLAGS=/DEBUG %L_FLAGS% -) +REM if "%release%"=="0" ( +REM set C_FLAGS=/Od %C_FLAGS% +REM set L_FLAGS=/DEBUG %L_FLAGS% +REM ) -set src=main utils events module parser pdb hashmap stack_walk disasm +set src=main utils events module parser pdb hashmap stack_walk disasm loader :: DBG :: Compile (for %%s in (%src%) do ( call set OBJS=%%OBJS%% %BUILD_DIR%\%%s.obj - cl /Fd:%BUILD_DIR%\%%s.pdb %C_FLAGS% src\%%s.c + clang -o %BUILD_DIR%\%%s.obj %C_FLAGS% src\%%s.c )) +:: cl /Fd:%BUILD_DIR%\%%s.pdb %C_FLAGS% src\%%s.c :: Link -link %L_FLAGS% /OUT:%BUILD_DIR%\main.exe %OBJS% kernel32.lib +REM link %L_FLAGS% /OUT:%BUILD_DIR%\main.exe %OBJS% kernel32.lib +lld-link %L_FLAGS% /OUT:%BUILD_DIR%\main.exe %OBJS% :: Test program set SRC_FILE=test :: Compile -cl /Fd:%BUILD_DIR%\%SRC_FILE%.pdb %C_FLAGS% src/%SRC_FILE%.c +REM cl /Fd:%BUILD_DIR%\%SRC_FILE%.pdb %C_FLAGS% src/%SRC_FILE%.c +:: clang -o %BUILD_DIR%\%SRC_FILE%.obj %C_FLAGS% src/%SRC_FILE%.c :: Link -link %L_FLAGS% %BUILD_DIR%\%SRC_FILE%.obj /OUT:%BUILD_DIR%\%SRC_FILE%.exe kernel32.lib +REM link %L_FLAGS% %BUILD_DIR%\%SRC_FILE%.obj /OUT:%BUILD_DIR%\%SRC_FILE%.exe kernel32.lib +:: lld-link %L_FLAGS% %BUILD_DIR%\%SRC_FILE%.obj %BUILD_DIR%\loader.obj /OUT:%BUILD_DIR%\%SRC_FILE%.exe diff --git a/include/cvinfo.h b/include/cvinfo.h index efbf706..0f55ead 100644 --- a/include/cvinfo.h +++ b/include/cvinfo.h @@ -1173,7 +1173,7 @@ typedef struct TYPTYPE { unsigned char data[CV_ZEROLEN]; } TYPTYPE; // general types record -__INLINE char *NextType ( _In_ char * pType) { +__INLINE char *NextType ( char * pType) { return (pType + ((TYPTYPE *)pType)->len + sizeof(unsigned short)); } @@ -4389,7 +4389,7 @@ typedef struct POGOINFO { unsigned short rectyp; // S_POGODATA unsigned long invocations; // Number of times function was called - __int64 dynCount; // Dynamic instruction count + i64 dynCount; // Dynamic instruction count unsigned long numInstrs; // Static instruction count unsigned long staInstLive; // Final static instruction count (post inlining) } POGOINFO; @@ -4568,7 +4568,7 @@ typedef struct PDBMAP { // V7 line number data types // -enum DEBUG_S_SUBSECTION_TYPE { +enum DEBUG_S_SUBSECTION_TYPE : i64 { DEBUG_S_IGNORE = 0x80000000, // if this bit is set in a subsection type then ignore the subsection contents DEBUG_S_SYMBOLS = 0xf1, diff --git a/include/events.h b/include/events.h index 65131c6..1055f84 100644 --- a/include/events.h +++ b/include/events.h @@ -1,19 +1,19 @@ #pragma once -extern void handle_create_process(); +extern void handle_create_process(void); -extern void handle_create_thread(); +extern void handle_create_thread(void); -extern void handle_exception(); +extern void handle_exception(void); -extern void handle_exit_process(); +extern void handle_exit_process(void); -extern void handle_exit_thread(); +extern void handle_exit_thread(void); -extern void handle_load_dll(); +extern void handle_load_dll(void); -extern void handle_unload_dll(); +extern void handle_unload_dll(void); -extern void handle_output_debug_string(); +extern void handle_output_debug_string(void); -extern void handle_rip(); +extern void handle_rip(void); diff --git a/include/funcs.h b/include/funcs.h new file mode 100644 index 0000000..7661539 --- /dev/null +++ b/include/funcs.h @@ -0,0 +1,35 @@ +KERNEL_BASE(VirtualAlloc) +KERNEL_BASE(VirtualFree) + +KERNEL32(CreateProcessA) +KERNEL32(OpenProcess) +KERNEL32(TerminateProcess) + +KERNEL32(OpenThread) +KERNEL32(GetThreadContext) +KERNEL32(SetThreadContext) + +KERNEL32(CreateFileA) +KERNEL32(ReadFile) +KERNEL32(WriteFile) +KERNEL32(SetFilePointer) +KERNEL32(GetStdHandle) +KERNEL32(GetLastError) + +KERNEL32(SetConsoleMode) +KERNEL32(ReadConsoleA) +KERNEL32(WriteConsoleA) + +KERNEL32(ReadProcessMemory) +KERNEL32(OutputDebugStringA) +KERNEL32(ContinueDebugEvent) +KERNEL32(WaitForDebugEventEx) + +KERNEL32(WideCharToMultiByte) +KERNEL32(GetFinalPathNameByHandleA) +KERNEL32(CompareStringA) + +KERNEL32(CloseHandle) + +KERNEL32(memset) +KERNEL32(memcpy) diff --git a/include/hashmap.h b/include/hashmap.h index 88490e7..7053419 100644 --- a/include/hashmap.h +++ b/include/hashmap.h @@ -17,7 +17,7 @@ struct hashmap { struct element* arr; }; -extern struct hashmap create_unordered_flat(); +extern struct hashmap create_unordered_flat(void); extern struct element* insert_elem(struct hashmap* map, u32 start, u32 end, u64 name); diff --git a/include/module.h b/include/module.h index 89a2d8c..f61437e 100644 --- a/include/module.h +++ b/include/module.h @@ -141,7 +141,7 @@ struct module { extern struct module modules[64U]; extern u64 modules_list; -extern u8 add_module(); +extern u8 add_module(void); extern void remove_module(u8 index); diff --git a/include/utils.h b/include/utils.h index d93d2bb..24083cf 100644 --- a/include/utils.h +++ b/include/utils.h @@ -5,9 +5,10 @@ #if defined (_DEBUG) #define assert(x) if (!(x)) __debugbreak(); #else -#define assert(x) (x) +#define assert(x) ((void)((x) ? 1 : 0)) #endif +#define NULL 0 #define TRUE 1 #define FALSE 0 diff --git a/include/win_funcs.h b/include/win_funcs.h new file mode 100644 index 0000000..9ea4510 --- /dev/null +++ b/include/win_funcs.h @@ -0,0 +1,401 @@ +#pragma once + +#include "types.h" + +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; + + +typedef struct _CONSOLE_READCONSOLE_CONTROL { + u32 nLength; + u32 nInitialChars; + u32 dwCtrlWakeupMask; + u32 dwControlKeyState; +} CONSOLE_READCONSOLE_CONTROL, *PCONSOLE_READCONSOLE_CONTROL; + +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; + +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 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; +typedef PCONTEXT LPCONTEXT; + +// ======================= +// ====== Funcs PFN ====== +// ======================= +typedef void*(*PFN_VirtualAlloc)(void*, u64, u32, u32); +typedef i32(*PFN_VirtualFree)(void*, size_t, u32); + +typedef i32(*PFN_CreateProcessA)(const i8*, i8*, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, i32, u32, void*, const i8*, LPSTARTUPINFOA, LPPROCESS_INFORMATION); +typedef void*(*PFN_OpenProcess)(u32, i32, u32); +typedef i32(*PFN_TerminateProcess)(void*, u32); + +typedef void*(*PFN_OpenThread)(u32, i32, u32); +typedef i32(*PFN_GetThreadContext)(void*, LPCONTEXT); +typedef i32(*PFN_SetThreadContext)(void*, const CONTEXT*); + +typedef void*(*PFN_CreateFileA)(const i8*, u32, u32, LPSECURITY_ATTRIBUTES, u32, u32, void*); +typedef i32(*PFN_ReadFile)(void*, void*, u32, u32*, LPOVERLAPPED); +typedef u32(*PFN_SetFilePointer)(void*, i32, i32*, u32); +typedef i32(*PFN_WriteFile)(void*, const void*, u32, u32*, LPOVERLAPPED); +typedef void*(*PFN_GetStdHandle)(u32); +typedef u32(*PFN_GetLastError)(void); + +typedef i32(*PFN_SetConsoleMode)(void*, u32); +typedef i32(*PFN_ReadConsoleA)(void*, void*, u32, u32*, PCONSOLE_READCONSOLE_CONTROL); +typedef i32(*PFN_WriteConsoleA)(void*, const void*, u32, u32*, void*); + +typedef i32(*PFN_ReadProcessMemory)(void*, const void*, void*, size_t, size_t*); +typedef i32(*PFN_OutputDebugStringA)(const char*); +typedef i32(*PFN_ContinueDebugEvent)(u32, u32, u32); +typedef i32(*PFN_WaitForDebugEventEx)(LPDEBUG_EVENT, u32); + + +typedef i32(*PFN_CompareStringA)(u32, u32, const i8*, i32, const i8*, i32); +typedef i32(*PFN_WideCharToMultiByte)(u32, u32, const u16*, i32, i8*, i32, i8*, i32*); +typedef u32(*PFN_GetFinalPathNameByHandleA)(void*, i8*, u32, u32); + +typedef i32(*PFN_CloseHandle)(void*); + +typedef i32(*PFN_memset)(void*, void*, size_t, char); +typedef i32(*PFN_memcpy)(void*, void*, size_t); + +// ========================== +// ====== Funcs extern ====== +// ========================== +#define KERNEL32(name) \ + extern PFN_##name name; +#define KERNEL_BASE(name) \ + extern PFN_##name name; + +#include "funcs.h" + +#undef KERNEL_BASE +#undef KERNEL32 diff --git a/src/disasm.c b/src/disasm.c index 6e425fb..6cceb53 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -197,7 +197,7 @@ const struct opcode primary_opcode_map[256U] = { { "OR", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // AL, need to understand and handle { "OR", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, { "PUSH", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO - {}, // Escape to secondary op code map + { "INVALID", { .src = None }, { .src = None }}, // Escape to secondary op code map { "ADC", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, { "ADC", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, { "ADC", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, @@ -284,49 +284,49 @@ const struct opcode primary_opcode_map[256U] = { { "ARPL", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "seg", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "seg", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Operand size overide prefix - {}, // Address size override prefix + { "INVALID", { .src = None }, { .src = None }}, // Operand size overide prefix + { "INVALID", { .src = None }, { .src = None }}, // Address size override prefix { "PUSH", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "IMUL", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "PUSH", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, // TODO { "IMUL", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "INSB", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "INSB", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "INSW/D", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "OUTS/B", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "OUTS/B", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "OUTS/W/D", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "JO", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "JNO", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "JB", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, // TODO { "JNB", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "JZ", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "JZ", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "JNZ", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "JBE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "JBE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "JNBE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "JS", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "JNS", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "JP", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, // TODO { "JNP", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "JL", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "JL", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "JNL", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "JLE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "JLE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "JNLE", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 1 Opcode - {}, // Group 1 Opcode - {}, // Group 1 Opcode - {}, // Group 1 Opcode - { "TEST", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "INVALID", { .src = None }, { .src = None }}, // Group 1 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 1 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 1 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 1 Opcode + { "TEST", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "TEST", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "MOV", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "MOV", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "MOV", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, // TODO { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "LEA", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO - {}, // Group 1 Opcode - { "NOP", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO + { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "INVALID", { .src = None }, { .src = None }}, // Group 1 Opcode + { "NOP", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "XCHG", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO @@ -374,38 +374,38 @@ const struct opcode primary_opcode_map[256U] = { { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "MOV", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 2 opcode - {}, // Group 2 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 opcode { "RET", { .src = ModRM_Reg, .type = TYPE_BYTE }, { .src = TYPE_E, .type = TYPE_BYTE }}, // TODO { "RET", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - { "LES", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO + { "LES", { .src = ModRM_Reg, .type = TYPE_v }, { .src = Imm, .type = TYPE_BYTE }}, // TODO { "LDS", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 11 opcode - {}, // Group 11 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 11 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 11 opcode { "ENTER", { .src = ModRM_Reg, .type = TYPE_WORD }, { .src = Imm, .type = TYPE_BYTE }}, { "LEAVE", { .src = None }, { .src = None }}, { "RET far", { .src = Imm, .type = TYPE_WORD }, { .src = None }}, { "RET far", { .src = None }, { .src = None }}, { "INT 3", { .src = None }, { .src = None }}, { "INT", { .src = Imm, .type = TYPE_BYTE }, { .src = None }}, - { "INTO", { .src = None }, { .src = None }}, // Invalid in 64bit mode + { "INTO", { .src = None }, { .src = None }}, // Invalid in 64bit mode { "IRET/D/Q", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 2 Opcode - {}, // Group 2 Opcode - {}, // Group 2 Opcode - {}, // Group 2 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 Opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 2 Opcode { "AAM", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "AAD", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO - {}, // invalid + { "INVALID", { .src = None }, { .src = None }}, // invalid { "XLAT", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions - {}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions + { "INVALID", { .src = None }, { .src = None }}, // TODO x87 instructions { "LOOPNE/NZ", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "LOOPE/Z", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "LOOP", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO @@ -428,16 +428,16 @@ const struct opcode primary_opcode_map[256U] = { { "REP/E", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "HLT", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "CMC", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 3 opcode - {}, // Group 3 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 3 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 3 opcode { "CLC", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "STC", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "CLI", { .src = TYPE_E, .type = TYPE_BYTE }, { .src = ModRM_Reg, .type = TYPE_BYTE }}, // TODO { "STI", { .src = TYPE_E, .type = TYPE_v}, { .src = ModRM_Reg, .type = TYPE_v }}, // TODO { "CLD", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO { "STD", { .src = ModRM_Reg, .type = TYPE_v }, { .src = TYPE_E, .type = TYPE_v }}, // TODO - {}, // Group 4 opcode - {}, // Group 5 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 4 opcode + { "INVALID", { .src = None }, { .src = None }}, // Group 5 opcode }; // TODO: Think about a smart way to retrieve groups opcodes @@ -721,8 +721,10 @@ void unassemble(u8* start, u64 size) { u8 legacy_prefixes_count = 0U; u8 effective_operand_size = 32U; // 32 by default in 64bit mode i32 effective_address = -1; + (void)effective_address; // Not used yet u8 operand_size_override_66 = FALSE; u8 operand_size_override_REX = FALSE; + (void)operand_size_override_REX; // Not used yet u8 REX = 0U; while (is_legacy_prefix(*current_byte) && legacy_prefixes_count < MAX_LEGACY_PREFIXES) { if (*current_byte == 0x66) { // Override effective operand size diff --git a/src/events.c b/src/events.c index 1886617..fd96966 100644 --- a/src/events.c +++ b/src/events.c @@ -114,68 +114,68 @@ typedef struct _DEBUG_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) +#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 @@ -276,84 +276,84 @@ extern u32 GetLastError(void); #define CP_UTF7 65000 // UTF-7 translation #define CP_UTF8 65001 // UTF-8 translation -extern i32 WideCharToMultiByte(u32 CodePage, u32 dwFlags, const u16* lpWideCharStr, i32 cchWideChar, i8* lpMultiByteStr, i32 cbMultiByte, const i8* lpDefaultChar, i32* lpUsedDefaultChar); +extern i32 WideCharToMultiByte(u32 CodePage, u32 dwFlags, const u16* lpWideCharStr, i32 cchWideChar, i8* lpMultiByteStr, i32 cbMultiByte, i8* lpDefaultChar, i32* lpUsedDefaultChar); extern u32 GetFinalPathNameByHandleA(void* hFile, i8* lpszFilePath, u32 cchFilePath, u32 dwFlags); -#define PAGE_NOACCESS 0x01 -#define PAGE_READONLY 0x02 -#define PAGE_READWRITE 0x04 -#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 +#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) +#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); @@ -707,7 +707,7 @@ void load_symbols(const void* base_addr, struct module* module) { VirtualFree(exception_table, exception_entry.Size, MEM_RELEASE); } -void handle_create_process() { +void handle_create_process(void) { print("%s\n", "CreateProcessDebugEvent"); CREATE_PROCESS_DEBUG_INFO proc_dbg_info = dbg_event.u.CreateProcessInfo; @@ -728,11 +728,11 @@ void handle_create_process() { load_symbols((const void*)proc_dbg_info.lpBaseOfImage, module); } -void handle_create_thread() { +void handle_create_thread(void) { print("%s\n", "CreateThreadDebugEvent"); } -void handle_exception() { +void handle_exception(void) { extern u32 continue_status; print("%s : ", "ExceptionDebugEvent"); @@ -749,16 +749,16 @@ void handle_exception() { } } -void handle_exit_process() { +void handle_exit_process(void) { print("%s\n", "ExitProcessDebugEvent"); TerminateProcess(NULL, 0U); } -void handle_exit_thread() { +void handle_exit_thread(void) { print("%s\n", "ExitThreadDebugEvent"); } -void handle_load_dll() { +void handle_load_dll(void) { LOAD_DLL_DEBUG_INFO dll_info = dbg_event.u.LoadDll; const void* dll_name_addr = dll_info.lpImageName; void* dll_base_addr = dll_info.lpBaseOfDll; @@ -776,11 +776,11 @@ void handle_load_dll() { load_symbols(dll_base_addr, module); } -void handle_unload_dll() { +void handle_unload_dll(void) { print("%s\n", "UnloadDLLDebugEvent"); } -void handle_output_debug_string() { +void handle_output_debug_string(void) { OUTPUT_DEBUG_STRING_INFO dbg_str_event = dbg_event.u.DebugString; char* str_addr = dbg_str_event.lpDebugStringData; size_t str_size = (size_t)dbg_str_event.nDebugStringLength; @@ -808,6 +808,6 @@ void handle_output_debug_string() { } } -void handle_rip() { +void handle_rip(void) { print("%s\n", "RIPEvent"); } diff --git a/src/hashmap.c b/src/hashmap.c index a218f26..8362736 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -87,7 +87,7 @@ void resize(struct hashmap* map) { } } -struct hashmap create_unordered_flat() { +struct hashmap create_unordered_flat(void) { struct hashmap map = { .capacity = initial_size / sizeof(struct element), .size = 0U, diff --git a/src/loader.c b/src/loader.c new file mode 100644 index 0000000..da98364 --- /dev/null +++ b/src/loader.c @@ -0,0 +1,235 @@ +#include "win_funcs.h" +#include "module.h" +#include "utils.h" + +// ======================= +// ====== windows.h ====== +// ======================= + +extern uint64_t __readgsqword(unsigned long offset); + +typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; +} LIST_ENTRY, *PLIST_ENTRY, *PRLIST_ENTRY; + +typedef struct _UNICODE_STRING { + u16 Length; + u16 MaximumLength; + u16* Buffer; +} UNICODE_STRING, *PUNICODE_STRING; + +typedef struct _LDR_DATA_TABLE_ENTRY { + void* Reserved1[2]; + LIST_ENTRY InMemoryOrderLinks; + void* Reserved2[2]; + void* DllBase; + void* Reserved3[2]; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + void* Reserved5[2]; + union + { + u32 CheckSum; + void* Reserved6; + }; + u32 TimeDateStamp; +} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + +typedef struct _PEB_LDR_DATA { + u8 Reserved1[8]; + void* Reserved2[3]; + LIST_ENTRY InMemoryOrderModuleList; +} PEB_LDR_DATA, *PPEB_LDR_DATA; + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + u8 Reserved1[16]; + void* Reserved2[10]; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +typedef void(*PS_POST_PROCESS_INIT_ROUTINE)(void); +typedef PS_POST_PROCESS_INIT_ROUTINE* PPS_POST_PROCESS_INIT_ROUTINE; + +typedef struct _PEB { + u8 Reserved1[2]; + u8 BeingDebugged; + u8 Reserved2[21]; + PPEB_LDR_DATA LoaderData; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + u8 Reserved3[520]; + PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; + u8 Reserved4[136]; + u32 SessionId; +} PEB, *PPEB; + +typedef struct _TEB { + void* Reserved1[12]; + PPEB ProcessEnvironmentBlock; + void* Reserved2[399]; + u8 Reserved3[1952]; + void* TlsSlots[64]; + u8 Reserved4[8]; + void* Reserved5[26]; + void* ReservedForOle; + void* Reserved6[4]; + void* TlsExpansionSlots; +} TEB, *PTEB; + +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; + +// +// 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 + +// ======================== +// ====== !windows.h ====== +// ======================== + +#define KERNEL32(name) \ + PFN_##name name = NULL; + +#define KERNEL_BASE(name) \ + PFN_##name name = NULL; + +#include "funcs.h" + +#undef KERNEL_BASE +#undef KERNEL32 + +i32 str_cmp(const i8* str1, size_t str1_len, const i8* str2, size_t str2_len) { + u32 min_len = str1_len < str2_len ? str1_len : str2_len; + + for (u32 index = 0U; index < min_len; index++) { + if (str1[index] < str2[index]) { + return -1; + } else if (str1[index] > str2[index]) { + return 1; + } + } + + return 0; +} + +i32 wstr_cmp(const u16* str1, size_t str1_len, const u16* str2, size_t str2_len) { + u32 min_len = str1_len < str2_len ? str1_len : str2_len; + + for (u32 index = 0U; index < min_len; index++) { + if (str1[index] < str2[index]) { + return -1; + } else if (str1[index] > str2[index]) { + return 1; + } + } + + return 0; +} + +PEB* get_PEB(void) { + return (PEB*)__readgsqword(__builtin_offsetof(TEB, ProcessEnvironmentBlock)); +} + +void* get_kernel32(void) { + const u16 kernel32_str[] = L"KERNEL32.DLL"; + PEB* PEB = get_PEB(); + LIST_ENTRY* last_entry = PEB->LoaderData->InMemoryOrderModuleList.Blink; + LIST_ENTRY* cur_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink; + + while(cur_entry != last_entry) { + LDR_DATA_TABLE_ENTRY* table_entry = (LDR_DATA_TABLE_ENTRY*)((u8*)cur_entry - 0x10); + UNICODE_STRING* BaseDllName = &table_entry->BaseDllName; + + if (BaseDllName->Buffer) { + if (wstr_cmp(kernel32_str, sizeof(kernel32_str) / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { + return table_entry->DllBase; + } + } + + cur_entry = cur_entry->Flink; + } + + return NULL; +} + +void* get_kernel_base(void) { + const u16 kernel32_str[] = L"KERNELBASE.dll"; + PEB* PEB = get_PEB(); + LIST_ENTRY* last_entry = PEB->LoaderData->InMemoryOrderModuleList.Blink; + LIST_ENTRY* cur_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink; + + while(cur_entry != last_entry) { + LDR_DATA_TABLE_ENTRY* table_entry = (LDR_DATA_TABLE_ENTRY*)((u8*)cur_entry - 0x10); + UNICODE_STRING* BaseDllName = &table_entry->BaseDllName; + + if (BaseDllName->Buffer) { + if (wstr_cmp(kernel32_str, sizeof(kernel32_str) / sizeof(u16), BaseDllName->Buffer, BaseDllName->Length / sizeof(u16)) == 0) { + return table_entry->DllBase; + } + } + + cur_entry = cur_entry->Flink; + } + + return NULL; +} + +void* load_func(u64 base_addr, const char* func_name, u32 func_name_len) { + IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)base_addr; + IMAGE_NT_HEADERS64* nt_header = (IMAGE_NT_HEADERS64*)(base_addr + dos_header->e_lfanew); + IMAGE_DATA_DIRECTORY export_table = nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + const IMAGE_EXPORT_DIRECTORY* export_dir = (const IMAGE_EXPORT_DIRECTORY*)(base_addr + export_table.VirtualAddress); + + u16* ordinals = (u16*)(base_addr + export_dir->AddressOfNameOrdinals); + u32* names_address = (u32*)(base_addr + export_dir->AddressOfNames); + u32* addresses = (u32*)(base_addr + export_dir->AddressOfFunctions); + + for (u32 name_index = 0U; name_index < export_dir->NumberOfNames; name_index++) { + const char* name = (const char*)(base_addr + names_address[name_index]); + u32 length = str_len(name, 256U); + + if (str_cmp((i8*)name, length, (i8*)func_name, func_name_len) == 0) { + return (void*)(base_addr + addresses[ordinals[name_index]]); + } + } + + return NULL; +} + +void load_funcs(void) { + void* kernel32 = get_kernel32(); + void* kernel_base = get_kernel_base(); + +#define KERNEL32(name) \ + name = (PFN_##name)load_func((u64)kernel32, #name, sizeof(#name)); + +#define KERNEL_BASE(name) \ + name = (PFN_##name)load_func((u64)kernel_base, #name, sizeof(#name)); + +#include "funcs.h" + +#undef KERNEL_BASE +#undef KERNEL32 + +} @@ -4,6 +4,8 @@ #include "events.h" #include "parser.h" +#include "win_funcs.h" + // ======================= // ====== windows.h ====== // ======================= @@ -120,98 +122,98 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; // 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 _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; -typedef struct _OUTPUT_DEBUG_STRING_INFO { - char* lpDebugStringData; - u16 fUnicode; - u16 nDebugStringLength; -} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO; +// extern i32 WaitForDebugEventEx(LPDEBUG_EVENT lpDebugEvent, u32 dwMilliseconds); -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; +// 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 @@ -270,41 +272,41 @@ typedef struct _PROCESS_INFORMATION { #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* VirtualAlloc(void* lpAddress, u64 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; +// extern void* GetStdHandle(u32 nStdHandle); -typedef struct _SECURITY_ATTRIBUTES { - u32 nLength; - void* lpSecurityDescriptor; - i32 bInheritHandle; -} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; +// 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 @@ -355,20 +357,20 @@ typedef struct _SECURITY_ATTRIBUTES { //#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); +// 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: @@ -395,36 +397,36 @@ extern i32 TerminateProcess(void* hProcess, u32 uExitCode); #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 SetConsoleMode(void* hConsoleHandle, u32 dwMode); -extern i32 ReadConsoleA( - void* hConsoleInput, - void* lpBuffer, - u32 nNumberOfCharsToRead, - u32* lpNumberOfCharsRead, - PCONSOLE_READCONSOLE_CONTROL pInputControl - ); +// typedef struct _CONSOLE_READCONSOLE_CONTROL { +// u32 nLength; +// u32 nInitialChars; +// u32 dwCtrlWakeupMask; +// u32 dwControlKeyState; +// } CONSOLE_READCONSOLE_CONTROL, *PCONSOLE_READCONSOLE_CONTROL; -extern i32 WriteConsoleA( - void* hConsoleOutput, - const void* lpBuffer, - u32 nNumberOfCharsToWrite, - u32* lpNumberOfCharsWritten, - void* lpReserved - ); +// 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; +u32 _fltused = TRUE; u8 is_open = TRUE; u8 process_commands = TRUE; @@ -438,7 +440,7 @@ u32 continue_status = DBG_EXCEPTION_NOT_HANDLED; u8* string_stack_base = NULL; u8* string_stack_current = NULL; -void dbg_loop() { +void dbg_loop(void) { while(is_open) { WaitForDebugEventEx(&dbg_event, INFINITE); @@ -488,7 +490,9 @@ void dbg_loop() { } } -int mainCRTStartup() { +extern void load_funcs(void); +int mainCRTStartup(void) { + load_funcs(); string_stack_current = string_stack_base = VirtualAlloc(NULL, 4096U * 64U, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); diff --git a/src/module.c b/src/module.c index ad50d7a..25ab2ad 100644 --- a/src/module.c +++ b/src/module.c @@ -2,12 +2,14 @@ #include "utils.h" +extern unsigned char _BitScanForward64(unsigned long *_Index, uint64_t _Mask); + struct module modules[64U] = { 0U }; u64 modules_list = ~0ULL; // u64 module_symbols -u8 add_module() { +u8 add_module(void) { // struct module* add_module() { assert(!modules_list); u32 module_index = 0U; @@ -19,7 +21,7 @@ u8 add_module() { #endif return (u8)module_index; -}; +} void remove_module(u8 index) { modules_list |= (u64)(0x1 << (((i8)index) - 1U)); @@ -372,7 +372,7 @@ void open_pdb(const i8* pdb_path, struct module* module) { print("END SYMBOL\n"); } else if (rec->rectyp == S_FRAMEPROC) { struct FRAMEPROCSYM* frameproc = (struct FRAMEPROCSYM*)cur_sym; - frameproc; + (void)frameproc; // Not used yet print("FRAMEPROC SYMBOL\n"); } else if (rec->rectyp == S_OBJNAME) { struct OBJNAMESYM* objname = (struct OBJNAMESYM*)cur_sym; @@ -408,7 +408,7 @@ void open_pdb(const i8* pdb_path, struct module* module) { print("REGREL32 SYMBOL %s\n", regrel->name); } else if (rec->rectyp == S_COMPILE2) { struct COMPILESYM* compile = (struct COMPILESYM*)cur_sym; - compile; + (void)compile; // Not used yet print("COMPILE2 SYMBOL\n"); } else if (rec->rectyp == S_SECTION) { struct SECTIONSYM* section = (struct SECTIONSYM*)cur_sym; @@ -418,14 +418,14 @@ void open_pdb(const i8* pdb_path, struct module* module) { print("COFFGROUP SYMBOL %s\n", coff->name); } else if (rec->rectyp == S_CALLSITEINFO) { struct CALLSITEINFO* callsiteinfo = (struct CALLSITEINFO*)cur_sym; - callsiteinfo; + (void)callsiteinfo; // Not used yet print("CALLSITEINFO SYMBOL\n"); } else if (rec->rectyp == S_COMPILE3) { struct COMPILESYM3* compile = (struct COMPILESYM3*)cur_sym; print("COMPILE3 SYMBOL %s\n", compile->verSz); } else if (rec->rectyp == S_BUILDINFO) { struct BUILDINFOSYM* buildinfo = (struct BUILDINFOSYM*)cur_sym; - buildinfo; + (void)buildinfo; // Not used yet print("BUILDINFO SYMBOL\n"); } else { print("Unknown symbol kind %x\n", rec->rectyp); diff --git a/src/stack_walk.c b/src/stack_walk.c index cbb6464..066b879 100644 --- a/src/stack_walk.c +++ b/src/stack_walk.c @@ -420,6 +420,7 @@ void walk_stack(void* ctx) { u64 addr = ((CONTEXT*)ctx)->Rip; u64 rsp = ((CONTEXT*)ctx)->Rsp; u64 rbp = ((CONTEXT*)ctx)->Rbp; + (void)rbp; // Not used struct module* module = NULL; struct UNWIND_INFO* u_info = VirtualAlloc(NULL, 4096U, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); while (addr) { @@ -1,7 +1,9 @@ -#include <Windows.h> +extern void OutputDebugStringA(const char* lpOutputString); + int mainCRTStartup() { __debugbreak(); unsigned long long int i = 0; + (void)i; while (1) { __debugbreak(); diff --git a/src/utils.c b/src/utils.c index d512238..0b3513d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -26,13 +26,18 @@ typedef struct _OVERLAPPED { #define SUCCEEDED(hr) (((i32)(hr)) >= 0) -#if _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #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)) +#elif defined(__clang__) + #define va_list __builtin_va_list + #define va_start __builtin_va_start + #define va_arg __builtin_va_arg + #define va_end __builtin_va_end #endif #define STD_INPUT_HANDLE ((u32)-10) @@ -44,6 +49,7 @@ 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 ====== // ======================== @@ -205,12 +211,12 @@ void print(const char* format, ...) { cur_char += length; } } else if(*cur_fmt == 'c') { - char c = va_arg(args, char); + i32 c = va_arg(args, i32); if (fill_count > 1U) { fill_chars((u8*)cur_char, ' ', (u32)fill_count - 1U); cur_char += fill_count; } - *cur_char = c; + *cur_char = (i8)c; cur_char++; } else if (*cur_fmt == 'x') { u64 number = va_arg(args, u64); |
