BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
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) throw ExeException("Cannot make an Exe from NULL buffer");
8}
9
10BYTE* Executable::getContentAt(offset_t offset, Executable::addr_type aType, bufsize_t size, bool allowExceptions)
11{
12 offset_t raw = this->toRaw(offset, aType, allowExceptions);
13 if (raw == INVALID_ADDR) {
14 return NULL;
15 }
16 return AbstractByteBuffer::getContentAt(raw, size, allowExceptions);
17}
18
20{
21 if (addr == INVALID_ADDR || addrType == Executable::NOT_ADDR) {
22 return false;
23 }
24 offset_t mappedFrom = (addrType == Executable::VA) ? this->getImageBase() : 0;
25 offset_t mappedTo = mappedFrom + this->getMappedSize(addrType);
26
27 return (addr >= mappedFrom && addr < mappedTo) ? true : false;
28}
29
31{
32 if (va == INVALID_ADDR) return INVALID_ADDR;
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 if (aT == Executable::RAW) {
92 if (offset >= this->getRawSize()) {
93 return INVALID_ADDR;
94 }
95 //no need to convert
96 return offset;
97 }
98
99 if (aT == Executable::VA) {
100 offset = VaToRva(offset, false);
101 aT = Executable::RVA;
102 }
103
104 offset_t convertedOffset = INVALID_ADDR;
105 if (aT == Executable::RVA){
106 try {
107 convertedOffset = this->rvaToRaw(offset);
108 } catch (CustomException) {
109 if (allowExceptions) throw;
110 }
111 }
112 //---
113 if (convertedOffset == INVALID_ADDR) {
115 "Address out of bounds: offset = %llX addrType = %u",
116 static_cast<unsigned long long>(offset),
117 static_cast<unsigned int>(aT)
118 );
119 if (allowExceptions) throw CustomException("Address out of bounds!");
120 }
121 //---
122 return convertedOffset;
123}
124
126{
127 if (hintType == Executable::RAW) {
128 if (this->isValidAddr(offset, hintType) == false) {
130 } else return hintType; // it is RAW
131 }
132
133 if (hintType == Executable::NOT_ADDR) {
134 hintType = Executable::RVA; // check RVA by default
135 }
136 if (this->isValidAddr(offset, hintType) == false) {
137 if (hintType == Executable::RVA) {
138 hintType = Executable::VA; // if not RVA, try VA
139 } else {
140 hintType = Executable::RVA; // if not VA, try RVA
141 }
142 }
143 if (this->isValidAddr(offset, hintType) == false) {
144 return Executable::NOT_ADDR; //every attempt failed! it's invalid!
145 }
146 return hintType;
147}
148
150{
151 FileBuffer* fBuf = dynamic_cast<FileBuffer*>(buf);
152 if (fBuf) {
153 return fBuf->getFileName();
154 }
155 return "";
156}
157
159{
160 if (!buf) return 0;
161
162 FileBuffer* fBuf = dynamic_cast<FileBuffer*>(buf);
163 if (fBuf) {
164 return fBuf->getFileSize();
165 }
166 return buf->getContentSize();
167}
168
169bool Executable::dumpFragment(offset_t offset, bufsize_t size, QString fileName)
170{
171 BufferView *view = new BufferView(this, offset, size);
172 if (!view) return false;
173
174 bufsize_t dumpedSize = FileBuffer::dump(fileName, *view, false);
175 delete view;
176
177 return dumpedSize ? true : false;
178}
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
virtual bufsize_t getContentSize()=0
virtual BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
QString getFileName()
Definition FileBuffer.h:23
static bufsize_t dump(const QString &fileName, AbstractByteBuffer &buf, bool allowExceptions=false)
AbstractByteBuffer * buf
Definition Executable.h:133
bufsize_t getFileSize() const
virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions=false)
virtual bool isValidAddr(offset_t addr, addr_type addrType)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
virtual offset_t getImageBase(bool recalculate=false)=0
QString getFileName()
Executable(AbstractByteBuffer *v_buf, exe_bits v_bitMode)
Definition Executable.cpp:4
virtual offset_t getRawSize() const
Definition Executable.h:62
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 convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType)
Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType)
virtual bool dumpFragment(offset_t offset, bufsize_t size, QString fileName)
virtual offset_t VaToRva(offset_t va, bool autodetect=false)
offset_t getFileSize()
Definition FileBuffer.h:74
bool append(dbg_level lvl, const char *format,...)
Definition Util.cpp:8
@ D_WARNING
Definition Util.h:26