Merge pull request #39 from jkolek/master

Bugfix - parse all possible relocation blocks
This commit is contained in:
Peter Goodman 2017-03-30 16:25:39 -04:00 committed by GitHub
commit 418cbfdb9a

View File

@ -1374,13 +1374,14 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
} }
::uint32_t rvaofft = vaAddr - d.sectionBase; ::uint32_t rvaofft = vaAddr - d.sectionBase;
while (rvaofft < relocDir.Size) {
::uint32_t pageRva; ::uint32_t pageRva;
::uint32_t blockSize; ::uint32_t blockSize;
if (readDword(d.sectionData, if (readDword(d.sectionData,
rvaofft+_offset(reloc_block, PageRVA), rvaofft+_offset(reloc_block, PageRVA),
pageRva) == false) pageRva) == false) {
{
deleteBuffer(remaining); deleteBuffer(remaining);
deleteBuffer(p->fileBuffer); deleteBuffer(p->fileBuffer);
delete p; delete p;
@ -1390,8 +1391,7 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
if (readDword(d.sectionData, if (readDword(d.sectionData,
rvaofft+_offset(reloc_block, BlockSize), rvaofft+_offset(reloc_block, BlockSize),
blockSize) == false) blockSize) == false) {
{
deleteBuffer(remaining); deleteBuffer(remaining);
deleteBuffer(p->fileBuffer); deleteBuffer(p->fileBuffer);
delete p; delete p;
@ -1399,17 +1399,22 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
return NULL; return NULL;
} }
//iter over all of the blocks // BlockSize - The total number of bytes in the base relocation block,
::uint32_t blockCount = blockSize/sizeof(::uint16_t); // including the Page RVA and Block Size fields and the Type/Offset fields
// that follow. Therefore we should subtract 8 bytes from BlockSize to
// exclude the Page RVA and Block Size fields.
::uint32_t entryCount = (blockSize - 8) / sizeof(::uint16_t);
// Skip the Page RVA and Block Size fields
rvaofft += sizeof(reloc_block); rvaofft += sizeof(reloc_block);
while(blockCount != 0) { // Iterate over all of the block Type/Offset entries
::uint16_t block; while (entryCount != 0) {
::uint16_t entry;
::uint8_t type; ::uint8_t type;
::uint16_t offset; ::uint16_t offset;
if(readWord(d.sectionData, rvaofft, block) == false) { if (readWord(d.sectionData, rvaofft, entry) == false) {
deleteBuffer(remaining); deleteBuffer(remaining);
deleteBuffer(p->fileBuffer); deleteBuffer(p->fileBuffer);
delete p; delete p;
@ -1417,12 +1422,12 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
return NULL; return NULL;
} }
//mask out the type and assign // Mask out the type and assign
type = block >> 12; type = entry >> 12;
//mask out the offset and assign // Mask out the offset and assign
offset = block & ~0xf000; offset = entry & ~0xf000;
//produce the VA of the relocation // Produce the VA of the relocation
::uint32_t relocVA; ::uint32_t relocVA;
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) { if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
relocVA = pageRva + offset + p->peHeader.nt.OptionalHeader.ImageBase; relocVA = pageRva + offset + p->peHeader.nt.OptionalHeader.ImageBase;
@ -1436,17 +1441,18 @@ parsed_pe *ParsePEFromFile(const char *filePath) {
return NULL; return NULL;
} }
//store in our list // Store in our list
reloc r; reloc r;
r.shiftedAddr = relocVA; r.shiftedAddr = relocVA;
r.type = (reloc_type)type; r.type = (reloc_type)type;
p->internal->relocs.push_back(r); p->internal->relocs.push_back(r);
blockCount--; entryCount--;
rvaofft += sizeof(::uint16_t); rvaofft += sizeof(::uint16_t);
} }
} }
}
//get imports //get imports
data_directory importDir; data_directory importDir;