aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c794
1 files changed, 537 insertions, 257 deletions
diff --git a/src/main.c b/src/main.c
index 6d63575..aac79c7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 = &sections[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 = &sections[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 = &sections[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);