diff options
author | midipix <writeonce@midipix.org> | 2017-02-04 10:44:29 -0500 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2017-02-04 10:44:29 -0500 |
commit | 862cb6666e59c88508b3a63213760308f6d6b78e (patch) | |
tree | db5b6538a8182882915a5dbe045dfe694263b299 | |
parent | 6b694b074a89801e7f098e4cb8cd12a6fd390bcf (diff) | |
download | perk-862cb6666e59c88508b3a63213760308f6d6b78e.tar.bz2 perk-862cb6666e59c88508b3a63213760308f6d6b78e.tar.xz |
pe_get_image_meta() and friends: added PE object support.
-rw-r--r-- | include/perk/perk.h | 1 | ||||
-rw-r--r-- | src/info/pe_get_image_abi.c | 41 | ||||
-rw-r--r-- | src/info/pe_get_image_subsystem.c | 5 | ||||
-rw-r--r-- | src/info/pe_get_image_subtype.c | 5 | ||||
-rw-r--r-- | src/logic/pe_get_image_meta.c | 51 |
5 files changed, 73 insertions, 30 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h index 06892b5..85d6694 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -105,6 +105,7 @@ struct pe_image_meta { struct pe_raw_image image; struct pe_raw_image_dos_hdr * ados; struct pe_raw_coff_image_hdr * acoff; + struct pe_raw_coff_object_hdr * aobj; union pe_raw_opt_hdr * aopt; struct pe_raw_sec_hdr * asectbl; diff --git a/src/info/pe_get_image_abi.c b/src/info/pe_get_image_abi.c index 5b7f311..9715fb5 100644 --- a/src/info/pe_get_image_abi.c +++ b/src/info/pe_get_image_abi.c @@ -19,18 +19,35 @@ int pe_get_image_abi(const struct pe_image_meta * m, struct pe_info_string * inf { int abi; - switch (m->opt.oh_std.coh_magic) { - case PE_MAGIC_PE32: - abi = PE_ABI_PE32; - break; - - case PE_MAGIC_PE32_PLUS: - abi = PE_ABI_PE64; - break; - - default: - abi = PE_ABI_UNSUPPORTED; - break; + if (m->aobj) { + switch (m->coff.cfh_machine) { + case PE_IMAGE_FILE_MACHINE_I386: + abi = PE_ABI_PE32; + break; + + case PE_IMAGE_FILE_MACHINE_IA64: + case PE_IMAGE_FILE_MACHINE_AMD64: + abi = PE_ABI_PE64; + break; + + default: + abi = PE_ABI_UNSUPPORTED; + break; + } + } else { + switch (m->opt.oh_std.coh_magic) { + case PE_MAGIC_PE32: + abi = PE_ABI_PE32; + break; + + case PE_MAGIC_PE32_PLUS: + abi = PE_ABI_PE64; + break; + + default: + abi = PE_ABI_UNSUPPORTED; + break; + } } if (infostr) diff --git a/src/info/pe_get_image_subsystem.c b/src/info/pe_get_image_subsystem.c index 2f4b2d8..d33361c 100644 --- a/src/info/pe_get_image_subsystem.c +++ b/src/info/pe_get_image_subsystem.c @@ -26,7 +26,10 @@ int pe_get_image_subsystem(const struct pe_image_meta * m, struct pe_info_string { int subsystem; - if (m->opt.oh_img.coh_subsystem >= 0x10) + if (m->aobj) + subsystem = 0; + + else if (m->opt.oh_img.coh_subsystem >= 0x10) subsystem = -1; else if (!pe_subsystem_str[m->opt.oh_img.coh_subsystem]) diff --git a/src/info/pe_get_image_subtype.c b/src/info/pe_get_image_subtype.c index df1ffd0..b3b4dac 100644 --- a/src/info/pe_get_image_subtype.c +++ b/src/info/pe_get_image_subtype.c @@ -22,7 +22,10 @@ int pe_get_image_subtype(const struct pe_image_meta * m, struct pe_info_string * { int subtype; - if (m->coff.cfh_characteristics & PE_IMAGE_FILE_DLL) + if (m->aobj) + subtype = PE_SUBTYPE_OBJ; + + else if (m->coff.cfh_characteristics & PE_IMAGE_FILE_DLL) subtype = PE_SUBTYPE_DLL; else diff --git a/src/logic/pe_get_image_meta.c b/src/logic/pe_get_image_meta.c index 0aed2de..3267d0f 100644 --- a/src/logic/pe_get_image_meta.c +++ b/src/logic/pe_get_image_meta.c @@ -48,6 +48,9 @@ int pe_get_block_section_index(const struct pe_image_meta * m, const struct pe_b int i; uint32_t low,high; + if (m->aobj) + return -1; + for (i=0; i<m->coff.cfh_num_of_sections; i++) { low = m->sectbl[i].sh_virtual_addr; high = low + m->sectbl[i].sh_virtual_size; @@ -112,6 +115,9 @@ int pe_get_expsym_by_name( const char * sym; unsigned i; + if (m->aobj) + return -1; + offset = m->hedata->sh_virtual_addr - m->hedata->sh_ptr_to_raw_data; symrva = (uint32_t *)((uintptr_t)m->image.addr + (m->edata.eh_name_ptr_rva - offset)); @@ -142,6 +148,9 @@ int pe_get_expsym_by_index( uint32_t * symrva; uintptr_t symaddr; + if (m->aobj) + return -1; + if (index >= m->edata.eh_num_of_name_ptrs) return -1; @@ -177,34 +186,44 @@ int pe_get_image_meta( if (!(m = calloc(1,sizeof(*m)))) return PERK_SYSTEM_ERROR(dctx); - m->ados = (struct pe_raw_image_dos_hdr *)base; + m->aobj = (struct pe_raw_coff_object_hdr *)base; - if ((ret = (pe_read_dos_header(m->ados,&m->dos)))) - return pe_free_image_meta_impl( - m,PERK_CUSTOM_ERROR(dctx,ret)); + if (pe_read_object_header(m->aobj,&m->coff)) { + m->aobj = 0; + m->ados = (struct pe_raw_image_dos_hdr *)base; - m->acoff = (struct pe_raw_coff_image_hdr *)(base + m->dos.dos_lfanew); + if ((ret = (pe_read_dos_header(m->ados,&m->dos)))) + return pe_free_image_meta_impl( + m,PERK_CUSTOM_ERROR(dctx,ret)); - if ((ret = (pe_read_coff_header(m->acoff,&m->coff)))) - return pe_free_image_meta_impl( - m,PERK_CUSTOM_ERROR(dctx,ret)); + m->acoff = (struct pe_raw_coff_image_hdr *)(base + m->dos.dos_lfanew); + + if ((ret = (pe_read_coff_header(m->acoff,&m->coff)))) + return pe_free_image_meta_impl( + m,PERK_CUSTOM_ERROR(dctx,ret)); + } - mark = (const unsigned char *)image->addr + m->coff.cfh_ptr_to_sym_tbl; + mark = (const unsigned char *)base + m->coff.cfh_ptr_to_sym_tbl; mark += m->coff.cfh_num_of_syms * sizeof(struct pe_raw_coff_symbol); m->coff.cfh_ptr_to_str_tbl = m->coff.cfh_ptr_to_sym_tbl; m->coff.cfh_ptr_to_str_tbl += m->coff.cfh_num_of_syms * sizeof(struct pe_raw_coff_symbol); m->coff.cfh_size_of_str_tbl = pe_read_long(mark); - mark = &m->acoff->cfh_signature[0]; - m->aopt = (union pe_raw_opt_hdr *)(mark + sizeof(*m->acoff)); + if (m->ados) { + mark = &m->acoff->cfh_signature[0]; + m->aopt = (union pe_raw_opt_hdr *)(mark + sizeof(*m->acoff)); - if ((ret = (pe_read_optional_header(m->aopt,&m->opt)))) - return pe_free_image_meta_impl( - m,PERK_CUSTOM_ERROR(dctx,ret)); + if ((ret = (pe_read_optional_header(m->aopt,&m->opt)))) + return pe_free_image_meta_impl( + m,PERK_CUSTOM_ERROR(dctx,ret)); - mark = &m->aopt->opt_hdr_32.coh_magic[0]; - m->asectbl = (struct pe_raw_sec_hdr *)(mark + m->coff.cfh_size_of_opt_hdr); + mark = &m->aopt->opt_hdr_32.coh_magic[0]; + m->asectbl = (struct pe_raw_sec_hdr *)(mark + m->coff.cfh_size_of_opt_hdr); + } else { + mark = &m->aobj->cfh_machine[0]; + m->asectbl = (struct pe_raw_sec_hdr *)(mark + sizeof(*m->aobj)); + } if (!(m->sectbl = calloc(m->coff.cfh_num_of_sections,sizeof(*(m->sectbl))))) return pe_free_image_meta_impl( |