diff options
| -rw-r--r-- | src/main.c | 794 |
1 files changed, 537 insertions, 257 deletions
@@ -1,18 +1,274 @@ -// #include <winternl.h> -#include <Windows.h> +// #include <Windows.h> +#include <stdarg.h> -#include <stdint.h> -#include <winnt.h> +#define NULL 0U -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; +typedef long HRESULT; +#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; +#define VOID void +typedef unsigned __int64 ULONGLONG; +typedef __int64 LONGLONG; +typedef char CHAR; +typedef short SHORT; +typedef long LONG; +typedef unsigned long DWORD; +typedef int BOOL; +typedef unsigned char BYTE; +typedef unsigned short WORD; + +typedef int INT; +typedef unsigned int UINT; +typedef unsigned int *PUINT; +typedef void* HANDLE; + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; + +typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; +} LARGE_INTEGER; + +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *PFILETIME, *LPFILETIME; + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + WORD e_magic; // Magic number + WORD e_cblp; // Bytes on last page of file + WORD e_cp; // Pages in file + WORD e_crlc; // Relocations + WORD e_cparhdr; // Size of header in paragraphs + WORD e_minalloc; // Minimum extra paragraphs needed + WORD e_maxalloc; // Maximum extra paragraphs needed + WORD e_ss; // Initial (relative) SS value + WORD e_sp; // Initial SP value + WORD e_csum; // Checksum + WORD e_ip; // Initial IP value + WORD e_cs; // Initial (relative) CS value + WORD e_lfarlc; // File address of relocation table + WORD e_ovno; // Overlay number + WORD e_res[4]; // Reserved words + WORD e_oemid; // OEM identifier (for e_oeminfo) + WORD e_oeminfo; // OEM information; e_oemid specific + WORD e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header + } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +// +// Directory format. +// + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +typedef struct _IMAGE_OPTIONAL_HEADER64 { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Aggressively trim working set +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_TARGET_HOST 0x0001 // Useful for indicating we want to interact with the host and not a WoW guest. +#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian +#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian +#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon +#define IMAGE_FILE_MACHINE_CEF 0x0CEF +#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code +#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) +#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian +#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian +#define IMAGE_FILE_MACHINE_CEE 0xC0EE + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define MEM_COMMIT 0x00001000 +#define MEM_RESERVE 0x00002000 +#define MEM_DECOMMIT 0x00004000 +#define MEM_RELEASE 0x00008000 +#define MEM_FREE 0x00010000 + +#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 FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 +#define FILE_SHARE_DELETE 0x00000004 + +#define GENERIC_READ (0x80000000L) +#define GENERIC_WRITE (0x40000000L) +#define GENERIC_EXECUTE (0x20000000L) +#define GENERIC_ALL (0x10000000L) + +#define STD_INPUT_HANDLE ((DWORD)-10) +#define STD_OUTPUT_HANDLE ((DWORD)-11) +#define STD_ERROR_HANDLE ((DWORD)-12) + +// +// Constants +// +#define CREATE_NEW 1 +#define CREATE_ALWAYS 2 +#define OPEN_EXISTING 3 +#define OPEN_ALWAYS 4 +#define TRUNCATE_EXISTING 5 + + typedef __int64 LONG_PTR, *PLONG_PTR; +#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) +#define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. + +void* GetStdHandle(u32); +s32 GetFileSizeEx(void*, LARGE_INTEGER*); +void* CreateFileA(const char*, u32, u32, void*, u32, u32, void*); +s32 ReadFile(void*, void*, u32, u32*, void*); +s32 WriteFile(void*, void*, u32, u32*, void*); +s32 CloseHandle(void*); +u32 GetEnvironmentVariableA(const char*, char*, u32); +void GetSystemTimeAsFileTime(PFILETIME); +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(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) @@ -58,11 +314,14 @@ static void mem_copy(void* src, void* dst, size_t size) { } } -static void mem_set(void* ptr, size_t size, u8 value) { +// static void mem_set(void* ptr, size_t size, u8 value) { +static void* memset(void* ptr, size_t size, u8 value) { u8* bytes = ptr; for (u32 index = 0U; index < size; index++) { bytes[index] = value; } + + return ptr; } static void u64toa(u64 number, char* str, u32 base) { @@ -217,11 +476,31 @@ static void print(const char* format, ...) { } +// +// Section characteristics. +// +// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. +// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. +// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. +// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. +// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. static const u32 BSS_SECTION_FLAGS = (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE); -static const u32 DRECTVE_SECTION_FLAGS = IMAGE_SCN_LNK_INFO; +// static const u32 DRECTVE_SECTION_FLAGS = IMAGE_SCN_LNK_INFO; static const u32 DATA_SECTION_FLAGS = (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE); static const u32 TEXT_SECTION_FLAGS = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ); -static const u64 lib_signature = 0x0A3E686372613C21; // IMAGE_ARCHIVE_START +// static const u64 lib_signature = 0x0A3E686372613C21; // IMAGE_ARCHIVE_START enum { NONE_SECTION_FLAG = 0U, @@ -255,7 +534,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); - mem_set((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]; @@ -269,13 +548,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.LowPart, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + section->file_buffer = (u8*)VirtualAlloc(NULL, file_size.DUMMYSTRUCTNAME.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)); - DWORD bread = 0U; - if (!ReadFile(obj_file_handle, (void*)header, file_size.LowPart, &bread, NULL)) { + u32 bread = 0U; + if (!ReadFile(obj_file_handle, (void*)header, file_size.DUMMYSTRUCTNAME.LowPart, &bread, NULL)) { CloseHandle(obj_file_handle); continue; } @@ -318,242 +597,242 @@ static struct COFF_sections* read_COFFs_header(const char* obj_files[], u32 obj_ return sections; } -static void read_COFF(u8* buffer) { - u8* next_byte = buffer; - IMAGE_FILE_HEADER header = *(IMAGE_FILE_HEADER*)next_byte; - next_byte += sizeof(header); - - if (header.Machine == IMAGE_FILE_MACHINE_AMD64) { - print("MACHINE: x64\n"); - } - - print("SECTIONS: %u\n", header.NumberOfSections); - print("SYMBOLS COUNT: %u\n", header.NumberOfSymbols); - - if (header.SizeOfOptionalHeader > 0U) { - IMAGE_OPTIONAL_HEADER64 optional_header = *(IMAGE_OPTIONAL_HEADER64*)next_byte; - print("MAGIC: %u\n", optional_header.Magic); - next_byte += header.SizeOfOptionalHeader; - } - - IMAGE_SYMBOL* symbol_table = (IMAGE_SYMBOL*)(buffer + header.PointerToSymbolTable); - u8* string_table = (u8*)symbol_table + sizeof(*symbol_table) * header.NumberOfSymbols; - - IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)next_byte; - next_byte += sizeof(sections[0]) * header.NumberOfSections; - for (u32 section_index = 0U; section_index < header.NumberOfSections; section_index++) { - IMAGE_SECTION_HEADER* section = §ions[section_index]; - print("\nSECTION NAME: %s\n", section->Name); - print("SECTION OFFSET: %u\n", section->PointerToRawData); - print("SECTION SIZE: %u\n", section->SizeOfRawData); - print("SECTION RELOCATIONS COUNT: %u\n", section->NumberOfRelocations); - - u8* reloc_start = &buffer[section->PointerToRelocations]; - IMAGE_RELOCATION* cur_reloc_entry = (IMAGE_RELOCATION*)reloc_start; - - // Section relocations - for (u32 reloc_index = 0U; reloc_index < 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("IMAGE_REL_AMD64_ABSOLUTE\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR64) { - print("IMAGE_REL_AMD64_ADDR64\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32) { - print("IMAGE_REL_AMD64_ADDR32\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32NB) { - print("IMAGE_REL_AMD64_ADDR32NB\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32) { - print("IMAGE_REL_AMD64_REL32\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_1) { - print("IMAGE_REL_AMD64_REL32_1\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_2) { - print("IMAGE_REL_AMD64_REL32_2\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_3) { - print("IMAGE_REL_AMD64_REL32_3\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_4) { - print("IMAGE_REL_AMD64_REL32_4\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_5) { - print("IMAGE_REL_AMD64_REL32_5\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECTION) { - print("IMAGE_REL_AMD64_SECTION\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL) { - print("IMAGE_REL_AMD64_SECREL\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL7) { - print("IMAGE_REL_AMD64_SECREL7\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_TOKEN) { - print("IMAGE_REL_AMD64_TOKEN\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SREL32) { - print("IMAGE_REL_AMD64_SREL32\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_PAIR) { - print("IMAGE_REL_AMD64_PAIR\n"); - } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SSPAN32) { - print("IMAGE_REL_AMD64_SSPAN32\n"); - } - } - - if (section->Characteristics & DRECTVE_SECTION_FLAGS) // .drectve - { - u8* drectve_start = &buffer[section->PointerToRawData]; - print("%s\n", drectve_start); - } else if ((section->Characteristics & DATA_SECTION_FLAGS) == DATA_SECTION_FLAGS) { // .data - u8* data_start = &buffer[section->PointerToRawData]; - u8* cur_data = data_start; - while ((cur_data - data_start) < section->SizeOfRawData) { - size_t len = str_len((const char*) cur_data, section->SizeOfRawData); - if (len == 0U) { - cur_data++; - } else { - print("%s\n", cur_data); - cur_data += len; - } - } - } else if ((section->Characteristics & TEXT_SECTION_FLAGS) == TEXT_SECTION_FLAGS) { // .text - // u8* text_start = &buffer[section->pointer_to_raw_data]; - } - } - print("\n"); - - // TODO: Check that this doesn't overlap with sections relocation symbols - IMAGE_SYMBOL* cur_symbol = symbol_table; - for (u32 symbol_index = 0U; symbol_index < header.NumberOfSymbols; symbol_index++, cur_symbol++) { - - if (cur_symbol->N.Name.Short == 0U) { - // use longname - print("SYMBOL NAME : %s\n", string_table + cur_symbol->N.Name.Long); - } else { - print("SYMBOL NAME : %s.8\n", cur_symbol->N.ShortName); - } - - if (cur_symbol->SectionNumber > 1) { - print("SECTION: %s\n", sections[(u16)cur_symbol->SectionNumber - 1U].Name); - } else if (cur_symbol->SectionNumber == IMAGE_SYM_UNDEFINED) { - print("SECTION: EXTERNAL SYMBOL\n"); - } else if (cur_symbol->SectionNumber == IMAGE_SYM_ABSOLUTE) { - print("SECTION: ABSOLUTE\n"); - } else if (cur_symbol->SectionNumber == IMAGE_SYM_DEBUG) { - print("SECTION: DEBUG\n"); - } - - if (cur_symbol->NumberOfAuxSymbols > 0U) { - cur_symbol += cur_symbol->NumberOfAuxSymbols; - symbol_index++; - } - } - print("\n"); -} +// static void read_COFF(u8* buffer) { +// u8* next_byte = buffer; +// IMAGE_FILE_HEADER header = *(IMAGE_FILE_HEADER*)next_byte; +// next_byte += sizeof(header); +// +// if (header.Machine == IMAGE_FILE_MACHINE_AMD64) { +// print("MACHINE: x64\n"); +// } +// +// print("SECTIONS: %u\n", header.NumberOfSections); +// print("SYMBOLS COUNT: %u\n", header.NumberOfSymbols); +// +// if (header.SizeOfOptionalHeader > 0U) { +// IMAGE_OPTIONAL_HEADER64 optional_header = *(IMAGE_OPTIONAL_HEADER64*)next_byte; +// print("MAGIC: %u\n", optional_header.Magic); +// next_byte += header.SizeOfOptionalHeader; +// } +// +// IMAGE_SYMBOL* symbol_table = (IMAGE_SYMBOL*)(buffer + header.PointerToSymbolTable); +// u8* string_table = (u8*)symbol_table + sizeof(*symbol_table) * header.NumberOfSymbols; +// +// IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)next_byte; +// next_byte += sizeof(sections[0]) * header.NumberOfSections; +// for (u32 section_index = 0U; section_index < header.NumberOfSections; section_index++) { +// IMAGE_SECTION_HEADER* section = §ions[section_index]; +// print("\nSECTION NAME: %s\n", section->Name); +// print("SECTION OFFSET: %u\n", section->PointerToRawData); +// print("SECTION SIZE: %u\n", section->SizeOfRawData); +// print("SECTION RELOCATIONS COUNT: %u\n", section->NumberOfRelocations); +// +// u8* reloc_start = &buffer[section->PointerToRelocations]; +// IMAGE_RELOCATION* cur_reloc_entry = (IMAGE_RELOCATION*)reloc_start; +// +// // Section relocations +// for (u32 reloc_index = 0U; reloc_index < 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("IMAGE_REL_AMD64_ABSOLUTE\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR64) { +// print("IMAGE_REL_AMD64_ADDR64\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32) { +// print("IMAGE_REL_AMD64_ADDR32\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_ADDR32NB) { +// print("IMAGE_REL_AMD64_ADDR32NB\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32) { +// print("IMAGE_REL_AMD64_REL32\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_1) { +// print("IMAGE_REL_AMD64_REL32_1\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_2) { +// print("IMAGE_REL_AMD64_REL32_2\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_3) { +// print("IMAGE_REL_AMD64_REL32_3\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_4) { +// print("IMAGE_REL_AMD64_REL32_4\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_REL32_5) { +// print("IMAGE_REL_AMD64_REL32_5\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECTION) { +// print("IMAGE_REL_AMD64_SECTION\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL) { +// print("IMAGE_REL_AMD64_SECREL\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SECREL7) { +// print("IMAGE_REL_AMD64_SECREL7\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_TOKEN) { +// print("IMAGE_REL_AMD64_TOKEN\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SREL32) { +// print("IMAGE_REL_AMD64_SREL32\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_PAIR) { +// print("IMAGE_REL_AMD64_PAIR\n"); +// } else if (cur_reloc_entry->Type == IMAGE_REL_AMD64_SSPAN32) { +// print("IMAGE_REL_AMD64_SSPAN32\n"); +// } +// } +// +// if (section->Characteristics & DRECTVE_SECTION_FLAGS) // .drectve +// { +// u8* drectve_start = &buffer[section->PointerToRawData]; +// print("%s\n", drectve_start); +// } else if ((section->Characteristics & DATA_SECTION_FLAGS) == DATA_SECTION_FLAGS) { // .data +// u8* data_start = &buffer[section->PointerToRawData]; +// u8* cur_data = data_start; +// while ((cur_data - data_start) < section->SizeOfRawData) { +// size_t len = str_len((const char*) cur_data, section->SizeOfRawData); +// if (len == 0U) { +// cur_data++; +// } else { +// print("%s\n", cur_data); +// cur_data += len; +// } +// } +// } else if ((section->Characteristics & TEXT_SECTION_FLAGS) == TEXT_SECTION_FLAGS) { // .text +// // u8* text_start = &buffer[section->pointer_to_raw_data]; +// } +// } +// print("\n"); +// +// // TODO: Check that this doesn't overlap with sections relocation symbols +// IMAGE_SYMBOL* cur_symbol = symbol_table; +// for (u32 symbol_index = 0U; symbol_index < header.NumberOfSymbols; symbol_index++, cur_symbol++) { +// +// if (cur_symbol->N.Name.Short == 0U) { +// // use longname +// print("SYMBOL NAME : %s\n", string_table + cur_symbol->N.Name.Long); +// } else { +// print("SYMBOL NAME : %s.8\n", cur_symbol->N.ShortName); +// } +// +// if (cur_symbol->SectionNumber > 1) { +// print("SECTION: %s\n", sections[(u16)cur_symbol->SectionNumber - 1U].Name); +// } else if (cur_symbol->SectionNumber == IMAGE_SYM_UNDEFINED) { +// print("SECTION: EXTERNAL SYMBOL\n"); +// } else if (cur_symbol->SectionNumber == IMAGE_SYM_ABSOLUTE) { +// print("SECTION: ABSOLUTE\n"); +// } else if (cur_symbol->SectionNumber == IMAGE_SYM_DEBUG) { +// print("SECTION: DEBUG\n"); +// } +// +// if (cur_symbol->NumberOfAuxSymbols > 0U) { +// cur_symbol += cur_symbol->NumberOfAuxSymbols; +// symbol_index++; +// } +// } +// print("\n"); +// } #define BSWAP32(x) ((x & 0x000000FF) << 24U) | ((x & 0x0000FF00) << 8U) | ((x & 0x00FF0000) >> 8U) | ((x & 0xFF000000) >> 24U) -static void read_lib(u8* buffer) { - u8* next_byte = buffer; - - { - print("FIRST LINKER MEMBER\n"); - IMAGE_ARCHIVE_MEMBER_HEADER* first_linker_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; - next_byte += sizeof(*first_linker_member); - if (first_linker_member->Name[0U] != '/') { // IMAGE_ARCHIVE_LINKER_MEMBER - return; - } - - u32 symbols_count = BSWAP32(*(u32*)next_byte); - next_byte += sizeof(symbols_count); - - u32* first_linker_offsets = (u32*)next_byte; - next_byte += sizeof(*first_linker_offsets) * symbols_count; - - u8* first_linker_string_table = next_byte; - u8* cur_string = first_linker_string_table; - for (u32 index = 0U; index < symbols_count; index++) { - size_t size = str_len((const char*)cur_string, 256U); - print("%s\n", cur_string); - cur_string += size + 1U; - } - - next_byte += cur_string - first_linker_string_table; - } - - u32 archive_members_count = 0U; - { - print("SECOND LINKER MEMBER\n"); - IMAGE_ARCHIVE_MEMBER_HEADER* second_linker_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; - next_byte += sizeof(*second_linker_member); - if (second_linker_member->Name[0U] != '/') { // IMAGE_ARCHIVE_LINKER_MEMBER - return; - } - - archive_members_count = *(u32*)next_byte; - next_byte += sizeof(archive_members_count); - - u32* archive_members_offsets = (u32*)next_byte; - next_byte += sizeof(*archive_members_offsets) * archive_members_count; - - u32 symbols_count = *(u32*)next_byte; - next_byte += sizeof(symbols_count); - - u16* symbols_indices = (u16*)next_byte; - next_byte += sizeof(*symbols_indices) * symbols_count; - - u8* second_linker_string_table = next_byte; - u8* cur_string = second_linker_string_table; - for (u32 index = 0U; index < symbols_count; index++) { - size_t size = str_len((const char*)cur_string, 256U); - print("%s\n", cur_string); - cur_string += size + 1U; - } - next_byte += cur_string - second_linker_string_table; - } - - { - IMAGE_ARCHIVE_MEMBER_HEADER* longnames_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; - if (longnames_member->Name[0U] == '/' && longnames_member->Name[1U] == '/') { // IMAGE_ARCHIVE_LONGNAMES_MEMBER - next_byte += sizeof(*longnames_member); - } - } - - print("ARCHIVE COUNT: %u\n", archive_members_count); - for (u32 archive_index = 0U; archive_index < archive_members_count; archive_index++) { - next_byte += (u64)next_byte % 2U; - IMAGE_ARCHIVE_MEMBER_HEADER* header = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; - next_byte += sizeof(*header); - - u32 size = 0U; - for (u8* c = (u8*)header->Size; *c != 0x20 && size< sizeof(header->Size) / sizeof(header->Size[0U]); c++, size++) { - } - u64 archive_size = atou64((char*)header->Size, size); - - - print("ARCHIVE NAME: %s.16\n", header->Name); - print("ARCHIVE SIZE: %s.10, %u\n", header->Size, archive_size); - - if (header->Name[0U] == '/') { // Special member - next_byte += archive_size; - continue; - } - - if (*(u16*)next_byte == 0U) { - IMPORT_OBJECT_HEADER* import_header = (IMPORT_OBJECT_HEADER*)next_byte; - char* import_name = (char*)next_byte + sizeof(*import_header); - - size_t len = str_len((char*)import_name, 256U); - print("IMPORT NAME: %s\n", import_name); - - char* dll_name = import_name + len; - print("DLL NAME: %s\n", dll_name); - } else { - read_COFF(next_byte); - } - next_byte += archive_size; - print("\n"); - } -} +// static void read_lib(u8* buffer) { +// u8* next_byte = buffer; +// +// { +// print("FIRST LINKER MEMBER\n"); +// IMAGE_ARCHIVE_MEMBER_HEADER* first_linker_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; +// next_byte += sizeof(*first_linker_member); +// if (first_linker_member->Name[0U] != '/') { // IMAGE_ARCHIVE_LINKER_MEMBER +// return; +// } +// +// u32 symbols_count = BSWAP32(*(u32*)next_byte); +// next_byte += sizeof(symbols_count); +// +// u32* first_linker_offsets = (u32*)next_byte; +// next_byte += sizeof(*first_linker_offsets) * symbols_count; +// +// u8* first_linker_string_table = next_byte; +// u8* cur_string = first_linker_string_table; +// for (u32 index = 0U; index < symbols_count; index++) { +// size_t size = str_len((const char*)cur_string, 256U); +// print("%s\n", cur_string); +// cur_string += size + 1U; +// } +// +// next_byte += cur_string - first_linker_string_table; +// } +// +// u32 archive_members_count = 0U; +// { +// print("SECOND LINKER MEMBER\n"); +// IMAGE_ARCHIVE_MEMBER_HEADER* second_linker_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; +// next_byte += sizeof(*second_linker_member); +// if (second_linker_member->Name[0U] != '/') { // IMAGE_ARCHIVE_LINKER_MEMBER +// return; +// } +// +// archive_members_count = *(u32*)next_byte; +// next_byte += sizeof(archive_members_count); +// +// u32* archive_members_offsets = (u32*)next_byte; +// next_byte += sizeof(*archive_members_offsets) * archive_members_count; +// +// u32 symbols_count = *(u32*)next_byte; +// next_byte += sizeof(symbols_count); +// +// u16* symbols_indices = (u16*)next_byte; +// next_byte += sizeof(*symbols_indices) * symbols_count; +// +// u8* second_linker_string_table = next_byte; +// u8* cur_string = second_linker_string_table; +// for (u32 index = 0U; index < symbols_count; index++) { +// size_t size = str_len((const char*)cur_string, 256U); +// print("%s\n", cur_string); +// cur_string += size + 1U; +// } +// next_byte += cur_string - second_linker_string_table; +// } +// +// { +// IMAGE_ARCHIVE_MEMBER_HEADER* longnames_member = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; +// if (longnames_member->Name[0U] == '/' && longnames_member->Name[1U] == '/') { // IMAGE_ARCHIVE_LONGNAMES_MEMBER +// next_byte += sizeof(*longnames_member); +// } +// } +// +// print("ARCHIVE COUNT: %u\n", archive_members_count); +// for (u32 archive_index = 0U; archive_index < archive_members_count; archive_index++) { +// next_byte += (u64)next_byte % 2U; +// IMAGE_ARCHIVE_MEMBER_HEADER* header = (IMAGE_ARCHIVE_MEMBER_HEADER*)next_byte; +// next_byte += sizeof(*header); +// +// u32 size = 0U; +// for (u8* c = (u8*)header->Size; *c != 0x20 && size< sizeof(header->Size) / sizeof(header->Size[0U]); c++, size++) { +// } +// u64 archive_size = atou64((char*)header->Size, size); +// +// +// print("ARCHIVE NAME: %s.16\n", header->Name); +// print("ARCHIVE SIZE: %s.10, %u\n", header->Size, archive_size); +// +// if (header->Name[0U] == '/') { // Special member +// next_byte += archive_size; +// continue; +// } +// +// if (*(u16*)next_byte == 0U) { +// IMPORT_OBJECT_HEADER* import_header = (IMPORT_OBJECT_HEADER*)next_byte; +// char* import_name = (char*)next_byte + sizeof(*import_header); +// +// size_t len = str_len((char*)import_name, 256U); +// print("IMPORT NAME: %s\n", import_name); +// +// char* dll_name = import_name + len; +// print("DLL NAME: %s\n", dll_name); +// } else { +// read_COFF(next_byte); +// } +// next_byte += archive_size; +// print("\n"); +// } +// } struct PE_headers { IMAGE_DOS_HEADER dos_header; @@ -589,7 +868,7 @@ 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 = offsetof(struct PE_headers, nt_signature), + .e_lfanew = __builtin_offsetof(struct PE_headers, nt_signature), }, .dos_stub = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -721,7 +1000,7 @@ int mainCRTStartup(void) { u32 c_arg = 1U; { - LPSTR args = GetCommandLineA(); + char* args = GetCommandLineA(); for (u32 char_index = 0U; *(args + char_index) != '\0'; char_index++) { char c = *(args + char_index); @@ -744,7 +1023,8 @@ int mainCRTStartup(void) { print("arg : %s, arg size : %u\n", arg, arg_size); } - const char* obj_files[64U] = { NULL }; + // const char* obj_files[64U] = { NULL }; + const char* obj_files[64U]; u32 c_obj_files = 0U; for (u32 arg_index = 0U; arg_index < c_arg; arg_index++) { @@ -829,7 +1109,7 @@ int mainCRTStartup(void) { // TODO: Reserve a huge block and commit when we need more memory u8* exe_buffer = VirtualAlloc(NULL, 4096U * 10U, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - HANDLE output_file = CreateFile("./test.exe", GENERIC_WRITE, 0U, NULL, CREATE_ALWAYS, 0U, NULL); + HANDLE output_file = CreateFileA("./test.exe", GENERIC_WRITE, 0U, NULL, CREATE_ALWAYS, 0U, NULL); // loop through all OBJs header to find out which sections we need u8 sections_flag = 0U; @@ -892,7 +1172,7 @@ int mainCRTStartup(void) { u32 size_of_image = ALIGN(section_table[c_sections - 1U].VirtualAddress + section_table[c_sections - 1U].Misc.VirtualSize, SECTION_ALIGNMENT); write_exe_headers(headers, c_sections, addr_entry_point, base_of_code, size_of_code, headers_size, size_of_image); - DWORD bwrite = 0U; + u32 bwrite = 0U; WriteFile(output_file, exe_buffer, headers->opt_header.SizeOfImage, &bwrite, NULL); ASSERT(bwrite == headers->opt_header.SizeOfImage); |
