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 
14 BYTE* 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 
85 offset_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) {
126  return Executable::NOT_ADDR;
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
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition: Executable.h:57
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
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