summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2026-07-12 00:47:54 +0200
committerladevieq <ladevie.quentin@gmail.com>2026-07-12 00:47:54 +0200
commit7b6964eb1bcf30a0ae7ed3391adce30565b262b4 (patch)
tree3bbf89d582a1466a2319ccaaf6d4cbb734bdd66b
parentce51256c91e566d339c6a670af11bab519f98349 (diff)
Load functions by hand
-rw-r--r--build.bat27
-rw-r--r--include/cvinfo.h6
-rw-r--r--include/events.h18
-rw-r--r--include/funcs.h35
-rw-r--r--include/hashmap.h2
-rw-r--r--include/module.h2
-rw-r--r--include/utils.h3
-rw-r--r--include/win_funcs.h401
-rw-r--r--src/disasm.c86
-rw-r--r--src/events.c284
-rw-r--r--src/hashmap.c2
-rw-r--r--src/loader.c235
-rw-r--r--src/main.c320
-rw-r--r--src/module.c6
-rw-r--r--src/pdb.c8
-rw-r--r--src/stack_walk.c1
-rw-r--r--src/test.c4
-rw-r--r--src/utils.c12
18 files changed, 1073 insertions, 379 deletions
diff --git a/build.bat b/build.bat
index cc27d15..91e961e 100644
--- a/build.bat
+++ b/build.bat
@@ -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
+
+}
diff --git a/src/main.c b/src/main.c
index dd84cea..3ad1e9f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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));
diff --git a/src/pdb.c b/src/pdb.c
index e9bb594..a189885 100644
--- a/src/pdb.c
+++ b/src/pdb.c
@@ -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) {
diff --git a/src/test.c b/src/test.c
index b53fc55..fd6ac8e 100644
--- a/src/test.c
+++ b/src/test.c
@@ -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);