BearParser
Portable Executable parsing library (from PE-bear)
Executable.cpp
Go to the documentation of this file.
1#include "Executable.h"
2#include "FileBuffer.h"
3
5 : buf(v_buf), bitMode(v_bitMode)
6{
7 if (v_buf == NULL) throw ExeException("Cannot make Exe from NULL buffer");
8 FileBuffer *fileBuf = dynamic_cast<FileBuffer*>(buf);
9 if (fileBuf) {
10 this->fileName = fileBuf->getFileName();
11 }
12}
13
14BYTE* Executable::getContentAt(offset_t offset, Executable::addr_type aType, bufsize_t size, bool allowExceptions)
15{
16 offset_t raw = this->toRaw(offset, aType, allowExceptions);
17 if (raw == INVALID_ADDR) {
18 return NULL;
19 }
20 BYTE *cAt = AbstractByteBuffer::getContentAt(raw, size, allowExceptions);
21 return cAt;
22}
23
25{
26 offset_t mappedFrom = (addrType == Executable::VA) ? this->getImageBase() : 0;
27 offset_t mappedTo = mappedFrom + this->getMappedSize(addrType);
28
29 return (addr >= mappedFrom && addr < mappedTo) ? true : false;
30}
31
33{
34 const offset_t mappedFrom = this->getImageBase();
35 const offset_t mappedTo = mappedFrom + this->getMappedSize(Executable::RVA);
36
37 if (autodetect && !isValidAddr(va, Executable::VA)) {
38 return va;
39 }
40 if (va < mappedFrom) return va;
41
42 offset_t rva = va - mappedFrom;
43 return rva;
44}
45
47{
48 if (inType == Executable::NOT_ADDR || outType == Executable::NOT_ADDR ) {
49 return INVALID_ADDR;
50 }
51 if (!isValidAddr(inAddr, inType)) {
52 return INVALID_ADDR;
53 }
54 if (inType == outType) return inAddr;
55
56 const offset_t imgBase = this->getImageBase();
57
58 if (outType == Executable::RAW) {
59 if (inType == Executable::VA) {
60 if (inAddr < imgBase) return INVALID_ADDR;
61 inAddr = inAddr - imgBase;
62 inType = Executable::RVA;
63 }
64 return this->rvaToRaw(inAddr);
65 }
66 if (inType == Executable::RAW) {
67 offset_t out = this->rawToRva(inAddr);
68 if (out == INVALID_ADDR) return INVALID_ADDR;
69
70 if (outType == Executable::VA) {
71 return out + imgBase;
72 }
73 return out;
74 }
75 if (outType == Executable::RVA) {
76 if (inAddr < imgBase) return INVALID_ADDR;
77 return inAddr - imgBase;
78 }
79 if (outType == Executable::VA) {
80 return inAddr + imgBase;
81 }
82 return INVALID_ADDR;
83}
84
85offset_t Executable::toRaw(offset_t offset, addr_type aT, bool allowExceptions)
86{
87 if (offset == INVALID_ADDR) {
88 return INVALID_ADDR;
89 }
90
91 offset_t convertedOffset = INVALID_ADDR;
92
93 if (aT == Executable::RAW) {
94 //no need to convert
95 return offset;
96 }
97
98 if (aT == Executable::VA) {
99 offset = VaToRva(offset, false);
100 aT = Executable::RVA;
101 }
102 if (aT == Executable::RVA){
103 try {
104 convertedOffset = this->rvaToRaw(offset);
105 } catch (CustomException &e) {
106 if (allowExceptions) throw e;
107 }
108 }
109 //---
110 if (convertedOffset == INVALID_ADDR) {
112 "Address out of bounds: offset = %llX addrType = %u",
113 static_cast<unsigned long long>(offset),
114 static_cast<unsigned int>(aT)
115 );
116 if (allowExceptions) throw CustomException("Address out of bounds!");
117 }
118 //---
119 return convertedOffset;
120}
121
123{
124 if (hintType == Executable::RAW) {
125 if (this->isValidAddr(offset, hintType) == false) {
127 } else return hintType; // it is RAW
128 }
129
130 if (hintType == Executable::NOT_ADDR) {
131 hintType = Executable::RVA; // check RVA by default
132 }
133 if (this->isValidAddr(offset, hintType) == false) {
134 if (hintType == Executable::RVA) {
135 hintType = Executable::VA; // if not RVA, try VA
136 } else {
137 hintType = Executable::RVA; // if not VA, try RVA
138 }
139 }
140 if (this->isValidAddr(offset, hintType) == false) {
141 return Executable::NOT_ADDR; //every attempt failed! it's invalid!
142 }
143 return hintType;
144}
145
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
virtual BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
QString getFileName()
Definition: FileBuffer.h:23
AbstractByteBuffer * buf
Definition: Executable.h:108
virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions=false)
Definition: Executable.cpp:85
virtual bool isValidAddr(offset_t addr, addr_type addrType)
Definition: Executable.cpp:24
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition: Executable.h:57
QString fileName
Definition: Executable.h:109
Executable(AbstractByteBuffer *v_buf, exe_bits v_bitMode)
Definition: Executable.cpp:4
virtual offset_t VaToRva(offset_t va, bool autodetect)
Definition: Executable.cpp:32
virtual bufsize_t getMappedSize(Executable::addr_type aType)=0
virtual offset_t rawToRva(offset_t raw)=0
virtual offset_t rvaToRaw(offset_t rva)=0
virtual offset_t getImageBase()=0
virtual offset_t convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType)
Definition: Executable.cpp:46
Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType)
Definition: Executable.cpp:122
bool append(dbg_level lvl, const char *format,...)
Definition: Util.cpp:8
@ D_WARNING
Definition: Util.h:26