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

View File

@ -5,28 +5,28 @@
namespace GleeBug namespace GleeBug
{ {
class Section : public Region < uint8 > class Section
{ {
public: public:
explicit Section() explicit Section(uint16 index, Region<IMAGE_SECTION_HEADER> & headers, Region<uint8> beforeData, Region<uint8> data)
: Region() : mIndex(index),
mHeaders(headers),
mBeforeData(beforeData),
mData(data)
{ {
} }
explicit Section(std::vector<uint8>* data, uint32 offset, uint32 size, PIMAGE_SECTION_HEADER header) uint16 GetIndex() const { return mIndex; }
: Region(data, offset, size), IMAGE_SECTION_HEADER & GetHeader() { return mHeaders[mIndex]; }
mHeader(header) const IMAGE_SECTION_HEADER & GetHeader() const { return mHeaders[mIndex]; }
{ const Region<uint8> & GetBeforeData() const { return mBeforeData; }
} const Region<uint8> & GetData() const { return mData; }
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; }
private: 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(); mData.clear();
mOffset = 0; mOffset = 0;
mIsPe64 = false;
mDosHeader.Clear(); mDosHeader.Clear();
mDosNtOverlap = false; mDosNtOverlap = false;
@ -38,7 +39,7 @@ namespace GleeBug
bool Pe::IsPe64() const bool Pe::IsPe64() const
{ {
return IsValidPe() ? mNtHeaders64.Valid() : false; return mIsPe64;
} }
Pe::Error Pe::Parse(bool allowOverlap) Pe::Error Pe::Parse(bool allowOverlap)
@ -115,6 +116,8 @@ namespace GleeBug
case IMAGE_FILE_MACHINE_AMD64: case IMAGE_FILE_MACHINE_AMD64:
{ {
mIsPe64 = true;
//read & verify the optional header //read & verify the optional header
realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER64)); realSizeOfIoh = uint32(sizeof(IMAGE_OPTIONAL_HEADER64));
auto ioh = readRegion<IMAGE_OPTIONAL_HEADER64>(); auto ioh = readRegion<IMAGE_OPTIONAL_HEADER64>();
@ -145,9 +148,11 @@ namespace GleeBug
} }
} }
auto numberOfSections = ifh->NumberOfSections;
//check the SizeOfOptionalHeader field //check the SizeOfOptionalHeader field
auto sizeOfIoh = ifh->SizeOfOptionalHeader; 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; return ErrorNtFileHeaderSizeOfOptionalHeaderOverlap;
//read data after the optional header (TODO: check if this is even possible) //read data after the optional header (TODO: check if this is even possible)
@ -155,13 +160,12 @@ namespace GleeBug
mAfterOptionalData = readRegion<uint8>(afterOptionalCount); mAfterOptionalData = readRegion<uint8>(afterOptionalCount);
//read the section headers //read the section headers
auto sectionCount = ifh->NumberOfSections; mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(numberOfSections);
mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount);
if (!mSectionHeaders) if (!mSectionHeaders)
return ErrorSectionsRead; return ErrorSectionHeadersRead;
//parse the sections //parse the sections
auto sectionsError = parseSections(sectionCount); auto sectionsError = parseSections(numberOfSections);
if (sectionsError != ErrorOk) if (sectionsError != ErrorOk)
return sectionsError; return sectionsError;
@ -171,34 +175,60 @@ namespace GleeBug
Pe::Error Pe::parseSections(uint16 count) Pe::Error Pe::parseSections(uint16 count)
{ {
if (count == 0) if (!count)
return ErrorOk; return ErrorOk;
auto sectionHeaders = GetSectionHeaders(); auto sectionHeaders = GetSectionHeaders();
struct SectionInfo struct SectionInfo
{ {
uint16 index; 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 //sort sections on raw address to prevent read errors and have a contiguous buffer
std::vector<SectionInfo> sortedHeaders; 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] }); sortedHeaders.push_back(SectionInfo{ i, sectionHeaders[i] });
std::sort(sortedHeaders.begin(), sortedHeaders.end(), [](const SectionInfo & a, const SectionInfo & b) 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 //get after section headers data
auto firstRawAddress = sortedHeaders[0].header->PointerToRawData; auto firstRawAddress = sortedHeaders[0].header.PointerToRawData;
if (mOffset < firstRawAddress) if (mOffset < firstRawAddress)
mAfterSectionHeadersData = readRegion<uint8>(firstRawAddress - mOffset); mAfterSectionHeadersData = readRegion<uint8>(firstRawAddress - mOffset);
//TODO: read the actual section data. //read the actual section data.
for (auto section : sortedHeaders) 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; return ErrorOk;
@ -235,6 +265,8 @@ namespace GleeBug
mErrorMap.insert({ ErrorNtOptionalHeaderRead, "ErrorNtOptionalHeaderRead" }); mErrorMap.insert({ ErrorNtOptionalHeaderRead, "ErrorNtOptionalHeaderRead" });
mErrorMap.insert({ ErrorNtOptionalHeaderMagic, "ErrorNtOptionalHeaderMagic" }); mErrorMap.insert({ ErrorNtOptionalHeaderMagic, "ErrorNtOptionalHeaderMagic" });
mErrorMap.insert({ ErrorNtHeadersRegionSize, "ErrorNtHeadersRegionSize" }); 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: public:
enum Error enum Error
{ {
ErrorOk = 0, ErrorOk,
ErrorDosHeaderRead = 1, ErrorDosHeaderRead,
ErrorDosHeaderMagic = 2, ErrorDosHeaderMagic,
ErrorDosHeaderNtHeaderOffset = 3, ErrorDosHeaderNtHeaderOffset,
ErrorDosHeaderNtHeaderOffsetOverlap = 4, ErrorDosHeaderNtHeaderOffsetOverlap,
ErrorAfterDosHeaderData = 5, ErrorAfterDosHeaderData,
ErrorNtSignatureRead = 6, ErrorNtSignatureRead,
ErrorNtSignatureMagic = 7, ErrorNtSignatureMagic,
ErrorNtFileHeaderRead = 8, ErrorNtFileHeaderRead,
ErrorNtFileHeaderSizeOfOptionalHeaderOverlap = 9, ErrorNtFileHeaderSizeOfOptionalHeaderOverlap,
ErrorNtFileHeaderUnsupportedMachine = 10, ErrorNtFileHeaderUnsupportedMachine,
ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead = 11, ErrorNtFileHeaderUnsupportedMachineOptionalHeaderRead,
ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize = 12, ErrorNtFileHeaderUnsupportedMachineNtHeadersRegionSize,
ErrorNtOptionalHeaderRead = 13, ErrorNtOptionalHeaderRead,
ErrorNtOptionalHeaderMagic = 14, ErrorNtOptionalHeaderMagic,
ErrorNtHeadersRegionSize = 15, ErrorNtHeadersRegionSize,
ErrorSectionsRead = 16 ErrorSectionHeadersRead,
ErrorBeforeSectionDataRead,
ErrorSectionDataRead
}; };
explicit Pe(File & file); explicit Pe(File & file);
@ -65,6 +67,7 @@ namespace GleeBug
File & mFile; File & mFile;
std::vector<uint8> mData; std::vector<uint8> mData;
uint32 mOffset; uint32 mOffset;
bool mIsPe64;
Region<IMAGE_DOS_HEADER> mDosHeader; Region<IMAGE_DOS_HEADER> mDosHeader;
bool mDosNtOverlap; bool mDosNtOverlap;

View File

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

View File

@ -9,10 +9,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter> </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>
<ItemGroup> <ItemGroup>
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">

View File

@ -27,14 +27,37 @@ static void testDebugger()
} }
template<typename T> 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, str,
region.Offset(), region.Offset(),
region.Size(), region.Size(),
region.Valid() ? "true" : "false", region.Valid() ? "true" : "false",
region.Empty() ? "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) 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(); auto afterDosData = pe.GetAfterDosData();
printRegion("After DOS Data", afterDosData); printRegion("After DOS Data", afterDosData);
#ifdef _WIN64 if (pe.IsPe64())
auto inth = pe.GetNtHeaders64(); printNtHeaders(pe.GetNtHeaders64());
#else //x32 else
auto inth = pe.GetNtHeaders32(); printNtHeaders(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);
auto afterOptionalData = pe.GetAfterOptionalData(); auto afterOptionalData = pe.GetAfterOptionalData();
printRegion("After Optional Data", afterOptionalData); printRegion("After Optional Data", afterOptionalData);
auto ish = pe.GetSectionHeaders(); auto ish = pe.GetSectionHeaders();
printRegion("Section Headers:", ish); printRegion("Section Headers", ish, false);
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);
}
auto afterSectionHeadersData = pe.GetAfterSectionHeadersData(); auto afterSectionHeadersData = pe.GetAfterSectionHeadersData();
printRegion("After Section Headers Data", afterSectionHeadersData); 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 else
printf("Pe::Parse failed (%s)!\n", pe.ErrorText(parseError)); printf("Pe::Parse failed (%s)!\n", pe.ErrorText(parseError));
@ -142,7 +150,7 @@ static void testCorkami()
int main() int main()
{ {
testPeFile(L"C:\\test64.exe"); testPeFile(L"C:\\test64.exe");
//testCorkami(); testCorkami();
puts(""); puts("");
system("pause"); system("pause");
return 0; return 0;

View File

@ -9,10 +9,6 @@
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter> </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>
<ItemGroup> <ItemGroup>
<ClCompile Include="TitanEngineEmulator.cpp"> <ClCompile Include="TitanEngineEmulator.cpp">