mirror of
https://github.com/hasherezade/bearparser
synced 2026-06-08 14:32:38 +00:00
120 lines
3.6 KiB
C++
120 lines
3.6 KiB
C++
#include "Executable.h"
|
|
#include "FileBuffer.h"
|
|
|
|
Executable::Executable(AbstractByteBuffer *v_buf, exe_bits v_bitMode)
|
|
: buf(v_buf), bitMode(v_bitMode)
|
|
{
|
|
if (v_buf == NULL) throw ExeException("Cannot make Exe from NULL buffer");
|
|
FileBuffer *fileBuf = dynamic_cast<FileBuffer*>(buf);
|
|
if (fileBuf) {
|
|
this->fileName = fileBuf->getFileName();
|
|
}
|
|
}
|
|
|
|
BYTE* Executable::getContentAt(offset_t offset, Executable::addr_type aType, bufsize_t size, bool allowExceptions)
|
|
{
|
|
offset_t raw = this->toRaw(offset, aType, allowExceptions);
|
|
if (raw == INVALID_ADDR) {
|
|
return NULL;
|
|
}
|
|
BYTE *cAt = AbstractByteBuffer::getContentAt(raw, size, allowExceptions);
|
|
return cAt;
|
|
}
|
|
|
|
bool Executable::isValidAddr(offset_t addr, addr_type addrType)
|
|
{
|
|
offset_t mappedFrom = (addrType == Executable::VA) ? this->getImageBase() : 0;
|
|
offset_t mappedTo = mappedFrom + this->getMappedSize(addrType);
|
|
|
|
return (addr >= mappedFrom && addr < mappedTo) ? true : false;
|
|
}
|
|
|
|
offset_t Executable::VaToRva(offset_t va, bool autodetect)
|
|
{
|
|
offset_t mappedFrom = this->getImageBase();
|
|
offset_t mappedTo = mappedFrom + this->getMappedSize(Executable::RVA);
|
|
|
|
if (autodetect && !isValidAddr(va, Executable::VA)) {
|
|
return va;
|
|
}
|
|
if (va < mappedFrom) return va;
|
|
|
|
offset_t rva = va - mappedFrom;
|
|
return rva;
|
|
}
|
|
|
|
offset_t Executable::convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType)
|
|
{
|
|
if (inType == Executable::NOT_ADDR || outType == Executable::NOT_ADDR ) {
|
|
return INVALID_ADDR;
|
|
}
|
|
if (!isValidAddr(inAddr, inType)) {
|
|
return INVALID_ADDR;
|
|
}
|
|
if (inType == outType) return inAddr;
|
|
if (inType == Executable::RAW && outType == Executable::RVA) {
|
|
return this->rawToRva(inAddr);
|
|
}
|
|
if (outType == Executable::VA) {
|
|
if (inType == Executable::RAW) inAddr = rawToRva(inAddr);
|
|
return inAddr + this->getImageBase();
|
|
}
|
|
if (outType == Executable::RAW) {
|
|
bool allowExceptions = false;
|
|
return toRaw(inAddr, inType, allowExceptions);
|
|
}
|
|
return INVALID_ADDR;
|
|
}
|
|
|
|
offset_t Executable::toRaw(offset_t offset, addr_type aT, bool allowExceptions)
|
|
{
|
|
if (offset == INVALID_ADDR) return INVALID_ADDR;
|
|
|
|
if (this->isValidAddr(offset, aT) == false) {
|
|
if (DBG_LVL) printf("Address out of bounds: offset = %llX addrType = %d\n", offset, 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;
|
|
}
|
|
|
|
Executable::addr_type Executable::detectAddrType(offset_t offset, Executable::addr_type hintType)
|
|
{
|
|
if (hintType == Executable::RAW) {
|
|
if (this->isValidAddr(offset, hintType) == false) {
|
|
return Executable::NOT_ADDR;
|
|
} else return hintType; // it is RAW
|
|
}
|
|
|
|
if (hintType == Executable::NOT_ADDR) {
|
|
hintType = Executable::RVA; // check RVA by default
|
|
}
|
|
if (this->isValidAddr(offset, hintType) == false) {
|
|
if (hintType == Executable::RVA) {
|
|
hintType = Executable::VA; // if not RVA, try VA
|
|
} else {
|
|
hintType = Executable::RVA; // if not VA, try RVA
|
|
}
|
|
}
|
|
if (this->isValidAddr(offset, hintType) == false) {
|
|
return Executable::NOT_ADDR; //every attempt failed! it's invalid!
|
|
}
|
|
return hintType;
|
|
}
|
|
|