BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
PEFile.h
Go to the documentation of this file.
1#pragma once
2
3#include "pe_formats.h"
4#include "PECore.h"
5
6#include "DOSExe.h"
7#include "RichHdrWrapper.h"
8#include "FileHdrWrapper.h"
9#include "OptHdrWrapper.h"
10#include "SectHdrsWrapper.h"
11#include "DataDirWrapper.h"
12
13#include "ImportDirWrapper.h"
14#include "DelayImpDirWrapper.h"
15#include "BoundImpDirWrapper.h"
16#include "DebugDirWrapper.h"
17#include "ExportDirWrapper.h"
18#include "SecurityDirWrapper.h"
19#include "TlsDirWrapper.h"
20#include "LdConfigDirWrapper.h"
21#include "RelocDirWrapper.h"
22#include "ExceptionDirWrapper.h"
23#include "ResourceDirWrapper.h"
24#include "ClrDirWrapper.h"
26#include "rsrc/ResourcesAlbum.h"
27
28#include "../WatchedLocker.h"
29
30#define PE_SHOW_LOCK false
31
32class PEFile;
33
35public:
37 virtual bool signatureMatches(AbstractByteBuffer *buf);
38 virtual Executable* build(AbstractByteBuffer *buf);
39 QString typeName() { return "PE"; }
40};
41
42//-------------------------------------------------------------
43
44class PEFile : public MappedExe
45{
46public:
59
60 static long computeChecksum(const BYTE *buffer, size_t bufferSize, offset_t checksumOffset);
61
63 virtual ~PEFile() { clearWrappers(); delete album; }
64
65 virtual void wrap(); // inherited from Executable
66 bool wrapDataDirs();
67
69 virtual bufsize_t getAlignment(Executable::addr_type aType) const { return core.getAlignment(aType); }
70 virtual offset_t getImageBase(bool recalculate = false) { return core.getImageBase(recalculate); }
71 virtual offset_t getEntryPoint(Executable::addr_type addrType = Executable::RVA); // returns INVALID_ADDR if failed
72
73 virtual exe_bits getBitMode() { return getHdrBitMode(); }
74 virtual exe_arch getArch() { return getHdrArch(); }
75 //---
76 // PEFile only:
77 offset_t peFileHdrOffset() const { return core.peFileHdrOffset(); }
78 offset_t peNtHdrOffset() const { return core.peSignatureOffset(); }
79 bufsize_t peNtHeadersSize() const { return core.peNtHeadersSize(); }
80 offset_t peOptHdrOffset() const { return core.peOptHdrOffset(); }
81 offset_t secHdrsOffset() const { return core.secHdrsOffset(); }
82
83 bufsize_t hdrsSize() { return core.hdrsSize(); }
84
85 ResourcesAlbum* getResourcesAlbum() const { return this->album; }
86
87 //get Rich header (if available)
88 pe::RICH_SIGNATURE* getRichHeaderSign();
89 pe::RICH_DANS_HEADER* getRichHeaderBgn(pe::RICH_SIGNATURE* sign);
90
91 IMAGE_DATA_DIRECTORY* getDataDirectory();
93
94 size_t hdrSectionsNum() const;
95
96 exe_bits getHdrBitMode() { return core.getHdrBitMode(); }
97
98 exe_arch getHdrArch() { return core.getHdrArch(); }
99
100/* mutex protected: section operations */
101
103 {
104 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
105 return _getLastMapped(aType);
106 }
107
108 // FileAddr <-> RVA
109 virtual offset_t rawToRva(offset_t raw);
110 virtual offset_t rvaToRaw(offset_t rva);
111
113
114 size_t getSectionsCount(bool useMapped = true)
115 {
116 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
117 return _getSectionsCount(useMapped);
118 }
119
120 // mutex protected
122 {
123 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
124 return _getSecIndex(sec);
125 }
126
127 // mutex protected
129 {
130 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
131 return _getSecHdr(index);
132 }
133
134 // mutex protected
135 SectionHdrWrapper* getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate = false, bool verbose = false)
136 {
137 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
138 return _getSecHdrAtOffset(offset, aType, recalculate, verbose);
139 }
140
141 // mutex protected
143 {
144 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
146 return this->_getSecHdrAtOffset(ep, Executable::RVA, true, false);
147 }
148
149 // mutex protected
151 {
152 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
154 return NULL; //not my section
155 }
156 const bufsize_t buf_size = sec->getContentSize(Executable::RAW, true);
157 if (!buf_size) return NULL;
158
159 offset_t start = sec->getContentOffset(Executable::RAW, true);
160 BYTE *ptr = this->getContentAt(start, buf_size);
161 return ptr;
162 }
163
164 // mutex protected
165 BufferView* createSectionView(size_t secNum);
166 //---
167
168 // mutex protected
170 {
171 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
173 return false; //not my section
174 }
175 BufferView *secView = this->_createSectionView(sec);
176 if (!secView) return false;
177
178 bool isOk = secView->fillContent(0);
179 delete secView;
180 return isOk;
181 }
182
183 // mutex protected
185 {
186 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
187 return _secHdrsEndOffset();
188 }
189
190 // mutex protected
192 {
193 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
194 return this->_getLastSection();
195 }
196
197 // mutex protected
199 {
200 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
201 return this->_canAddNewSection();
202 }
203
204 // mutex protected
205 SectionHdrWrapper* addNewSection(QString name, bufsize_t size, bufsize_t v_size=0);
206
207 // mutex protected
209
210 // mutex protected
211 bool dumpSection(SectionHdrWrapper *sec, QString fileName);
212
213/* resource operations */
214
215 ResourcesContainer* getResourcesOfType(pe::resource_type typeId)
216 {
217 return (this->album == NULL) ? NULL : album->getResourcesOfType(typeId);
218 }
219
220 DataDirEntryWrapper* getDataDirEntry(pe::dir_entry eType);
221
222 //modifications:
224 bool moveDataDirEntry(pe::dir_entry id, offset_t newOffset, Executable::addr_type addType = Executable::RAW); //throws CustomException
225
226 bool unbindImports();
227
229 {
230 return dynamic_cast<DosHdrWrapper*>(getWrapper(PEFile::WR_DOS_HDR));
231 }
232
237
242
247
252
253 /* wrappers for fetching the initialized directories */
255 {
256 return dynamic_cast<ImportDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_IMPORT));
257 }
258
260 {
261 return dynamic_cast<DelayImpDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_DELAY_IMPORT));
262 }
263
265 {
266 return dynamic_cast<BoundImpDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_BOUND_IMPORT));
267 }
268
270 {
271 return dynamic_cast<DebugDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_DEBUG));
272 }
273
275 {
276 return dynamic_cast<ExportDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_EXPORT));
277 }
278
280 {
281 return dynamic_cast<SecurityDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_SECURITY));
282 }
283
285 {
286 return dynamic_cast<TlsDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_TLS));
287 }
288
290 {
291 return dynamic_cast<LdConfigDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_LOAD_CONFIG));
292 }
293
295 {
296 return dynamic_cast<RelocDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_BASERELOC));
297 }
298
300 {
301 return dynamic_cast<ExceptionDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_EXCEPTION));
302 }
303
305 {
306 return dynamic_cast<ResourceDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_RESOURCE));
307 }
308
310 {
311 return dynamic_cast<ClrDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_COM_DESCRIPTOR));
312 }
313
314 /* All Entry Points of the application, including: main EP, Exports, TLS Callbacks */
315 virtual size_t getAllEntryPoints(QMap<offset_t,QString> &entrypoints, Executable::addr_type aType = Executable::RVA)
316 {
317 size_t initialSize = entrypoints.size();
318
319 Executable::getAllEntryPoints(entrypoints, aType);
320 this->getExportsMap(entrypoints, aType);
321
322 return entrypoints.size() - initialSize;
323 }
324
325 /* wrappers:
326 */
327 bool hasDirectory(const pe::dir_entry &dirNum)
328 {
329 return this->getDataDirEntry(dirNum) ? true : false;
330 }
331
333 {
334 return this->getAlignment(Executable::RAW);
335 }
336
338 {
339 return this->getAlignment(Executable::RVA);
340 }
341
343 {
344 this->setVirtualSize(newSize);
345 }
346
347 bool canResize(bufsize_t newSize)
348 {
349 bufsize_t currentSize = (bufsize_t)this->getRawSize();
350 if (newSize > currentSize) {
351 return true;
352 }
353 bufsize_t hEnd = bufsize_t(this->peNtHdrOffset()) + this->peNtHeadersSize();
354 if (newSize < hEnd) {
355 return false; // the resize will harm headers!
356 }
357 return true;
358 }
359
361 {
362 bool isRepro = false;
363 DebugDirWrapper* dbgDir = dynamic_cast<DebugDirWrapper*>(dataDirEntries[pe::DIR_DEBUG]);
364 if (dbgDir && dbgDir->isRepro()) {
365 isRepro = true;
366 }
367 return isRepro;
368 }
369
370protected:
371 void wrapCore();
372
374 bool _canAddNewSection();
375
377 {
378 const offset_t offset = secHdrsOffset();
379 if (offset == INVALID_ADDR) {
380 return INVALID_ADDR;
381 }
382 const offset_t secHdrSize = this->_getSectionsCount() * sizeof(IMAGE_SECTION_HEADER);
383 return offset + secHdrSize;
384 }
385
387
388 size_t _getSectionsCount(bool useMapped = true) const;
389
391 {
392 return (sects) ? sects->getSecIndex(sec) : SectHdrsWrapper::SECT_INVALID_INDEX;
393 }
394
395 SectionHdrWrapper* _getSecHdr(size_t index) const
396 {
397 return (sects) ? sects->_getSecHdr(index) : NULL;
398 }
399
400 SectionHdrWrapper* _getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate = false, bool verbose = false)
401 {
402 return (sects) ? sects->getSecHdrAtOffset(offset, aType, recalculate, verbose) : NULL;
403 }
404
406
407 size_t getExportsMap(QMap<offset_t,QString> &entrypoints, Executable::addr_type aType = Executable::RVA);
408
409 virtual void clearWrappers();
410
411 void _init(AbstractByteBuffer *v_buf);
412 void initDirEntries();
413
414 //---
415 //modifications:
416 bool setHdrSectionsNum(size_t newNum);
417 bool setVirtualSize(bufsize_t newSize);
418
421
425
427 DataDirEntryWrapper* dataDirEntries[pe::DIR_ENTRIES_COUNT];
428 QMutex m_peMutex;
429
430friend class SectHdrsWrapper;
431friend class SectionHdrWrapper;
432};
433
const offset_t INVALID_ADDR
uint64_t offset_t
size_t bufsize_t
#define PE_SHOW_LOCK
Definition PEFile.h:30
bool fillContent(BYTE filling)
@ WR_DOS_HDR
Definition DOSExe.h:23
virtual ExeElementWrapper * getWrapper(size_t wrapperId)
Definition MappedExe.cpp:13
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
virtual offset_t getRawSize() const
Definition Executable.h:62
virtual size_t getAllEntryPoints(QMap< offset_t, QString > &entrypoints, Executable::addr_type aType=Executable::RVA)
Definition Executable.h:77
MappedExe(AbstractByteBuffer *v_buf, exe_bits v_bitMode)
Definition MappedExe.h:52
Definition PECore.h:8
PEFileBuilder()
Definition PEFile.h:36
virtual Executable * build(AbstractByteBuffer *buf)
Definition PEFile.cpp:31
QString typeName()
Definition PEFile.h:39
virtual bool signatureMatches(AbstractByteBuffer *buf)
Definition PEFile.cpp:4
DataDirEntryWrapper * dataDirEntries[pe::DIR_ENTRIES_COUNT]
Definition PEFile.h:427
DebugDirWrapper * getDebugDir()
Definition PEFile.h:269
QMutex m_peMutex
Definition PEFile.h:428
FileHdrWrapper * getFileHdrWrapper()
Definition PEFile.h:233
virtual bufsize_t getMappedSize(Executable::addr_type aType)
Definition PEFile.cpp:298
BufferView * _createSectionView(SectionHdrWrapper *sec)
Definition PEFile.cpp:697
size_t getExportsMap(QMap< offset_t, QString > &entrypoints, Executable::addr_type aType=Executable::RVA)
Definition PEFile.cpp:708
offset_t secHdrsEndOffset()
Definition PEFile.h:184
RelocDirWrapper * getRelocsDir()
Definition PEFile.h:294
bufsize_t getSectionAlignment() const
Definition PEFile.h:337
offset_t peFileHdrOffset() const
Definition PEFile.h:77
SectHdrsWrapper * sects
Definition PEFile.h:424
SectionHdrWrapper * _getSecHdr(size_t index) const
Definition PEFile.h:395
bufsize_t peNtHeadersSize() const
Definition PEFile.h:79
ImportDirWrapper * getImportsDir()
Definition PEFile.h:254
virtual ~PEFile()
Definition PEFile.h:63
bool unbindImports()
Definition PEFile.cpp:676
offset_t peDataDirOffset()
Definition PEFile.cpp:286
virtual offset_t getEntryPoint(Executable::addr_type addrType=Executable::RVA)
Definition PEFile.cpp:316
offset_t secHdrsOffset() const
Definition PEFile.h:81
void _init(AbstractByteBuffer *v_buf)
Definition PEFile.cpp:116
SecurityDirWrapper * getSecurityDir()
Definition PEFile.h:279
offset_t getMinSecRVA()
Definition PEFile.cpp:273
friend class SectHdrsWrapper
Definition PEFile.h:430
offset_t getLastMapped(Executable::addr_type aType)
Definition PEFile.h:102
FileHdrWrapper * fHdr
Definition PEFile.h:422
bool wrapDataDirs()
Definition PEFile.cpp:193
size_t _getSecIndex(SectionHdrWrapper *sec) const
Definition PEFile.h:390
ResourcesAlbum * album
Definition PEFile.h:426
bool setEntryPoint(offset_t entry, Executable::addr_type aType)
Definition PEFile.cpp:331
pe::RICH_DANS_HEADER * getRichHeaderBgn(pe::RICH_SIGNATURE *sign)
Definition PEFile.cpp:217
virtual size_t getAllEntryPoints(QMap< offset_t, QString > &entrypoints, Executable::addr_type aType=Executable::RVA)
Definition PEFile.h:315
virtual offset_t getImageBase(bool recalculate=false)
Definition PEFile.h:70
SectionHdrWrapper * extendLastSection(bufsize_t addedSize)
Definition PEFile.cpp:620
WRAPPERS
Definition PEFile.h:47
@ WR_DIR_ENTRY
Definition PEFile.h:55
@ WR_DATADIR
Definition PEFile.h:53
@ WR_NONE
Definition PEFile.h:48
@ WR_DIR_ENTRY_END
Definition PEFile.h:56
@ WR_OPTIONAL_HDR
Definition PEFile.h:52
@ WR_FILE_HDR
Definition PEFile.h:51
@ WR_DOS_HDR
Definition PEFile.h:49
@ WR_SECTIONS
Definition PEFile.h:54
@ WR_RICH_HDR
Definition PEFile.h:50
@ COUNT_WRAPPERS
Definition PEFile.h:57
DataDirWrapper * getDataDirWrapper()
Definition PEFile.h:243
PECore core
Definition PEFile.h:419
size_t getSectionsCount(bool useMapped=true)
Definition PEFile.h:114
void initDirEntries()
Definition PEFile.cpp:173
virtual void wrap()
Definition PEFile.cpp:211
SectionHdrWrapper * getLastSection()
Definition PEFile.h:191
OptHdrWrapper * optHdr
Definition PEFile.h:423
bool dumpSection(SectionHdrWrapper *sec, QString fileName)
Definition PEFile.cpp:661
ClrDirWrapper * getClsDir()
Definition PEFile.h:309
offset_t _getLastMapped(Executable::addr_type aType)
Definition PEFile.cpp:576
void setImageSize(bufsize_t newSize)
Definition PEFile.h:342
virtual offset_t rvaToRaw(offset_t rva)
Definition PEFile.cpp:407
BufferView * createSectionView(size_t secNum)
Definition PEFile.cpp:447
BoundImpDirWrapper * getBoundImportsDir()
Definition PEFile.h:264
ResourcesAlbum * getResourcesAlbum() const
Definition PEFile.h:85
offset_t peOptHdrOffset() const
Definition PEFile.h:80
bool setHdrSectionsNum(size_t newNum)
Definition PEFile.cpp:349
DelayImpDirWrapper * getDelayedImportsDir()
Definition PEFile.h:259
bool setVirtualSize(bufsize_t newSize)
Definition PEFile.cpp:360
bool _canAddNewSection()
Definition PEFile.cpp:494
static long computeChecksum(const BYTE *buffer, size_t bufferSize, offset_t checksumOffset)
Definition PEFile.cpp:45
void wrapCore()
Definition PEFile.cpp:180
friend class SectionHdrWrapper
Definition PEFile.h:431
DataDirEntryWrapper * getDataDirEntry(pe::dir_entry eType)
Definition PEFile.cpp:441
SectionHdrWrapper * _getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate=false, bool verbose=false)
Definition PEFile.h:400
bool clearContent(SectionHdrWrapper *sec)
Definition PEFile.h:169
bool moveDataDirEntry(pe::dir_entry id, offset_t newOffset, Executable::addr_type addType=Executable::RAW)
Definition PEFile.cpp:458
SectionHdrWrapper * _getLastSection()
Definition PEFile.cpp:570
virtual void clearWrappers()
Definition PEFile.cpp:162
size_t getSecIndex(SectionHdrWrapper *sec)
Definition PEFile.h:121
offset_t _secHdrsEndOffset()
Definition PEFile.h:376
SectionHdrWrapper * getSecHdr(size_t index)
Definition PEFile.h:128
IMAGE_DATA_DIRECTORY * getDataDirectory()
Definition PEFile.cpp:292
virtual offset_t rawToRva(offset_t raw)
Definition PEFile.cpp:379
ResourceDirWrapper * getResourcesDir()
Definition PEFile.h:304
LdConfigDirWrapper * getLoadConfigDir()
Definition PEFile.h:289
bufsize_t hdrsSize()
Definition PEFile.h:83
size_t hdrSectionsNum() const
Definition PEFile.cpp:340
RichHdrWrapper * getRichHdrWrapper()
Definition PEFile.h:248
exe_arch getHdrArch()
Definition PEFile.h:98
virtual exe_arch getArch()
Definition PEFile.h:74
SectionHdrWrapper * getEntrySection()
Definition PEFile.h:142
PEFile(AbstractByteBuffer *v_buf)
Definition PEFile.cpp:105
offset_t peNtHdrOffset() const
Definition PEFile.h:78
bufsize_t getFileAlignment() const
Definition PEFile.h:332
bool hasDirectory(const pe::dir_entry &dirNum)
Definition PEFile.h:327
virtual bufsize_t getAlignment(Executable::addr_type aType) const
Definition PEFile.h:69
virtual exe_bits getBitMode()
Definition PEFile.h:73
BYTE * getSecContent(SectionHdrWrapper *sec)
Definition PEFile.h:150
pe::RICH_SIGNATURE * getRichHeaderSign()
Definition PEFile.cpp:244
bool canResize(bufsize_t newSize)
Definition PEFile.h:347
ExceptionDirWrapper * getExceptionsDir()
Definition PEFile.h:299
bool canAddNewSection()
Definition PEFile.h:198
ExportDirWrapper * getExportsDir()
Definition PEFile.h:274
DosHdrWrapper * dosHdrWrapper
Definition PEFile.h:420
OptHdrWrapper * getOptHdrWrapper()
Definition PEFile.h:238
ResourcesContainer * getResourcesOfType(pe::resource_type typeId)
Definition PEFile.h:215
exe_bits getHdrBitMode()
Definition PEFile.h:96
TlsDirWrapper * getTlsDir()
Definition PEFile.h:284
bool isReproBuild()
Definition PEFile.h:360
SectionHdrWrapper * getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate=false, bool verbose=false)
Definition PEFile.h:135
size_t _getSectionsCount(bool useMapped=true) const
Definition PEFile.cpp:371
SectionHdrWrapper * addNewSection(QString name, bufsize_t size, bufsize_t v_size=0)
Definition PEFile.cpp:508
DosHdrWrapper * getDosHdrWrapper()
Definition PEFile.h:228
static size_t SECT_INVALID_INDEX
bufsize_t getContentSize(Executable::addr_type aType, bool recalculate)
offset_t getContentOffset(Executable::addr_type aType, bool useMapped=true)