6 if (buf == NULL)
return false;
9 WORD *magic = (WORD*) buf->
getContentAt(dosOffset,
sizeof(WORD));
10 if (magic == NULL)
return false;
12 if ((*magic) != pe::S_DOS) {
15 offset_t newOffset = dosOffset + (
sizeof(IMAGE_DOS_HEADER) -
sizeof(LONG));
16 LONG* lfnew = (LONG*) buf->
getContentAt(newOffset,
sizeof(LONG));
21 DWORD *peMagic = (DWORD*) buf->
getContentAt(peOffset,
sizeof(DWORD));
22 if (peMagic == NULL) {
25 if (*peMagic == pe::S_NT) {
47 if (!buffer || !bufferSize)
return 0;
49 WORD* wordsBuff =
reinterpret_cast<WORD*
>(buffer);
50 const size_t wordsCount = bufferSize /
sizeof(WORD);
51 const size_t remainingBytes = bufferSize %
sizeof(WORD);
53 size_t checksumBgn = 0;
54 size_t checksumEnd = 0;
56 checksumBgn = size_t(checksumOffset);
57 checksumEnd = checksumBgn +
sizeof(DWORD);
60 const long long maxVal = ((
long long)1) << 32;
61 long long checksum = 0;
63 for (
int i = 0; i < wordsCount; i++) {
64 WORD chunk = wordsBuff[i];
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;
73 checksum = (checksum & 0xffffffff) + chunk + (checksum >> 32);
74 if (checksum > maxVal) {
75 checksum = (checksum & 0xffffffff) + (checksum >> 32);
80 if (remainingBytes > 0) {
82 memcpy(&chunk, buffer + wordsCount *
sizeof(WORD), remainingBytes);
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;
91 checksum = (checksum & 0xffffffff) + chunk + (checksum >> 32);
92 if (checksum > maxVal) {
93 checksum = (checksum & 0xffffffff) + (checksum >> 32);
96 checksum = (checksum & 0xffff) + (checksum >> 16);
97 checksum = (checksum)+(checksum >> 16);
98 checksum = checksum & 0xffff;
99 checksum += bufferSize;
107 dosHdrWrapper(NULL), fHdr(NULL), optHdr(NULL), sects(NULL),
153 for (
int i = 0; i < pe::DIR_ENTRIES_COUNT; i++) {
175 for (
size_t i = 0 ; i < pe::DIR_ENTRIES_COUNT; i++) {
195 bool anyModified =
false;
197 for (
size_t i = 0 ; i < pe::DIR_ENTRIES_COUNT; i++) {
219 if (!richSign)
return NULL;
221 DWORD xorkey = richSign->checksum;
224 pe::RICH_DANS_HEADER* dansHdr = NULL;
226 offset_t offset = richOffset -
sizeof(pe::RICH_DANS_HEADER);
228 dansHdr = (pe::RICH_DANS_HEADER*) this->
getContentAt(offset,
sizeof(pe::RICH_DANS_HEADER));
232 if (dansHdr->dansId == (pe::DANS_HDR_MAGIC ^ xorkey)) {
236 offset -=
sizeof(DWORD);
238 if (!dansHdr || dansHdr->dansId != (pe::DANS_HDR_MAGIC ^ xorkey)) {
246 size_t dosStubOffset = this->
core.
dos->e_lfarlc;
247 size_t dosStubEnd = this->
core.
dos->e_lfanew;
248 const size_t maxSize = dosStubEnd - dosStubOffset;
249 BYTE *dosPtr = this->
getContentAt(dosStubOffset, maxSize);
254 pe::RICH_SIGNATURE* richSign = NULL;
255 size_t toSearchSize = maxSize;
256 const offset_t startOffset = dosStubOffset;
257 const size_t step =
sizeof(DWORD);
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;
264 toSearchSize -= step;
266 if (!richSign)
return NULL;
267 if (richSign->richId != pe::RICH_HDR_MAGIC) {
305 const size_t unit_size = 0x1000;
310 if (vSize < unit_size) {
325 if (addrType != epType) {
326 entryPoint = this->
convertAddr(entryPoint, epType, addrType);
333 if (
optHdr == NULL)
return false;
344 if (isOk ==
false)
return 0;
346 return static_cast<size_t> (secNum);
351 uint64_t count = newNum;
353 if (canSet ==
false) {
362 uint64_t size = newSize;
364 if (canSet ==
false) {
373 if (useMapped ==
false) {
422 if (curr >= rawSize) {
426 return bgnRaw + curr;
443 if (eType >= pe::DIR_ENTRIES_COUNT)
return NULL;
460 bool allowExceptions =
true;
464 if (allowExceptions)
throw ExeException(
"No such Data Directory");
469 if (ddirWrapper == NULL || ddir == NULL) {
470 if (allowExceptions)
throw ExeException(
"Cannot fetch DataDirTable");
476 if (allowExceptions)
throw ExeException(
"Invalid new offset");
481 if (allowExceptions)
throw ExeException(
"Cannot copy: no space at such offset");
485 if (allowExceptions)
throw ExeException(
"Cannot copy: error occured");
489 ddir[dirNum].VirtualAddress =
static_cast<DWORD
>(dataDirAddr);
510 if (!r_size && !v_size)
return nullptr;
527 newSize = roundedRawEnd + r_size;
528 const bufsize_t newVirtualSize = roundedVirtualEnd + v_size;
536 if (
resize(newSize) ==
false) {
549 IMAGE_SECTION_HEADER secHdr;
550 ::memset(&secHdr, 0,
sizeof(IMAGE_SECTION_HEADER));
553 const size_t nameLen = name.length();
554 const size_t bufSize =
sizeof(secHdr.Name);
555 const size_t copySize = (nameLen < bufSize) ? nameLen : bufSize;
557 ::memcpy(secHdr.Name, name.toStdString().c_str(), copySize);
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;
573 return (secCount > 0) ? this->
_getSecHdr(secCount - 1) :
nullptr;
586 for (
size_t i = 0; i < secCounter; i++) {
594 if (size == 0)
continue;
596 secLastMapped += size;
597 if (secLastMapped > lastMapped) {
598 lastMapped = secLastMapped;
609 if (lastMapped < peHdrsEnd) {
610 lastMapped = peHdrsEnd;
614 if (lastMapped < ntHeadersEndOffset) {
615 lastMapped = ntHeadersEndOffset;
627 if (!secHdr)
return nullptr;
631 newSize = fullSize + addedSize;
637 const bufsize_t secNewRSize = newSize - secROffset;
644 if (secVSize < secNewRSize) {
649 bufsize_t newVSize = secVOffset + secNewRSize;
668 if (!secView)
return false;
673 return dumpedSize ? true :
false;
679 if (ddir[pe::DIR_BOUND_IMPORT].VirtualAddress == 0 && ddir[pe::DIR_BOUND_IMPORT].Size == 0) {
683 ddir[pe::DIR_BOUND_IMPORT].VirtualAddress = 0;
684 ddir[pe::DIR_BOUND_IMPORT].Size = 0;
690 bool isOk = bImp->
wrap();
710 size_t initialSize = entrypoints.size();
713 if (!exports)
return 0;
716 if (entriesCnt == 0)
return 0;
718 for (
int i = 0; i < entriesCnt; i++) {
720 if (!entry)
continue;
723 if (forwarder.length()) {
731 entrypoints.insert(offset, entry->
getName());
733 return entrypoints.size() - initialSize;
const offset_t INVALID_ADDR
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 ExeNodeWrapper * getEntryAt(size_t fieldId)
virtual bool canAddEntry()
virtual size_t getEntriesCount()
virtual ExeNodeWrapper * addEntry(ExeNodeWrapper *entry)
std::map< size_t, ExeElementWrapper * > wrappers
virtual ExeElementWrapper * getWrapper(size_t wrapperId)
virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions=false)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
virtual offset_t convertAddr(offset_t inAddr, Executable::addr_type inType, Executable::addr_type outType)
virtual bufsize_t getContentSize()
QString getForwarderStr()
virtual QString getName()
virtual bool resize(bufsize_t newSize)
bufsize_t hdrsSize() const
bool wrap(AbstractByteBuffer *v_buf)
virtual bufsize_t getImageSize()
offset_t peSignatureOffset() const
bufsize_t peNtHeadersSize() const
virtual Executable * build(AbstractByteBuffer *buf)
virtual bool signatureMatches(AbstractByteBuffer *buf)
DataDirEntryWrapper * dataDirEntries[pe::DIR_ENTRIES_COUNT]
virtual bufsize_t getMappedSize(Executable::addr_type aType)
BufferView * _createSectionView(SectionHdrWrapper *sec)
size_t getExportsMap(QMap< offset_t, QString > &entrypoints, Executable::addr_type aType=Executable::RVA)
SectionHdrWrapper * _getSecHdr(size_t index) const
offset_t peDataDirOffset()
virtual offset_t getEntryPoint(Executable::addr_type addrType=Executable::RVA)
void _init(AbstractByteBuffer *v_buf)
friend class SectHdrsWrapper
size_t _getSecIndex(SectionHdrWrapper *sec) const
bool setEntryPoint(offset_t entry, Executable::addr_type aType)
pe::RICH_DANS_HEADER * getRichHeaderBgn(pe::RICH_SIGNATURE *sign)
SectionHdrWrapper * extendLastSection(bufsize_t addedSize)
SectionHdrWrapper * getLastSection()
bool dumpSection(SectionHdrWrapper *sec, QString fileName)
offset_t _getLastMapped(Executable::addr_type aType)
virtual offset_t rvaToRaw(offset_t rva)
BufferView * createSectionView(size_t secNum)
bool setHdrSectionsNum(size_t newNum)
bool setVirtualSize(bufsize_t newSize)
DataDirEntryWrapper * getDataDirEntry(pe::dir_entry eType)
SectionHdrWrapper * _getSecHdrAtOffset(offset_t offset, Executable::addr_type aType, bool recalculate=false, bool verbose=false)
bool moveDataDirEntry(pe::dir_entry id, offset_t newOffset, Executable::addr_type addType=Executable::RAW)
SectionHdrWrapper * _getLastSection()
virtual void clearWrappers()
offset_t _secHdrsEndOffset()
IMAGE_DATA_DIRECTORY * getDataDirectory()
virtual offset_t rawToRva(offset_t raw)
size_t hdrSectionsNum() const
PEFile(AbstractByteBuffer *v_buf)
virtual bufsize_t getAlignment(Executable::addr_type aType) const
pe::RICH_SIGNATURE * getRichHeaderSign()
static long computeChecksum(BYTE *buffer, size_t bufferSize, offset_t checksumOffset)
DosHdrWrapper * dosHdrWrapper
size_t _getSectionsCount(bool useMapped=true) const
SectionHdrWrapper * addNewSection(QString name, bufsize_t size, bufsize_t v_size=0)
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,...)
bufsize_t roundupToUnit(bufsize_t size, bufsize_t unit)