diff --git a/GleeBug/Debugger.Thread.Registers.Register.h b/GleeBug/Debugger.Thread.Registers.Register.h index e8a9eea..9a59675 100644 --- a/GleeBug/Debugger.Thread.Registers.Register.h +++ b/GleeBug/Debugger.Thread.Registers.Register.h @@ -251,7 +251,7 @@ public: \brief Increment operator. \return The register before the operation. */ - Register & operator++() + Register operator++() { auto ret = *this; Set(Get() + 1); @@ -262,7 +262,7 @@ public: \brief Increment operator. \return The register before the operation. */ - Register & operator++(int) + Register operator++(int) { return operator++(); } diff --git a/GleeBug/Static.Pe.Section.h b/GleeBug/Static.Pe.Section.h index c0bef30..9fdaa22 100644 --- a/GleeBug/Static.Pe.Section.h +++ b/GleeBug/Static.Pe.Section.h @@ -5,28 +5,28 @@ namespace GleeBug { - class Section : public Region < uint8 > + class Section { public: - explicit Section() - : Region() + explicit Section(uint16 index, Region & headers, Region beforeData, Region data) + : mIndex(index), + mHeaders(headers), + mBeforeData(beforeData), + mData(data) { } - explicit Section(std::vector* 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 & GetBeforeData() const { return mBeforeData; } + const Region & GetData() const { return mData; } private: - PIMAGE_SECTION_HEADER mHeader; + uint16 mIndex; + Region mHeaders; + Region mBeforeData; + Region mData; }; }; diff --git a/GleeBug/Static.Pe.cpp b/GleeBug/Static.Pe.cpp index 0739c90..d60dc23 100644 --- a/GleeBug/Static.Pe.cpp +++ b/GleeBug/Static.Pe.cpp @@ -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(); @@ -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(afterOptionalCount); //read the section headers - auto sectionCount = ifh->NumberOfSections; - mSectionHeaders = readRegion(sectionCount); + mSectionHeaders = readRegion(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 beforeData; + Region data; }; //sort sections on raw address to prevent read errors and have a contiguous buffer std::vector 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(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(beforeSize); + if (!section.beforeData) + return ErrorBeforeSectionDataRead; + section.data = readRegion(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" }); } }; \ No newline at end of file diff --git a/GleeBug/Static.Pe.h b/GleeBug/Static.Pe.h index 5153189..eb49408 100644 --- a/GleeBug/Static.Pe.h +++ b/GleeBug/Static.Pe.h @@ -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 mData; uint32 mOffset; + bool mIsPe64; Region mDosHeader; bool mDosNtOverlap; diff --git a/GleeBug/Static.Region.h b/GleeBug/Static.Region.h index f046fe9..210efcf 100644 --- a/GleeBug/Static.Region.h +++ b/GleeBug/Static.Region.h @@ -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: diff --git a/MyDebugger/MyDebugger.vcxproj.filters b/MyDebugger/MyDebugger.vcxproj.filters index bec50a8..9d9f477 100644 --- a/MyDebugger/MyDebugger.vcxproj.filters +++ b/MyDebugger/MyDebugger.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - diff --git a/MyDebugger/main.cpp b/MyDebugger/main.cpp index e34cfb5..941b9a5 100644 --- a/MyDebugger/main.cpp +++ b/MyDebugger/main.cpp @@ -27,14 +27,37 @@ static void testDebugger() } template -static void printRegion(const char* str, Region region) +static void printRegion(const char* str, Region 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 +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; diff --git a/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters b/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters index 522d6e8..ee93720 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters +++ b/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms -