support to print out relocations

This commit is contained in:
Andrew 2013-07-30 17:55:52 -04:00
parent fe933ff9d6
commit e83e171b8c
4 changed files with 194 additions and 105 deletions

View File

@ -44,7 +44,7 @@ void printImports(void *N, RVA impAddr, string &modName, string &symName) {
return;
}
void printRelocs(void *N, RVA relocAddr) {
void printRelocs(void *N, VA relocAddr, reloc_type type) {
return;
}

View File

@ -153,4 +153,21 @@ struct import_dir_entry {
boost::uint32_t AddressRVA;
};
enum reloc_type {
ABSOLUTE = 0,
HIGH = 1,
LOW = 2,
HIGHLOW = 3,
HIGHADJ = 4,
MIPS_JMPADDR = 5,
MIPS_JMPADDR16 = 9,
IA64_IMM64 = 9,
DIR64 = 10
};
struct reloc_block {
boost::uint32_t PageRVA;
boost::uint32_t BlockSize;
};
#endif

View File

@ -43,13 +43,14 @@ struct importent {
};
struct reloc {
RVA shiftedAddr;
RVA shiftedTo;
VA shiftedAddr;
reloc_type type;
};
struct parsed_pe_internal {
list<section> secs;
list<importent> imports;
list<reloc> relocs;
};
bool getSecForRVA(list<section> &secs, RVA v, section &sec) {
@ -348,13 +349,78 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
data_directory exportDir =
p->peHeader.nt.OptionalHeader.DataDirectory[DIR_EXPORT];
//get relocations
//get relocations, if exist
data_directory relocDir =
p->peHeader.nt.OptionalHeader.DataDirectory[DIR_BASERELOC];
if(relocDir.Size != 0) {
section d;
::uint32_t rvaAddr =
relocDir.VirtualAddress + p->peHeader.nt.OptionalHeader.ImageBase;
if(getSecForRVA(p->internal->secs, rvaAddr, d) == false) {
deleteBuffer(remaining);
deleteBuffer(p->fileBuffer);
delete p;
return NULL;
}
::uint32_t rvaofft = rvaAddr - d.sectionBase;
::uint32_t pageRva;
::uint32_t blockSize;
if(readDword( d.sectionData,
rvaofft+_offset(reloc_block, PageRVA),
pageRva) == false)
{
return NULL;
}
if(readDword( d.sectionData,
rvaofft+_offset(reloc_block, BlockSize),
blockSize) == false)
{
return NULL;
}
//iter over all of the RVA blocks
::uint32_t blockCount = blockSize/sizeof(::uint16_t);
rvaofft += sizeof(reloc_block);
while(blockCount != 0) {
::uint16_t block;
::uint8_t type;
::uint16_t offset;
if(readWord(d.sectionData, rvaofft, block) == false) {
return NULL;
}
//mask out the type and assign
type = block >> 12;
//mask out the offset and assign
offset = block & ~0xf000;
//produce the VA of the relocation
::uint32_t relocVA = pageRva + offset +
p->peHeader.nt.OptionalHeader.ImageBase;
//store in our list
reloc r;
r.shiftedAddr = relocVA;
r.type = (reloc_type)type;
p->internal->relocs.push_back(r);
blockCount--;
rvaofft += sizeof(::uint16_t);
}
}
//get imports
data_directory importDir =
p->peHeader.nt.OptionalHeader.DataDirectory[DIR_IMPORT];
if(importDir.Size != 0) {
//get section for the RVA in importDir
section c;
::uint32_t addr =
@ -391,7 +457,9 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
}
//then, try and get the name of this particular module...
::uint32_t name = curEnt.NameRVA + p->peHeader.nt.OptionalHeader.ImageBase;
::uint32_t name =
curEnt.NameRVA + p->peHeader.nt.OptionalHeader.ImageBase;
section nameSec;
if(getSecForRVA(p->internal->secs, name, nameSec) == false) {
return NULL;
@ -463,7 +531,9 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
//okay now we know the pair... add it
importent ent;
ent.addr = curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
ent.addr =
curEnt.AddressRVA + p->peHeader.nt.OptionalHeader.ImageBase;
ent.symbolName = symName;
ent.moduleName = modName;
p->internal->imports.push_back(ent);
@ -476,6 +546,7 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
offt += sizeof(import_dir_entry);
} while(true);
}
deleteBuffer(remaining);
@ -507,7 +578,7 @@ void IterRelocs(parsed_pe *pe, iterReloc cb, void *cbd) {
}
//iterate over the exports by RVA
void IterExpRVA(parsed_pe *pe, iterRVA cb, void *cbd) {
void IterExpRVA(parsed_pe *pe, iterExp cb, void *cbd) {
return;
}

View File

@ -30,6 +30,7 @@ THE SOFTWARE.
#include "nt-headers.h"
typedef boost::uint32_t RVA;
typedef boost::uint32_t VA;
typedef struct _bounded_buffer {
boost::uint8_t *buf;
@ -68,12 +69,12 @@ typedef void (*iterRVAStr)(void *, RVA, std::string &, std::string &);
void IterImpRVAString(parsed_pe *pe, iterRVAStr cb, void *cbd);
//iterate over relocations in the PE file
typedef void (*iterReloc)(void *, RVA);
typedef void (*iterReloc)(void *, VA, reloc_type);
void IterRelocs(parsed_pe *pe, iterReloc cb, void *cbd);
//iterate over the exports
typedef void (*iterRVA)(void *, RVA, std::string &, std::string &);
void IterExpRVA(parsed_pe *pe, iterRVA cb, void *cbd);
typedef void (*iterExp)(void *, RVA, std::string &, std::string &);
void IterExpRVA(parsed_pe *pe, iterExp cb, void *cbd);
//iterate over sections
typedef void (*iterSec)(void *, RVA secBase, std::string &, bounded_buffer *b);