summaryrefslogtreecommitdiffstats
path: root/src
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 /src
parentce51256c91e566d339c6a670af11bab519f98349 (diff)
Load functions by hand
Diffstat (limited to 'src')
-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
10 files changed, 605 insertions, 353 deletions
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);