diff --git a/GleeBug/Static.Pe.cpp b/GleeBug/Static.Pe.cpp index 2360f02..4775cf5 100644 --- a/GleeBug/Static.Pe.cpp +++ b/GleeBug/Static.Pe.cpp @@ -15,13 +15,14 @@ namespace GleeBug mData.clear(); mOffset = 0; mDosHeader = Region(); + mDosNtOverlap = false; mAfterDosData = Region(); mNtHeaders32 = Region(); mNtHeaders64 = Region(); mSectionHeaders = Region(); } - Pe::Error Pe::ParseHeaders() + Pe::Error Pe::ParseHeaders(bool allowOverlap) { //clear all current data Clear(); @@ -42,15 +43,23 @@ namespace GleeBug if (newOffset < 0 || uint32(newOffset) >= mFile.GetSize()) return ErrorDosHeaderNtHeaderOffset; - //TODO: special case where DOS and PE header overlap (tinygui.exe) + //special case where DOS and PE header overlap (tinygui.exe) if (uint32(newOffset) < mOffset) - return ErrorDosHeaderNtHeaderOffsetOverlap; + { + if (!allowOverlap) + return ErrorDosHeaderNtHeaderOffsetOverlap; - //read & verify the data between the DOS header and the NT headers - auto afterDosCount = newOffset - mOffset; - mAfterDosData = readRegion(afterDosCount); - if (!mAfterDosData) - return ErrorAfterDosHeaderData; + mDosNtOverlap = true; + mOffset = newOffset; + } + else + { + //read & verify the data between the DOS header and the NT headers + auto afterDosCount = newOffset - mOffset; + mAfterDosData = readRegion(afterDosCount); + if (!mAfterDosData) + return ErrorAfterDosHeaderData; + } //read & verify the signature auto signature = readRegion(); @@ -73,7 +82,7 @@ namespace GleeBug //read & verify the optional header realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER32)); auto ioh = readRegion(); - if (!ioh) + if (!ioh) //TODO: support truncated optional header (tinyXP.exe) return ErrorNtOptionalHeaderRead; if (ioh->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) return ErrorNtOptionalHeaderMagic; diff --git a/GleeBug/Static.Pe.h b/GleeBug/Static.Pe.h index 3ddf728..b5d3412 100644 --- a/GleeBug/Static.Pe.h +++ b/GleeBug/Static.Pe.h @@ -32,11 +32,12 @@ namespace GleeBug explicit Pe(File & file); void Clear(); - Error ParseHeaders(); + Error ParseHeaders(bool allowOverlap = false); bool IsValidPe() const; bool IsPe64() const; const Region & GetDosHeader() const { return mDosHeader; } + bool GetDosNtOverlap() const { return mDosNtOverlap; } const Region & GetAfterDosData() const { return mAfterDosData; } const Region & GetNtHeaders32() const { return mNtHeaders32; } const Region & GetNtHeaders64() const { return mNtHeaders64; } @@ -48,7 +49,7 @@ namespace GleeBug void setupErrorMap(); template - inline Region readRegion(uint32 count = 1) + Region readRegion(uint32 count = 1) { return Region(&mData, readData(sizeof(T) * count), count); } @@ -60,6 +61,7 @@ namespace GleeBug uint32 mOffset; Region mDosHeader; + bool mDosNtOverlap; Region mAfterDosData; Region mNtHeaders32; Region mNtHeaders64; diff --git a/MyDebugger/main.cpp b/MyDebugger/main.cpp index bd0c436..e4af39e 100644 --- a/MyDebugger/main.cpp +++ b/MyDebugger/main.cpp @@ -50,7 +50,7 @@ static bool testPeFile(const wchar_t* szFileName, bool dumpData = true) { BufferFile file(diskData.data(), diskSize); Pe pe(file); - auto parseError = pe.ParseHeaders(); + auto parseError = pe.ParseHeaders(true); if (parseError == Pe::ErrorOk) { result = true;