diff --git a/include/perk/perk.h b/include/perk/perk.h index 332ddde..5d3227a 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -204,6 +204,9 @@ perk_api int pe_read_export_header (const struct pe_export_hdr *, struct pe_me perk_api int pe_read_import_header (const struct pe_import_hdr *, struct pe_meta_import_hdr *); perk_api int pe_read_import_lookup (const union pe_import_lookup_item *, struct pe_meta_import_lookup_item *, uint32_t magic); +perk_api int pe_read_coff_symbol (const struct pe_coff_symbol *, struct pe_meta_coff_symbol *, + const struct pe_meta_coff_file_hdr *, void * base); + #ifdef __cplusplus } #endif diff --git a/project/common.mk b/project/common.mk index 2c98c93..5ae9b5d 100644 --- a/project/common.mk +++ b/project/common.mk @@ -16,6 +16,7 @@ API_SRCS = \ src/output/pe_output_image_symbols.c \ src/output/pe_output_import_libraries.c \ src/reader/pe_read_coff_header.c \ + src/reader/pe_read_coff_symbol.c \ src/reader/pe_read_dos_header.c \ src/reader/pe_read_export_header.c \ src/reader/pe_read_import_header.c \ diff --git a/src/reader/pe_read_coff_symbol.c b/src/reader/pe_read_coff_symbol.c new file mode 100644 index 0000000..2cd63cc --- /dev/null +++ b/src/reader/pe_read_coff_symbol.c @@ -0,0 +1,55 @@ +/***************************************************************/ +/* perk: PE Resource Kit */ +/* Copyright (C) 2015--2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PERK. */ +/***************************************************************/ + +#include + +#include +#include "perk_endian_impl.h" +#include "perk_reader_impl.h" + +int pe_read_coff_symbol( + const struct pe_coff_symbol * p, + struct pe_meta_coff_symbol * m, + const struct pe_meta_coff_file_hdr * coff, + void * base) +{ + uint32_t roffset; + char * mark; + unsigned bias = 0; + + m->long_name = 0; + m->value = pe_read_long(p->value); + m->section_number = pe_read_short(p->section_number); + m->type = pe_read_short(p->type); + m->storage_class = p->storage_class[0]; + m->num_of_aux_symbols = p->num_of_aux_symbols[0]; + + memset(m->name,0,sizeof(m->name)); + + if (p->storage_class[0] == PE_IMAGE_SYM_CLASS_FILE) + if (p->num_of_aux_symbols[0]) + if (!p[1].value[0]) + bias = 1; + + p += bias; + + if (!bias && (p->storage_class[0] == PE_IMAGE_SYM_CLASS_FILE) + && p->num_of_aux_symbols[0]) { + memcpy(m->name,p[1].name,sizeof(*p)); + + } else if (p->name[0]) { + memcpy(m->name,p->name,sizeof(p->name)); + + } else if (!p->name[1] && !p->name[2] && !p->name[3]) { + mark = (char *)base; + roffset = pe_read_long(&p->name[4]); + + if (roffset < coff->size_of_string_tbl) + m->long_name = mark + coff->ptr_to_string_tbl + roffset; + } + + return 0; +}