mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-04 12:58:41 +00:00
pe: added helpers for image checksum debug directory, and entry point names
This commit is contained in:
+172
-20
@@ -25,28 +25,48 @@ pe_slot_count_from_unwind_op_code(PE_UnwindOpCode opcode)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String8
|
read_only struct
|
||||||
pe_string_from_windows_subsystem(PE_WindowsSubsystem subsystem)
|
|
||||||
{
|
{
|
||||||
String8 result = {0};
|
String8 string;
|
||||||
switch(subsystem)
|
PE_WindowsSubsystem type;
|
||||||
{
|
} g_pe_subsystem_map[] = {
|
||||||
default:{}break;
|
{ str8_lit_comp(""), PE_WindowsSubsystem_UNKNOWN },
|
||||||
case PE_WindowsSubsystem_UNKNOWN: result = str8_lit("UNKNOWN"); break;
|
{ str8_lit_comp("native"), PE_WindowsSubsystem_NATIVE },
|
||||||
case PE_WindowsSubsystem_NATIVE: result = str8_lit("NATIVE"); break;
|
{ str8_lit_comp("windows"), PE_WindowsSubsystem_WINDOWS_GUI },
|
||||||
case PE_WindowsSubsystem_WINDOWS_GUI: result = str8_lit("WINDOWS_GUI"); break;
|
{ str8_lit_comp("console"), PE_WindowsSubsystem_WINDOWS_CUI },
|
||||||
case PE_WindowsSubsystem_WINDOWS_CUI: result = str8_lit("WINDOWS_CUI"); break;
|
{ str8_lit_comp("os2_cui"), PE_WindowsSubsystem_OS2_CUI },
|
||||||
case PE_WindowsSubsystem_OS2_CUI: result = str8_lit("OS2_CUI"); break;
|
{ str8_lit_comp("posix"), PE_WindowsSubsystem_POSIX_CUI },
|
||||||
case PE_WindowsSubsystem_POSIX_CUI: result = str8_lit("POSIX_CUI"); break;
|
{ str8_lit_comp("native_windows"), PE_WindowsSubsystem_NATIVE_WINDOWS },
|
||||||
case PE_WindowsSubsystem_NATIVE_WINDOWS: result = str8_lit("NATIVE_WINDOWS"); break;
|
{ str8_lit_comp("windows_ce_gui"), PE_WindowsSubsystem_WINDOWS_CE_GUI },
|
||||||
case PE_WindowsSubsystem_WINDOWS_CE_GUI: result = str8_lit("WINDOWS_CE_GUID"); break;
|
{ str8_lit_comp("efi_application"), PE_WindowsSubsystem_EFI_APPLICATION },
|
||||||
case PE_WindowsSubsystem_EFI_APPLICATION: result = str8_lit("EFI_APPLICATION"); break;
|
{ str8_lit_comp("efi_boot_service_driver"), PE_WindowsSubsystem_EFI_BOOT_SERVICE_DRIVER },
|
||||||
case PE_WindowsSubsystem_EFI_BOOT_SERVICE_DRIVER: result = str8_lit("EFI_BOOT_SERVICE_DRIVER"); break;
|
{ str8_lit_comp("efi_runtime_driver"), PE_WindowsSubsystem_EFI_RUNTIME_DRIVER },
|
||||||
case PE_WindowsSubsystem_EFI_ROM: result = str8_lit("EFI_ROM"); break;
|
{ str8_lit_comp("efi_rom"), PE_WindowsSubsystem_EFI_ROM },
|
||||||
case PE_WindowsSubsystem_XBOX: result = str8_lit("XBOX"); break;
|
{ str8_lit_comp("xbox"), PE_WindowsSubsystem_XBOX },
|
||||||
case PE_WindowsSubsystem_WINDOWS_BOOT_APPLICATION: result = str8_lit("WINDOWS_BOOT_APPLICATION"); break;
|
{ str8_lit_comp("windows_boot_application"), PE_WindowsSubsystem_WINDOWS_BOOT_APPLICATION },
|
||||||
|
};
|
||||||
|
StaticAssert(ArrayCount(g_pe_subsystem_map) == PE_WindowsSubsystem_COUNT, g_pe_subsystem_map_count_check);
|
||||||
|
|
||||||
|
internal String8
|
||||||
|
pe_string_from_subsystem(PE_WindowsSubsystem subsystem)
|
||||||
|
{
|
||||||
|
for (U64 i = 0; i < ArrayCount(g_pe_subsystem_map); i += 1) {
|
||||||
|
if (g_pe_subsystem_map[i].type == subsystem) {
|
||||||
|
return g_pe_subsystem_map[i].string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return str8(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal PE_WindowsSubsystem
|
||||||
|
pe_subsystem_from_string(String8 string)
|
||||||
|
{
|
||||||
|
for (U64 i = 0; i < ArrayCount(g_pe_subsystem_map); i += 1) {
|
||||||
|
if (str8_match(g_pe_subsystem_map[i].string, string, StringMatchFlag_CaseInsensitive)) {
|
||||||
|
return g_pe_subsystem_map[i].type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PE_WindowsSubsystem_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
@@ -548,6 +568,74 @@ pe_tls_rng_from_bin_base_vaddr(String8 data, PE_BinInfo *bin, U64 base_vaddr)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal String8Array
|
||||||
|
pe_get_entry_point_names(COFF_MachineType machine,
|
||||||
|
PE_WindowsSubsystem subsystem,
|
||||||
|
PE_ImageFileCharacteristics file_characteristics)
|
||||||
|
{
|
||||||
|
String8Array entry_point_names = {0};
|
||||||
|
|
||||||
|
if (file_characteristics & PE_ImageFileCharacteristic_FILE_DLL) {
|
||||||
|
if (machine == COFF_MachineType_X86) {
|
||||||
|
read_only static String8 dll_entry_point_arr[] = {
|
||||||
|
str8_lit_comp("__DllMainCRTStartup@12"),
|
||||||
|
};
|
||||||
|
|
||||||
|
entry_point_names.v = &dll_entry_point_arr[0];
|
||||||
|
entry_point_names.count = ArrayCount(dll_entry_point_arr);
|
||||||
|
} else {
|
||||||
|
read_only static String8 dll_entry_point_arr[] = {
|
||||||
|
str8_lit_comp("_DllMainCRTStartup"),
|
||||||
|
};
|
||||||
|
|
||||||
|
entry_point_names.v = &dll_entry_point_arr[0];
|
||||||
|
entry_point_names.count = ArrayCount(dll_entry_point_arr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (subsystem) {
|
||||||
|
case PE_WindowsSubsystem_UNKNOWN: break;
|
||||||
|
case PE_WindowsSubsystem_WINDOWS_GUI: {
|
||||||
|
read_only static String8 gui_entry_point_arr[] = {
|
||||||
|
str8_lit_comp("WinMain"),
|
||||||
|
str8_lit_comp("wWinMain"),
|
||||||
|
str8_lit_comp("WinMainCRTStartup"),
|
||||||
|
str8_lit_comp("wWinMainCRTStartup"),
|
||||||
|
};
|
||||||
|
|
||||||
|
entry_point_names.v = &gui_entry_point_arr[0];
|
||||||
|
entry_point_names.count = ArrayCount(gui_entry_point_arr);
|
||||||
|
} break;
|
||||||
|
case PE_WindowsSubsystem_WINDOWS_CUI: {
|
||||||
|
read_only static String8 cui_entry_point_arr[] = {
|
||||||
|
str8_lit_comp("main"),
|
||||||
|
str8_lit_comp("wmain"),
|
||||||
|
str8_lit_comp("mainCRTStartup"),
|
||||||
|
str8_lit_comp("wmainCRTStartup"),
|
||||||
|
};
|
||||||
|
|
||||||
|
entry_point_names.v = &cui_entry_point_arr[0];
|
||||||
|
entry_point_names.count = ArrayCount(cui_entry_point_arr);
|
||||||
|
} break;
|
||||||
|
case PE_WindowsSubsystem_NATIVE:
|
||||||
|
case PE_WindowsSubsystem_OS2_CUI:
|
||||||
|
case PE_WindowsSubsystem_POSIX_CUI:
|
||||||
|
case PE_WindowsSubsystem_NATIVE_WINDOWS:
|
||||||
|
case PE_WindowsSubsystem_WINDOWS_CE_GUI:
|
||||||
|
case PE_WindowsSubsystem_EFI_APPLICATION:
|
||||||
|
case PE_WindowsSubsystem_EFI_BOOT_SERVICE_DRIVER:
|
||||||
|
case PE_WindowsSubsystem_EFI_RUNTIME_DRIVER:
|
||||||
|
case PE_WindowsSubsystem_EFI_ROM:
|
||||||
|
case PE_WindowsSubsystem_XBOX:
|
||||||
|
case PE_WindowsSubsystem_WINDOWS_BOOT_APPLICATION: {
|
||||||
|
// TODO
|
||||||
|
NotImplemented;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry_point_names;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
internal B32
|
internal B32
|
||||||
@@ -813,3 +901,67 @@ pe_resource_table_from_directory_data(Arena *arena, String8 data)
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return bottom_frame->table;
|
return bottom_frame->table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Debug Directory
|
||||||
|
|
||||||
|
internal String8
|
||||||
|
pe_make_debug_header_pdb70(Arena *arena, OS_Guid guid, U32 age, String8 pdb_path)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
|
PE_CvHeaderPDB70 header = {0};
|
||||||
|
header.magic = PE_CODEVIEW_PDB70_MAGIC;
|
||||||
|
header.guid = guid;
|
||||||
|
header.age = age;
|
||||||
|
|
||||||
|
String8List cv_list = {0};
|
||||||
|
str8_serial_begin(scratch.arena, &cv_list);
|
||||||
|
str8_serial_push_struct(scratch.arena, &cv_list, &header);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &cv_list, pdb_path);
|
||||||
|
|
||||||
|
String8 cv_data = str8_serial_end(arena, &cv_list);
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
return cv_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal String8
|
||||||
|
pe_make_debug_header_rdi(Arena *arena, OS_Guid guid, String8 rdi_path)
|
||||||
|
{
|
||||||
|
Temp scratch = scratch_begin(&arena,1);
|
||||||
|
|
||||||
|
PE_CvHeaderRDI header = {0};
|
||||||
|
header.magic = PE_CODEVIEW_RDI_MAGIC;
|
||||||
|
header.guid = guid;
|
||||||
|
|
||||||
|
String8List list = {0};
|
||||||
|
str8_serial_begin(scratch.arena, &list);
|
||||||
|
str8_serial_push_struct(scratch.arena, &list, &header);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &list, rdi_path);
|
||||||
|
|
||||||
|
String8 cv_data = str8_serial_end(arena, &list);
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
|
return cv_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Image Checksum
|
||||||
|
|
||||||
|
internal U32
|
||||||
|
pe_compute_checksum(U8 *buffer, U64 buffer_size)
|
||||||
|
{
|
||||||
|
// https://bytepointer.com/resources/microsoft_pe_checksum_algo_distilled.htm
|
||||||
|
U32 hash = 0;
|
||||||
|
for (U16 *ptr16 = (U16*)buffer, *opl16 = (U16*)(buffer + buffer_size);
|
||||||
|
ptr16 < opl16;
|
||||||
|
ptr16 += 1) {
|
||||||
|
hash += *ptr16;
|
||||||
|
hash = (hash >> 16) + (hash & 0xffff);
|
||||||
|
}
|
||||||
|
hash = (U16)(((hash >> 16) + hash) & 0xffff);
|
||||||
|
hash += buffer_size;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-8
@@ -357,6 +357,7 @@ struct PE_IntelPdata
|
|||||||
|
|
||||||
#define PE_CODEVIEW_PDB20_MAGIC 0x3031424e
|
#define PE_CODEVIEW_PDB20_MAGIC 0x3031424e
|
||||||
#define PE_CODEVIEW_PDB70_MAGIC 0x53445352
|
#define PE_CODEVIEW_PDB70_MAGIC 0x53445352
|
||||||
|
#define PE_CODEVIEW_RDI_MAGIC '0IDR'
|
||||||
|
|
||||||
typedef struct PE_CvHeaderPDB20 PE_CvHeaderPDB20;
|
typedef struct PE_CvHeaderPDB20 PE_CvHeaderPDB20;
|
||||||
struct PE_CvHeaderPDB20
|
struct PE_CvHeaderPDB20
|
||||||
@@ -377,6 +378,14 @@ struct PE_CvHeaderPDB70
|
|||||||
// file name packed after struct
|
// file name packed after struct
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct PE_CvHeaderRDI PE_CvHeaderRDI;
|
||||||
|
struct PE_CvHeaderRDI
|
||||||
|
{
|
||||||
|
U32 magic;
|
||||||
|
OS_Guid guid;
|
||||||
|
// file name packed after struct
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct PE_ImportEntry PE_ImportEntry;
|
typedef struct PE_ImportEntry PE_ImportEntry;
|
||||||
struct PE_ImportEntry
|
struct PE_ImportEntry
|
||||||
{
|
{
|
||||||
@@ -737,8 +746,9 @@ struct PE_BinInfo
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Basic Enum Functions
|
//~ rjf: Basic Enum Functions
|
||||||
|
|
||||||
internal U32 pe_slot_count_from_unwind_op_code(PE_UnwindOpCode opcode);
|
internal U32 pe_slot_count_from_unwind_op_code(PE_UnwindOpCode opcode);
|
||||||
internal String8 pe_string_from_windows_subsystem(PE_WindowsSubsystem subsystem);
|
internal String8 pe_string_from_subsystem(PE_WindowsSubsystem subsystem);
|
||||||
|
internal PE_WindowsSubsystem pe_subsystem_from_string(String8 string);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Parser Functions
|
//~ rjf: Parser Functions
|
||||||
@@ -748,13 +758,14 @@ internal PE_BinInfo pe_bin_info_from_data(Arena *arena, String8 data);
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ rjf: Helpers
|
//~ rjf: Helpers
|
||||||
|
|
||||||
internal U64 pe_intel_pdata_off_from_voff__binary_search(String8 data, PE_BinInfo *bin, U64 voff);
|
internal U64 pe_intel_pdata_off_from_voff__binary_search(String8 data, PE_BinInfo *bin, U64 voff);
|
||||||
internal void *pe_ptr_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
internal void * pe_ptr_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
||||||
internal U64 pe_section_num_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
internal U64 pe_section_num_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
||||||
internal void *pe_ptr_from_section_num(String8 data, PE_BinInfo *bin, U64 n);
|
internal void * pe_ptr_from_section_num(String8 data, PE_BinInfo *bin, U64 n);
|
||||||
internal U64 pe_foff_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
internal U64 pe_foff_from_voff(String8 data, PE_BinInfo *bin, U64 voff);
|
||||||
internal PE_BaseRelocBlockList pe_base_reloc_block_list_from_bin(Arena *arena, String8 data, PE_BinInfo *bin);
|
internal PE_BaseRelocBlockList pe_base_reloc_block_list_from_bin(Arena *arena, String8 data, PE_BinInfo *bin);
|
||||||
internal Rng1U64 pe_tls_rng_from_bin_base_vaddr(String8 data, PE_BinInfo *bin, U64 base_vaddr);
|
internal Rng1U64 pe_tls_rng_from_bin_base_vaddr(String8 data, PE_BinInfo *bin, U64 base_vaddr);
|
||||||
|
internal String8Array pe_get_entry_point_names(COFF_MachineType machine, PE_WindowsSubsystem subsystem, PE_ImageFileCharacteristics file_characteristics);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Resource Helpers
|
//~ Resource Helpers
|
||||||
@@ -770,4 +781,15 @@ internal PE_Resource * pe_resource_dir_search(PE_ResourceDir *dir, COFF_Reso
|
|||||||
internal PE_ResourceArray pe_resource_list_to_array(Arena *arena, PE_ResourceList *list);
|
internal PE_ResourceArray pe_resource_list_to_array(Arena *arena, PE_ResourceList *list);
|
||||||
internal PE_ResourceDir * pe_resource_table_from_directory_data(Arena *arena, String8 data);
|
internal PE_ResourceDir * pe_resource_table_from_directory_data(Arena *arena, String8 data);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Debug Directory
|
||||||
|
|
||||||
|
internal String8 pe_make_debug_header_pdb70(Arena *arena, OS_Guid guid, U32 age, String8 pdb_path);
|
||||||
|
internal String8 pe_make_debug_header_rdi(Arena *arena, OS_Guid guid, String8 rdi_path);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
//~ Image Checksum
|
||||||
|
|
||||||
|
internal U32 pe_compute_checksum(U8 *buffer, U64 buffer_size);
|
||||||
|
|
||||||
#endif // PE_H
|
#endif // PE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user