(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(); mData.clear();
mOffset = 0; mOffset = 0;
mDosHeader = Region<IMAGE_DOS_HEADER>(); mDosHeader = Region<IMAGE_DOS_HEADER>();
mDosNtOverlap = false;
mAfterDosData = Region<uint8>(); mAfterDosData = Region<uint8>();
mNtHeaders32 = Region<IMAGE_NT_HEADERS32>(); mNtHeaders32 = Region<IMAGE_NT_HEADERS32>();
mNtHeaders64 = Region<IMAGE_NT_HEADERS64>(); mNtHeaders64 = Region<IMAGE_NT_HEADERS64>();
mSectionHeaders = Region<IMAGE_SECTION_HEADER>(); mSectionHeaders = Region<IMAGE_SECTION_HEADER>();
} }
Pe::Error Pe::ParseHeaders() Pe::Error Pe::ParseHeaders(bool allowOverlap)
{ {
//clear all current data //clear all current data
Clear(); Clear();
@ -42,15 +43,23 @@ namespace GleeBug
if (newOffset < 0 || uint32(newOffset) >= mFile.GetSize()) if (newOffset < 0 || uint32(newOffset) >= mFile.GetSize())
return ErrorDosHeaderNtHeaderOffset; 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) if (uint32(newOffset) < mOffset)
return ErrorDosHeaderNtHeaderOffsetOverlap; {
if (!allowOverlap)
return ErrorDosHeaderNtHeaderOffsetOverlap;
//read & verify the data between the DOS header and the NT headers mDosNtOverlap = true;
auto afterDosCount = newOffset - mOffset; mOffset = newOffset;
mAfterDosData = readRegion<uint8>(afterDosCount); }
if (!mAfterDosData) else
return ErrorAfterDosHeaderData; {
//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 //read & verify the signature
auto signature = readRegion<DWORD>(); auto signature = readRegion<DWORD>();
@ -73,7 +82,7 @@ namespace GleeBug
//read & verify the optional header //read & verify the optional header
realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER32)); realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER32));
auto ioh = readRegion<IMAGE_OPTIONAL_HEADER32>(); auto ioh = readRegion<IMAGE_OPTIONAL_HEADER32>();
if (!ioh) if (!ioh) //TODO: support truncated optional header (tinyXP.exe)
return ErrorNtOptionalHeaderRead; return ErrorNtOptionalHeaderRead;
if (ioh->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) if (ioh->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return ErrorNtOptionalHeaderMagic; return ErrorNtOptionalHeaderMagic;

View File

@ -32,11 +32,12 @@ namespace GleeBug
explicit Pe(File & file); explicit Pe(File & file);
void Clear(); void Clear();
Error ParseHeaders(); Error ParseHeaders(bool allowOverlap = false);
bool IsValidPe() const; bool IsValidPe() const;
bool IsPe64() const; bool IsPe64() const;
const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; } const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; }
bool GetDosNtOverlap() const { return mDosNtOverlap; }
const Region<uint8> & GetAfterDosData() const { return mAfterDosData; } const Region<uint8> & GetAfterDosData() const { return mAfterDosData; }
const Region<IMAGE_NT_HEADERS32> & GetNtHeaders32() const { return mNtHeaders32; } const Region<IMAGE_NT_HEADERS32> & GetNtHeaders32() const { return mNtHeaders32; }
const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; } const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; }
@ -48,7 +49,7 @@ namespace GleeBug
void setupErrorMap(); void setupErrorMap();
template<typename T> 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); return Region<T>(&mData, readData(sizeof(T) * count), count);
} }
@ -60,6 +61,7 @@ namespace GleeBug
uint32 mOffset; uint32 mOffset;
Region<IMAGE_DOS_HEADER> mDosHeader; Region<IMAGE_DOS_HEADER> mDosHeader;
bool mDosNtOverlap;
Region<uint8> mAfterDosData; Region<uint8> mAfterDosData;
Region<IMAGE_NT_HEADERS32> mNtHeaders32; Region<IMAGE_NT_HEADERS32> mNtHeaders32;
Region<IMAGE_NT_HEADERS64> mNtHeaders64; 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); BufferFile file(diskData.data(), diskSize);
Pe pe(file); Pe pe(file);
auto parseError = pe.ParseHeaders(); auto parseError = pe.ParseHeaders(true);
if (parseError == Pe::ErrorOk) if (parseError == Pe::ErrorOk)
{ {
result = true; result = true;