diff options
author | midipix <writeonce@midipix.org> | 2025-06-15 04:46:43 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2025-06-15 04:46:43 +0000 |
commit | fd49520ef216652d3ba8954e9a402bd071955ca7 (patch) | |
tree | 7268e8d9f83d1d510dfc92b961aafd7c15dae2ab | |
parent | 5470da3f921eb2bc04dec41fa4f222965438923c (diff) | |
download | perk-fd49520ef216652d3ba8954e9a402bd071955ca7.tar.bz2 perk-fd49520ef216652d3ba8954e9a402bd071955ca7.tar.xz |
pe_meta_get_image_meta(): count base relocations and base relocation blocks.
-rw-r--r-- | include/perk/perk.h | 1 | ||||
-rw-r--r-- | src/logic/pe_image_meta_data.c | 52 |
2 files changed, 53 insertions, 0 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h index 6d64f95..8d61316 100644 --- a/include/perk/perk.h +++ b/include/perk/perk.h @@ -157,6 +157,7 @@ struct pe_meta_stats { int32_t t_ndsolibs; int32_t t_ndsosyms; int32_t t_nsymbols; + int32_t t_nrelblks; int32_t t_nrelocs; }; diff --git a/src/logic/pe_image_meta_data.c b/src/logic/pe_image_meta_data.c index b789100..db76769 100644 --- a/src/logic/pe_image_meta_data.c +++ b/src/logic/pe_image_meta_data.c @@ -15,6 +15,7 @@ #include <perk/perk.h> #include <perk/perk_consts.h> #include <perk/perk_structs.h> +#include "perk_endian_impl.h" #include "perk_reader_impl.h" #include "perk_errinfo_impl.h" @@ -365,6 +366,7 @@ int pe_meta_get_image_meta( void * addr; char * base; const unsigned char * mark; + const unsigned char * cap; uint64_t vaddr; struct pe_image_meta * m; @@ -483,6 +485,56 @@ int pe_meta_get_image_meta( m->m_sectbl[i].sh_name = base + m->m_coff.cfh_ptr_to_str_tbl + l; } + /* .relocs */ + struct pe_raw_base_reloc_block * r; + struct pe_block b; + + i = pe_get_named_section_index(m,".reloc"); + s = pe_get_block_section_index(m,&m->m_opt.oh_dirs.coh_base_reloc_tbl); + + if ((i >= 0) && (i != s)) + return pe_free_image_meta_impl( + m,PERK_CUSTOM_ERROR(dctx,PERK_ERR_IMAGE_MALFORMED)); + + + if (s >= 0) { + mark = image->map_addr; + mark += m->m_sectbl[s].sh_ptr_to_raw_data; + mark += m->m_opt.oh_dirs.coh_base_reloc_tbl.dh_rva; + mark -= m->m_sectbl[s].sh_virtual_addr; + cap = &mark[m->m_sectbl[s].sh_virtual_size]; + + } else if (i >= 0) { + mark = image->map_addr; + mark += m->m_sectbl[i].sh_ptr_to_raw_data; + cap = &mark[m->m_sectbl[s].sh_virtual_size]; + + } else { + mark = 0; + cap = 0; + } + + + + for (; mark < cap; ) { + r = (struct pe_raw_base_reloc_block *)mark; + + b.dh_rva = pe_read_long(r->blk_rva); + b.dh_size = pe_read_long(r->blk_size); + + if (b.dh_size <= offsetof(struct pe_raw_base_reloc_block,blk_data)) + return pe_free_image_meta_impl( + m,PERK_CUSTOM_ERROR( + dctx, + PERK_ERR_IMAGE_MALFORMED)); + + mark += b.dh_size; + b.dh_size -= offsetof(struct pe_raw_base_reloc_block,blk_data); + + m->m_stats.t_nrelocs += b.dh_size / sizeof(uint16_t); + m->m_stats.t_nrelblks++; + } + /* .edata */ i = pe_get_named_section_index(m,".edata"); s = pe_get_block_section_index(m,&m->m_opt.oh_dirs.coh_export_tbl); |