mirror of https://github.com/x64dbg/GleeBug
initial section commit (not working perfectly at the moment)
This commit is contained in:
parent
aabf3ee53f
commit
e152448267
|
|
@ -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++();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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" });
|
||||
}
|
||||
};
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
Loading…
Reference in New Issue