180 lines
3.4 KiB
C++
Raw Normal View History

2013-07-24 18:52:38 -04:00
#include <list>
2013-07-24 17:32:23 -04:00
#include "parse.h"
2013-07-25 13:31:49 -04:00
#include "nt-headers.h"
2013-07-24 17:32:23 -04:00
2013-07-24 18:52:38 -04:00
using namespace std;
2013-07-25 13:31:49 -04:00
using namespace boost;
2013-07-24 18:52:38 -04:00
struct section {
string sectionName;
RVA sectionBase;
2013-07-24 19:15:53 -04:00
bounded_buffer sectionData;
2013-07-24 18:52:38 -04:00
};
2013-07-25 12:13:10 -04:00
struct reloc {
RVA shiftedAddr;
RVA shiftedTo;
};
2013-07-24 18:52:38 -04:00
struct parsed_pe_internal {
2013-07-24 19:15:53 -04:00
list<section> secs;
2013-07-24 18:52:38 -04:00
};
2013-07-24 19:15:53 -04:00
list<section> getSections(bounded_buffer *file) {
list<section> sections;
return sections;
}
2013-07-25 17:10:26 -04:00
bool readOptionalHeader(bounded_buffer *b, optional_header_32 &header) {
return false;
}
bool readFileHeader(bounded_buffer *b, file_header &header) {
return false;
}
2013-07-25 16:44:12 -04:00
bool readNtHeader(bounded_buffer *b, nt_header_32 &header) {
2013-07-25 16:52:03 -04:00
if(b == NULL) {
return false;
}
2013-07-25 16:44:12 -04:00
2013-07-25 17:10:26 -04:00
::uint32_t pe_magic;
::uint32_t curOffset =0;
if(readDword(b, curOffset, pe_magic) == false || pe_magic != NT_MAGIC) {
return false;
}
header.Signature = pe_magic;
bounded_buffer *fhb =
splitBuffer(b, _offset(nt_header_32, FileHeader), b->bufLen);
if(readFileHeader(fhb, header.FileHeader) == false) {
return false;
}
bounded_buffer *ohb =
splitBuffer(b, _offset(nt_header_32, OptionalHeader), b->bufLen);
if(readOptionalHeader(ohb, header.OptionalHeader) == false) {
return false;
}
2013-07-25 16:44:12 -04:00
return false;
}
bool getHeader(bounded_buffer *file) {
2013-07-24 19:15:53 -04:00
pe_header p;
2013-07-25 16:52:03 -04:00
if(file == NULL) {
return false;
}
2013-07-25 16:44:12 -04:00
//start by reading MZ
::uint16_t tmp = 0;
::uint32_t curOffset = 0;
readWord(file, curOffset, tmp);
if(tmp != MZ_MAGIC) {
return false;
}
//read the offset to the NT headers
::uint32_t offset;
2013-07-25 17:10:26 -04:00
if(readDword(file, _offset(dos_header, e_lfanew), offset) == false) {
2013-07-25 16:44:12 -04:00
return false;
}
curOffset += offset;
//now, we can read out the fields of the NT headers
2013-07-25 16:52:03 -04:00
nt_header_32 nt;
2013-07-25 17:10:26 -04:00
if(readNtHeader(splitBuffer(file, curOffset, file->bufLen), nt) == false) {
2013-07-25 16:44:12 -04:00
return false;
}
return true;
2013-07-24 19:15:53 -04:00
}
2013-07-24 17:32:23 -04:00
parsed_pe *ParsePEFromFile(const char *filePath) {
2013-07-24 18:32:56 -04:00
//first, create a new parsed_pe structure
parsed_pe *p = new parsed_pe();
if(p == NULL) {
return NULL;
}
//make a new buffer object to hold just our file data
p->fileBuffer = readFileToFileBuffer(filePath);
2013-07-24 18:52:38 -04:00
if(p->fileBuffer == NULL) {
delete p;
return NULL;
}
p->internal = new parsed_pe_internal();
if(p->internal == NULL) {
deleteBuffer(p->fileBuffer);
delete p;
return NULL;
}
2013-07-24 19:15:53 -04:00
//now, we need to do some actual PE parsing and file carving.
2013-07-25 12:13:10 -04:00
//get header information
2013-07-25 16:44:12 -04:00
if(getHeader(p->fileBuffer) == false) {
deleteBuffer(p->fileBuffer);
delete p;
return NULL;
}
2013-07-25 12:13:10 -04:00
//get the raw data of each section
2013-07-24 19:15:53 -04:00
p->internal->secs = getSections(p->fileBuffer);
2013-07-24 18:32:56 -04:00
2013-07-25 12:13:10 -04:00
//get exports
//get relocations
2013-07-24 18:32:56 -04:00
return p;
2013-07-24 17:32:23 -04:00
}
void DestructParsedPE(parsed_pe *p) {
2013-07-24 19:15:53 -04:00
delete p;
2013-07-24 17:32:23 -04:00
return;
}
2013-07-24 18:32:56 -04:00
//iterate over the imports by RVA and string
void IterImpRVAString(parsed_pe *pe, iterRVAStr cb, void *cbd) {
return;
}
//iterate over relocations in the PE file
void IterRelocs(parsed_pe *pe, iterReloc cb, void *cbd) {
return;
}
//iterate over the exports by RVA
void IterExpRVA(parsed_pe *pe, iterRVA cb, void *cbd) {
return;
}
//iterate over sections
void IterSec(parsed_pe *pe, iterSec cb, void *cbd) {
2013-07-24 18:52:38 -04:00
parsed_pe_internal *pint = pe->internal;
for(list<section>::iterator sit = pint->secs.begin(), e = pint->secs.end();
sit != e;
++sit)
{
section s = *sit;
2013-07-24 19:15:53 -04:00
cb(cbd, s.sectionBase, s.sectionName, &s.sectionData);
2013-07-24 18:52:38 -04:00
}
2013-07-24 18:32:56 -04:00
return;
}