initial section commit (not working perfectly at the moment)

This commit is contained in:
mrexodia 2016-01-10 16:02:42 +01:00
parent aabf3ee53f
commit e152448267
8 changed files with 138 additions and 101 deletions

View File

@ -251,7 +251,7 @@ public:
\brief Increment operator.
\return The register before the operation.
*/
Register<RegisterIndex, Type> & operator++()
Register<RegisterIndex, Type> operator++()
{
auto ret = *this;
Set(Get() + 1);
@ -262,7 +262,7 @@ public:
\brief Increment operator.
\return The register before the operation.
*/
Register<RegisterIndex, Type> & operator++(int)
Register<RegisterIndex, Type> operator++(int)
{
return operator++();
}

View File

@ -5,28 +5,28 @@
namespace GleeBug
{
class Section : public Region < uint8 >
class Section
{
public:
explicit Section()
: Region()
explicit Section(uint16 index, Region<IMAGE_SECTION_HEADER> & headers, Region<uint8> beforeData, Region<uint8> data)
: mIndex(index),
mHeaders(headers),
mBeforeData(beforeData),
mData(data)
{
}
explicit Section(std::vector<uint8>* data, uint32 offset, uint32 size, PIMAGE_SECTION_HEADER header)
: Region(data, offset, size),
mHeader(header)
{
}
PIMAGE_SECTION_HEADER GetHeader() { return mHeader; }
uint32 GetVirtualAddress() { return mHeader->VirtualAddress; }
uint32 GetVirtualSize() { return mHeader->Misc.VirtualSize; }
uint32 GetRawAddress() { return mHeader->PointerToRawData; }
uint32 GetRawSize() { return mHeader->SizeOfRawData; }
uint16 GetIndex() const { return mIndex; }
IMAGE_SECTION_HEADER & GetHeader() { return mHeaders[mIndex]; }
const IMAGE_SECTION_HEADER & GetHeader() const { return mHeaders[mIndex]; }
const Region<uint8> & GetBeforeData() const { return mBeforeData; }
const Region<uint8> & GetData() const { return mData; }
private:
PIMAGE_SECTION_HEADER mHeader;
uint16 mIndex;
Region<IMAGE_SECTION_HEADER> mHeaders;
Region<uint8> mBeforeData;
Region<uint8> mData;
};
};

View File

@ -13,6 +13,7 @@ namespace GleeBug
{
mData.clear();
mOffset = 0;
mIsPe64 = false;
mDosHeader.Clear();
mDosNtOverlap = false;
@ -38,7 +39,7 @@ namespace GleeBug
bool Pe::IsPe64() const
{
return IsValidPe() ? mNtHeaders64.Valid() : false;
return mIsPe64;
}
Pe::Error Pe::Parse(bool allowOverlap)
@ -115,6 +116,8 @@ namespace GleeBug
case IMAGE_FILE_MACHINE_AMD64:
{
mIsPe64 = true;
//read & verify the optional header
realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER64));
auto ioh = readRegion<IMAGE_OPTIONAL_HEADER64>();
@ -145,9 +148,11 @@ namespace GleeBug
}
}
auto numberOfSections = ifh->NumberOfSections;
//check the SizeOfOptionalHeader field
auto sizeOfIoh = ifh->SizeOfOptionalHeader;
if (ifh->NumberOfSections && sizeOfIoh < realSizeOfIoh) //TODO: this can be valid in certain circumstances (nullSOH-XP)
if (numberOfSections && sizeOfIoh < realSizeOfIoh) //TODO: this can be valid in certain circumstances (nullSOH-XP)
return ErrorNtFileHeaderSizeOfOptionalHeaderOverlap;
//read data after the optional header (TODO: check if this is even possible)
@ -155,13 +160,12 @@ namespace GleeBug
mAfterOptionalData = readRegion<uint8>(afterOptionalCount);
//read the section headers
auto sectionCount = ifh->NumberOfSections;
mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount);
mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(numberOfSections);
if (!mSectionHeaders)
return ErrorSectionsRead;
return ErrorSectionHeadersRead;
//parse the sections
auto sectionsError = parseSections(sectionCount);
auto sectionsError = parseSections(numberOfSections);
if (sectionsError != ErrorOk)
return sectionsError;
@ -171,34 +175,60 @@ namespace GleeBug
Pe::Error Pe::parseSections(uint16 count)
{
if (count == 0)
if (!count)
return ErrorOk;
auto sectionHeaders = GetSectionHeaders();
struct SectionInfo
{
uint16 index;
PIMAGE_SECTION_HEADER header;
IMAGE_SECTION_HEADER header; //by value to prevent pointer invalidation
Region<uint8> beforeData;
Region<uint8> data;
};
//sort sections on raw address to prevent read errors and have a contiguous buffer
std::vector<SectionInfo> sortedHeaders;
for (uint32 i = 0; i < count; i++)
sortedHeaders.reserve(count);
for (uint16 i = 0; i < count; i++)
sortedHeaders.push_back(SectionInfo{ i, sectionHeaders[i] });
std::sort(sortedHeaders.begin(), sortedHeaders.end(), [](const SectionInfo & a, const SectionInfo & b)
{
return a.header->PointerToRawData < b.header->PointerToRawData;
return a.header.PointerToRawData < b.header.PointerToRawData;
});
//get after section headers data
auto firstRawAddress = sortedHeaders[0].header->PointerToRawData;
auto firstRawAddress = sortedHeaders[0].header.PointerToRawData;
if (mOffset < firstRawAddress)
mAfterSectionHeadersData = readRegion<uint8>(firstRawAddress - mOffset);
//TODO: read the actual section data.
for (auto section : sortedHeaders)
//read the actual section data.
for (auto & section : sortedHeaders)
{
auto rawAddress = section.header.PointerToRawData;
auto beforeSize = mOffset < rawAddress ? rawAddress - mOffset : 0;
section.beforeData = readRegion<uint8>(beforeSize);
if (!section.beforeData)
return ErrorBeforeSectionDataRead;
section.data = readRegion<uint8>(section.header.SizeOfRawData);
if (!section.data)
return ErrorSectionDataRead;
}
//re-sort the sections by index
std::sort(sortedHeaders.begin(), sortedHeaders.end(), [](const SectionInfo & a, const SectionInfo & b)
{
return a.index < b.index;
});
//add the sections to the mSections vector
mSections.reserve(count);
for (uint16 i = 0; i < count; i++)
{
const auto & section = sortedHeaders[i];
mSections.push_back(Section(i, mSectionHeaders, section.beforeData, section.data));
}
return ErrorOk;
@ -235,6 +265,8 @@ namespace GleeBug
mErrorMap.insert({ ErrorNtOptionalHeaderRead, "ErrorNtOptionalHeaderRead" });
mErrorMap.insert({ ErrorNtOptionalHeaderMagic, "ErrorNtOptionalHeaderMagic" });
mErrorMap.insert({ ErrorNtHeadersRegionSize, "ErrorNtHeadersRegionSize" });
mErrorMap.insert({ ErrorSectionsRead, "ErrorSectionsRead" });
mErrorMap.insert({ ErrorSectionHeadersRead, "ErrorSectionHeadersRead" });
mErrorMap.insert({ ErrorBeforeSectionDataRead, "ErrorBeforeSectionDataRead" });
mErrorMap.insert({ ErrorSectionDataRead, "ErrorSectionDataRead" });
}
};

View File

@ -12,23 +12,25 @@ namespace GleeBug
public:
enum Error
{
ErrorOk = 0,
ErrorDosHeaderRead = 1,
ErrorDosHeaderMagic = 2,
ErrorDosHeaderNtHeaderOffset = 3,
ErrorDosHeaderNtHeaderOffsetOverlap = 4,
ErrorAfterDosHeaderData = 5,
ErrorNtSignatureRead = 6,
ErrorNtSignatureMagic = 7,
ErrorNtFileHeaderRead = 8,
ErrorNtFileHeaderSizeOfOptionalHeaderOverlap = 9,
ErrorNtFileHeaderUnsupportedMachine = 10,
ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead = 11,
ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize = 12,
ErrorNtOptionalHeaderRead = 13,
ErrorNtOptionalHeaderMagic = 14,
ErrorNtHeadersRegionSize = 15,
ErrorSectionsRead = 16
ErrorOk,
ErrorDosHeaderRead,
ErrorDosHeaderMagic,
ErrorDosHeaderNtHeaderOffset,
ErrorDosHeaderNtHeaderOffsetOverlap,
ErrorAfterDosHeaderData,
ErrorNtSignatureRead,
ErrorNtSignatureMagic,
ErrorNtFileHeaderRead,
ErrorNtFileHeaderSizeOfOptionalHeaderOverlap,
ErrorNtFileHeaderUnsupportedMachine,
ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead,
ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize,
ErrorNtOptionalHeaderRead,
ErrorNtOptionalHeaderMagic,
ErrorNtHeadersRegionSize,
ErrorSectionHeadersRead,
ErrorBeforeSectionDataRead,
ErrorSectionDataRead
};
explicit Pe(File & file);
@ -65,6 +67,7 @@ namespace GleeBug
File & mFile;
std::vector<uint8> mData;
uint32 mOffset;
bool mIsPe64;
Region<IMAGE_DOS_HEADER> mDosHeader;
bool mDosNtOverlap;

View File

@ -117,12 +117,14 @@ namespace GleeBug
return Data();
}
T* operator[](uint32 index) const
const T & operator[](uint32 index) const
{
auto data = Data();
if (!data || index >= mCount)
return nullptr;
return data + index;
return Data()[index];
}
T & operator[](uint32 index)
{
return Data()[index];
}
protected:

View File

@ -9,10 +9,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">

View File

@ -27,14 +27,37 @@ static void testDebugger()
}
template<typename T>
static void printRegion(const char* str, Region<T> region)
static void printRegion(const char* str, Region<T> region, bool newline = true)
{
printf("\n%s (offset: 0x%X, size: 0x%X, v: %s, e: %s)\n",
printf("\n%s (offset: 0x%X, size: 0x%X, v: %s, e: %s)",
str,
region.Offset(),
region.Size(),
region.Valid() ? "true" : "false",
region.Empty() ? "true" : "false");
if (newline)
puts("");
}
template<typename T>
static void printNtHeaders(T inth)
{
printRegion("NT Headers:", inth);
printf(" Signature: %08X\n", inth->Signature);
auto ifh = &inth->FileHeader;
puts("\n File Header:");
printf(" Machine : %04X\n", ifh->Machine);
printf(" NumberOfSections : %04X\n", ifh->NumberOfSections);
printf(" TimeDateStamp : %08X\n", ifh->TimeDateStamp);
printf(" SizeOfOptionalHeader: %04X\n", ifh->SizeOfOptionalHeader);
auto ioh = &inth->OptionalHeader;
puts("\n Optional Header:");
printf(" Magic : %04X\n", ioh->Magic);
printf(" EntryPoint: %08X\n", ioh->AddressOfEntryPoint);
printf(" ImageBase : %p\n", PVOID(ioh->ImageBase));
printf(" Subsystem : %04X\n", ioh->Subsystem);
}
static bool testPeFile(const wchar_t* szFileName, bool dumpData = true)
@ -64,50 +87,35 @@ static bool testPeFile(const wchar_t* szFileName, bool dumpData = true)
auto afterDosData = pe.GetAfterDosData();
printRegion("After DOS Data", afterDosData);
#ifdef _WIN64
auto inth = pe.GetNtHeaders64();
#else //x32
auto inth = pe.GetNtHeaders32();
#endif //_WIN64
printRegion("NT Headers:", inth);
printf(" Signature: %08X\n", inth->Signature);
PIMAGE_FILE_HEADER ifh = &inth->FileHeader;
puts("\n File Header:");
printf(" Machine : %04X\n", ifh->Machine);
printf(" NumberOfSections : %04X\n", ifh->NumberOfSections);
printf(" TimeDateStamp : %08X\n", ifh->TimeDateStamp);
printf(" SizeOfOptionalHeader: %04X\n", ifh->SizeOfOptionalHeader);
PIMAGE_OPTIONAL_HEADER ioh = &inth->OptionalHeader;
puts("\n Optional Header:");
printf(" Magic : %04X\n", ioh->Magic);
printf(" EntryPoint: %08X\n", ioh->AddressOfEntryPoint);
printf(" ImageBase : %p\n", ioh->ImageBase);
printf(" Subsystem : %04X\n", ioh->Subsystem);
if (pe.IsPe64())
printNtHeaders(pe.GetNtHeaders64());
else
printNtHeaders(pe.GetNtHeaders32());
auto afterOptionalData = pe.GetAfterOptionalData();
printRegion("After Optional Data", afterOptionalData);
auto ish = pe.GetSectionHeaders();
printRegion("Section Headers:", ish);
for (auto i = 0; i < ifh->NumberOfSections; i++)
{
if (i)
puts("");
auto cur = ish.Data() + i;
printf(" Section %d:\n", i + 1);
char name[9] = "";
memcpy(name, cur->Name, sizeof(cur->Name));
printf(" Name : %s\n", name);
printf(" VSize: %08X\n", cur->Misc.VirtualSize);
printf(" VAddr: %08X\n", cur->VirtualAddress);
printf(" RSize: %08X\n", cur->SizeOfRawData);
printf(" RAddr: %08X\n", cur->PointerToRawData);
}
printRegion("Section Headers", ish, false);
auto afterSectionHeadersData = pe.GetAfterSectionHeadersData();
printRegion("After Section Headers Data", afterSectionHeadersData);
auto sections = pe.GetSections();
for (const auto & section : sections)
{
if (section.GetIndex())
puts("");
printf(" Section %d:\n", section.GetIndex());
auto cur = section.GetHeader();
char name[9] = "";
memcpy(name, cur.Name, sizeof(cur.Name));
printf(" Name : %s\n", name);
printf(" VSize: %08X\n", cur.Misc.VirtualSize);
printf(" VAddr: %08X\n", cur.VirtualAddress);
printf(" RSize: %08X\n", cur.SizeOfRawData);
printf(" RAddr: %08X", cur.PointerToRawData);
printRegion(" Before Data", section.GetBeforeData(), false);
printRegion(" Data", section.GetData());
}
}
else
printf("Pe::Parse failed (%s)!\n", pe.ErrorText(parseError));
@ -142,7 +150,7 @@ static void testCorkami()
int main()
{
testPeFile(L"C:\\test64.exe");
//testCorkami();
testCorkami();
puts("");
system("pause");
return 0;

View File

@ -9,10 +9,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TitanEngineEmulator.cpp">