(optionally) allow overlapping DOS and NT headers (went from 209/228 -> 218/228 corkami passes)

This commit is contained in:
mrexodia 2016-01-05 03:54:23 +01:00
parent e3375376ec
commit 94809cb4e9
3 changed files with 23 additions and 12 deletions

View File

@ -15,13 +15,14 @@ namespace GleeBug
mData.clear();
mOffset = 0;
mDosHeader = Region<IMAGE_DOS_HEADER>();
mDosNtOverlap = false;
mAfterDosData = Region<uint8>();
mNtHeaders32 = Region<IMAGE_NT_HEADERS32>();
mNtHeaders64 = Region<IMAGE_NT_HEADERS64>();
mSectionHeaders = Region<IMAGE_SECTION_HEADER>();
}
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<uint8>(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<uint8>(afterDosCount);
if (!mAfterDosData)
return ErrorAfterDosHeaderData;
}
//read & verify the signature
auto signature = readRegion<DWORD>();
@ -73,7 +82,7 @@ namespace GleeBug
//read & verify the optional header
realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER32));
auto ioh = readRegion<IMAGE_OPTIONAL_HEADER32>();
if (!ioh)
if (!ioh) //TODO: support truncated optional header (tinyXP.exe)
return ErrorNtOptionalHeaderRead;
if (ioh->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return ErrorNtOptionalHeaderMagic;

View File

@ -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<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; }
bool GetDosNtOverlap() const { return mDosNtOverlap; }
const Region<uint8> & GetAfterDosData() const { return mAfterDosData; }
const Region<IMAGE_NT_HEADERS32> & GetNtHeaders32() const { return mNtHeaders32; }
const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; }
@ -48,7 +49,7 @@ namespace GleeBug
void setupErrorMap();
template<typename T>
inline Region<T> readRegion(uint32 count = 1)
Region<T> readRegion(uint32 count = 1)
{
return Region<T>(&mData, readData(sizeof(T) * count), count);
}
@ -60,6 +61,7 @@ namespace GleeBug
uint32 mOffset;
Region<IMAGE_DOS_HEADER> mDosHeader;
bool mDosNtOverlap;
Region<uint8> mAfterDosData;
Region<IMAGE_NT_HEADERS32> mNtHeaders32;
Region<IMAGE_NT_HEADERS64> mNtHeaders64;

View File

@ -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;