Improve PE deciphering
This commit is contained in:
parent
dacb9334e5
commit
e75a4a7855
@ -738,6 +738,7 @@ fn u64 strlen (const char* c_string)
|
||||
#define strlit(s) (String){ .pointer = (u8*)(s), .length = strlit_len(s), }
|
||||
#define ch_to_str(ch) (String){ .pointer = &ch, .length = 1 }
|
||||
#define array_to_slice(arr) { .pointer = (arr), .length = array_length(arr) }
|
||||
#define array_to_bytes(arr) { .pointer = (u8*)(arr), .length = sizeof(arr) }
|
||||
#define pointer_to_bytes(p) (String) { .pointer = (u8*)(p), .length = sizeof(*p) }
|
||||
#define struct_to_bytes(s) pointer_to_bytes(&(s))
|
||||
#define string_to_c(s) ((char*)((s).pointer))
|
||||
@ -3240,6 +3241,7 @@ may_be_unused fn u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
|
||||
|
||||
#define vb_add(a, count) (typeof((a)->pointer)) vb_generic_add((VirtualBuffer(u8)*)(a), sizeof(*((a)->pointer)), count)
|
||||
#define vb_add_struct(a, S) (S*) vb_generic_add(a, 1, sizeof(S))
|
||||
#define vb_copy_struct(vb, s) *vb_add_struct(vb, typeof(s)) = s
|
||||
#define vb_append_struct(a, T, s) *(vb_add_struct(a, T)) = s
|
||||
#define vb_append_one(a, item) (typeof((a)->pointer)) vb_generic_append((VirtualBuffer(u8)*)(a), &(item), sizeof(*((a)->pointer)), 1)
|
||||
#define vb_to_bytes(vb) (Slice(u8)) { .pointer = (u8*)((vb).pointer), .length = sizeof(*((vb).pointer)) * (vb).length, }
|
||||
|
246
bootstrap/main.c
246
bootstrap/main.c
@ -38,6 +38,7 @@ fn String file_read(Arena* arena, String path)
|
||||
.truncate = 0,
|
||||
.executable = 0,
|
||||
});
|
||||
|
||||
if (os_file_descriptor_is_valid(file_descriptor))
|
||||
{
|
||||
auto file_size = os_file_get_size(file_descriptor);
|
||||
@ -10788,9 +10789,14 @@ STRUCT(COFFLoaderFlags)
|
||||
|
||||
static_assert(sizeof(COFFLoaderFlags) == sizeof(u32));
|
||||
|
||||
STRUCT(COFFSignature)
|
||||
{
|
||||
u8 data[4];
|
||||
};
|
||||
|
||||
STRUCT(COFFHeader)
|
||||
{
|
||||
u32 signature;
|
||||
COFFSignature signature;
|
||||
COFFArchitecture architecture;
|
||||
u16 section_count;
|
||||
u32 time_date_stamp;
|
||||
@ -10902,13 +10908,116 @@ fn COFFSectionName coff_section_name(String name)
|
||||
return result;
|
||||
}
|
||||
|
||||
STRUCT(COFFExceptionTableEntry_x86_64)
|
||||
{
|
||||
u32 start_rva;
|
||||
u32 end_rva;
|
||||
u32 unwind_information_rva;
|
||||
};
|
||||
|
||||
typedef enum COFFDebugType : u32
|
||||
{
|
||||
COFF_DEBUG_UNKNOWN = 0,
|
||||
COFF_DEBUG_COFF = 1,
|
||||
COFF_DEBUG_CODEVIEW = 2,
|
||||
COFF_DEBUG_FPO = 3,
|
||||
COFF_DEBUG_MISC = 4,
|
||||
COFF_DEBUG_EXCEPTION = 5,
|
||||
COFF_DEBUG_FIXUP = 6,
|
||||
COFF_DEBUG_OMAP_TO_SRC = 7,
|
||||
COFF_DEBUG_OMAP_FROM_SRC = 8,
|
||||
COFF_DEBUG_BORLAND = 9,
|
||||
COFF_DEBUG_RESERVED10 = 10,
|
||||
COFF_DEBUG_CLSID = 11,
|
||||
COFF_DEBUG_REPRO = 16,
|
||||
COFF_DEBUG_EXTENDED_DLL_CHARACTERISTICS = 20,
|
||||
} COFFDebugType;
|
||||
|
||||
STRUCT(COFFDebugDirectory)
|
||||
{
|
||||
u32 characteristics;
|
||||
u32 timestamp;
|
||||
u16 major_version;
|
||||
u16 minor_version;
|
||||
COFFDebugType type;
|
||||
u32 data_size;
|
||||
u32 data_rva;
|
||||
u32 data_offset;
|
||||
};
|
||||
|
||||
STRUCT(COFFGUID)
|
||||
{
|
||||
u8 data[16];
|
||||
};
|
||||
|
||||
STRUCT(COFFRSDS)
|
||||
{
|
||||
COFFSignature signature;
|
||||
COFFGUID guid;
|
||||
u32 age;
|
||||
u8 path[];
|
||||
};
|
||||
|
||||
static_assert(sizeof(COFFRSDS) == 4 + 16 + 4);
|
||||
|
||||
fn void file_write_coff_rsds(VirtualBuffer(u8)* file, String guid, u32 age, String path)
|
||||
{
|
||||
assert(guid.length == 16);
|
||||
assert(path.pointer[path.length] == 0);
|
||||
|
||||
COFFRSDS rsds = {
|
||||
.signature = { 'R', 'S', 'D', 'S' },
|
||||
.age = age,
|
||||
};
|
||||
memcpy(rsds.guid.data, guid.pointer, 16);
|
||||
|
||||
vb_copy_struct(file, rsds);
|
||||
|
||||
auto string_size = cast(u32, u64, path.length + 1);
|
||||
memcpy(vb_add(file, string_size), path.pointer, string_size);
|
||||
}
|
||||
|
||||
STRUCT(COFFImportDirectory)
|
||||
{
|
||||
u32 lookup_table_rva;
|
||||
u32 time_date_stamp;
|
||||
u32 forwarder_chain;
|
||||
u32 dll_name_rva;
|
||||
u32 address_table_rva;
|
||||
};
|
||||
|
||||
STRUCT(COFFImportLookup)
|
||||
{
|
||||
u32 name_table_rva;
|
||||
u8 padding[4];
|
||||
};
|
||||
|
||||
STRUCT(COFFImportAddress)
|
||||
{
|
||||
u32 name_table_rva;
|
||||
u8 padding[4];
|
||||
};
|
||||
|
||||
STRUCT(COFFImportName)
|
||||
{
|
||||
u16 hint;
|
||||
u8 name[];
|
||||
};
|
||||
|
||||
fn void coff_import_name(VirtualBuffer(u8)* file, u16 hint, String name)
|
||||
{
|
||||
vb_copy_struct(file, hint);
|
||||
|
||||
auto name_size = cast(u32, u64, name.length + 1);
|
||||
memcpy(vb_add(file, name_size), name.pointer, name_size);
|
||||
}
|
||||
|
||||
may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
{
|
||||
VirtualBuffer(u8) file = {};
|
||||
auto* mz = "MZ";
|
||||
auto signature = *(u16*)mz;
|
||||
*vb_add_struct(&file, DOSHeader) = (DOSHeader)
|
||||
{
|
||||
auto dos_header = (DOSHeader){
|
||||
.signature = signature,
|
||||
.extra_page_size = 144,
|
||||
.page_count = 3,
|
||||
@ -10925,6 +11034,8 @@ may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
.overlay_number = 0,
|
||||
.coff_header_pointer = 208,
|
||||
};
|
||||
vb_copy_struct(&file, dos_header);
|
||||
|
||||
u8 code[] = { 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, };
|
||||
vb_add_array(&file, code);
|
||||
|
||||
@ -10999,9 +11110,10 @@ may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
.directory_count = array_length(directories),
|
||||
};
|
||||
|
||||
u8 coff_signature[] = { 'P', 'E', 0, 0 };
|
||||
auto coff_header = (COFFHeader) {
|
||||
.signature = *(u32*)coff_signature,
|
||||
.signature = {
|
||||
.data = { 'P', 'E', 0, 0 },
|
||||
},
|
||||
.architecture = COFF_ARCH_AMD64,
|
||||
.section_count = 3,
|
||||
.time_date_stamp = 1727882096,
|
||||
@ -11058,21 +11170,45 @@ may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
};
|
||||
vb_add_array(&file, section_headers);
|
||||
|
||||
// .text
|
||||
vb_align(&file, 0x200);
|
||||
assert(file.length == 0x400);
|
||||
u8 text_content[] = { 0x48, 0x83, 0xEC, 0x28, 0x33, 0xC9, 0xFF, 0x15, 0xF4, 0x0F, 0x00, 0x00, 0x90, 0x48, 0x83, 0xC4, 0x28, 0xC3, };
|
||||
vb_add_array(&file, text_content);
|
||||
|
||||
u8 rdata_content[] = {
|
||||
0xF0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x70, 0x63, 0xFD, 0x66, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x84, 0x20, 0x00, 0x00, 0x84, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x70, 0x63, 0xFD, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0xC0, 0x20, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x63, 0xFD, 0x66,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00, 0xD4, 0x20, 0x00, 0x00,
|
||||
0xD4, 0x06, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7C, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x12, 0x00, 0x00, 0x00, 0x52, 0x53, 0x44, 0x53, 0x3D, 0x15, 0x84, 0x0A, 0xBC, 0x9F, 0xA1, 0x4B,
|
||||
0x82, 0xB4, 0x94, 0xF1, 0x5B, 0x91, 0x63, 0x3A, 0x03, 0x00, 0x00, 0x00, 0x43, 0x3A, 0x5C, 0x55,
|
||||
0x73, 0x65, 0x72, 0x73, 0x5C, 0x44, 0x61, 0x76, 0x69, 0x64, 0x5C, 0x64, 0x65, 0x76, 0x5C, 0x6D,
|
||||
0x69, 0x6E, 0x69, 0x6D, 0x61, 0x6C, 0x5C, 0x6D, 0x61, 0x69, 0x6E, 0x2E, 0x70, 0x64, 0x62, 0x00,
|
||||
// .rdata
|
||||
vb_align(&file, 0x200);
|
||||
assert(file.length == 0x600);
|
||||
u8 rdata_chunk_0[] = { 0xF0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
|
||||
vb_add_array(&file, rdata_chunk_0);
|
||||
|
||||
COFFDebugDirectory debug_directory = {
|
||||
.characteristics = 0,
|
||||
.timestamp = 1727882096,
|
||||
.major_version = 0,
|
||||
.minor_version = 0,
|
||||
.type = COFF_DEBUG_CODEVIEW,
|
||||
.data_size = 60,
|
||||
.data_rva = 0x2084,
|
||||
.data_offset = 0x684,
|
||||
};
|
||||
vb_copy_struct(&file, debug_directory);
|
||||
|
||||
u8 rdata_chunk_1[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x70, 0x63, 0xFD, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x70, 0x63, 0xFD, 0x66, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0xDC, 0x00, 0x00, 0x00,
|
||||
0xD4, 0x20, 0x00, 0x00, 0xD4, 0x06, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
};
|
||||
vb_add_array(&file, rdata_chunk_1);
|
||||
|
||||
u8 rsds_guid[] = { 0x3D, 0x15, 0x84, 0x0A, 0xBC, 0x9F, 0xA1, 0x4B, 0x82, 0xB4, 0x94, 0xF1, 0x5B, 0x91, 0x63, 0x3A, };
|
||||
u32 rsds_age = 3;
|
||||
file_write_coff_rsds(&file, (String)array_to_slice(rsds_guid), rsds_age, strlit("C:\\Users\\David\\dev\\minimal\\main.pdb"));
|
||||
|
||||
u8 rdata_chunk_2[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x2E, 0x74, 0x65, 0x78, 0x74, 0x24, 0x6D, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||
@ -11088,32 +11224,68 @@ may_be_unused fn String write_pe(Thread* thread, ObjectOptions options)
|
||||
0x2E, 0x69, 0x64, 0x61, 0x74, 0x61, 0x24, 0x34, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x21, 0x00, 0x00,
|
||||
0x1C, 0x00, 0x00, 0x00, 0x2E, 0x69, 0x64, 0x61, 0x74, 0x61, 0x24, 0x36, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x2E, 0x70, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00,
|
||||
0x01, 0x04, 0x01, 0x00, 0x04, 0x42, 0x00, 0x00, 0xE0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFE, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x78, 0x01, 0x45, 0x78, 0x69, 0x74, 0x50, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x00, 0x4B, 0x45,
|
||||
0x52, 0x4E, 0x45, 0x4C, 0x33, 0x32, 0x2E, 0x64, 0x6C, 0x6C, 0x00, 0x00,
|
||||
0x01, 0x04, 0x01, 0x00, 0x04, 0x42, 0x00, 0x00,
|
||||
};
|
||||
vb_add_array(&file, rdata_chunk_2);
|
||||
|
||||
assert(file.length == 0x7b8);
|
||||
// IAT
|
||||
COFFImportDirectory import_directories[] = {
|
||||
{
|
||||
.lookup_table_rva = 0x21e0,
|
||||
.time_date_stamp = 0,
|
||||
.forwarder_chain = 0,
|
||||
.dll_name_rva = 0x21fe,
|
||||
.address_table_rva = 0x2000,
|
||||
},
|
||||
};
|
||||
|
||||
u8 pdata_content[] = { 0x00, 0x10, 0x00, 0x00, 0x12, 0x10, 0x00, 0x00, 0xB0, 0x21, 0x00, 0x00, };
|
||||
assert(import_directories[array_length(import_directories) - 1].forwarder_chain == 0);
|
||||
vb_add_array(&file, import_directories);
|
||||
|
||||
String section_contents[] = {
|
||||
{ text_content, sizeof(text_content) },
|
||||
{ rdata_content, sizeof(rdata_content) },
|
||||
{ pdata_content, sizeof(pdata_content) },
|
||||
u8 weird_padding[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
|
||||
vb_add_array(&file, weird_padding);
|
||||
|
||||
COFFImportLookup import_lookups[] = {
|
||||
{
|
||||
.name_table_rva = 0x21f0,
|
||||
},
|
||||
};
|
||||
assert(array_length(import_directories) == array_length(import_lookups));
|
||||
vb_add_array(&file, import_lookups);
|
||||
|
||||
// This goes back to the first .rdata offset
|
||||
// COFFImportAddress import_addresses[] = {
|
||||
// {
|
||||
// .name_table_rva = 0x21f0,
|
||||
// },
|
||||
// };
|
||||
|
||||
vb_align(&file, 0x10);
|
||||
assert(file.length == 0x7f0);
|
||||
|
||||
coff_import_name(&file, 376, strlit("ExitProcess"));
|
||||
|
||||
assert(file.length == 0x7fe);
|
||||
|
||||
auto dll_name = strlit("KERNEL32.dll");
|
||||
auto dll_name_size = cast(u32, u64, dll_name.length + 1);
|
||||
memcpy(vb_add(&file, dll_name_size), dll_name.pointer, dll_name_size);
|
||||
|
||||
// .pdata content
|
||||
vb_align(&file, 0x200);
|
||||
|
||||
for (u32 i = 0; i < array_length(section_contents); i += 1)
|
||||
{
|
||||
auto section_content = section_contents[i];
|
||||
assert(file.length == 0xa00);
|
||||
COFFExceptionTableEntry_x86_64 pdata_content[] = {
|
||||
{
|
||||
.start_rva = 0x1000,
|
||||
.end_rva = 0x1012,
|
||||
.unwind_information_rva = 0x21b0,
|
||||
},
|
||||
};
|
||||
vb_add_array(&file, pdata_content);
|
||||
|
||||
memcpy(vb_add(&file, cast(u32, u64, section_content.length)), section_content.pointer, section_content.length);
|
||||
|
||||
vb_align(&file, 0x200);
|
||||
}
|
||||
vb_align(&file, 0x200);
|
||||
|
||||
// Check if file matches
|
||||
#define CHECK_PE_MATCH 0
|
||||
@ -13527,8 +13699,6 @@ STRUCT(MachOSection)
|
||||
};
|
||||
static_assert(sizeof(MachOSection) == 0x50);
|
||||
|
||||
#define vb_copy_struct(vb, s) *vb_add_struct(&file, typeof(s)) = s
|
||||
|
||||
may_be_unused fn String write_macho(Thread* restrict thread, ObjectOptions options)
|
||||
{
|
||||
unused(thread);
|
||||
|
Loading…
x
Reference in New Issue
Block a user