BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
PEFile.cpp
Go to the documentation of this file.
1#include "pe/PEFile.h"
2#include "FileBuffer.h"
3
5{
6 if (buf == NULL) return false;
7
8 offset_t dosOffset = 0;
9 WORD *magic = (WORD*) buf->getContentAt(dosOffset, sizeof(WORD));
10 if (magic == NULL) return false;
11
12 if ((*magic) != pe::S_DOS) {
13 return false;
14 }
15 offset_t newOffset = dosOffset + (sizeof(IMAGE_DOS_HEADER) - sizeof(LONG));
16 LONG* lfnew = (LONG*) buf->getContentAt(newOffset, sizeof(LONG));
17 if (lfnew == NULL) {
18 return false;
19 }
20 offset_t peOffset = static_cast<offset_t>(*lfnew);
21 DWORD *peMagic = (DWORD*) buf->getContentAt(peOffset, sizeof(DWORD));
22 if (peMagic == NULL) {
23 return false;
24 }
25 if (*peMagic == pe::S_NT) {
26 return true;
27 }
28 return false;
29}
30
32{
33 Executable *exe = NULL;
34 if (signatureMatches(buf) == false) return NULL;
35
36 try {
37 exe = new PEFile(buf);
38 } catch (ExeException) {
39 exe = NULL;
40 }
41 return exe;
42}
43
44//-------------------------------------------------------------
45long PEFile::computeChecksum(BYTE* buffer, size_t bufferSize, offset_t checksumOffset)
46{
47 if (!buffer || !bufferSize) return 0;
48
49 WORD* wordsBuff = reinterpret_cast<WORD*>(buffer);
50 const size_t wordsCount = bufferSize / sizeof(WORD);
51 const size_t remainingBytes = bufferSize % sizeof(WORD);
52
53 size_t checksumBgn = 0;
54 size_t checksumEnd = 0;
55 if (checksumOffset != INVALID_ADDR) {
56 checksumBgn = size_t(checksumOffset);
57 checksumEnd = checksumBgn + sizeof(DWORD);
58 }
59
60 const long long maxVal = ((long long)1) << 32;
61 long long checksum = 0;
62
63 for (int i = 0; i < wordsCount; i++) {
64 WORD chunk = wordsBuff[i];
65
66 size_t bI = i * sizeof(WORD);
67 if (checksumBgn != checksumEnd && bI >= checksumBgn && bI < checksumEnd) {
68 size_t mask = (checksumEnd - bI) % sizeof(WORD);
69 size_t shift = (sizeof(WORD) - mask) * 8;
70 chunk = (chunk >> shift) << shift;
71 }
72
73 checksum = (checksum & 0xffffffff) + chunk + (checksum >> 32);
74 if (checksum > maxVal) {
75 checksum = (checksum & 0xffffffff) + (checksum >> 32);
76 }
77 }
78
79 // Handle the remaining bytes
80 if (remainingBytes > 0) {
81 WORD chunk = 0;
82 memcpy(&chunk, buffer + wordsCount * sizeof(WORD), remainingBytes);
83
84 size_t bI = wordsCount * sizeof(WORD);
85 if (checksumBgn != checksumEnd && bI >= checksumBgn && bI < checksumEnd) {
86 size_t mask = (checksumEnd - bI) % sizeof(WORD);
87 size_t shift = (sizeof(WORD) - mask) * 8;
88 chunk = (chunk >> shift) << shift;
89 }
90
91 checksum = (checksum & 0xffffffff) + chunk + (checksum >> 32);
92 if (checksum > maxVal) {
93 checksum = (checksum & 0xffffffff) + (checksum >> 32);
94 }
95 }
96 checksum = (checksum & 0xffff) + (checksum >> 16);
97 checksum = (checksum)+(checksum >> 16);
98 checksum = checksum & 0xffff;
99 checksum += bufferSize;
100 return checksum;
101}
102
104
106 : MappedExe(v_buf, Executable::BITS_32),
107 dosHdrWrapper(NULL), fHdr(NULL), optHdr(NULL), sects(NULL),
108 album(NULL)
109{
111
112 _init(v_buf);
114}
115
117{
118 // wrap the core:
119 core.wrap(v_buf);
120
121 album = new ResourcesAlbum(this);
122
123 //generate wrappers:
124 this->dosHdrWrapper = new DosHdrWrapper(this);
125 this->wrappers[WR_DOS_HDR] = this->dosHdrWrapper;
126
127 this->fHdr = new FileHdrWrapper(this);
128 if (fHdr->getPtr() == NULL) throw ExeException("Cannot parse FileHdr: It is not PE File!");
129 this->wrappers[WR_FILE_HDR] = fHdr;
130 this->wrappers[WR_RICH_HDR] = new RichHdrWrapper(this);
131
132 this->optHdr = new OptHdrWrapper(this);
133 if (optHdr->getPtr() == NULL) throw ExeException("Cannot parse OptionalHeader: It is not PE File!");
135
136 this->sects = new SectHdrsWrapper(this);
137 this->wrappers[WR_SECTIONS] = sects;
138
139 this->wrappers[WR_DATADIR] = new DataDirWrapper(this);
140 dataDirEntries[pe::DIR_IMPORT] = new ImportDirWrapper(this);
141 dataDirEntries[pe::DIR_DELAY_IMPORT] = new DelayImpDirWrapper(this);
142 dataDirEntries[pe::DIR_BOUND_IMPORT] = new BoundImpDirWrapper(this);
143 dataDirEntries[pe::DIR_DEBUG] = new DebugDirWrapper(this);
144 dataDirEntries[pe::DIR_EXPORT] = new ExportDirWrapper(this);
145 dataDirEntries[pe::DIR_SECURITY] = new SecurityDirWrapper(this);
146 dataDirEntries[pe::DIR_TLS] = new TlsDirWrapper(this);
147 dataDirEntries[pe::DIR_LOAD_CONFIG] = new LdConfigDirWrapper(this);
148 dataDirEntries[pe::DIR_BASERELOC] = new RelocDirWrapper(this);
149 dataDirEntries[pe::DIR_EXCEPTION] = new ExceptionDirWrapper(this);
150 dataDirEntries[pe::DIR_RESOURCE] = new ResourceDirWrapper(this, album);
151 dataDirEntries[pe::DIR_COM_DESCRIPTOR] = new ClrDirWrapper(this);
152
153 for (int i = 0; i < pe::DIR_ENTRIES_COUNT; i++) {
154 this->wrappers[WR_DIR_ENTRY + i] = dataDirEntries[i];
155 }
156 if (this->album) {
157 this->album->wrapLeafsContent();
158 }
159}
160
161
163{
166
167 this->dosHdrWrapper = NULL;
168 this->fHdr = NULL;
169 this->optHdr = NULL;
170 this->sects = NULL;
171}
172
174{
175 for (size_t i = 0 ; i < pe::DIR_ENTRIES_COUNT; i++) {
176 dataDirEntries[i] = NULL;
177 }
178}
179
181{
182 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
183 // rewrap the core:
184 core.wrap(this->buf);
185 // rewrap the PE headers:
186 for (int i = 0; i < WR_DIR_ENTRY; i++) {
187 this->wrappers[i]->wrap();
188 }
189 // rewrap the sections:
190 this->sects->wrap();
191}
192
194{
195 bool anyModified = false;
196 // rewrap directories
197 for (size_t i = 0 ; i < pe::DIR_ENTRIES_COUNT; i++) {
198 if (dataDirEntries[i]) {
199 if (dataDirEntries[i]->wrap()) {
200 anyModified = true;
201 }
202 }
203 }
204 // rewrap resources
205 if (this->album) {
206 this->album->wrapLeafsContent();
207 }
208 return anyModified;
209}
210
212{
213 wrapCore();
214 wrapDataDirs();
215}
216
217pe::RICH_DANS_HEADER* PEFile::getRichHeaderBgn(pe::RICH_SIGNATURE* richSign)
218{
219 if (!richSign) return NULL;
220
221 DWORD xorkey = richSign->checksum;
222 const offset_t richOffset = this->getOffset(richSign);
223
224 pe::RICH_DANS_HEADER* dansHdr = NULL;
225
226 offset_t offset = richOffset - sizeof(pe::RICH_DANS_HEADER);
227 while (offset > 0) {
228 dansHdr = (pe::RICH_DANS_HEADER*) this->getContentAt(offset, sizeof(pe::RICH_DANS_HEADER));
229 if (!dansHdr) {
230 break;
231 }
232 if (dansHdr->dansId == (pe::DANS_HDR_MAGIC ^ xorkey)) {
233 break; //got it!
234 }
235 //walking back
236 offset -= sizeof(DWORD);
237 }
238 if (!dansHdr || dansHdr->dansId != (pe::DANS_HDR_MAGIC ^ xorkey)) {
239 return NULL; //not found
240 }
241 return dansHdr;
242}
243
244pe::RICH_SIGNATURE* PEFile::getRichHeaderSign()
245{
246 size_t dosStubOffset = this->core.dos->e_lfarlc;
247 size_t dosStubEnd = this->core.dos->e_lfanew; // PE header start
248 const size_t maxSize = dosStubEnd - dosStubOffset; // Rich Header is somewhere in the space between DOS and PE headers
249 BYTE *dosPtr = this->getContentAt(dosStubOffset, maxSize);
250 if (!dosPtr) {
251 return NULL;
252 }
253
254 pe::RICH_SIGNATURE* richSign = NULL;
255 size_t toSearchSize = maxSize;
256 const offset_t startOffset = dosStubOffset; //we are starting from the beginning of DOS stub
257 const size_t step = sizeof(DWORD); //RichHeader is padded by DWORDS
258
259 while (toSearchSize > 0) {
260 richSign = (pe::RICH_SIGNATURE*) this->getContentAt(startOffset + toSearchSize, sizeof(pe::RICH_SIGNATURE));
261 if (!richSign) break;
262 if (richSign->richId == pe::RICH_HDR_MAGIC) break; //got it!
263 // the search goes backward.
264 toSearchSize -= step;
265 }
266 if (!richSign) return NULL;
267 if (richSign->richId != pe::RICH_HDR_MAGIC) {
268 return NULL; //invalid
269 }
270 return richSign;
271}
272
274{
275 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
276 if (!this->_getSectionsCount()) {
277 return INVALID_ADDR;
278 }
279 SectionHdrWrapper* sec = this->_getSecHdr(0);
280 if (!sec) {
281 return INVALID_ADDR;
282 }
284}
285
287{
288 if (this->optHdr == NULL) return INVALID_ADDR;
290}
291
292IMAGE_DATA_DIRECTORY* PEFile::getDataDirectory()
293{
294 if (this->wrappers[WR_DATADIR] == NULL) return NULL;
295 return static_cast<IMAGE_DATA_DIRECTORY*>(this->wrappers[WR_DATADIR]->getPtr());
296}
297
299{
300 if (aType == Executable::NOT_ADDR) return 0;
301
302 if (aType == Executable::RAW) {
303 return this->getContentSize();
304 }
305 const size_t unit_size = 0x1000;
306 bufsize_t vSize = 0;
307 if (aType == Executable::VA || aType == Executable::RVA) {
308 vSize = core.getImageSize();
309 }
310 if (vSize < unit_size) {
311 return unit_size;
312 }
313 return vSize;
314}
315
317{
318 if (optHdr == NULL) return INVALID_ADDR;
319
320 bool isOk = false;
321 offset_t entryPoint = static_cast<offset_t> (optHdr->getNumValue(OptHdrWrapper::EP, &isOk));
322 if (isOk == false) return INVALID_ADDR;
323
325 if (addrType != epType) {
326 entryPoint = this->convertAddr(entryPoint, epType, addrType);
327 }
328 return entryPoint;
329}
330
332{
333 if (optHdr == NULL) return false;
334
335 offset_t epRva = this->convertAddr(entry, aType, Executable::RVA);
336 bool isOk = optHdr->setNumValue(OptHdrWrapper::EP, epRva);
337 return isOk;
338}
339
341{
342 bool isOk = false;
343 uint64_t secNum = this->fHdr->getNumValue(FileHdrWrapper::SEC_NUM , &isOk);
344 if (isOk == false) return 0;
345
346 return static_cast<size_t> (secNum);
347}
348
349bool PEFile::setHdrSectionsNum(size_t newNum)
350{
351 uint64_t count = newNum;
352 bool canSet = fHdr->setNumValue(FileHdrWrapper::SEC_NUM , count);
353 if (canSet == false) {
354 Logger::append(Logger::D_ERROR,"Can not change FileHdr!");
355 return false;
356 }
357 return true;
358}
359
361{
362 uint64_t size = newSize;
363 bool canSet = optHdr->setNumValue(OptHdrWrapper::IMAGE_SIZE, size);
364 if (canSet == false) {
365 Logger::append(Logger::D_ERROR, "Can not change OptHdr!");
366 return false;
367 }
368 return true;
369}
370
371size_t PEFile::_getSectionsCount(bool useMapped) const
372{
373 if (useMapped == false) {
374 return hdrSectionsNum();
375 }
376 return (this->sects) ? this->sects->getEntriesCount() : 0;
377}
378
380{
381 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
382 if (raw >= this->getMappedSize(Executable::RAW)) return INVALID_ADDR;
383
385 if (sec) {
388 if (bgnVA == INVALID_ADDR || bgnRaw == INVALID_ADDR) return INVALID_ADDR;
389
390 bufsize_t curr = (raw - bgnRaw);
391
392 bufsize_t vSize = sec->getContentSize(Executable::VA, true);
393 if (curr >= vSize) {
394 //address out of section
395 return INVALID_ADDR;
396 }
397 return bgnVA + curr;
398 }
399 //TODO: make more tests
400 if (this->_getSectionsCount() == 0) return raw;
401 if (raw < this->hdrsSize()) {
402 return raw;
403 } //else: content that is between the end of sections headers and the first virtual section is not mapped
404 return INVALID_ADDR;
405}
406
408{
409 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
410 if (rva >= this->getMappedSize(Executable::RVA)) {
411 return INVALID_ADDR;
412 }
414 if (sec) {
417 if (bgnRVA == INVALID_ADDR || bgnRaw == INVALID_ADDR) {
418 return INVALID_ADDR;
419 }
420 bufsize_t curr = (rva - bgnRVA);
421 bufsize_t rawSize = sec->getContentSize(Executable::RAW, true);
422 if (curr >= rawSize) {
423 // the address might be in a virtual cave that is not related to any raw address
424 return INVALID_ADDR;
425 }
426 return bgnRaw + curr;
427 }
428 if (rva >= this->getMappedSize(Executable::RAW)) {
429 return INVALID_ADDR;
430 }
431 if (this->_getSectionsCount()) { // do this check only if sections count is non-zero
432 if (rva >= this->hdrsSize()) {
433 // the address is in the cave between the headers and the first section: cannot be mapped
434 return INVALID_ADDR;
435 }
436 }
437 // at this point we are sure that the address is within the raw size:
438 return rva;
439}
440
442{
443 if (eType >= pe::DIR_ENTRIES_COUNT) return NULL;
444 return dataDirEntries[eType];
445}
446
448{
449 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
450 SectionHdrWrapper *sec = this->_getSecHdr(secId);
451 if (!sec) {
452 Logger::append(Logger::D_WARNING, "No such section");
453 return NULL;
454 }
455 return _createSectionView(sec);
456}
457
458bool PEFile::moveDataDirEntry(pe::dir_entry dirNum, offset_t newOffset, Executable::addr_type addrType)
459{
460 bool allowExceptions = true; //TODO: configure exception mode outside...
461
462 DataDirEntryWrapper *entry = getDataDirEntry(dirNum);
463 if (entry == NULL) {
464 if (allowExceptions) throw ExeException("No such Data Directory");
465 return false;
466 }
467 DataDirWrapper* ddirWrapper = dynamic_cast<DataDirWrapper*> (this->wrappers[WR_DATADIR]);
468 IMAGE_DATA_DIRECTORY *ddir = this->getDataDirectory();
469 if (ddirWrapper == NULL || ddir == NULL) {
470 if (allowExceptions) throw ExeException("Cannot fetch DataDirTable");
471 return false;
472 }
473 Executable::addr_type dataDirAddrType = ddirWrapper->containsAddrType(dirNum, DataDirWrapper::ADDRESS);
474 offset_t dataDirAddr = this->convertAddr(newOffset, addrType, dataDirAddrType);
475 if (dataDirAddr == INVALID_ADDR) {
476 if (allowExceptions) throw ExeException("Invalid new offset");
477 return false;
478 }
479 offset_t targetRaw = this->toRaw(newOffset, addrType);
480 if (entry->canCopyToOffset(targetRaw) == false) {
481 if (allowExceptions) throw ExeException("Cannot copy: no space at such offset");
482 return false;
483 }
484 if (entry->copyToOffset(targetRaw) == false) {
485 if (allowExceptions) throw ExeException("Cannot copy: error occured");
486 return false;
487 }
488 entry->fillContent(0);
489 ddir[dirNum].VirtualAddress = static_cast<DWORD>(dataDirAddr);
490 entry->wrap();
491 return true;
492}
493
495{
497 if (sec == NULL || sec->canAddEntry() == false) {
498 return false;
499 }
500 const size_t secCount = hdrSectionsNum();
501 if (secCount == SectHdrsWrapper::SECT_COUNT_MAX) {
502 return false; //limit exceeded
503 }
504 //TODO: some more checks? overlay?
505 return true;
506}
507
509{
510 if (!r_size && !v_size) return nullptr; //nothing to add
511
512 bufsize_t newSize = 0;
513 bufsize_t roundedRawEnd = 0;
514 bufsize_t roundedVirtualEnd = 0;
515 SectionHdrWrapper* secHdrWr = nullptr;
516 { //scope0
517 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
518 if (!_canAddNewSection()) {
519 return nullptr;
520 }
521
522 if (!v_size) {
523 v_size = r_size;
524 }
527 newSize = roundedRawEnd + r_size;
528 const bufsize_t newVirtualSize = roundedVirtualEnd + v_size;
529 if (setVirtualSize(newVirtualSize) == false) {
530 Logger::append(Logger::D_ERROR, "Failed to change virtual size to: %X", newVirtualSize);
531 return nullptr;
532 }
533 } //scope0
534
535 // the PE file is resized and rewrapped:
536 if (resize(newSize) == false) {
537 Logger::append(Logger::D_ERROR, "Failed to resize");
538 return nullptr;
539 }
540
541 { //scope1
542 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
543 // fetch again after resize:
545 if (!sec) {
546 return nullptr;
547 }
548
549 IMAGE_SECTION_HEADER secHdr;
550 ::memset(&secHdr, 0, sizeof(IMAGE_SECTION_HEADER));
551
552 //name copy:
553 const size_t nameLen = name.length();
554 const size_t bufSize = sizeof(secHdr.Name);
555 const size_t copySize = (nameLen < bufSize) ? nameLen : bufSize;
556 if (copySize) {
557 ::memcpy(secHdr.Name, name.toStdString().c_str(), copySize);
558 }
559 secHdr.PointerToRawData = static_cast<DWORD>(roundedRawEnd);
560 secHdr.VirtualAddress = static_cast<DWORD>(roundedVirtualEnd);
561 secHdr.SizeOfRawData = r_size;
562 secHdr.Misc.VirtualSize = v_size;
563
564 SectionHdrWrapper wr(this, &secHdr);
565 secHdrWr = dynamic_cast<SectionHdrWrapper*>(sec->addEntry(&wr));
566 }
567 return secHdrWr;
568}
569
571{
572 size_t secCount = this->_getSectionsCount(true);
573 return (secCount > 0) ? this->_getSecHdr(secCount - 1) : nullptr;
574}
575
577{
578 offset_t lastMapped = 0;
579
580 /* check sections bounds */
581 const size_t secCounter = this->_getSectionsCount(true);
582 if (!secCounter) {
583 // if PE file has no sections, full file will be mapped
584 return getMappedSize(aType);
585 }
586 for (size_t i = 0; i < secCounter; i++) {
587 SectionHdrWrapper *sec = this->_getSecHdr(i);
588 if (!sec) continue;
589
590 offset_t secLastMapped= sec->getContentOffset(aType, true);
591 if (secLastMapped == INVALID_ADDR) continue;
592
593 const size_t size = (aType == Executable::RAW) ? sec->getMappedRawSize() : sec->getMappedVirtualSize();
594 if (size == 0) continue; // exclude not mapped sections
595
596 secLastMapped += size;
597 if (secLastMapped > lastMapped) {
598 lastMapped = secLastMapped;
599 }
600 }
601
602 /* check header bounds */
603 /* section headers: */
604 if (lastMapped < this->_secHdrsEndOffset()) {
605 lastMapped = this->_secHdrsEndOffset();
606 }
607 // PE hdrs ending:
608 const offset_t peHdrsEnd = this->core.peSignatureOffset() + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + this->core.peNtHeadersSize();
609 if (lastMapped < peHdrsEnd) {
610 lastMapped = peHdrsEnd;
611 }
612 // OptionalHdr -> SizeOfHeaders:
613 const offset_t ntHeadersEndOffset = this->core.hdrsSize();
614 if (lastMapped < ntHeadersEndOffset) {
615 lastMapped = ntHeadersEndOffset;
616 }
617 return lastMapped;
618}
619
621{
622 bufsize_t newSize = 0;
623
624 { //scope0
625 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
627 if (!secHdr) return nullptr;
628
629 //TODO: check overlay...
630 const bufsize_t fullSize = getContentSize();
631 newSize = fullSize + addedSize;
632
633 const offset_t secROffset = secHdr->getContentOffset(Executable::RAW, false);
634 if (secROffset == INVALID_ADDR) {
635 return NULL;
636 }
637 const bufsize_t secNewRSize = newSize - secROffset; //include overlay in section
638 secHdr->setNumValue(SectionHdrWrapper::RSIZE, uint64_t(secNewRSize));
639
640 const offset_t secVOffset = secHdr->getContentOffset(Executable::RVA, false);
641 const bufsize_t secVSize = secHdr->getContentSize(Executable::RVA, false);
642
643 // if the previous virtual size is smaller than the new raw size, then update it:
644 if (secVSize < secNewRSize) {
645 secHdr->setNumValue(SectionHdrWrapper::VSIZE, uint64_t(secNewRSize));
646
647 // if the virtual size of section has changed,
648 // update the Size of Image (saved in the header):
649 bufsize_t newVSize = secVOffset + secNewRSize;
650 this->setVirtualSize(newVSize);
651 }
652
653 }
654
655 //update raw size:
656 this->resize(newSize);
657 //finally, retrieve the resized section:
658 return getLastSection();
659}
660
661bool PEFile::dumpSection(SectionHdrWrapper *sec, QString fileName)
662{
663 WatchedLocker lock(&m_peMutex, PE_SHOW_LOCK, __FUNCTION__);
665 return false; //not my section
666 }
667 BufferView *secView = this->_createSectionView(sec);
668 if (!secView) return false;
669
670 bufsize_t dumpedSize = FileBuffer::dump(fileName, *secView, false);
671 delete secView;
672
673 return dumpedSize ? true : false;
674}
675
677{
678 IMAGE_DATA_DIRECTORY* ddir = this->getDataDirectory();
679 if (ddir[pe::DIR_BOUND_IMPORT].VirtualAddress == 0 && ddir[pe::DIR_BOUND_IMPORT].Size == 0) {
680 // No bound imports already, nothing to do here!
681 return true;
682 }
683 ddir[pe::DIR_BOUND_IMPORT].VirtualAddress = 0;
684 ddir[pe::DIR_BOUND_IMPORT].Size = 0;
685 DataDirEntryWrapper *bImp = this->getDataDirEntry(pe::DIR_BOUND_IMPORT);
686 if (bImp == NULL) {
687 //printf("No Bound imports wrapper!\n");
688 return false; // todo: throw error?
689 }
690 bool isOk = bImp->wrap();
691 //TODO: change timestamp for all library entries from (-1 : BOUND) to 0 : NOT BOUND
692 return isOk;
693}
694
695//protected:
696
698{
700 offset_t start = sec->getContentOffset(aType, true);
701 bufsize_t size = sec->getContentSize(aType, true);
702 if (start == INVALID_ADDR || size == 0) {
703 return NULL;
704 }
705 return new BufferView(this, start, size);
706}
707
708size_t PEFile::getExportsMap(QMap<offset_t,QString> &entrypoints, Executable::addr_type aType)
709{
710 size_t initialSize = entrypoints.size();
711
712 ExportDirWrapper* exports = dynamic_cast<ExportDirWrapper*>(this->getWrapper(PEFile::WR_DIR_ENTRY + pe::DIR_EXPORT));
713 if (!exports) return 0;
714
715 const size_t entriesCnt = exports->getEntriesCount();
716 if (entriesCnt == 0) return 0;
717
718 for (int i = 0; i < entriesCnt; i++) {
719 ExportEntryWrapper* entry = dynamic_cast<ExportEntryWrapper*>(exports->getEntryAt(i));
720 if (!entry) continue;
721
722 QString forwarder = entry->getForwarderStr();
723 if (forwarder.length()) {
724 continue;
725 }
726 offset_t rva = entry->getFuncRva();
727 offset_t offset = this->convertAddr(rva, Executable::RVA, aType);
728 if (offset == INVALID_ADDR) {
729 continue;
730 }
731 entrypoints.insert(offset, entry->getName());
732 }
733 return entrypoints.size() - initialSize;
734}
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
#define PE_SHOW_LOCK
Definition PEFile.h:30
virtual BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
virtual offset_t getOffset(void *ptr, bool allowExceptions=false)
bool fillContent(BYTE filling)
static bufsize_t dump(const QString &fileName, AbstractByteBuffer &buf, bool allowExceptions=false)
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
virtual bool setNumValue(size_t fieldId, size_t subField, uint64_t val)
virtual bool canCopyToOffset(offset_t rawOffset)
virtual offset_t getFieldOffset(size_t fieldId, size_t subField=FIELD_NONE)
bool copyToOffset(offset_t rawOffset)
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
virtual bool wrap()
virtual ExeNodeWrapper * getEntryAt(size_t fieldId)
virtual bool canAddEntry()
virtual size_t getEntriesCount()
virtual ExeNodeWrapper * addEntry(ExeNodeWrapper *entry)
std::map< size_t, ExeElementWrapper * > wrappers
Definition MappedExe.h:27
virtual ExeElementWrapper * getWrapper(size_t wrapperId)
Definition MappedExe.cpp:13
AbstractByteBuffer * buf
Definition Executable.h:133
virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions=false)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
virtual offset_t convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType)
virtual bufsize_t getContentSize()
Definition Executable.h:59
QString getForwarderStr()
offset_t getFuncRva()
virtual QString getName()
virtual void * getPtr()
virtual bool resize(bufsize_t newSize)
Definition MappedExe.h:38
virtual void * getPtr()
bufsize_t hdrsSize() const
Definition PECore.cpp:144
bool wrap(AbstractByteBuffer *v_buf)
Definition PECore.cpp:13
virtual bufsize_t getImageSize()
Definition PECore.cpp:132
offset_t peSignatureOffset() const
Definition PECore.cpp:73
bufsize_t peNtHeadersSize() const
Definition PECore.cpp:98
IMAGE_DOS_HEADER * dos
Definition PECore.h:55
virtual Executable * build(AbstractByteBuffer *buf)
Definition PEFile.cpp:31
virtual bool signatureMatches(AbstractByteBuffer *buf)
Definition PEFile.cpp:4
DataDirEntryWrapper * dataDirEntries[pe::DIR_ENTRIES_COUNT]
Definition PEFile.h:403
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
SectHdrsWrapper * sects
Definition PEFile.h:400
SectionHdrWrapper * _getSecHdr(size_t index) const
Definition PEFile.h:371
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
void _init(AbstractByteBuffer *v_buf)
Definition PEFile.cpp:116
offset_t getMinSecRVA()
Definition PEFile.cpp:273
friend class SectHdrsWrapper
Definition PEFile.h:406
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
SectionHdrWrapper * extendLastSection(bufsize_t addedSize)
Definition PEFile.cpp:620
@ WR_DIR_ENTRY
Definition PEFile.h:55
@ WR_DATADIR
Definition PEFile.h:53
@ 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
PECore core
Definition PEFile.h:395
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
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
bool setHdrSectionsNum(size_t newNum)
Definition PEFile.cpp:349
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 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
offset_t _secHdrsEndOffset()
Definition PEFile.h:352
IMAGE_DATA_DIRECTORY * getDataDirectory()
Definition PEFile.cpp:292
virtual offset_t rawToRva(offset_t raw)
Definition PEFile.cpp:379
bufsize_t hdrsSize()
Definition PEFile.h:83
size_t hdrSectionsNum() const
Definition PEFile.cpp:340
PEFile(AbstractByteBuffer *v_buf)
Definition PEFile.cpp:105
virtual bufsize_t getAlignment(Executable::addr_type aType) const
Definition PEFile.h:69
pe::RICH_SIGNATURE * getRichHeaderSign()
Definition PEFile.cpp:244
static long computeChecksum(BYTE *buffer, size_t bufferSize, offset_t checksumOffset)
Definition PEFile.cpp:45
DosHdrWrapper * dosHdrWrapper
Definition PEFile.h:396
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
static size_t SECT_COUNT_MAX
static size_t SECT_INVALID_INDEX
bufsize_t getMappedVirtualSize()
bufsize_t getContentSize(Executable::addr_type aType, bool recalculate)
offset_t getContentOffset(Executable::addr_type aType, bool useMapped=true)
bufsize_t getMappedRawSize()
bool append(dbg_level lvl, const char *format,...)
Definition Util.cpp:8
@ D_ERROR
Definition Util.h:26
@ D_WARNING
Definition Util.h:26
@ D_INFO
Definition Util.h:26
bufsize_t roundupToUnit(bufsize_t size, bufsize_t unit)