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(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:
82
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
97
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
228 /* wrappers for fetching the initialized directories */
230 {
231 return dynamic_cast<ImportDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_IMPORT));
232 }
233
235 {
236 return dynamic_cast<DelayImpDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_DELAY_IMPORT));
237 }
238
240 {
241 return dynamic_cast<BoundImpDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_BOUND_IMPORT));
242 }
243
245 {
246 return dynamic_cast<DebugDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_DEBUG));
247 }
248
250 {
251 return dynamic_cast<ExportDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_EXPORT));
252 }
253
255 {
256 return dynamic_cast<SecurityDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_SECURITY));
257 }
258
260 {
261 return dynamic_cast<TlsDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_TLS));
262 }
263
265 {
266 return dynamic_cast<LdConfigDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_LOAD_CONFIG));
267 }
268
270 {
271 return dynamic_cast<RelocDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_BASERELOC));
272 }
273
275 {
276 return dynamic_cast<ExceptionDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_EXCEPTION));
277 }
278
280 {
281 return dynamic_cast<ResourceDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_RESOURCE));
282 }
283
285 {
286 return dynamic_cast<ClrDirWrapper*>(getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_COM_DESCRIPTOR));
287 }
288
289 /* All Entry Points of the application, including: main EP, Exports, TLS Callbacks */
290 virtual size_t getAllEntryPoints(QMap<offset_t,QString> &entrypoints, Executable::addr_type aType = Executable::RVA)
291 {
292 size_t initialSize = entrypoints.size();
293
294 Executable::getAllEntryPoints(entrypoints, aType);
295 this->getExportsMap(entrypoints, aType);
296
297 return entrypoints.size() - initialSize;
298 }
299
300 /* wrappers:
301 */
302 bool hasDirectory(pe::dir_entry dirNum)
303 {
304 return this->getDataDirEntry(dirNum) ? true : false;
305 }
306
308 {
309 return this->getAlignment(Executable::RAW);
310 }
311
313 {
314 return this->getAlignment(Executable::RVA);
315 }
316
317
318 void setImageSize(size_t newSize)
319 {
320 this->setVirtualSize(newSize);
321 }
322
323 bool canResize(bufsize_t newSize)
324 {
325 bufsize_t currentSize = (bufsize_t)this->getRawSize();
326 if (newSize > currentSize) {
327 return true;
328 }
329 bufsize_t hEnd = bufsize_t(this->peNtHdrOffset()) + this->peNtHeadersSize();
330 if (newSize < hEnd) {
331 return false; // the resize will harm headers!
332 }
333 return true;
334 }
335
337 {
338 bool isRepro = false;
339 DebugDirWrapper* dbgDir = dynamic_cast<DebugDirWrapper*>(dataDirEntries[pe::DIR_DEBUG]);
340 if (dbgDir && dbgDir->isRepro()) {
341 isRepro = true;
342 }
343 return isRepro;
344 }
345
346protected:
347 void wrapCore();
348
350 bool _canAddNewSection();
351
353 {
354 const offset_t offset = secHdrsOffset();
355 if (offset == INVALID_ADDR) {
356 return INVALID_ADDR;
357 }
358 const offset_t secHdrSize = this->_getSectionsCount() * sizeof(IMAGE_SECTION_HEADER);
359 return offset + secHdrSize;
360 }
361
363
364 size_t _getSectionsCount(bool useMapped = true) const;
365
367 {
369 }
370
371 SectionHdrWrapper* _getSecHdr(size_t index) const
372 {
373 return (sects) ? sects->_getSecHdr(index) : NULL;
374 }
375
376 SectionHdrWrapper* _getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate = false, bool verbose = false)
377 {
378 return (sects) ? sects->getSecHdrAtOffset(offset, aType, recalculate, verbose) : NULL;
379 }
380
382
383 size_t getExportsMap(QMap<offset_t,QString> &entrypoints, Executable::addr_type aType = Executable::RVA);
384
385 virtual void clearWrappers();
386
387 void _init(AbstractByteBuffer *v_buf);
388 void initDirEntries();
389
390 //---
391 //modifications:
392 bool setHdrSectionsNum(size_t newNum);
393 bool setVirtualSize(bufsize_t newSize);
394
397
401
403 DataDirEntryWrapper* dataDirEntries[pe::DIR_ENTRIES_COUNT];
404 QMutex m_peMutex;
405
406friend class SectHdrsWrapper;
407friend class SectionHdrWrapper;
408};
409
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_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
Definition PECore.h:8
Executable::exe_arch getHdrArch() const
Definition PECore.cpp:59
virtual bufsize_t getAlignment(Executable::addr_type aType) const
Definition PECore.cpp:119
bufsize_t hdrsSize() const
Definition PECore.cpp:144
offset_t peOptHdrOffset() const
Definition PECore.cpp:89
virtual offset_t getImageBase(bool recalculate=false)
Definition PECore.cpp:156
offset_t peFileHdrOffset() const
Definition PECore.cpp:79
offset_t peSignatureOffset() const
Definition PECore.cpp:73
bufsize_t peNtHeadersSize() const
Definition PECore.cpp:98
offset_t secHdrsOffset() const
Definition PECore.cpp:106
Executable::exe_bits getHdrBitMode() const
Definition PECore.cpp:51
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:403
DebugDirWrapper * getDebugDir()
Definition PEFile.h:244
QMutex m_peMutex
Definition PEFile.h:404
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:269
bufsize_t getSectionAlignment() const
Definition PEFile.h:312
offset_t peFileHdrOffset() const
Definition PEFile.h:77
SectHdrsWrapper * sects
Definition PEFile.h:400
SectionHdrWrapper * _getSecHdr(size_t index) const
Definition PEFile.h:371
bufsize_t peNtHeadersSize() const
Definition PEFile.h:79
ImportDirWrapper * getImportsDir()
Definition PEFile.h:229
bool hasDirectory(pe::dir_entry dirNum)
Definition PEFile.h:302
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:254
offset_t getMinSecRVA()
Definition PEFile.cpp:273
offset_t getLastMapped(Executable::addr_type aType)
Definition PEFile.h:102
FileHdrWrapper * fHdr
Definition PEFile.h:398
bool wrapDataDirs()
Definition PEFile.cpp:193
size_t _getSecIndex(SectionHdrWrapper *sec) const
Definition PEFile.h:366
ResourcesAlbum * album
Definition PEFile.h:402
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:290
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
PECore core
Definition PEFile.h:395
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:399
bool dumpSection(SectionHdrWrapper *sec, QString fileName)
Definition PEFile.cpp:661
ClrDirWrapper * getClsDir()
Definition PEFile.h:284
offset_t _getLastMapped(Executable::addr_type aType)
Definition PEFile.cpp:576
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:239
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:234
bool setVirtualSize(bufsize_t newSize)
Definition PEFile.cpp:360
bool _canAddNewSection()
Definition PEFile.cpp:494
void wrapCore()
Definition PEFile.cpp:180
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:376
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:352
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:279
LdConfigDirWrapper * getLoadConfigDir()
Definition PEFile.h:264
bufsize_t hdrsSize()
Definition PEFile.h:83
size_t hdrSectionsNum() const
Definition PEFile.cpp:340
exe_arch getHdrArch()
Definition PEFile.h:98
virtual exe_arch getArch()
Definition PEFile.h:74
SectionHdrWrapper * getEntrySection()
Definition PEFile.h:142
void setImageSize(size_t newSize)
Definition PEFile.h:318
PEFile(AbstractByteBuffer *v_buf)
Definition PEFile.cpp:105
offset_t peNtHdrOffset() const
Definition PEFile.h:78
bufsize_t getFileAlignment() const
Definition PEFile.h:307
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:323
ExceptionDirWrapper * getExceptionsDir()
Definition PEFile.h:274
bool canAddNewSection()
Definition PEFile.h:198
ExportDirWrapper * getExportsDir()
Definition PEFile.h:249
static long computeChecksum(BYTE *buffer, size_t bufferSize, offset_t checksumOffset)
Definition PEFile.cpp:45
DosHdrWrapper * dosHdrWrapper
Definition PEFile.h:396
ResourcesContainer * getResourcesOfType(pe::resource_type typeId)
Definition PEFile.h:215
exe_bits getHdrBitMode()
Definition PEFile.h:96
TlsDirWrapper * getTlsDir()
Definition PEFile.h:259
bool isReproBuild()
Definition PEFile.h:336
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
ResourcesContainer * getResourcesOfType(pe::resource_type typeId)
SectionHdrWrapper * _getSecHdr(size_t index)
SectionHdrWrapper * getSecHdrAtOffset(offset_t offset, Executable::addr_type addrType, bool roundup, bool verbose=false)
size_t getSecIndex(SectionHdrWrapper *sec) const
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)