summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/disasm.c5
-rw-r--r--src/events.c103
-rw-r--r--src/hashmap.c4
-rw-r--r--src/loader.c67
-rw-r--r--src/parser.c300
-rw-r--r--src/pdb.c38
-rw-r--r--src/stack_walk.c199
-rw-r--r--src/test.c4
-rw-r--r--src/utils.c54
9 files changed, 61 insertions, 713 deletions
diff --git a/src/disasm.c b/src/disasm.c
index 6cceb53..c9b839d 100644
--- a/src/disasm.c
+++ b/src/disasm.c
@@ -1,5 +1,7 @@
#include "disasm.h"
+
#include "utils.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
@@ -62,9 +64,6 @@
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64
-extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect);
-extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType);
-
// ========================
// ====== !windows.h ======
// ========================
diff --git a/src/events.c b/src/events.c
index fd96966..8c0f8ad 100644
--- a/src/events.c
+++ b/src/events.c
@@ -1,5 +1,6 @@
#include "utils.h"
#include "pdb.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
@@ -23,94 +24,6 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
-//
-// Exception record definition.
-//
-
-typedef struct _EXCEPTION_RECORD {
- u32 ExceptionCode;
- u32 ExceptionFlags;
- struct _EXCEPTION_RECORD *ExceptionRecord;
- void* ExceptionAddress;
- u32 NumberParameters;
- u64* ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
- } EXCEPTION_RECORD;
-
-typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
-
-typedef struct _EXCEPTION_DEBUG_INFO {
- EXCEPTION_RECORD ExceptionRecord;
- u32 dwFirstChance;
-} EXCEPTION_DEBUG_INFO, *LPEXCEPTION_DEBUG_INFO;
-
-typedef struct _CREATE_THREAD_DEBUG_INFO {
- void* hThread;
- void* lpThreadLocalBase;
- LPTHREAD_START_ROUTINE lpStartAddress;
-} CREATE_THREAD_DEBUG_INFO, *LPCREATE_THREAD_DEBUG_INFO;
-
-typedef struct _CREATE_PROCESS_DEBUG_INFO {
- void* hFile;
- void* hProcess;
- void* hThread;
- void* lpBaseOfImage;
- u32 dwDebugInfoFileOffset;
- u32 nDebugInfoSize;
- void* lpThreadLocalBase;
- LPTHREAD_START_ROUTINE lpStartAddress;
- void* lpImageName;
- u16 fUnicode;
-} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO;
-
-typedef struct _EXIT_THREAD_DEBUG_INFO {
- u32 dwExitCode;
-} EXIT_THREAD_DEBUG_INFO, *LPEXIT_THREAD_DEBUG_INFO;
-
-typedef struct _EXIT_PROCESS_DEBUG_INFO {
- u32 dwExitCode;
-} EXIT_PROCESS_DEBUG_INFO, *LPEXIT_PROCESS_DEBUG_INFO;
-
-typedef struct _LOAD_DLL_DEBUG_INFO {
- void* hFile;
- void* lpBaseOfDll;
- u32 dwDebugInfoFileOffset;
- u32 nDebugInfoSize;
- void* lpImageName;
- u16 fUnicode;
-} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO;
-
-typedef struct _UNLOAD_DLL_DEBUG_INFO {
- void* lpBaseOfDll;
-} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO;
-
-typedef struct _OUTPUT_DEBUG_STRING_INFO {
- char* lpDebugStringData;
- u16 fUnicode;
- u16 nDebugStringLength;
-} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO;
-
-typedef struct _RIP_INFO {
- u32 dwError;
- u32 dwType;
-} RIP_INFO, *LPRIP_INFO;
-
-typedef struct _DEBUG_EVENT {
- u32 dwDebugEventCode;
- u32 dwProcessId;
- u32 dwThreadId;
- union {
- EXCEPTION_DEBUG_INFO Exception;
- CREATE_THREAD_DEBUG_INFO CreateThread;
- CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
- EXIT_THREAD_DEBUG_INFO ExitThread;
- EXIT_PROCESS_DEBUG_INFO ExitProcess;
- LOAD_DLL_DEBUG_INFO LoadDll;
- UNLOAD_DLL_DEBUG_INFO UnloadDll;
- OUTPUT_DEBUG_STRING_INFO DebugString;
- RIP_INFO RipInfo;
- } u;
-} DEBUG_EVENT, *LPDEBUG_EVENT;
-
#define FILE_NAME_NORMALIZED 0x0 //default
#define FILE_NAME_OPENED 0x8
@@ -261,8 +174,6 @@ typedef struct _IMAGE_DEBUG_DIRECTORY {
typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-extern u32 GetLastError(void);
-
//
// Code Page Default Values.
// Please Use Unicode, either UTF-16 (as in WCHAR) or UTF-8 (code page CP_ACP)
@@ -276,10 +187,6 @@ 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, 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
@@ -337,9 +244,6 @@ extern u32 GetFinalPathNameByHandleA(void* hFile, i8* lpszFilePath, u32 cchFileP
#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)
@@ -355,9 +259,6 @@ extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType);
#define PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
#define PROCESS_SET_LIMITED_INFORMATION (0x2000)
-extern void* OpenProcess(u32 dwDesiredAccess, i32 bInheritHandle, u32 dwProcessId);
-extern i32 TerminateProcess(void* hProcess, u32 uExitCode);
-
// ========================
// ====== !windows.h ======
// ========================
@@ -496,7 +397,7 @@ void load_symbols(const void* base_addr, struct module* module) {
assert(string_stack_current - 16U * 4096U < string_stack_base);
void* name_address = (void*)((u64)module->base_addr + names_address[name_index]);
read_memory(name_address, name, 256U);
- length = str_len((const char*)name, 256U);
+ length = str_len((const char*)name);
break;
}
}
diff --git a/src/hashmap.c b/src/hashmap.c
index 8362736..526a95b 100644
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -1,6 +1,7 @@
#include "hashmap.h"
#include "utils.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
@@ -63,9 +64,6 @@
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64
-extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect);
-extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType);
-
// ========================
// ====== !windows.h ======
// ========================
diff --git a/src/loader.c b/src/loader.c
index da98364..2e79e67 100644
--- a/src/loader.c
+++ b/src/loader.c
@@ -114,11 +114,25 @@ typedef struct _IMAGE_EXPORT_DIRECTORY {
#define KERNEL_BASE(name) \
PFN_##name name = NULL;
+#define NTDLL(name) \
+ PFN_##name name = NULL;
+
#include "funcs.h"
+#undef NTDLL
#undef KERNEL_BASE
#undef KERNEL32
+size_t str_len(const char* str) {
+ const char* c = str;
+ size_t count = 0U;
+ while (*c != '\0') {
+ c++;
+ count++;
+ }
+ return count;
+}
+
i32 str_cmp(const i8* str1, size_t str1_len, const i8* str2, size_t str2_len) {
u32 min_len = str1_len < str2_len ? str1_len : str2_len;
@@ -151,46 +165,23 @@ PEB* get_PEB(void) {
return (PEB*)__readgsqword(__builtin_offsetof(TEB, ProcessEnvironmentBlock));
}
-void* get_kernel32(void) {
- const u16 kernel32_str[] = L"KERNEL32.DLL";
+void* get_module(u16* name, size_t name_size) {
PEB* PEB = get_PEB();
- LIST_ENTRY* last_entry = PEB->LoaderData->InMemoryOrderModuleList.Blink;
- LIST_ENTRY* cur_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink;
+ LIST_ENTRY* first_entry = PEB->LoaderData->InMemoryOrderModuleList.Flink;
+ LIST_ENTRY* cur_entry = first_entry;
- while(cur_entry != last_entry) {
+ do {
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) {
+ if (wstr_cmp(name, name_size / 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;
- }
+ } while(cur_entry != first_entry);
return NULL;
}
@@ -207,7 +198,7 @@ void* load_func(u64 base_addr, const char* func_name, u32 func_name_len) {
for (u32 name_index = 0U; name_index < export_dir->NumberOfNames; name_index++) {
const char* name = (const char*)(base_addr + names_address[name_index]);
- u32 length = str_len(name, 256U);
+ u32 length = str_len(name);
if (str_cmp((i8*)name, length, (i8*)func_name, func_name_len) == 0) {
return (void*)(base_addr + addresses[ordinals[name_index]]);
@@ -218,17 +209,25 @@ void* load_func(u64 base_addr, const char* func_name, u32 func_name_len) {
}
void load_funcs(void) {
- void* kernel32 = get_kernel32();
- void* kernel_base = get_kernel_base();
+ u16 kernel32_str[] = L"KERNEL32.DLL";
+ u16 kernel_base_str[] = L"KERNELBASE.dll";
+ u16 ntdll_str[] = L"ntdll.dll";
+ void* kernel32 = get_module(kernel32_str, sizeof(kernel32_str));
+ void* kernel_base = get_module(kernel_base_str, sizeof(kernel_base_str));
+ void* ntdll = get_module(ntdll_str, sizeof(ntdll_str));
-#define KERNEL32(name) \
+#define KERNEL32(name) \
name = (PFN_##name)load_func((u64)kernel32, #name, sizeof(#name));
-#define KERNEL_BASE(name) \
+#define KERNEL_BASE(name) \
name = (PFN_##name)load_func((u64)kernel_base, #name, sizeof(#name));
+#define NTDLL(name) \
+ name = (PFN_##name)load_func((u64)ntdll, #name, sizeof(#name));
+
#include "funcs.h"
+#undef NTDLL
#undef KERNEL_BASE
#undef KERNEL32
diff --git a/src/parser.c b/src/parser.c
index 40133a7..8dcbc76 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -4,6 +4,7 @@
#include "module.h"
#include "stack_walk.h"
#include "disasm.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
@@ -27,202 +28,6 @@
#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x00000040L)
#define CONTEXT_KERNEL_CET (CONTEXT_AMD64 | 0x00000080L)
-//
-// Define 128-bit 16-byte aligned xmm register type.
-//
-
-typedef struct __declspec(align(16)) _M128A {
- u64 Low;
- i64 High;
-} M128A, *PM128A;
-
-//
-// Format of data for (F)XSAVE/(F)XRSTOR instruction
-//
-
-typedef struct __declspec(align(16)) _XSAVE_FORMAT {
- u16 ControlWord;
- u16 StatusWord;
- u8 TagWord;
- u8 Reserved1;
- u16 ErrorOpcode;
- u32 ErrorOffset;
- u16 ErrorSelector;
- u16 Reserved2;
- u32 DataOffset;
- u16 DataSelector;
- u16 Reserved3;
- u32 MxCsr;
- u32 MxCsr_Mask;
- M128A FloatRegisters[8];
-
-#if defined(_WIN64)
-
- M128A XmmRegisters[16];
- u8 Reserved4[96];
-
-#else
-
- M128A XmmRegisters[8];
- BYTE Reserved4[224];
-
-#endif
-
-} XSAVE_FORMAT, *PXSAVE_FORMAT;
-
-typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
-
-//
-// Context Frame
-//
-// This frame has a several purposes: 1) it is used as an argument to
-// NtContinue, 2) it is used to constuct a call frame for APC delivery,
-// and 3) it is used in the user level thread creation routines.
-//
-//
-// The flags field within this record controls the contents of a CONTEXT
-// record.
-//
-// If the context record is used as an input parameter, then for each
-// portion of the context record controlled by a flag whose value is
-// set, it is assumed that that portion of the context record contains
-// valid context. If the context record is being used to modify a threads
-// context, then only that portion of the threads context is modified.
-//
-// If the context record is used as an output parameter to capture the
-// context of a thread, then only those portions of the thread's context
-// corresponding to set flags will be returned.
-//
-// CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags.
-//
-// CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15.
-//
-// CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs.
-//
-// CONTEXT_FLOATING_POINT specifies Xmm0-Xmm15.
-//
-// CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7.
-//
-
-typedef struct __declspec(align(16)) _CONTEXT {
-
- //
- // Register parameter home addresses.
- //
- // N.B. These fields are for convience - they could be used to extend the
- // context record in the future.
- //
-
- u64 P1Home;
- u64 P2Home;
- u64 P3Home;
- u64 P4Home;
- u64 P5Home;
- u64 P6Home;
-
- //
- // Control flags.
- //
-
- u32 ContextFlags;
- u32 MxCsr;
-
- //
- // Segment Registers and processor flags.
- //
-
- u16 SegCs;
- u16 SegDs;
- u16 SegEs;
- u16 SegFs;
- u16 SegGs;
- u16 SegSs;
- u32 EFlags;
-
- //
- // Debug registers
- //
-
- u64 Dr0;
- u64 Dr1;
- u64 Dr2;
- u64 Dr3;
- u64 Dr6;
- u64 Dr7;
-
- //
- // Integer registers.
- //
-
- u64 Rax;
- u64 Rcx;
- u64 Rdx;
- u64 Rbx;
- u64 Rsp;
- u64 Rbp;
- u64 Rsi;
- u64 Rdi;
- u64 R8;
- u64 R9;
- u64 R10;
- u64 R11;
- u64 R12;
- u64 R13;
- u64 R14;
- u64 R15;
-
- //
- // Program counter.
- //
-
- u64 Rip;
-
- //
- // Floating point state.
- //
-
- union {
- XMM_SAVE_AREA32 FltSave;
- struct {
- M128A Header[2];
- M128A Legacy[8];
- M128A Xmm0;
- M128A Xmm1;
- M128A Xmm2;
- M128A Xmm3;
- M128A Xmm4;
- M128A Xmm5;
- M128A Xmm6;
- M128A Xmm7;
- M128A Xmm8;
- M128A Xmm9;
- M128A Xmm10;
- M128A Xmm11;
- M128A Xmm12;
- M128A Xmm13;
- M128A Xmm14;
- M128A Xmm15;
- };
- };
-
- //
- // Vector registers.
- //
-
- M128A VectorRegister[26];
- u64 VectorControl;
-
- //
- // Special debug control registers.
- //
-
- u64 DebugControl;
- u64 LastBranchToRip;
- u64 LastBranchFromRip;
- u64 LastExceptionToRip;
- u64 LastExceptionFromRip;
-} CONTEXT, *PCONTEXT;
-
#define THREAD_TERMINATE (0x0001)
#define THREAD_SUSPEND_RESUME (0x0002)
#define THREAD_GET_CONTEXT (0x0008)
@@ -254,101 +59,8 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
#define EXCEPTION_MAXIMUM_PARAMETERS 15 // maximum number of exception parameters
-//
-// Exception record definition.
-//
-
-typedef struct _EXCEPTION_RECORD {
- u32 ExceptionCode;
- u32 ExceptionFlags;
- struct _EXCEPTION_RECORD *ExceptionRecord;
- void* ExceptionAddress;
- u32 NumberParameters;
- u64* ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
- } EXCEPTION_RECORD;
-
-typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;
-
-typedef struct _EXCEPTION_DEBUG_INFO {
- EXCEPTION_RECORD ExceptionRecord;
- u32 dwFirstChance;
-} EXCEPTION_DEBUG_INFO, *LPEXCEPTION_DEBUG_INFO;
-
-typedef struct _CREATE_THREAD_DEBUG_INFO {
- void* hThread;
- void* lpThreadLocalBase;
- LPTHREAD_START_ROUTINE lpStartAddress;
-} CREATE_THREAD_DEBUG_INFO, *LPCREATE_THREAD_DEBUG_INFO;
-
-typedef struct _CREATE_PROCESS_DEBUG_INFO {
- void* hFile;
- void* hProcess;
- void* hThread;
- void* lpBaseOfImage;
- u32 dwDebugInfoFileOffset;
- u32 nDebugInfoSize;
- void* lpThreadLocalBase;
- LPTHREAD_START_ROUTINE lpStartAddress;
- void* lpImageName;
- u16 fUnicode;
-} CREATE_PROCESS_DEBUG_INFO, *LPCREATE_PROCESS_DEBUG_INFO;
-
-typedef struct _EXIT_THREAD_DEBUG_INFO {
- u32 dwExitCode;
-} EXIT_THREAD_DEBUG_INFO, *LPEXIT_THREAD_DEBUG_INFO;
-
-typedef struct _EXIT_PROCESS_DEBUG_INFO {
- u32 dwExitCode;
-} EXIT_PROCESS_DEBUG_INFO, *LPEXIT_PROCESS_DEBUG_INFO;
-
-typedef struct _LOAD_DLL_DEBUG_INFO {
- void* hFile;
- void* lpBaseOfDll;
- u32 dwDebugInfoFileOffset;
- u32 nDebugInfoSize;
- void* lpImageName;
- u16 fUnicode;
-} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO;
-
-typedef struct _UNLOAD_DLL_DEBUG_INFO {
- void* lpBaseOfDll;
-} UNLOAD_DLL_DEBUG_INFO, *LPUNLOAD_DLL_DEBUG_INFO;
-
-typedef struct _OUTPUT_DEBUG_STRING_INFO {
- char* lpDebugStringData;
- u16 fUnicode;
- u16 nDebugStringLength;
-} OUTPUT_DEBUG_STRING_INFO, *LPOUTPUT_DEBUG_STRING_INFO;
-
-typedef struct _RIP_INFO {
- u32 dwError;
- u32 dwType;
-} RIP_INFO, *LPRIP_INFO;
-
-typedef struct _DEBUG_EVENT {
- u32 dwDebugEventCode;
- u32 dwProcessId;
- u32 dwThreadId;
- union {
- EXCEPTION_DEBUG_INFO Exception;
- CREATE_THREAD_DEBUG_INFO CreateThread;
- CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
- EXIT_THREAD_DEBUG_INFO ExitThread;
- EXIT_PROCESS_DEBUG_INFO ExitProcess;
- LOAD_DLL_DEBUG_INFO LoadDll;
- UNLOAD_DLL_DEBUG_INFO UnloadDll;
- OUTPUT_DEBUG_STRING_INFO DebugString;
- RIP_INFO RipInfo;
- } u;
-} DEBUG_EVENT, *LPDEBUG_EVENT;
-
-extern i32 ContinueDebugEvent(u32 dwProcessId, u32 dwThreadId, u32 dwContinueStatus);
-
typedef PCONTEXT LPCONTEXT;
-extern i32 GetThreadContext(void* hThread, LPCONTEXT lpContext);
-extern i32 SetThreadContext(void* hThread, const CONTEXT* lpContext);
-
#define SORT_DEFAULT 0x0 // sorting default
#define LANG_NEUTRAL 0x00
@@ -368,8 +80,6 @@ extern i32 SetThreadContext(void* hThread, const CONTEXT* lpContext);
#define CSTR_EQUAL 2 // string 1 equal to string 2
#define CSTR_GREATER_THAN 3 // string 1 greater than string 2
-extern i32 CompareStringA(u32 Locale, u32 dwCmpFlags, const i8* lpString1, i32 cchCount1, const i8* lpString2, i32 cchCount2);
-
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
@@ -427,14 +137,6 @@ extern i32 CompareStringA(u32 Locale, u32 dwCmpFlags, const i8* lpString1, i32 c
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64
-extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect);
-extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType);
-
-extern void* OpenThread(u32 dwDesiredAccess, i32 bInheritHandle, u32 dwThreadId);
-extern i32 CloseHandle(void* hObject);
-
-extern u32 GetLastError(void);
-
// ========================
// ====== !windows.h ======
// ========================
diff --git a/src/pdb.c b/src/pdb.c
index a189885..91c7ddb 100644
--- a/src/pdb.c
+++ b/src/pdb.c
@@ -2,33 +2,13 @@
#include "cvinfo.h"
#include "utils.h"
+#include "win_funcs.h"
+
// =======================
// ====== windows.h ======
// =======================
-extern u32 GetLastError(void);
-
-typedef struct _SECURITY_ATTRIBUTES {
- u32 nLength;
- void* lpSecurityDescriptor;
- i32 bInheritHandle;
-} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
-
-typedef struct _OVERLAPPED {
- u64* Internal;
- u64* InternalHigh;
- union {
- struct {
- u32 Offset;
- u32 OffsetHigh;
- };
- void* Pointer;
- };
-
- void* hEvent;
-} OVERLAPPED, *LPOVERLAPPED;
-
//
// Define access rights to files and directories
//
@@ -197,14 +177,6 @@ typedef struct _OVERLAPPED {
//
#define INVALID_HANDLE_VALUE ((void*)(i64*)-1)
-extern void* CreateFileA(const i8* lpFileName, u32 dwDesiredAccess, u32 dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, u32 dwCreationDisposition, u32 dwFlagsAndAttributes, void* hTemplateFile);
-
-extern u32 SetFilePointer(void* hFile, i32 lDistanceToMove, i32* lpDistanceToMoveHigh, u32 dwMoveMethod);
-
-extern i32 ReadFile(void* hFile, void* lpBuffer, u32 nNumberOfBytesToRead, u32* lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
-
-extern i32 CloseHandle(void* hObject);
-
// ========================
// ====== !windows.h ======
// ========================
@@ -349,11 +321,11 @@ void open_pdb(const i8* pdb_path, struct module* module) {
print("Module symbol stream index %x\n", modules_info[module_index]->ModuleSymStream);
print("Module name : %s\n", modules_name[module_index]);
size_t module_name_length = 0U;
- module_name_length = str_len((const char*)modules_name[module_index], 256U);
+ module_name_length = str_len((const char*)modules_name[module_index]);
obj_files_name[module_index] = &DBI_block[byte_index + sizeof(struct mod_info) + module_name_length + 1U];
print("Obj file name : %s\n", obj_files_name[module_index]);
- size_t obj_file_name_length = str_len((const char*)obj_files_name[module_index], 256U);
+ size_t obj_file_name_length = str_len((const char*)obj_files_name[module_index]);
u32 module_info_size = sizeof(*modules_info[0U]) + (i32)module_name_length + 1 + (i32)obj_file_name_length + 1;
module_info_size = ((module_info_size + 3U) / 4U) * 4U;
@@ -388,7 +360,7 @@ void open_pdb(const i8* pdb_path, struct module* module) {
print("PROC32 SYMBOL %s\n", proc->name);
// TODO: Add string management code
assert(string_stack_current - 16U * 4096U < string_stack_base);
- size_t length = str_len((const char*)proc->name, 256U);
+ size_t length = str_len((const char*)proc->name);
str_cat((char*)string_stack_current, (const char*)proc->name, length);
string_stack_current[length] = '\0';
u32 start_address = proc->off + module->nt_header.OptionalHeader.BaseOfCode;
diff --git a/src/stack_walk.c b/src/stack_walk.c
index 066b879..1cd97e4 100644
--- a/src/stack_walk.c
+++ b/src/stack_walk.c
@@ -2,6 +2,7 @@
#include "module.h"
#include "utils.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
@@ -25,201 +26,6 @@
#define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x00000040L)
#define CONTEXT_KERNEL_CET (CONTEXT_AMD64 | 0x00000080L)
-//
-// Define 128-bit 16-byte aligned xmm register type.
-//
-
-typedef struct __declspec(align(16)) _M128A {
- u64 Low;
- i64 High;
-} M128A, *PM128A;
-
-//
-// Format of data for (F)XSAVE/(F)XRSTOR instruction
-//
-
-typedef struct __declspec(align(16)) _XSAVE_FORMAT {
- u16 ControlWord;
- u16 StatusWord;
- u8 TagWord;
- u8 Reserved1;
- u16 ErrorOpcode;
- u32 ErrorOffset;
- u16 ErrorSelector;
- u16 Reserved2;
- u32 DataOffset;
- u16 DataSelector;
- u16 Reserved3;
- u32 MxCsr;
- u32 MxCsr_Mask;
- M128A FloatRegisters[8];
-
-#if defined(_WIN64)
-
- M128A XmmRegisters[16];
- u8 Reserved4[96];
-
-#else
-
- M128A XmmRegisters[8];
- BYTE Reserved4[224];
-
-#endif
-
-} XSAVE_FORMAT, *PXSAVE_FORMAT;
-
-typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
-
-//
-// Context Frame
-//
-// This frame has a several purposes: 1) it is used as an argument to
-// NtContinue, 2) it is used to constuct a call frame for APC delivery,
-// and 3) it is used in the user level thread creation routines.
-//
-//
-// The flags field within this record controls the contents of a CONTEXT
-// record.
-//
-// If the context record is used as an input parameter, then for each
-// portion of the context record controlled by a flag whose value is
-// set, it is assumed that that portion of the context record contains
-// valid context. If the context record is being used to modify a threads
-// context, then only that portion of the threads context is modified.
-//
-// If the context record is used as an output parameter to capture the
-// context of a thread, then only those portions of the thread's context
-// corresponding to set flags will be returned.
-//
-// CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags.
-//
-// CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15.
-//
-// CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs.
-//
-// CONTEXT_FLOATING_POINT specifies Xmm0-Xmm15.
-//
-// CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7.
-//
-
-typedef struct __declspec(align(16)) _CONTEXT {
-
- //
- // Register parameter home addresses.
- //
- // N.B. These fields are for convience - they could be used to extend the
- // context record in the future.
- //
-
- u64 P1Home;
- u64 P2Home;
- u64 P3Home;
- u64 P4Home;
- u64 P5Home;
- u64 P6Home;
-
- //
- // Control flags.
- //
-
- u32 ContextFlags;
- u32 MxCsr;
-
- //
- // Segment Registers and processor flags.
- //
-
- u16 SegCs;
- u16 SegDs;
- u16 SegEs;
- u16 SegFs;
- u16 SegGs;
- u16 SegSs;
- u32 EFlags;
-
- //
- // Debug registers
- //
-
- u64 Dr0;
- u64 Dr1;
- u64 Dr2;
- u64 Dr3;
- u64 Dr6;
- u64 Dr7;
-
- //
- // Integer registers.
- //
-
- u64 Rax;
- u64 Rcx;
- u64 Rdx;
- u64 Rbx;
- u64 Rsp;
- u64 Rbp;
- u64 Rsi;
- u64 Rdi;
- u64 R8;
- u64 R9;
- u64 R10;
- u64 R11;
- u64 R12;
- u64 R13;
- u64 R14;
- u64 R15;
-
- //
- // Program counter.
- //
-
- u64 Rip;
-
- //
- // Floating point state.
- //
-
- union {
- XMM_SAVE_AREA32 FltSave;
- struct {
- M128A Header[2];
- M128A Legacy[8];
- M128A Xmm0;
- M128A Xmm1;
- M128A Xmm2;
- M128A Xmm3;
- M128A Xmm4;
- M128A Xmm5;
- M128A Xmm6;
- M128A Xmm7;
- M128A Xmm8;
- M128A Xmm9;
- M128A Xmm10;
- M128A Xmm11;
- M128A Xmm12;
- M128A Xmm13;
- M128A Xmm14;
- M128A Xmm15;
- };
- };
-
- //
- // Vector registers.
- //
-
- M128A VectorRegister[26];
- u64 VectorControl;
-
- //
- // Special debug control registers.
- //
-
- u64 DebugControl;
- u64 LastBranchToRip;
- u64 LastBranchFromRip;
- u64 LastExceptionToRip;
- u64 LastExceptionFromRip;
-} CONTEXT, *PCONTEXT;
#define PAGE_NOACCESS 0x01
#define PAGE_READONLY 0x02
#define PAGE_READWRITE 0x04
@@ -277,9 +83,6 @@ typedef struct __declspec(align(16)) _CONTEXT {
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64
-extern void* VirtualAlloc(void* lpAddress, size_t dwSize, u32 flAllocationType, u32 flProtect);
-extern i32 VirtualFree(void* lpAddress, size_t dwSize, u32 dwFreeType);
-
// ========================
// ====== !windows.h ======
// ========================
diff --git a/src/test.c b/src/test.c
index fd6ac8e..51a0b34 100644
--- a/src/test.c
+++ b/src/test.c
@@ -1,4 +1,4 @@
-extern void OutputDebugStringA(const char* lpOutputString);
+// #include "win_funcs.h"
int mainCRTStartup() {
__debugbreak();
@@ -7,7 +7,7 @@ int mainCRTStartup() {
while (1) {
__debugbreak();
- OutputDebugStringA("Hello World !");
+ // OutputDebugStringA("Hello World !");
i++;
}
diff --git a/src/utils.c b/src/utils.c
index 0b3513d..95a1d80 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,30 +1,10 @@
#include "utils.h"
+#include "win_funcs.h"
// =======================
// ====== windows.h ======
// =======================
-typedef struct _PROCESS_INFORMATION {
- void* hProcess;
- void* hThread;
- u32 dwProcessId;
- u32 dwThreadId;
-} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
-typedef struct _OVERLAPPED {
- u32* Internal;
- u32* InternalHigh;
- union {
- struct {
- u32 Offset;
- u32 OffsetHigh;
- } DUMMYSTRUCTNAME;
- void* Pointer;
- } DUMMYUNIONNAME;
-
- void* hEvent;
-} OVERLAPPED, *LPOVERLAPPED;
-
-#define SUCCEEDED(hr) (((i32)(hr)) >= 0)
#if defined(_MSC_VER) && !defined(__clang__)
#define va_start(ap, x) ((void)(__va_start(&ap, x)))
@@ -44,12 +24,6 @@ typedef struct _OVERLAPPED {
#define STD_OUTPUT_HANDLE ((u32)-11)
#define STD_ERROR_HANDLE ((u32)-12)
-extern void* GetStdHandle(u32 nStdHandle);
-
-extern i32 WriteFile(void* hFile, const void* lpBuffer, u32 nNumberOfBytesToWrite, u32* lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
-
-extern i32 ReadProcessMemory(void* hProcess, const void* lpBaseAddress, void* lpBuffer, size_t nSize, size_t* lpNumberOfBytesRead);
-
// ========================
// ====== !windows.h ======
// ========================
@@ -66,19 +40,7 @@ u8 is_hexadecimal_digit(char c) {
return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
}
-
// TODO: Improve basic functions perfs
-// max_size: str allocated size
-size_t str_len(const char* str, size_t max_size) {
- const char* c = str;
- size_t count = 0U;
- while (*c != '\0' && count < max_size) {
- c++;
- count++;
- }
- return count;
-}
-
void str_cat(char* out, const char* str, size_t c_str) {
char* cur_out = out;
const char* cur_str = str;
@@ -91,6 +53,18 @@ void str_cat(char* out, const char* str, size_t c_str) {
}
}
+void memcpy(void* restrict dst, const void* restrict src, size_t size) {
+ RtlCopyMemory(dst, src, size);
+}
+
+void memset(void* dst, int fill, size_t count) {
+ if (fill == 0) {
+ RtlZeroMemory(dst, count);
+ } else {
+ RtlFillMemory(dst, count, fill);
+ }
+}
+
void u64toa(u64 number, char* str, u32 base) {
static char codes[16U] = {
'0',
@@ -201,7 +175,7 @@ void print(const char* format, ...) {
if (*cur_fmt == 's') {
const char* str = va_arg(args, const char*);
if(str != NULL) {
- size_t length = str_len(str, sizeof(formatted_str));
+ size_t length = str_len(str);
i64 relative_fill_count = fill_count - length;
if (relative_fill_count > 1) {
fill_chars((u8*)cur_char, ' ', (u32)relative_fill_count);