diff options
-rw-r--r-- | include/perk/perk.h | 7 | ||||
-rw-r--r-- | include/perk/perk_meta.h | 2 | ||||
-rw-r--r-- | src/crc/pe_crc32.c | 5 | ||||
-rw-r--r-- | src/crc/pe_crc64.c | 5 | ||||
-rw-r--r-- | src/logic/pe_image_meta_data.c | 54 | ||||
-rw-r--r-- | src/output/pe_output_image_symbols.c | 58 |
6 files changed, 97 insertions, 34 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h index 29030ef..47302b4 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -183,6 +183,9 @@ struct pe_image_meta { struct pe_meta_sec_hdr * m_sectbl; struct pe_meta_coff_symbol * m_symtbl; + struct pe_meta_coff_symbol ** m_symvec_crc32; + struct pe_meta_coff_symbol ** m_symvec_crc64; + struct pe_meta_export_hdr m_edata; struct pe_meta_import_hdr * m_idata; @@ -357,8 +360,8 @@ perk_api int pe_read_import_lookup (const unsigned char *, uint32_t magic); /* low-level symtbl api */ -perk_api uint32_t pe_hash_mbstr_crc32 (const unsigned char *, size_t *); -perk_api uint64_t pe_hash_mbstr_crc64 (const unsigned char *, size_t *); +perk_api uint32_t pe_hash_mbstr_crc32 (const unsigned char *); +perk_api uint64_t pe_hash_mbstr_crc64 (const unsigned char *); /* archiver api */ perk_api int pe_ar_get_archive_meta (const struct pe_driver_ctx *, diff --git a/include/perk/perk_meta.h b/include/perk/perk_meta.h index fca10ad..61fc199 100644 --- a/include/perk/perk_meta.h +++ b/include/perk/perk_meta.h @@ -254,6 +254,8 @@ struct pe_meta_import_lookup { struct pe_meta_coff_symbol { char * cs_name; uint32_t cs_value; + uint32_t cs_crc32; + uint64_t cs_crc64; int16_t cs_section_number; uint16_t cs_type; unsigned char cs_storage_class; diff --git a/src/crc/pe_crc32.c b/src/crc/pe_crc32.c index a2cfdd5..68c28dd 100644 --- a/src/crc/pe_crc32.c +++ b/src/crc/pe_crc32.c @@ -12,7 +12,7 @@ static const uint32_t crc32_table[256] = PERK_CRC32_TABLE; -uint32_t pe_hash_mbstr_crc32(const unsigned char * str, size_t * symlen) +uint32_t pe_hash_mbstr_crc32(const unsigned char * str) { const unsigned char * ch; uint32_t crc32; @@ -25,8 +25,5 @@ uint32_t pe_hash_mbstr_crc32(const unsigned char * str, size_t * symlen) ch++; } - if (symlen) - *symlen = ch - str; - return (crc32 ^ 0xFFFFFFFF); } diff --git a/src/crc/pe_crc64.c b/src/crc/pe_crc64.c index 8296432..3cd6e06 100644 --- a/src/crc/pe_crc64.c +++ b/src/crc/pe_crc64.c @@ -12,7 +12,7 @@ static const uint64_t crc64_table[256] = PERK_CRC64_TABLE; -uint64_t pe_hash_mbstr_crc64(const unsigned char * str, size_t * symlen) +uint64_t pe_hash_mbstr_crc64(const unsigned char * str) { const unsigned char * ch; uint64_t crc64; @@ -25,8 +25,5 @@ uint64_t pe_hash_mbstr_crc64(const unsigned char * str, size_t * symlen) ch++; } - if (symlen) - *symlen = ch - str; - return (crc64 ^ 0xFFFFFFFFFFFFFFFF); } diff --git a/src/logic/pe_image_meta_data.c b/src/logic/pe_image_meta_data.c index 274275c..9846818 100644 --- a/src/logic/pe_image_meta_data.c +++ b/src/logic/pe_image_meta_data.c @@ -26,7 +26,11 @@ static int pe_free_image_meta_impl(struct pe_image_meta * meta, int ret) for (i=0; i<meta->m_stats.t_nimplibs; i++) free(meta->m_idata[i].ih_items); + free(meta->m_symvec_crc32); + free(meta->m_symvec_crc64); + free(meta->m_idata); + free(meta->m_symtbl); free(meta->m_sectbl); free(meta); } @@ -39,6 +43,24 @@ void pe_meta_free_image_meta(struct pe_image_meta * meta) pe_free_image_meta_impl(meta,0); } +static int pe_symrec_crc32_compare(const void * a, const void * b) +{ + struct pe_meta_coff_symbol * syma = *(struct pe_meta_coff_symbol **)a; + struct pe_meta_coff_symbol * symb = *(struct pe_meta_coff_symbol **)b; + int eqor = !!(syma->cs_crc32 - symb->cs_crc32); + + return eqor * (syma->cs_crc32 > symb->cs_crc32 ? (1) : (-1)); +} + +static int pe_symrec_crc64_compare(const void * a, const void * b) +{ + struct pe_meta_coff_symbol * syma = *(struct pe_meta_coff_symbol **)a; + struct pe_meta_coff_symbol * symb = *(struct pe_meta_coff_symbol **)b; + int eqor = !!(syma->cs_crc64 - symb->cs_crc64); + + return eqor * (syma->cs_crc64 > symb->cs_crc64 ? (1) : (-1)); +} + static int pe_get_named_section_index(const struct pe_image_meta * m, const char * name) { int i; for (i=0; i<m->m_coff.cfh_num_of_sections; i++) @@ -339,6 +361,7 @@ int pe_meta_get_image_meta( long l; unsigned j; + void * addr; char * base; const unsigned char * mark; uint64_t vaddr; @@ -346,6 +369,7 @@ int pe_meta_get_image_meta( struct pe_image_meta * m; struct pe_meta_coff_symbol * symrec; int nrecs; + int nsyms; base = image->map_addr; @@ -389,11 +413,41 @@ int pe_meta_get_image_meta( &m->r_symtbl[i],symrec, &m->m_coff,base); + addr = symrec->cs_name; + mark = addr; + + symrec->cs_crc32 = pe_hash_mbstr_crc32(mark); + symrec->cs_crc64 = pe_hash_mbstr_crc64(mark); + i += m->r_symtbl[i].cs_num_of_aux_recs[0]; } m->m_stats.t_nsymbols = symrec - m->m_symtbl; + if ((nsyms = m->m_stats.t_nsymbols) && true) { + if (!(m->m_symvec_crc32 = calloc(nsyms,sizeof(*m->m_symvec_crc32)))) + return PERK_SYSTEM_ERROR(dctx); + + for (i=0; i<nsyms; i++) + m->m_symvec_crc32[i] = &m->m_symtbl[i]; + + qsort(&m->m_symvec_crc32[0],nsyms, + sizeof(*m->m_symvec_crc32), + pe_symrec_crc32_compare); + } + + if (nsyms && true) { + if (!(m->m_symvec_crc64 = calloc(nsyms,sizeof(*m->m_symvec_crc64)))) + return PERK_SYSTEM_ERROR(dctx); + + for (i=0; i<nsyms; i++) + m->m_symvec_crc64[i] = &m->m_symtbl[i]; + + qsort(m->m_symvec_crc64,nsyms, + sizeof(*m->m_symvec_crc64), + pe_symrec_crc64_compare); + } + if (m->r_dos) { mark = &m->r_coff->cfh_signature[0]; m->r_opt = (union pe_raw_opt_hdr *)(mark + sizeof(*m->r_coff)); diff --git a/src/output/pe_output_image_symbols.c b/src/output/pe_output_image_symbols.c index 90fd618..26269ac 100644 --- a/src/output/pe_output_image_symbols.c +++ b/src/output/pe_output_image_symbols.c @@ -15,40 +15,50 @@ #include "perk_dprintf_impl.h" #include "perk_errinfo_impl.h" -int pe_output_image_symbols( +static int pe_output_symbol_names( const struct pe_driver_ctx * dctx, - const struct pe_image_meta * meta) + const struct pe_image_meta * meta, + int fdout) { - unsigned i; - unsigned nrecs; - int fdout; - char * mark; - struct pe_raw_coff_symbol * symtbl; - struct pe_meta_coff_symbol symrec; - const char * dash = ""; - - fdout = pe_driver_fdout(dctx); - nrecs = meta->m_coff.cfh_size_of_sym_tbl / sizeof(struct pe_raw_coff_symbol); + struct pe_meta_coff_symbol * symrec; - if (dctx->cctx->fmtflags & PERK_PRETTY_YAML) { - if (pe_dprintf(fdout,"symbols:\n") < 0) + for (symrec=meta->m_symtbl; symrec->cs_name; symrec++) + if (pe_dprintf(fdout,"%s\n",symrec->cs_name) < 0) return PERK_FILE_ERROR(dctx); - dash = "- "; - } + return 0; +} - mark = (char *)meta->r_image.map_addr; - symtbl = (struct pe_raw_coff_symbol *)(mark + meta->m_coff.cfh_ptr_to_sym_tbl); +static int pe_output_symbol_names_yaml( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta, + int fdout) +{ + struct pe_meta_coff_symbol * symrec; - for (i=0; i<nrecs; i++) { - pe_read_coff_symbol( - &symtbl[i],&symrec, - &meta->m_coff,meta->r_image.map_addr); + if (pe_dprintf(fdout," - Symbols:\n") < 0) + return PERK_FILE_ERROR(dctx); - if (pe_dprintf(fdout,"%s%s\n",dash,symrec.cs_name) < 0) + for (symrec=meta->m_symtbl; symrec->cs_name; symrec++) + if (pe_dprintf(fdout," - [ symbol: %s ]\n",symrec->cs_name) < 0) return PERK_FILE_ERROR(dctx); - i += symtbl[i].cs_num_of_aux_recs[0]; + return 0; +} + +int pe_output_image_symbols( + const struct pe_driver_ctx * dctx, + const struct pe_image_meta * meta) +{ + int fdout = pe_driver_fdout(dctx); + + if (dctx->cctx->fmtflags & PERK_PRETTY_YAML) { + if (pe_output_symbol_names_yaml(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); + + } else { + if (pe_output_symbol_names(dctx,meta,fdout) < 0) + return PERK_NESTED_ERROR(dctx); } return 0; |