Skip to content

Commit

Permalink
Fixed conversions of raw/virtual addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Nov 6, 2016
2 parents acf0b02 + 2ca8bfb commit 826c08c
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 34 deletions.
49 changes: 26 additions & 23 deletions parser/Executable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ offset_t Executable::convertAddr(offset_t inAddr, Executable::addr_type inType,
return INVALID_ADDR;
}
if (inType == outType) return inAddr;

const offset_t imgBase = this->getImageBase();

if (outType == Executable::RAW) {
Expand All @@ -67,49 +68,51 @@ offset_t Executable::convertAddr(offset_t inAddr, Executable::addr_type inType,
if (out == INVALID_ADDR) return INVALID_ADDR;

if (outType == Executable::VA) {
return out + getImageBase();
return out + imgBase;
}
return out;
}
if (outType == Executable::RVA) {
if (inAddr < imgBase) return INVALID_ADDR;
return inAddr - this->getImageBase();
return inAddr - imgBase;
}
if (outType == Executable::VA) {
return inAddr + this->getImageBase();
return inAddr + imgBase;
}
return INVALID_ADDR;
}

offset_t Executable::toRaw(offset_t offset, addr_type aT, bool allowExceptions)
{
if (offset == INVALID_ADDR) return INVALID_ADDR;
if (offset == INVALID_ADDR) {
return INVALID_ADDR;
}

offset_t convertedOffset = INVALID_ADDR;

if (this->isValidAddr(offset, aT) == false) {
Logger::append(Logger::ERROR,
if (aT == Executable::RAW) {
//no need to convert
convertedOffset = offset;
} else if (aT == Executable::VA) {
convertedOffset = VaToRva(offset, false);
} else if (aT == Executable::RVA){
try {
convertedOffset = this->rvaToRaw(offset);
} catch (CustomException e) {
if (allowExceptions) throw e;
}
}
//---
if (convertedOffset == INVALID_ADDR) {
Logger::append(Logger::WARNING,
"Address out of bounds: offset = %llX addrType = %u",
static_cast<unsigned long long>(offset),
static_cast<unsigned int>(aT)
);
if (allowExceptions) throw CustomException("Address out of bounds!");
return INVALID_ADDR;
}

if (aT == Executable::RAW) {
//no need to convert
return offset;
}

if (aT == Executable::VA) {
offset = VaToRva(offset, false);
}
try {
offset = this->rvaToRaw(offset);
} catch (CustomException e) {
if (allowExceptions) throw e;
return INVALID_ADDR;
}
return offset;
//---
return convertedOffset;
}

Executable::addr_type Executable::detectAddrType(offset_t offset, Executable::addr_type hintType)
Expand Down
14 changes: 13 additions & 1 deletion parser/pe/PECore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ bufsize_t PECore::getAlignment(Executable::addr_type aType)

bufsize_t PECore::getImageSize()
{
offset_t imgSize = 0;
bufsize_t imgSize = 0;
if (this->opt32) {
imgSize = opt32->SizeOfImage;
}
Expand All @@ -122,6 +122,18 @@ bufsize_t PECore::getImageSize()
return imgSize;
}

bufsize_t PECore::hdrsSize()
{
bufsize_t hdrsSize = 0;
if (this->opt32) {
hdrsSize = opt32->SizeOfHeaders;
}
if (this->opt64) {
hdrsSize = opt64->SizeOfHeaders;
}
return hdrsSize;
}

offset_t PECore::getImageBase()
{
offset_t imgBase = 0;
Expand Down
1 change: 1 addition & 0 deletions parser/pe/PECore.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PECore
offset_t peFileHdrOffset();
offset_t secHdrsOffset();
offset_t peOptHdrOffset();
bufsize_t hdrsSize();

protected:
void reset();
Expand Down
38 changes: 28 additions & 10 deletions parser/pe/PEFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ void PEFile::wrap(AbstractByteBuffer *v_buf)
}
}

offset_t PEFile::getMinSecRVA()
{
if (this->getSectionsCount() < 1) {
return INVALID_ADDR;
}
SectionHdrWrapper* sec = this->getSecHdr(0);
if (!sec) {
return INVALID_ADDR;
}
return sec->getContentOffset(Executable::RVA);
}

offset_t PEFile::peDataDirOffset()
{
if (this->optHdr == NULL) return INVALID_ADDR;
Expand All @@ -132,11 +144,15 @@ bufsize_t PEFile::getMappedSize(Executable::addr_type aType)
if (aType == Executable::RAW) {
return this->getContentSize();
}
//TODO...
const size_t PAGE_SIZE = 0x1000;
bufsize_t vSize = 0;
if (aType == Executable::VA || aType == Executable::RVA) {
return core.getImageSize();
vSize = core.getImageSize();
}
if (vSize < PAGE_SIZE) {
return PAGE_SIZE;
}
return 0;
return vSize;
}

offset_t PEFile::getEntryPoint(Executable::addr_type addrType)
Expand Down Expand Up @@ -221,9 +237,11 @@ offset_t PEFile::rawToRva(offset_t raw)
}
return bgnVA + curr;
}
//TODO...
//TODO: make more tests
if (this->getSectionsCount() == 0) return raw;
if (raw < this->getAlignment(Executable::RVA)) return raw;
if (raw < this->hdrsSize()) {
return raw;
} //else: content that is between the end of sections headers and the first virtual section is not mapped
return INVALID_ADDR;
}

Expand All @@ -240,14 +258,14 @@ offset_t PEFile::rvaToRaw(offset_t rva)
bufsize_t curr = (rva - bgnRVA);
bufsize_t rawSize = sec->getContentSize(Executable::RAW, true);
if (curr >= rawSize) {
//address out of section
// the address might be in a virtual cave that is not related to any raw address
return INVALID_ADDR;
}
return bgnRaw + curr;
}
if (this->getSectionsCount() == 0) return rva;
if (rva < this->getAlignment(Executable::RAW)) return rva;
return INVALID_ADDR;
if (rva >= this->getMappedSize(Executable::RAW)) return INVALID_ADDR;
// at this point we are sure that the address is within the raw size:
return rva;
}

DataDirEntryWrapper* PEFile::getDataDirEntry(pe::dir_entry eType)
Expand Down Expand Up @@ -313,7 +331,7 @@ bool PEFile::canAddNewSection()
if (sec == NULL || sec->canAddEntry() == false) {
return false;
}
size_t secCount = hdrSectionsNum();
const size_t secCount = hdrSectionsNum();
if (secCount == SectHdrsWrapper::SECT_COUNT_MAX) return false; //limit exceeded

//TODO: some more checks? overlay?
Expand Down
2 changes: 2 additions & 0 deletions parser/pe/PEFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class PEFile : public MappedExe
offset_t peNtHdrOffset() { return core.peSignatureOffset(); }
offset_t peOptHdrOffset() { return core.peOptHdrOffset(); }
offset_t secHdrsOffset() { return core.secHdrsOffset(); }
bufsize_t hdrsSize() { return core.hdrsSize(); }
offset_t getMinSecRVA();

ResourcesAlbum* getResourcesAlbum() const { return this->album; }

Expand Down

0 comments on commit 826c08c

Please sign in to comment.