/***************************************************************/ /* perk: PE Resource Kit */ /* Copyright (C) 2015--2017 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.PERK. */ /***************************************************************/ #include #include #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; }