trim down the PE parsing code; switch to lighter weight image pointer retrieval via '__ImageBase'

main
Allen Webster 2025-05-02 12:32:34 -07:00
parent 6c7c13f93b
commit 14fb4e3944
18 changed files with 92 additions and 4419 deletions

View File

@ -8,6 +8,7 @@ patterns = {
"*.bat",
"*.sh",
"*.4coder",
"*.txt",
};
blacklist_patterns = {
".*",

View File

@ -34,21 +34,11 @@ str8_match(String8 a, String8 b, U32 flags){
#if OS_WINDOWS
static RangePtr
// see: https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
static void*
os_this_image(void){
RangePtr result = {0};
HMODULE module = 0;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPWSTR)os_this_image, &module);
if (module != 0){
HANDLE process = GetCurrentProcess();
MODULEINFO module_info = {0};
if (GetModuleInformation(process, module,
&module_info, sizeof(module_info))){
result.first = (U8*)module_info.lpBaseOfDll;
result.opl = result.first + module_info.SizeOfImage;
}
}
extern U8 __ImageBase[];
void *result = __ImageBase;
return(result);
}
@ -59,18 +49,11 @@ os_this_image(void){
#if OS_WINDOWS
# include "binary/pe/mr4th_pe.h"
# include "binary/pe/mr4th_pe.parse.h"
# include "binary/pe/mr4th_pe.parse.c"
# include "binary/pe/mr4th_pe.img_get_section.c"
static RangePtr
selfimg_get_section(RangePtr image, String8 name){
RangePtr result = {0};
String8 image_str = str8(image.first, image.opl - image.first);
PE_SectionHeader *section = pe_section_header_from_name(image_str, name);
if (section != 0){
result.first = image.first + section->voff;
result.opl = result.first + section->vsize;
}
self_img_get_section(void *image, String8 name){
RangePtr result = pe_img_get_section(image, name);
return(result);
}

View File

@ -247,5 +247,6 @@ typedef struct String8{
static String8 str8(U8 *str, U64 size);
static B32 str8_match(String8 a, String8 b, U32 flags);
static RangePtr os_this_image(void);
static RangePtr selfimg_get_section(RangePtr image, String8 name);
static void* os_this_image(void);
static RangePtr self_img_get_section(void *image, String8 name);

View File

@ -1,30 +0,0 @@
#ifndef MR4TH_BINARY_H
#define MR4TH_BINARY_H
/* TODO:
** BINARY FILE PROJECT
**
** Research Questions:
** [ ] What the heck is that blob of data between the
** DOS header and the PE signature/COFF header?
** And why does it change so much from binary to binary?
** [ ] Unwind Info: The docs say there is a ULONG after the unwind codes???
**
** TASKS:
**
** [x] Useful PE/COFF Table Tool
** [ ] PE/COFF Linker
** [ ] PE/COFF ObjFromRaw
** [ ] PE/COFF editing to hard wire magic IDs without a data section
** [ ] PE/COFF editing to merge separate data sections to
** consolidate magic gathered arrays into plain old .data
**
** [ ] Renaming pass over mr4th_elf.dump (similar to pe.dump -> pe.parsex)
** [ ] ELF Generator
** [ ] Useful ELF ASCII Visualizer
** [ ] ELF Linker
** [ ] Debug Information (CODEVIEW,DWARF)
**
*/
#endif //MR4TH_BINARY_H

View File

@ -1,277 +0,0 @@
////////////////////////////////
// Functions: COFF / PE
// properties
MR4TH_SYM_COMPTIME U32
pe_unwind_num_code_slot_from_opcode_opinfo(PE_UnwindOpCode opcode, U8 opinfo){
U32 num = 1;
switch (opcode){
case PE_UnwindOpCode_PUSH_NONVOL:
case PE_UnwindOpCode_ALLOC_SMALL:
case PE_UnwindOpCode_SET_FPREG:
case PE_UnwindOpCode_PUSH_MACHFRAME:
case PE_UnwindOpCode_EPILOG:
case PE_UnwindOpCode_SPARE:
{
num = 1;
}break;
case PE_UnwindOpCode_ALLOC_LARGE:
{
if (opinfo == 0){
num = 2;
}
else{
num = 3;
}
}break;
case PE_UnwindOpCode_SAVE_NONVOL:
case PE_UnwindOpCode_SAVE_XMM128:
{
num = 2;
}break;
case PE_UnwindOpCode_SAVE_NONVOL_FAR:
case PE_UnwindOpCode_SAVE_XMM128_FAR:
{
num = 3;
}break;
}
return(num);
}
// checks
MR4TH_SYM_COMPTIME B32
pe_machine_type_is_valid(PE_MachineType machine_type){
B32 result = 0;
switch (machine_type){
#define X(N,C) case C:
PE_MachineType_XList(X)
#undef X
result = 1; break;
}
return(result);
}
// strings
MR4TH_SYM_COMPTIME String8
pe_str8_from_machine_type(PE_MachineType machine_type){
String8 result = str8_lit("ERROR");
switch (machine_type){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_MachineType_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME void
pe_str8list_from_flags(Arena *arena, String8List *out, PE_Flags flags){
U32 f = 1;
for (U32 i = 0; i < 8*sizeof(flags); i += 1){
if ((flags & f) != 0){
switch (f){
#define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break;
PE_Flags_XList(X)
#undef X
}
}
f <<= 1;
}
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_flags(Arena *arena, PE_Flags flags){
ArenaTemp scratch = arena_get_scratch(&arena, 1);
String8List list = {0};
pe_str8list_from_flags(scratch.arena, &list, flags);
String8 result = str8_join_flags(arena, &list);
arena_release_scratch(&scratch);
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_optional_header_magic(PE_OptionalHeaderMagic magic){
String8 result = str8_lit("ERROR");
switch (magic){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_OptionalHeaderMagic_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_windows_subsystem(PE_WindowsSubsystem subsystem){
String8 result = str8_lit("ERROR");
switch (subsystem){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_WindowsSubsystem_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME void
pe_str8list_from_dll_flags(Arena *arena, String8List *out, PE_DLLFlags dll_flags){
U32 f = 1;
for (U32 i = 0; i < 8*sizeof(dll_flags); i += 1){
if ((dll_flags & f) != 0){
switch (f){
#define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break;
PE_DLLFlags_XList(X)
#undef X
}
}
f <<= 1;
}
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_dll_flags(Arena *arena, PE_DLLFlags dll_flags){
ArenaTemp scratch = arena_get_scratch(&arena, 1);
String8List list = {0};
pe_str8list_from_dll_flags(scratch.arena, &list, dll_flags);
String8 result = str8_join_flags(arena, &list);
arena_release_scratch(&scratch);
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_data_directory_idx(PE_DataDirectoryIdx idx){
String8 result = {0};
switch (idx){
#define X(N,D,C) case C: result = str8_lit(#N); break;
PE_DataDirectoryIdx_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_display_string_from_data_directory_idx(PE_DataDirectoryIdx idx){
String8 result = {0};
switch (idx){
#define X(N,D,C) case C: result = str8_lit(D); break;
PE_DataDirectoryIdx_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_sec_alignment(U32 alignment){
String8 result = {0};
switch (alignment){
#define X(Z,C) case C: result = str8_lit("ALIGN_" #Z "BYTES"); break;
PE_SectionAlign_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME void
pe_str8list_from_sec_flags(Arena *arena, String8List *out, PE_SectionFlags sec_flags){
// align
U32 section_align = PE_SectionAlignFromSectionFlags(sec_flags);
String8 align_str = pe_str8_from_sec_alignment(section_align);
if (align_str.size > 0){
str8_list_push(arena, out, align_str);
}
// other flags
U32 f = 1;
for (U32 i = 0; i < 8*sizeof(sec_flags); i += 1){
if ((sec_flags & f) != 0){
switch (f){
#define X(N,C) case C: str8_list_push(arena, out, str8_lit(#N)); break;
PE_SectionFlags_XList(X)
#undef X
}
}
f <<= 1;
}
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_sec_flags(Arena *arena, PE_SectionFlags sec_flags){
ArenaTemp scratch = arena_get_scratch(&arena, 1);
String8List list = {0};
pe_str8list_from_sec_flags(scratch.arena, &list, sec_flags);
String8 result = str8_join_flags(arena, &list);
arena_release_scratch(&scratch);
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_coff_relocation_type(PE_CoffRelocationType type){
String8 result = str8_lit("ERROR");
switch (type){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_CoffRelocationType_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_coff_symbol_type(Arena *arena, PE_CoffSymbolType type){
String8 lo = str8_lit("ERROR");
switch (type & 0xF){
#define X(N,C) case C: lo = str8_lit(#N); break;
PE_CoffSymbolTypeLo_XList(X)
#undef X
}
String8 result = lo;
switch ((type >> 4) & 0xF){
case PE_CoffSymbolTypeHi_NULL: break;
case PE_CoffSymbolTypeHi_POINTER:
result = str8_pushf(arena, "POINTER %S", lo); break;
case PE_CoffSymbolTypeHi_FUNCTION:
result = str8_pushf(arena, "FUNCTION %S", lo); break;
case PE_CoffSymbolTypeHi_ARRAY:
result = str8_pushf(arena, "ARRAY %S", lo); break;
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_coff_symbol_storage_class(PE_CoffSymbolStorageClass storage_class){
String8 result = str8_lit("ERROR");
switch (storage_class){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_CoffSymbolStorageClass_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_base_relocation_type(PE_BaseRelocationType type){
String8 result = str8_lit("ERROR");
switch (type){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_BaseRelocationType_XList(X)
#undef X
}
return(result);
}
MR4TH_SYM_COMPTIME String8
pe_str8_from_debug_type(PE_DebugType debug_type){
String8 result = str8_lit("ERROR");
switch (debug_type){
#define X(N,C) case C: result = str8_lit(#N); break;
PE_DebugType_XList(X)
#undef X
}
return(result);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,463 +0,0 @@
#ifndef MR4TH_PE_GEN_H
#define MR4TH_PE_GEN_H
////////////////////////////////
// PE Generator Types
// data block system
typedef struct PEGEN_Block{
struct PEGEN_Block *next_bucket;
struct PEGEN_Block *next_sibling;
struct PEGEN_Block *first_child;
struct PEGEN_Block *last_child;
struct PEGEN_Block *parent;
U32 child_count;
B8 attached;
U8 padding_fillbyte;
U32 base_alignment;
U8 *data;
U32 total_size;
U32 off_within_parent;
} PEGEN_Block;
typedef struct PEGEN_Ctx{
Arena *arena;
PEGEN_Block *first_block;
PEGEN_Block *last_block;
U64 block_count;
} PEGEN_Ctx;
typedef struct PEGEN_Label{
PEGEN_Block *block;
U32 off;
} PEGEN_Label;
// sections
typedef struct PEGEN_Section{
struct PEGEN_Section *next;
PEGEN_Block *block;
U8 *name;
U32 name_size;
U16 secnum;
PE_SectionFlags flags;
U32 vsize;
struct PEGEN_CoffRelocList *coff_relocs;
} PEGEN_Section;
typedef struct PEGEN_SectionList{
PEGEN_Section *first;
PEGEN_Section *last;
U64 count;
} PEGEN_SectionList;
// patches for pe/coff files
typedef enum PEGEN_PatchKind{
PEGEN_PatchKind_FileAbsolute,
PEGEN_PatchKind_FileRelative,
PEGEN_PatchKind_VirtAbsolute,
PEGEN_PatchKind_VirtRelative,
PEGEN_PatchKind_VirtAddress,
PEGEN_PatchKind_SectionNumber,
PEGEN_PatchKind_SectionOffset,
} PEGEN_PatchKind;
typedef struct PEGEN_Patch{
struct PEGEN_Patch *next;
// positions
PEGEN_Label patchpos;
PEGEN_Label targetpos;
// patch bits
U8 patch_bitoff;
U8 patch_numbits;
// value calculation
PEGEN_PatchKind kind;
S8 bias;
U8 shift;
// val = ( (flags.SecIdx?IdxOf(SecOf(target)):VoffOf(target))
// + (flags.Vaddr?ImageBaseVaddr:0)
// - (flags.RelocRel?AddrOf(reloc):0)
// - (flags.SecRel?AddrOf(SecOf(target)):0)
// + bias) >> shift
} PEGEN_Patch;
typedef struct PEGEN_PatchList{
PEGEN_Patch *first;
PEGEN_Patch *last;
U64 count;
} PEGEN_PatchList;
// image config
typedef struct PEGEN_ImgConfig{
U64 base_vaddr;
U32 file_align;
U32 virt_align;
PEGEN_Label entry_point;
PEGEN_Block *data_directories[PE_DataDirectoryIdx_COUNT];
} PEGEN_ImgConfig;
// object config
typedef struct PEGEN_ObjConfig{
struct PEGEN_SymbolTableBaked *symbol_table;
} PEGEN_ObjConfig;
// headers & layouts
typedef struct PEGEN_LayoutSection{
PEGEN_Block *block;
U8 *name;
U32 name_size;
U32 voff;
U32 foff;
U32 vsize;
U32 fsize;
U16 fsize_padding;
PE_SectionFlags flags;
U16 reloc_count;
PEGEN_Block *reloc_block;
} PEGEN_LayoutSection;
typedef struct PEGEN_Layout{
PEGEN_LayoutSection *sections;
U32 section_count;
U64 image_base_vaddr;
} PEGEN_Layout;
typedef struct PEGEN_HeaderAndLayout{
PEGEN_Block *header;
PEGEN_Layout *layout;
} PEGEN_HeaderAndLayout;
// symbol table
typedef struct PEGEN_Symbol{
struct PEGEN_Symbol *next;
String8 name;
PE_CoffSymbolStorageClass storage_class;
PE_CoffSymbolType type;
PEGEN_Label pos;
} PEGEN_Symbol;
typedef struct PEGEN_SymbolTable{
PEGEN_Symbol *first;
PEGEN_Symbol *last;
U64 count;
} PEGEN_SymbolTable;
typedef struct PEGEN_SymbolTableBaked{
PEGEN_Block *block;
U64 symbol_count;
// TODO(allen): accelerate Ptr -> Idx
PEGEN_Symbol **symbols;
U32 *symbol_idxs;
} PEGEN_SymbolTableBaked;
// coff relocs
typedef struct PEGEN_CoffReloc{
struct PEGEN_CoffReloc *next;
U32 off;
PEGEN_Symbol *symbol;
PE_CoffRelocationType type;
} PEGEN_CoffReloc;
typedef struct PEGEN_CoffRelocList{
PEGEN_CoffReloc *first;
PEGEN_CoffReloc *last;
U64 count;
} PEGEN_CoffRelocList;
// exports
typedef struct PEGEN_Export{
struct PEGEN_Export *next;
PEGEN_Label symbol_label;
String8 symbol_fwdname;
String8List names;
} PEGEN_Export;
typedef struct PEGEN_ExportTable{
PEGEN_Export *first;
PEGEN_Export *last;
U32 count;
U32 name_count;
U32 time_stamp;
U16 version_major;
U16 version_minor;
String8 binary_name;
} PEGEN_ExportTable;
// imports
typedef struct PEGEN_Import{
struct PEGEN_Import *next;
String8 name;
U16 ordinal;
} PEGEN_Import;
// TODO(allen): renaming - these aren't "tables"
typedef struct PEGEN_ImportTable{
struct PEGEN_ImportTable *next;
PEGEN_Import *first;
PEGEN_Import *last;
U32 count;
U32 time_stamp;
String8 binary_name;
} PEGEN_ImportTable;
typedef struct PEGEN_ImportList{
PEGEN_ImportTable *first_table;
PEGEN_ImportTable *last_table;
U64 table_count;
} PEGEN_ImportList;
typedef struct PEGEN_ImportBlocks{
PEGEN_Block *directory_table;
PEGEN_Block *iat;
PEGEN_Block *import_data;
} PEGEN_ImportBlocks;
// base relocations
typedef struct PEGEN_BaseRelocationLoose{
struct PEGEN_BaseRelocationLoose *next;
PE_BaseRelocationType type;
PEGEN_Label label;
} PEGEN_BaseRelocationLoose;
typedef struct PEGEN_BaseRelocationList{
PEGEN_BaseRelocationLoose *first;
PEGEN_BaseRelocationLoose *last;
U64 count;
} PEGEN_BaseRelocationList;
typedef struct PEGEN_BaseRelocation{
PE_BaseRelocationType type;
U32 voff;
} PEGEN_BaseRelocation;
// unwind info
typedef struct PEGEN_UnwindCode{
struct PEGEN_UnwindCode *next;
U8 offset;
U8 opcode;
U8 opinfo;
U32 x;
} PEGEN_UnwindCode;
typedef struct PEGEN_UnwindInfo{
struct PEGEN_UnwindInfo *next;
PEGEN_Label start_pos;
PEGEN_Label opl_pos;
PE_UnwindInfoFlags flags;
U8 prolog_size;
U8 frame_reg;
U8 frame_off;
PEGEN_UnwindCode *first_code;
PEGEN_UnwindCode *last_code;
U8 code_count;
U8 code_slot_count;
} PEGEN_UnwindInfo;
typedef struct PEGEN_UnwindInfoList{
PEGEN_UnwindInfo *first;
PEGEN_UnwindInfo *last;
U64 count;
} PEGEN_UnwindInfoList;
typedef struct PEGEN_UnwindBlocks{
PEGEN_Block *exception_handlers;
PEGEN_Block *unwind_info;
} PEGEN_UnwindBlocks;
////////////////////////////////
// PE Generator Functions
/// gen api ///
// ctx
function PEGEN_Ctx* pegen_begin(void);
function void pegen_release(PEGEN_Ctx *gen);
// data blocks
function PEGEN_Block* pegen_block_new(PEGEN_Ctx *gen);
function PEGEN_Block* pegen_block_new_write(PEGEN_Ctx *gen, String8 data);
function PEGEN_Block* pegen_block_new_aligned(PEGEN_Ctx *gen, U32 align);
function void*pegen_block_push(PEGEN_Ctx *gen, PEGEN_Block* block, U32 size);
function void*pegen_block_push_write(PEGEN_Ctx *gen, PEGEN_Block* block, String8 data);
function U8* pegen_block_push_cstring(PEGEN_Ctx *gen, PEGEN_Block* block, String8 string);
#define pegen_block_push_array(gen,block,T,c) (T*)pegen_block_push((gen),(block),sizeof(T)*(c))
function void pegen_block_align(PEGEN_Ctx *gen, PEGEN_Block* block, U8 fillbyte, U32 align);
function void pegen_block_fill_to_size(PEGEN_Ctx *gen, PEGEN_Block *block, U8 fillbyte, U32 target_size);
function void pegen_block_push_block(PEGEN_Ctx *gen, PEGEN_Block *list, PEGEN_Block *block);
function U32 pegen_block_get_size(PEGEN_Block* block);
function String8 pegen_block_flatten(Arena *arena, PEGEN_Block *block);
function void pegen_block_flatten__recursive(PEGEN_Block *block, U8 *dst);
function U32 pegen_block_off_relative_to_ancestor(PEGEN_Block *block, PEGEN_Block *ancestor);
// labels
function PEGEN_Label pegen_label(PEGEN_Ctx *gen, PEGEN_Block *block, U32 off);
function PEGEN_Label pegen_label_from_pointer(PEGEN_Ctx *gen, void *ptr);
function void* pegen_pointer_from_block_off(PEGEN_Ctx *gen, PEGEN_Block *block, U32 off);
function void* pegen_pointer_from_label(PEGEN_Ctx *gen, PEGEN_Label label);
// patches
function PEGEN_PatchList* pegen_patch_list_new(PEGEN_Ctx *gen);
function PEGEN_Patch* pegen_patch_push(PEGEN_Ctx *gen, PEGEN_PatchList *list);
function void pegen_patch_foff32_label(PEGEN_Ctx *gen, PEGEN_PatchList *list, void *patchpos_ptr, PEGEN_Label targetpos);
function void pegen_patch_voff32_label(PEGEN_Ctx *gen, PEGEN_PatchList *list, void *patchpos_ptr, PEGEN_Label targetpos);
function void pegen_patch_voff32(PEGEN_Ctx *gen, PEGEN_PatchList *list, void *patchpos_ptr, void *targetpos_ptr);
function void pegen_patch_vrel32_label(PEGEN_Ctx *gen, PEGEN_PatchList *list, PEGEN_Label patchpos, PEGEN_Label targetpos, S8 bias);
function void pegen_patch_vaddr64_label(PEGEN_Ctx *gen, PEGEN_PatchList *list, PEGEN_Label patchpos, PEGEN_Label targetpos);
function void pegen_patch_secnum16(PEGEN_Ctx *gen, PEGEN_PatchList *list, void *patchpos_ptr, PEGEN_Label targetpos);
function void pegen_patch_secoff32(PEGEN_Ctx *gen, PEGEN_PatchList *list, void *patchpos_ptr, PEGEN_Label targetpos);
function void pegen_data_apply_patches(PEGEN_Ctx *gen, U8 *data, U64 size, PEGEN_Block *block, PEGEN_Layout *layout, PEGEN_PatchList *patch_list);
// sections
function PEGEN_SectionList* pegen_section_list_new(PEGEN_Ctx *gen);
function PEGEN_Section*
pegen_section_push(PEGEN_Ctx *gen, PEGEN_SectionList *list,
String8 name, PE_SectionFlags flags, U32 vsize,
PEGEN_Block *block);
function void
pegen_section_equip_coff_relocs(PEGEN_Section *section,
PEGEN_CoffRelocList *list);
#define PEGEN_DefaultVSize (~((U32)0))
// image config
function PEGEN_ImgConfig* pegen_img_config_new(PEGEN_Ctx *gen);
function void pegen_img_config_base_vaddr(PEGEN_Ctx *gen, PEGEN_ImgConfig *config, U64 base_vaddr);
function void pegen_img_config_file_align(PEGEN_Ctx *gen, PEGEN_ImgConfig *config, U32 file_align);
function void pegen_img_config_virt_align(PEGEN_Ctx *gen, PEGEN_ImgConfig *config, U32 virt_align);
function void pegen_img_config_entry_point(PEGEN_Ctx *gen, PEGEN_ImgConfig *config, PEGEN_Label label);
function void pegen_img_config_data_directory(PEGEN_Ctx *gen, PEGEN_ImgConfig *config,
PE_DataDirectoryIdx idx, PEGEN_Block *block);
// object config
function PEGEN_ObjConfig* pegen_obj_config_new(PEGEN_Ctx *gen);
function void pegen_obj_config_symbol_table(PEGEN_Ctx *gen, PEGEN_ObjConfig *config,
PEGEN_SymbolTableBaked *table);
// headers & layouts
function PEGEN_HeaderAndLayout
pegen_img_header_bake(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list,
PEGEN_SectionList *section_list,
PEGEN_ImgConfig *img_config);
function PEGEN_HeaderAndLayout
pegen_obj_header_bake(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list,
PEGEN_SectionList *section_list,
PEGEN_ObjConfig *obj_config);
function U32 pegen_layout_voff_from_foff(PEGEN_Layout *layout, U32 foff);
function U32 pegen_layout_secnum_from_foff(PEGEN_Layout *layout, U32 foff);
function U32 pegen_layout_secoff_from_foff(PEGEN_Layout *layout, U32 foff);
function U32 pegen_layout_voff_from_block(PEGEN_Layout *layout, PEGEN_Block *block);
function U32 pegen_layout_voff_from_label(PEGEN_Layout *layout, PEGEN_Label label);
// symbol table
function PEGEN_SymbolTable* pegen_symbol_table_new(PEGEN_Ctx *gen);
function PEGEN_Symbol* pegen_symbol_push(PEGEN_Ctx *gen, PEGEN_SymbolTable *symbols,
String8 name, PE_CoffSymbolStorageClass storage_class,
PE_CoffSymbolType type,
PEGEN_Label pos);
function PEGEN_SymbolTableBaked*
pegen_block_from_symbol_table(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list,
PEGEN_SymbolTable *symbol_table);
function U32 pegen_symbol_idx_from_ptr(PEGEN_SymbolTableBaked *table,
PEGEN_Symbol *symbol);
// coff relocs
function PEGEN_CoffRelocList* pegen_coff_reloc_list_new(PEGEN_Ctx *gen);
function void pegen_coff_reloc_push(PEGEN_Ctx *gen, PEGEN_CoffRelocList *list,
U32 off, PEGEN_Symbol *symbol,
PE_CoffRelocationType reloc_type);
function PEGEN_Block*
pegen_block_from_coff_reloc_list(PEGEN_Ctx *gen,
PEGEN_SymbolTableBaked *symbol_table,
PEGEN_CoffRelocList *list);
// export table
function PEGEN_ExportTable* pegen_export_table_new(PEGEN_Ctx *gen);
function void pegen_export_table_set_binary_name(PEGEN_Ctx *gen, PEGEN_ExportTable *table, String8 name);
function void pegen_export_table_set_time_stamp(PEGEN_Ctx *gen, PEGEN_ExportTable *table, U32 timestamp);
function void pegen_export_table_set_version(PEGEN_Ctx *gen, PEGEN_ExportTable *table, U16 major, U16 minor);
function PEGEN_Export* pegen_export_new(PEGEN_Ctx *gen, PEGEN_ExportTable *table, PEGEN_Label label);
function PEGEN_Export* pegen_export_new_fwd(PEGEN_Ctx *gen, PEGEN_ExportTable *table, String8 fwdname);
function void pegen_export_add_name(PEGEN_Ctx *gen, PEGEN_ExportTable *table, PEGEN_Export *exp, String8 name);
function PEGEN_Block* pegen_block_from_exports(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list_out, PEGEN_ExportTable *table);
// import table
function PEGEN_ImportList* pegen_import_list_new(PEGEN_Ctx *gen);
function PEGEN_ImportTable* pegen_import_table_new(PEGEN_Ctx *gen, PEGEN_ImportList *list,
String8 binary_name, U32 time_stamp);
function void pegen_import_new(PEGEN_Ctx *gen, PEGEN_ImportTable *table,
String8 name, U16 ordinal);
function PEGEN_ImportBlocks pegen_blocks_from_imports(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list, PEGEN_ImportList *imports);
// base relocations
function PEGEN_BaseRelocationList* pegen_base_relocation_list_new(PEGEN_Ctx *gen);
function void pegen_base_relocation_new(PEGEN_Ctx *gen, PEGEN_BaseRelocationList *list,
PE_BaseRelocationType type, PEGEN_Label label);
function PEGEN_Block* pegen_block_from_base_relocations(PEGEN_Ctx *gen, PEGEN_Layout *layout, PEGEN_BaseRelocationList *list);
function S32 pegen_base_relocation_compare(void *a, void *b, void *udata);
// unwind info
function PEGEN_UnwindInfoList* pegen_unwind_info_list_new(PEGEN_Ctx *gen);
function PEGEN_UnwindInfo* pegen_unwind_info_push(PEGEN_Ctx *gen, PEGEN_UnwindInfoList *list);
function void pegen_unwind_info_code(PEGEN_Ctx *gen, PEGEN_UnwindInfo *handler,
U8 offset, U8 opcode, U8 opinfo, U32 x);
function PEGEN_UnwindBlocks pegen_blocks_from_unwind_info(PEGEN_Ctx *gen, PEGEN_PatchList *patch_list, PEGEN_UnwindInfoList *list);
#endif //MR4TH_PE_GEN_H

View File

@ -1,257 +0,0 @@
/*
** PE File Generator Development
*/
#include "mr4th_base.h"
#include "mr4th_base.stdio.h"
#include "mr4th_keywords.h"
#include "block/mr4th_block.h"
#include "mr4th_pe.h"
#include "mr4th_pe.gen.h"
#include "mr4th_base.c"
#include "mr4th_pe.c"
#include "mr4th_pe.gen.c"
#include "block/mr4th_block.c"
////////////////////////////////
// Entry Point
int main(int argc, char **argv){
os_main_init(argc, argv);
PEGEN_Ctx *gen = pegen_begin();
String8 output_filename = str8_lit("generated.obj");
B32 gen_img = 0;
// time stamp
DateTime date = os_now_universal_time();
DateTime local_date = os_local_time_from_universal(&date);
U32 time_stamp = os_time_stamp_32_from_date_time(&local_date);
/// loose construction helper ///
PEGEN_SectionList *section_list = pegen_section_list_new(gen);
PEGEN_PatchList *patch_list = pegen_patch_list_new(gen);
PEGEN_UnwindInfoList *unwind_info_list = pegen_unwind_info_list_new(gen);
/// loose construction helper (image) ///
PEGEN_ImgConfig *img_config = 0;
PEGEN_ExportTable *exports = 0;
PEGEN_ImportList *imports = 0;
PEGEN_BaseRelocationList *base_relocs = 0;
if (gen_img){
// init img config
img_config = pegen_img_config_new(gen);
// init exports
exports = pegen_export_table_new(gen);
pegen_export_table_set_binary_name(gen, exports, output_filename);
pegen_export_table_set_time_stamp(gen, exports, time_stamp);
pegen_export_table_set_version(gen, exports, 0, 0);
// init imports
imports = pegen_import_list_new(gen);
#if 0
PEGEN_ImportTable *table =
pegen_import_table_new(gen, imports, str8_lit("api-ms-win-crt-heap-l1-1-0.dll"), time_stamp);
pegen_import_new(gen, table, str8_lit("malloc"), 25);
#endif
// init base relocations
base_relocs = pegen_base_relocation_list_new(gen);
}
/// loose construction helper (object) ///
PEGEN_ObjConfig *obj_config = 0;
PEGEN_SymbolTable *symbol_table = 0;
if (!gen_img){
// init obj config
obj_config = pegen_obj_config_new(gen);
// init symbol table
symbol_table = pegen_symbol_table_new(gen);
}
// arrange section data
{
// bake imports
PEGEN_ImportBlocks import_blocks = {0};
if (gen_img){
import_blocks = pegen_blocks_from_imports(gen, patch_list, imports);
pegen_img_config_data_directory(gen, img_config,
PE_DataDirectoryIdx_ImportTable,
import_blocks.directory_table);
pegen_img_config_data_directory(gen, img_config,
PE_DataDirectoryIdx_IAT,
import_blocks.iat);
}
// text & data
PEGEN_Block *text_block = pegen_block_new_write(gen, str8(text, sizeof(text)));
PEGEN_Section *text_section =
pegen_section_push(gen, section_list, str8_lit(".text$mn"),
PE_SectionFlag_CNT_CODE |
PE_SectionFlag_MEM_EXECUTE |
PE_SectionFlag_MEM_READ,
PEGEN_DefaultVSize,
text_block);
PEGEN_CoffRelocList *text_relocs = 0;
if (!gen_img){
text_relocs = pegen_coff_reloc_list_new(gen);
pegen_section_equip_coff_relocs(text_section, text_relocs);
}
PEGEN_Block *data_block = pegen_block_new_write(gen, str8(data, sizeof(data)));
pegen_section_push(gen, section_list, str8_lit(".data"),
PE_SectionFlag_CNT_INITIALIZED_DATA |
PE_SectionFlag_MEM_READ |
PE_SectionFlag_MEM_WRITE,
PEGEN_DefaultVSize,
data_block);
// entry point
if (gen_img){
PEGEN_Label entry_point = pegen_label(gen, text_block, 0);
pegen_img_config_entry_point(gen, img_config, entry_point);
}
// symbol table
PEGEN_Symbol *sym_sum_longname = 0;
PEGEN_Symbol *sym_variable = 0;
if (!gen_img){
{
PEGEN_Label pos = pegen_label(gen, text_block, 0);
sym_sum_longname =
pegen_symbol_push(gen, symbol_table, str8_lit("sum_longname"),
PE_CoffSymbolStorageClass_EXTERNAL,
(PE_CoffSymbolTypeHi_FUNCTION << 4), pos);
}
{
PEGEN_Label pos = pegen_label(gen, data_block, 0);
sym_variable =
pegen_symbol_push(gen, symbol_table, str8_lit("variable"),
PE_CoffSymbolStorageClass_EXTERNAL, 0, pos);
}
}
// text coff relocation
if (!gen_img){
pegen_coff_reloc_push(gen, text_relocs, 9, sym_variable,
PE_CoffRelocationType_REL32);
}
// bake exports
PEGEN_Block *export_block = 0;
if (gen_img){
export_block = pegen_block_from_exports(gen, patch_list, exports);
pegen_img_config_data_directory(gen, img_config,
PE_DataDirectoryIdx_ExportTable,
export_block);
}
// bake unwind info
PEGEN_UnwindBlocks unwind_blocks = {0};
if (gen_img){
unwind_blocks = pegen_blocks_from_unwind_info(gen, patch_list, unwind_info_list);
pegen_img_config_data_directory(gen, img_config,
PE_DataDirectoryIdx_ExceptionTable,
unwind_blocks.exception_handlers);
}
// bake symbol table
PEGEN_SymbolTableBaked *symbol_table_baked = 0;
if (!gen_img){
symbol_table_baked =
pegen_block_from_symbol_table(gen, patch_list, symbol_table);
pegen_obj_config_symbol_table(gen, obj_config, symbol_table_baked);
}
// put exports & imports into rdata
if (gen_img){
PEGEN_Block *rdata_block = pegen_block_new(gen);
pegen_block_push_block(gen, rdata_block, import_blocks.iat);
pegen_block_push_block(gen, rdata_block, export_block);
pegen_block_push_block(gen, rdata_block, unwind_blocks.unwind_info);
pegen_block_push_block(gen, rdata_block, import_blocks.directory_table);
pegen_block_push_block(gen, rdata_block, import_blocks.import_data);
if (pegen_block_get_size(rdata_block) > 0){
pegen_section_push(gen, section_list, str8_lit(".rdata"),
PE_SectionFlag_CNT_INITIALIZED_DATA |
PE_SectionFlag_MEM_READ,
PEGEN_DefaultVSize,
rdata_block);
}
}
// put exception handlers into pdata
if (gen_img){
if (pegen_block_get_size(unwind_blocks.exception_handlers) > 0){
pegen_section_push(gen, section_list, str8_lit(".pdata"),
PE_SectionFlag_CNT_INITIALIZED_DATA |
PE_SectionFlag_MEM_READ,
PEGEN_DefaultVSize,
unwind_blocks.exception_handlers);
}
}
}
// header block
PEGEN_HeaderAndLayout hdr_layout = {0};
if (gen_img){
hdr_layout = pegen_img_header_bake(gen, patch_list, section_list, img_config);
}
else{
hdr_layout = pegen_obj_header_bake(gen, patch_list, section_list, obj_config);
}
// assemble file
PEGEN_Block *file = pegen_block_new(gen);
{
pegen_block_push_block(gen, file, hdr_layout.header);
for (U32 i = 0; i < hdr_layout.layout->section_count; i += 1){
PEGEN_LayoutSection *sec = hdr_layout.layout->sections + i;
pegen_block_fill_to_size(gen, file, 0, sec->foff);
pegen_block_push_block(gen, file, sec->block);
U32 aligned_up_foff = sec->foff + sec->fsize + sec->fsize_padding;
pegen_block_fill_to_size(gen, file, 0, aligned_up_foff);
if (sec->reloc_block != 0){
pegen_block_push_block(gen, file, sec->reloc_block);
}
}
if (!gen_img){
if (obj_config->symbol_table != 0){
pegen_block_push_block(gen, file, obj_config->symbol_table->block);
}
}
}
// render file
{
Arena *arena = arena_alloc();
String8 data = pegen_block_flatten(arena, file);
pegen_data_apply_patches(gen, data.str, data.size, file,
hdr_layout.layout, patch_list);
os_file_write(output_filename, data);
}
return(0);
}

View File

@ -0,0 +1,68 @@
////////////////////////////////
// PE Get Section Function
static RangePtr
pe_img_get_section(void *image_raw, String8 name){
U8 *image = (U8*)image_raw;
// dos header
PE_DosHeader *dos_header = (PE_DosHeader*)(image);
if (dos_header->magic != PE_MSDOS_MAGIC){
dos_header = 0;
}
// coff header
PE_CoffHeader *coff_header = 0;
U64 after_coff_header_offset = 0;
if (dos_header != 0){
U64 pe_signature_offset = dos_header->coff_file_offset;
U64 coff_header_offset = pe_signature_offset + sizeof(U32);
U32 pe_signature = *(U32*)(image + pe_signature_offset);
if (pe_signature == PE_SIGNATURE){
coff_header = (PE_CoffHeader*)(image + coff_header_offset);
after_coff_header_offset = coff_header_offset + sizeof(*coff_header);
}
}
// section table offset & count
U32 section_table_offset = 0;
U32 section_count = 0;
if (coff_header != 0){
section_table_offset = ( after_coff_header_offset
+ coff_header->optional_header_size);
section_count = coff_header->section_count;
}
// scan section table
PE_SectionHeader *match = 0;
{
PE_SectionHeader *sec = (PE_SectionHeader*)(image + section_table_offset);
for (U32 i = 0; i < section_count; i += 1, sec += 1){
U8 *secptr = sec->name;
U8 *secopl = sec->name + sizeof(sec->name);
U8 *keyptr = name.str;
U8 *keyopl = name.str + name.size;
B32 string_match = 1;
for (;*secptr != 0 && secptr < secopl && keyptr < keyopl;
secptr += 1, keyptr += 1){
if (*secptr != *keyptr){
string_match = 0;
break;
}
}
if (string_match){
match = sec;
break;
}
}
}
// fill result
RangePtr result = {0};
if (match != 0){
result.first = image + match->voff;
result.opl = result.first + match->vsize;
}
return(result);
}

View File

@ -0,0 +1,9 @@
#ifndef MR4TH_PE_IMG_GET_SECTION_H
#define MR4TH_PE_IMG_GET_SECTION_H
////////////////////////////////
// PE Get Section Function
static RangePtr pe_img_get_section(void *image, String8 name);
#endif //MR4TH_PE_IMG_GET_SECTION_H

View File

@ -1,66 +0,0 @@
////////////////////////////////
// PE Parse Functions
static PE_SectionHeader*
pe_section_header_from_name(String8 img, String8 name){
// extract dos header
PE_DosHeader *dos_header = 0;
if (sizeof(*dos_header) <= img.size){
dos_header = (PE_DosHeader*)(img.str);
if (dos_header->magic != PE_MSDOS_MAGIC){
dos_header = 0;
}
}
// extract coff file offset
U32 coff_file_offset = 0;
if (dos_header != 0){
coff_file_offset = dos_header->coff_file_offset;
}
// extract pe signature
U32 pe_signature = 0;
U32 coff_header_offset = 0;
if (0 < coff_file_offset &&
coff_file_offset + sizeof(pe_signature) <= img.size){
pe_signature = *(U32*)(img.str + coff_file_offset);
if (pe_signature == PE_SIGNATURE){
coff_header_offset = coff_file_offset + sizeof(pe_signature);
}
}
// extract coff header
PE_CoffHeader *coff_header = 0;
if (0 < coff_header_offset &&
coff_header_offset + sizeof(*coff_header) <= img.size){
coff_header = (PE_CoffHeader*)(img.str + coff_header_offset);
}
// extract section table offset & count
U32 section_table_offset = 0;
U32 section_count = 0;
if (coff_header != 0){
section_table_offset = ( coff_header_offset
+ sizeof(*coff_header)
+ coff_header->optional_header_size);
section_count = coff_header->section_count;
}
// scan section table
PE_SectionHeader *match = 0;
if (0 < section_table_offset &&
section_table_offset + sizeof(PE_SectionHeader)*section_count <= img.size){
PE_SectionHeader *sec = (PE_SectionHeader*)(img.str + section_table_offset);
for (U32 i = 0; i < section_count; i += 1, sec += 1){
U8 *ptr = sec->name;
for (;*ptr != 0 && ptr < sec->name + sizeof(sec->name); ptr += 1);
String8 secname = str8(sec->name, ptr - sec->name);
if (str8_match(name, secname, 0)){
match = sec;
break;
}
}
}
return(match);
}

View File

@ -1,9 +0,0 @@
#ifndef MR4TH_PE_PARSE_H
#define MR4TH_PE_PARSE_H
////////////////////////////////
// PE Parse Functions
static PE_SectionHeader* pe_section_header_from_name(String8 img, String8 name);
#endif //MR4TH_PE_PARSE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
#ifndef MR4TH_PE_PARSE_EXAMPLE_H
#define MR4TH_PE_PARSE_EXAMPLE_H
////////////////////////////////
// PE Parse Example Arguments Types
typedef struct PEDUMP_Arguments{
String8 input_file_name;
} PEDUMP_Arguments;
////////////////////////////////
// PE Parse Example Helper Types
typedef struct PEDUMP_CoffSymbol{
String8 name;
U32 val;
S16 sec_number;
PE_CoffSymbolType type;
PE_CoffSymbolStorageClass storage_class;
U8 aux_symbol_count;
} PEDUMP_CoffSymbol;
typedef struct PEDUMP_ExportSymbol{
U32 voff;
String8 fwd;
String8 name;
} PEDUMP_ExportSymbol;
typedef struct PEDUMP_ImportSymbol{
U16 ordinal;
String8 name;
} PEDUMP_ImportSymbol;
typedef struct PEDUMP_ImportTable{
struct PEDUMP_ImportTable *next;
U32 time_stamp;
U32 first_forwarder_idx;
String8 name;
PEDUMP_ImportSymbol *syms;
U64 lookup_count;
} PEDUMP_ImportTable;
typedef struct PEDUMP_BaseRelocation{
U32 type;
U32 voff;
} PEDUMP_BaseRelocation;
typedef struct PEDUMP_UnwindCode{
struct PEDUMP_UnwindCode *next;
U8 offset;
U8 opcode;
U8 opinfo;
U8 extra_slot_count;
U32 x;
} PEDUMP_UnwindCode;
typedef struct PEDUMP_UnwindInfo{
U8 version;
U8 flags;
U8 prolog_size;
U8 code_slot_count;
U8 code_count;
U8 frame_reg;
U8 frame_off;
PEDUMP_UnwindCode *first_code;
PEDUMP_UnwindCode *last_code;
} PEDUMP_UnwindInfo;
////////////////////////////////
// PE Parse Example Arguments Functions
function PEDUMP_Arguments* pedump_args(Arena *arena, String8List *args);
////////////////////////////////
// Entry Point
int main(int argc, char **argv);
#endif //MR4TH_PE_PARSE_EXAMPLE_H

View File

@ -1,186 +0,0 @@
/*
** PE Tabulator
*/
#include "mr4th_base.h"
#include "mr4th_base.stdio.h"
#include "mr4th_keywords.h"
#include "mr4th_pe.h"
#include "mr4th_stream.h"
#include "mr4th_ascii.h"
#include "mr4th_pe.table.h"
#include "mr4th_base.c"
#include "mr4th_pe.c"
#include "mr4th_stream.c"
#include "mr4th_ascii.c"
////////////////////////////////
// PE Tabulator Argument Functions
function PETAB_Args*
petab_args(Arena *arena, String8List *command_line_args){
// parse
CMDLN *cmdln = cmdln_from_args(arena, command_line_args);
// setup args
PETAB_Args *args = push_array(arena, PETAB_Args, 1);
// get input file name
args->input_file_name = cmdln_input_from_idx(cmdln, 0);
return(args);
}
////////////////////////////////
// Entry Point
int main(int argc, char **argv){
os_main_init(argc, argv);
Arena *arena = arena_alloc();
// arguments
String8List command_line_args = os_command_line_arguments();
PETAB_Args *args = petab_args(arena, &command_line_args);
// load input file
String8 data = os_file_read(arena, args->input_file_name);
/////////////////
///// PARSE /////
/////////////////
// extract dos header
PE_DosHeader *dos_header = 0;
if (sizeof(*dos_header) <= data.size){
dos_header = (PE_DosHeader*)(data.str);
if (dos_header->magic != PE_MSDOS_MAGIC){
dos_header = 0;
}
}
// extract coff file offset
U32 coff_file_offset = 0;
if (dos_header != 0){
coff_file_offset = dos_header->coff_file_offset;
}
// extract pe signature
U32 pe_signature = 0;
U32 coff_header_offset = 0;
if (0 < coff_file_offset &&
coff_file_offset + sizeof(pe_signature) <= data.size){
pe_signature = *(U32*)(data.str + coff_file_offset);
if (pe_signature == PE_SIGNATURE){
coff_header_offset = coff_file_offset + sizeof(pe_signature);
}
}
// extract coff header
PE_CoffHeader *coff_header = 0;
U64 coff_header_opl = 0;
if (When(dos_header != 0, 0 < coff_header_offset) &&
coff_header_offset + sizeof(*coff_header) <= data.size){
coff_header = (PE_CoffHeader*)(data.str + coff_header_offset);
coff_header_opl = coff_header_offset + sizeof(*coff_header);
}
// optional header
U64 optional_header_opl = coff_header_opl;
if (coff_header != 0 &&
coff_header->optional_header_size > 0){
optional_header_opl = coff_header_opl + coff_header->optional_header_size;
}
// determine if this is an image file
B32 is_image = (coff_header_offset != 0);
// parse section table
PE_SectionHeader *section_table = 0;
U64 section_count = 0;
if (coff_header != 0){
U64 section_table_offset = optional_header_opl;
U64 section_table_opl = section_table_offset + coff_header->section_count*sizeof(PE_SectionHeader);
if (section_table_opl <= data.size){
section_table = (PE_SectionHeader*)(data.str + section_table_offset);
section_count = coff_header->section_count;
}
}
/////////////////
///// PRINT /////
/////////////////
STREAM *stream = stream_new();
STREAM *tempstr = stream_new();
{
TABLE *table = table_begin(arena);
{
table_default_align(table, TABLE_CellFlag_CenterAlign);
// TODO(allen): conditionals on columns
table_row(arena, table);
table_cellf(arena, table, "#");
table_cellf(arena, table, "Name");
table_cellf(arena, table, "V.Size");
table_cellf(arena, table, "V.Off");
table_cellf(arena, table, "F.Size");
table_cellf(arena, table, "F.Off");
table_cellf(arena, table, "Mem");
table_cellf(arena, table, "#Relocs");
table_cellf(arena, table, "#Lines");
table_hz_separator(arena, table);
table_default_align(table, TABLE_CellFlag_LeftAlign);
}
{
PE_SectionHeader *sec = section_table;
for (U64 i = 0; i < section_count; i += 1, sec += 1){
table_row(arena, table);
table_cellf(arena, table, "%u", i + 1);
table_cell_align(table, TABLE_CellFlag_RightAlign);
table_cellf(arena, table, "%.*s", ArrayCount(sec->name), sec->name);
table_default_align(table, TABLE_CellFlag_RightAlign);
table_cellf(arena, table, "%$u", sec->vsize);
table_cellf(arena, table, "0x%x", sec->voff);
table_cellf(arena, table, "%$u", sec->fsize);
table_cellf(arena, table, "0x%x", sec->foff);
table_default_align(table, TABLE_CellFlag_LeftAlign);
// memory flags
// TODO(allen): here we want to be able to write this cell
// by writing into a stream
{
stream_clear(tempstr);
stream_printf(tempstr, (sec->flags & PE_SectionFlag_MEM_READ )?"r":"-");
stream_printf(tempstr, (sec->flags & PE_SectionFlag_MEM_WRITE )?"w":"-");
stream_printf(tempstr, (sec->flags & PE_SectionFlag_MEM_EXECUTE)?"x":"-");
table_cell(arena, table, stream_read(arena, tempstr));
}
table_default_align(table, TABLE_CellFlag_RightAlign);
table_cellf(arena, table, "%u", sec->relocation_count);
table_cellf(arena, table, "%u", sec->line_number_count);
table_default_align(table, TABLE_CellFlag_LeftAlign);
}
}
stream_printf(stream, "SECTIONS: (Total %u)\n", section_count);
table_print(stream, table, &table_wire_style);
stream_printf(stream, "\n");
}
stream_fprint(stdout, stream);
return(0);
}

View File

@ -1,21 +0,0 @@
#ifndef MR4TH_PE_TABLE_H
#define MR4TH_PE_TABLE_H
////////////////////////////////
// PE Tabulator Argument Types
typedef struct PETAB_Args{
String8 input_file_name;
} PETAB_Args;
////////////////////////////////
// PE Tabulator Argument Functions
function PETAB_Args* petab_args(Arena *arena, String8List *args);
////////////////////////////////
// Entry Point
int main(int argc, char **argv);
#endif //MR4TH_PE_TABLE_H

View File

@ -5,8 +5,8 @@ static SYMBOL__TYPE(SYMBOL_SET_DEFINE) SYMBOL__SYM(SYMBOL_SET_DEFINE,0);
# pragma SYMBOL__CL_PRAGMA
#endif
BEFORE_MAIN(){
RangePtr image = os_this_image();
RangePtr range = selfimg_get_section(image, str8_lit(GLUE(SYMBOL_SET_DEFINE,_section)));
void *image = os_this_image();
RangePtr range = self_img_get_section(image, str8_lit(GLUE(SYMBOL_SET_DEFINE,_section)));
SymbolCount(SYMBOL_SET_DEFINE) = (range.opl - range.first)/sizeof(SYMBOL__TYPE(SYMBOL_SET_DEFINE));
SymbolBasePtr(SYMBOL_SET_DEFINE) = (SYMBOL__TYPE(SYMBOL_SET_DEFINE)*)(range.first);
}

View File

@ -30,7 +30,9 @@ OSs: Win32, Linux, Mac
Development:
[ ] experiment with __ImageBase pseudo variable (linker variable)
[ ] Small as possible binary parser for "selfimg" purposes
[x] PE