From ab1af9de1931e6b210386ab88930942ee42d5876 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Thu, 21 May 2026 23:23:59 +0200 Subject: Save work --- src/main.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 171 insertions(+), 25 deletions(-) (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c index aac79c7..405c5f0 100644 --- a/src/main.c +++ b/src/main.c @@ -1,14 +1,14 @@ // #include #include -#define NULL 0U +// #define NULL 0U typedef long HRESULT; #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #define VOID void -typedef unsigned __int64 ULONGLONG; -typedef __int64 LONGLONG; +typedef unsigned long long ULONGLONG; +typedef long long LONGLONG; typedef char CHAR; typedef short SHORT; typedef long LONG; @@ -36,7 +36,7 @@ typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; - } DUMMYSTRUCTNAME; + }; struct { DWORD LowPart; LONG HighPart; @@ -199,6 +199,92 @@ typedef struct _IMAGE_SECTION_HEADER { #define IMAGE_SIZEOF_FILE_HEADER 20 +// +// Relocation format. +// + +#pragma pack(push, 2) // Symbols, relocs, and linenumbers are 2 byte packed +typedef struct _IMAGE_RELOCATION { + union { + DWORD VirtualAddress; + DWORD RelocCount; // Set to the real count when IMAGE_SCN_LNK_NRELOC_OVFL is set + }; + DWORD SymbolTableIndex; + WORD Type; +} IMAGE_RELOCATION; +typedef IMAGE_RELOCATION __unaligned *PIMAGE_RELOCATION; + +// +// x64 relocations +// +#define IMAGE_REL_AMD64_ABSOLUTE 0x0000 // Reference is absolute, no relocation is necessary +#define IMAGE_REL_AMD64_ADDR64 0x0001 // 64-bit address (VA). +#define IMAGE_REL_AMD64_ADDR32 0x0002 // 32-bit address (VA). +#define IMAGE_REL_AMD64_ADDR32NB 0x0003 // 32-bit address w/o image base (RVA). +#define IMAGE_REL_AMD64_REL32 0x0004 // 32-bit relative address from byte following reloc +#define IMAGE_REL_AMD64_REL32_1 0x0005 // 32-bit relative address from byte distance 1 from reloc +#define IMAGE_REL_AMD64_REL32_2 0x0006 // 32-bit relative address from byte distance 2 from reloc +#define IMAGE_REL_AMD64_REL32_3 0x0007 // 32-bit relative address from byte distance 3 from reloc +#define IMAGE_REL_AMD64_REL32_4 0x0008 // 32-bit relative address from byte distance 4 from reloc +#define IMAGE_REL_AMD64_REL32_5 0x0009 // 32-bit relative address from byte distance 5 from reloc +#define IMAGE_REL_AMD64_SECTION 0x000A // Section index +#define IMAGE_REL_AMD64_SECREL 0x000B // 32 bit offset from base of section containing target +#define IMAGE_REL_AMD64_SECREL7 0x000C // 7 bit unsigned offset from base of section containing target +#define IMAGE_REL_AMD64_TOKEN 0x000D // 32 bit metadata token +#define IMAGE_REL_AMD64_SREL32 0x000E // 32 bit signed span-dependent value emitted into object +#define IMAGE_REL_AMD64_PAIR 0x000F +#define IMAGE_REL_AMD64_SSPAN32 0x0010 // 32 bit signed span-dependent value applied at link time +#define IMAGE_REL_AMD64_EHANDLER 0x0011 +#define IMAGE_REL_AMD64_IMPORT_BR 0x0012 // Indirect branch to an import +#define IMAGE_REL_AMD64_IMPORT_CALL 0x0013 // Indirect call to an import +#define IMAGE_REL_AMD64_CFG_BR 0x0014 // Indirect branch to a CFG check +#define IMAGE_REL_AMD64_CFG_BR_REX 0x0015 // Indirect branch to a CFG check, with REX.W prefix +#define IMAGE_REL_AMD64_CFG_CALL 0x0016 // Indirect call to a CFG check +#define IMAGE_REL_AMD64_INDIR_BR 0x0017 // Indirect branch to a target in RAX (no CFG) +#define IMAGE_REL_AMD64_INDIR_BR_REX 0x0018 // Indirect branch to a target in RAX, with REX.W prefix (no CFG) +#define IMAGE_REL_AMD64_INDIR_CALL 0x0019 // Indirect call to a target in RAX (no CFG) +#define IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_FIRST 0x0020 // Indirect branch for a switch table using Reg 0 (RAX) +#define IMAGE_REL_AMD64_INDIR_BR_SWITCHTABLE_LAST 0x002F // Indirect branch for a switch table using Reg 15 (R15) + +// +// Symbol format. +// + +__declspec(align(1)) typedef struct _IMAGE_SYMBOL { + union { + BYTE ShortName[8]; + struct { + DWORD Short; // if 0, use LongName + DWORD Long; // offset into string table + } Name; + DWORD LongName[2]; // PBYTE [2] + } N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} IMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +typedef struct _IMAGE_SYMBOL_EX { + union { + BYTE ShortName[8]; + struct { + DWORD Short; // if 0, use LongName + DWORD Long; // offset into string table + } Name; + DWORD LongName[2]; // PBYTE [2] + } N; + DWORD Value; + LONG SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} IMAGE_SYMBOL_EX; +#pragma pack(pop) + #define MEM_COMMIT 0x00001000 #define MEM_RESERVE 0x00002000 #define MEM_DECOMMIT 0x00004000 @@ -260,15 +346,15 @@ char* GetCommandLineA(); void* VirtualAlloc(void*, u64, u32, u32); s32 VirtualFree(void*, u64, u32); -_Static_assert(sizeof(s8) == 1U, ""); -_Static_assert(sizeof(s16) == 2U, ""); -_Static_assert(sizeof(s32) == 4U, ""); -_Static_assert(sizeof(s64) == 8U, ""); +static_assert(sizeof(s8) == 1U, ""); +static_assert(sizeof(s16) == 2U, ""); +static_assert(sizeof(s32) == 4U, ""); +static_assert(sizeof(s64) == 8U, ""); -_Static_assert(sizeof(u8) == 1U, ""); -_Static_assert(sizeof(u16) == 2U, ""); -_Static_assert(sizeof(u32) == 4U, ""); -_Static_assert(sizeof(u64) == 8U, ""); +static_assert(sizeof(u8) == 1U, ""); +static_assert(sizeof(u16) == 2U, ""); +static_assert(sizeof(u32) == 4U, ""); +static_assert(sizeof(u64) == 8U, ""); #define ALIGN(x, align) (((x) + (align - 1U)) / (align)) * (align) @@ -305,25 +391,29 @@ static void str_cat(char* out, const char* str, size_t c_str) { index++; } } -static void mem_copy(void* src, void* dst, size_t size) { + +void* memcpy(void* dst, void* src, size_t size) { u8* byte_src = (u8*)src; u8* byte_dst = (u8*)dst; for (u32 index = 0U; index < size; index++) { byte_dst[index] = byte_src[index]; } + + return dst; } -// static void mem_set(void* ptr, size_t size, u8 value) { -static void* memset(void* ptr, size_t size, u8 value) { +// static void* mem_set(void* ptr, size_t size, u8 value) { +void* memset(void* ptr, s32 value, size_t size) { u8* bytes = ptr; for (u32 index = 0U; index < size; index++) { - bytes[index] = value; + bytes[index] = (u8)value; } return ptr; } + static void u64toa(u64 number, char* str, u32 base) { static char codes[16U] = { '0', @@ -534,7 +624,7 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_ u32 nb_sections_size = sizeof(struct COFF_sections) * obj_files_count; struct COFF_sections* sections = (struct COFF_sections*)VirtualAlloc(NULL, nb_sections_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - memset((void*)sections, nb_sections_size, 0U); + // memset((void*)sections, nb_sections_size, 0U); for (u32 obj_id = 0U; obj_id < obj_files_count; obj_id++) { struct COFF_sections* section = §ions[obj_id]; @@ -548,13 +638,13 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_ LARGE_INTEGER file_size = { 0 }; GetFileSizeEx(obj_file_handle, &file_size); - section->file_buffer = (u8*)VirtualAlloc(NULL, file_size.DUMMYSTRUCTNAME.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + section->file_buffer = (u8*)VirtualAlloc(NULL, file_size.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); IMAGE_FILE_HEADER* header = (IMAGE_FILE_HEADER*)section->file_buffer; IMAGE_SECTION_HEADER* section_table = (IMAGE_SECTION_HEADER*)(((u8*)header) + sizeof(*header)); u32 bread = 0U; - if (!ReadFile(obj_file_handle, (void*)header, file_size.DUMMYSTRUCTNAME.LowPart, &bread, NULL)) { + if (!ReadFile(obj_file_handle, (void*)section->file_buffer, file_size.LowPart, &bread, NULL)) { CloseHandle(obj_file_handle); continue; } @@ -562,6 +652,9 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_ section->symbol_table_off = header->PointerToSymbolTable; section->symbols_count = header->NumberOfSymbols; + IMAGE_SYMBOL* symbol_table = (IMAGE_SYMBOL*)(section->file_buffer + section->symbol_table_off); + u8* string_table = (u8*)symbol_table + sizeof(*symbol_table) * section->symbols_count; + for (u32 section_index = 0U; section_index < header->NumberOfSections; section_index++) { IMAGE_SECTION_HEADER* curr_section = §ion_table[section_index]; if ((curr_section->Characteristics & BSS_SECTION_FLAGS) == BSS_SECTION_FLAGS) { @@ -589,6 +682,58 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_ section->text_section_off = curr_section->PointerToRawData; section->text_section_size = curr_section->SizeOfRawData; } + + u8* reloc_start = §ion->file_buffer[curr_section->PointerToRelocations]; + PIMAGE_RELOCATION cur_reloc_entry = (PIMAGE_RELOCATION)reloc_start; + + // Section relocations + for (u32 reloc_index = 0U; reloc_index < curr_section->NumberOfRelocations; reloc_index++, cur_reloc_entry++) { + print("SYMBOL INDEX : %u\n", cur_reloc_entry->SymbolTableIndex); + + IMAGE_SYMBOL* sym = symbol_table + cur_reloc_entry->SymbolTableIndex; + if (sym->N.Name.Short == 0U) { // use longname + print("SYMBOL NAME : %s\n", string_table + sym->N.Name.Long); + } else { + print("SYMBOL NAME : %s.8\n", sym->N.ShortName); + } + + if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ABSOLUTE) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_ABSOLUTE\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR64) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR64\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR32\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32NB) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_ADDR32NB\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_1) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_1\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_2) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_2\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_3) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_3\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_4) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_4\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_5) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_REL32_5\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECTION) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_SECTION\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_SECREL\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL7) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_SECREL7\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_TOKEN) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_TOKEN\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SREL32) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_SREL32\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_PAIR) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_PAIR\n"); + } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SSPAN32) { + print("SYMBOL TYPE : IMAGE_REL_AMD64_SSPAN32\n"); + } + print("\n\n"); + } } CloseHandle(obj_file_handle); } @@ -868,7 +1013,8 @@ static void write_exe_headers(struct PE_headers * buffer, u16 c_sections, u32 ad .e_oemid = 0x0U, .e_oeminfo = 0x0U, .e_res2 = { 0x0 }, - .e_lfanew = __builtin_offsetof(struct PE_headers, nt_signature), + // .e_lfanew = __builtin_offsetof(struct PE_headers, nt_signature), + .e_lfanew = 256, }, .dos_stub = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -940,12 +1086,12 @@ static void write_exe_headers(struct PE_headers * buffer, u16 c_sections, u32 ad PE_headers.opt_header.SizeOfImage = size_of_image; PE_headers.opt_header.SizeOfHeaders = size_of_headers; - mem_copy(&PE_headers, buffer, sizeof(PE_headers)); + memcpy(buffer, &PE_headers, sizeof(PE_headers)); } static void write_text_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) { IMAGE_SECTION_HEADER* text_section_header = §ion_table[*section_count]; - mem_copy(".text", text_section_header->Name, 6U); + memcpy(text_section_header->Name, ".text", 6U); text_section_header->VirtualAddress = 0x0U; text_section_header->PointerToRawData = 0x0U; @@ -960,7 +1106,7 @@ static void write_text_section_header(IMAGE_SECTION_HEADER* section_table, u16* static void write_data_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) { IMAGE_SECTION_HEADER* data_section_header = §ion_table[*section_count]; - mem_copy(".text", data_section_header->Name, 6U); + memcpy(data_section_header->Name, ".data", 6U); data_section_header->VirtualAddress = 0x0U; data_section_header->PointerToRawData = 0x0U; @@ -975,7 +1121,7 @@ static void write_data_section_header(IMAGE_SECTION_HEADER* section_table, u16* static void write_bss_section_header(IMAGE_SECTION_HEADER* section_table, u16* section_count) { IMAGE_SECTION_HEADER* bss_section_header = §ion_table[*section_count]; - mem_copy(".text", bss_section_header->Name, 6U); + memcpy(bss_section_header->Name, ".bss", 6U); bss_section_header->VirtualAddress = 0x0U; bss_section_header->PointerToRawData = 0x0U; @@ -1144,7 +1290,7 @@ int mainCRTStartup(void) { for (u32 COFF_section_index = 0U; COFF_section_index < c_COFF_sections; COFF_section_index++) { struct COFF_sections const* cur_section = §ions[COFF_section_index]; if ( cur_section->text_section_off ) { - mem_copy((void*)(cur_section->file_buffer + cur_section->text_section_off), text_start, cur_section->text_section_size); + memcpy(text_start, (void*)(cur_section->file_buffer + cur_section->text_section_off), cur_section->text_section_size); section_table[0U].SizeOfRawData = ALIGN(cur_section->text_section_size, FILE_ALIGNMENT); section_table[0U].Misc.VirtualSize = ALIGN(cur_section->text_section_size, SECTION_ALIGNMENT); } -- cgit v1.3