mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-05-05 16:29:33 +00:00
support to print out relocations
This commit is contained in:
parent
fe933ff9d6
commit
e83e171b8c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user