From b73ae8503fd4afff6821e3bed84d408e1f8a3f0c Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 3 Nov 2018 23:20:41 -0400 Subject: internals: added pe_output_hex_{header|footer}(), pe_output_raw_element(). --- src/internal/perk_hdrdump_impl.c | 234 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 src/internal/perk_hdrdump_impl.c (limited to 'src/internal/perk_hdrdump_impl.c') diff --git a/src/internal/perk_hdrdump_impl.c b/src/internal/perk_hdrdump_impl.c new file mode 100644 index 0000000..eadd725 --- /dev/null +++ b/src/internal/perk_hdrdump_impl.c @@ -0,0 +1,234 @@ +/***************************************************************/ +/* perk: PE Resource Kit */ +/* Copyright (C) 2015--2017 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PERK. */ +/***************************************************************/ + +#include +#include + +#include +#include "perk_hdrdump_impl.h" + +#define PE_TABWIDTH 8 +#define PE_HDRSPACE 40 + +static const char pe_hex_header_hex[] = + " 0 1 2 3 4 5 6 7 8 9 a b c d e f 01234567 89abcdef\n"; + +static const char pe_hex_header_dot[] = + " .-------------------------------------------------. .-----------------.\n"; + +static const char pe_hex_footer[] = + "|---------------------------------------------------| |-----------------|\n\n"; + +size_t pe_output_hex_header( + char * buf, + const char * sname, + uint64_t faddr, + uint64_t vaddr, + int bits) +{ + char * ch; + size_t hlen; + size_t dlen; + size_t slen; + size_t nlen; + uint32_t high; + uint32_t low; + + ch = buf; + hlen = strlen(pe_hex_header_hex); + dlen = strlen(pe_hex_header_dot); + slen = strlen(sname); + + switch (bits) { + case 32: + low = faddr; + nlen = sprintf(ch,"faddr: 0x%08x\n",low); + break; + + case 64: + low = faddr; + high = faddr >> 32; + nlen = sprintf(ch,"faddr: 0x%08x%08x\n",high,low); + break; + + default: + return -1; + } + + ch += nlen; + + switch (bits) { + case 32: + low = vaddr; + nlen = sprintf(ch,"vaddr: 0x%08x",low); + break; + + default: + low = vaddr; + high = vaddr >> 32; + nlen = sprintf(ch,"vaddr: 0x%08x%08x",high,low); + break; + } + + ch += nlen; + memset(ch,' ',PE_HDRSPACE - nlen); + ch += PE_HDRSPACE - nlen; + + memcpy(ch,pe_hex_header_hex,hlen); + ch += hlen; + + memcpy(ch,sname,slen); + + ch += slen; + memset(ch,' ',PE_HDRSPACE - slen); + ch += PE_HDRSPACE - slen; + + memcpy(ch,pe_hex_header_dot,dlen); + ch += dlen; + + return ch - buf; +} + +size_t pe_output_hex_footer(char * buf) +{ + size_t nlen; + + memset(buf,' ',PE_HDRSPACE); + buf += PE_HDRSPACE; + + nlen = strlen(pe_hex_footer); + memcpy(buf,pe_hex_footer,nlen); + + return PE_HDRSPACE + nlen; +} + +size_t pe_output_raw_element( + char * ch, + const void * rdata, + const char * mname, + uint32_t moffset, + uint32_t msize) +{ + size_t nlen; + char * base; + uintptr_t addr; + const unsigned char * src; + const unsigned char * cap; + const unsigned char * mark; + size_t pos; + size_t xpos; + const char xch[] = "0123456789abcdef"; + + /* init */ + base = ch; + + /* pos */ + addr = (uintptr_t)rdata; + addr += moffset; + pos = addr % 0x10; + xpos = pos; + + /* struct member name */ + memset(ch,' ',PE_TABWIDTH); + ch += PE_TABWIDTH; + + *ch++ = '.'; + nlen = strlen(mname); + memcpy(ch,mname,nlen); + + ch += nlen; + *ch++ = ':'; + + /* hex dump column */ + nlen = PE_HDRSPACE - PE_TABWIDTH - nlen - 2; + memset(ch,' ',nlen); + ch += nlen; + + *ch++ = '|'; + *ch++ = ' '; + + nlen = 3 * pos; + memset(ch,' ',nlen); + ch += nlen; + + if (pos >= 8) { + *ch++ = ' '; + *ch++ = ' '; + } + + /* hex dump */ + src = rdata; + src += moffset; + + mark = src; + cap = src + msize; + + for (; src= 7); + memset(ch,' ',nlen); + ch += nlen; + + /* binary dump */ + for (; mark= 0x20) && (*mark < 0x7f) + ? *mark : '.'; + + /* pretty columns */ + if ((++mark < src) && (++xpos == 8)) { + *ch++ = ' '; + xpos = 0; + } + } + + nlen = 0xf - pos; + nlen += (pos <= 7); + + memset(ch,' ',nlen); + ch += nlen; + + *ch++ = '|'; + *ch++ = '\n'; + } + + /* does member hex dump span across more than one line? */ + if ((src < cap) && (++pos == 0x10)) { + memset(ch,' ',PE_HDRSPACE); + ch += PE_HDRSPACE; + *ch++ = '|'; + *ch++ = ' '; + + mark = src; + pos = 0; + xpos = 0; + } + } + + return ch - base; +} -- cgit v1.2.3