summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/perk/perk.h1
-rw-r--r--src/info/pe_get_image_abi.c41
-rw-r--r--src/info/pe_get_image_subsystem.c5
-rw-r--r--src/info/pe_get_image_subtype.c5
-rw-r--r--src/logic/pe_get_image_meta.c51
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(