initial work on reading the section data

This commit is contained in:
mrexodia 2016-01-10 14:11:54 +01:00
parent c817cfc96e
commit aabf3ee53f
5 changed files with 63 additions and 8 deletions

View File

@ -9,6 +9,7 @@
#include <map> #include <map>
#include <set> #include <set>
#include <functional> #include <functional>
#include <algorithm>
#include <windows.h> #include <windows.h>
#include <psapi.h> #include <psapi.h>

View File

@ -21,9 +21,16 @@ namespace GleeBug
mNtHeaders64.Clear(); mNtHeaders64.Clear();
mAfterOptionalData.Clear(); mAfterOptionalData.Clear();
mSectionHeaders.Clear(); mSectionHeaders.Clear();
mAfterSectionHeadersData.Clear();
mSections.clear(); mSections.clear();
} }
const char* Pe::ErrorText(Error error) const
{
auto found = mErrorMap.find(error);
return found == mErrorMap.end() ? "" : found->second;
}
bool Pe::IsValidPe() const bool Pe::IsValidPe() const
{ {
return IsPe64() ? mNtHeaders64.Valid() : mNtHeaders32.Valid(); return IsPe64() ? mNtHeaders64.Valid() : mNtHeaders32.Valid();
@ -150,9 +157,11 @@ namespace GleeBug
//read the section headers //read the section headers
auto sectionCount = ifh->NumberOfSections; auto sectionCount = ifh->NumberOfSections;
mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount); mSectionHeaders = readRegion<IMAGE_SECTION_HEADER>(sectionCount);
if (!mSectionHeaders)
return ErrorSectionsRead;
//parse the sections //parse the sections
auto sectionsError = parseSections(); auto sectionsError = parseSections(sectionCount);
if (sectionsError != ErrorOk) if (sectionsError != ErrorOk)
return sectionsError; return sectionsError;
@ -160,10 +169,38 @@ namespace GleeBug
return ErrorOk; return ErrorOk;
} }
Pe::Error Pe::parseSections() Pe::Error Pe::parseSections(uint16 count)
{ {
auto numberOfSections = mSectionHeaders.Count(); if (count == 0)
//TODO: parse section data return ErrorOk;
auto sectionHeaders = GetSectionHeaders();
struct SectionInfo
{
uint16 index;
PIMAGE_SECTION_HEADER header;
};
//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.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;
});
//get after section headers data
auto firstRawAddress = sortedHeaders[0].header->PointerToRawData;
if (mOffset < firstRawAddress)
mAfterSectionHeadersData = readRegion<uint8>(firstRawAddress - mOffset);
//TODO: read the actual section data.
for (auto section : sortedHeaders)
{
}
return ErrorOk; return ErrorOk;
} }
@ -198,5 +235,6 @@ 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" });
} }
}; };

View File

@ -28,13 +28,15 @@ namespace GleeBug
ErrorNtOptionalHeaderRead = 13, ErrorNtOptionalHeaderRead = 13,
ErrorNtOptionalHeaderMagic = 14, ErrorNtOptionalHeaderMagic = 14,
ErrorNtHeadersRegionSize = 15, ErrorNtHeadersRegionSize = 15,
ErrorSectionsRead = 16
}; };
explicit Pe(File & file); explicit Pe(File & file);
void Clear();
const char* ErrorText(Error error) const;
bool IsValidPe() const; bool IsValidPe() const;
bool IsPe64() const; bool IsPe64() const;
void Clear();
Error Parse(bool allowOverlap = false); Error Parse(bool allowOverlap = false);
const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; } const Region<IMAGE_DOS_HEADER> & GetDosHeader() const { return mDosHeader; }
@ -44,10 +46,11 @@ namespace GleeBug
const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; } const Region<IMAGE_NT_HEADERS64> & GetNtHeaders64() const { return mNtHeaders64; }
const Region<uint8> & GetAfterOptionalData() const { return mAfterOptionalData; } const Region<uint8> & GetAfterOptionalData() const { return mAfterOptionalData; }
const Region<IMAGE_SECTION_HEADER> & GetSectionHeaders() const { return mSectionHeaders; } const Region<IMAGE_SECTION_HEADER> & GetSectionHeaders() const { return mSectionHeaders; }
const Region<uint8> & GetAfterSectionHeadersData() const { return mAfterSectionHeadersData; }
const std::vector<Section> & GetSections() const { return mSections; } const std::vector<Section> & GetSections() const { return mSections; }
private: private:
Error parseSections(); Error parseSections(uint16 count);
uint32 readData(uint32 size); uint32 readData(uint32 size);
void setupErrorMap(); void setupErrorMap();
@ -70,6 +73,7 @@ namespace GleeBug
Region<IMAGE_NT_HEADERS64> mNtHeaders64; Region<IMAGE_NT_HEADERS64> mNtHeaders64;
Region<uint8> mAfterOptionalData; Region<uint8> mAfterOptionalData;
Region<IMAGE_SECTION_HEADER> mSectionHeaders; Region<IMAGE_SECTION_HEADER> mSectionHeaders;
Region<uint8> mAfterSectionHeadersData;
std::vector<Section> mSections; std::vector<Section> mSections;
}; };
}; };

View File

@ -117,6 +117,14 @@ namespace GleeBug
return Data(); return Data();
} }
T* operator[](uint32 index) const
{
auto data = Data();
if (!data || index >= mCount)
return nullptr;
return data + index;
}
protected: protected:
std::vector<uint8>* mData; std::vector<uint8>* mData;
uint32 mOffset; uint32 mOffset;

View File

@ -105,9 +105,12 @@ static bool testPeFile(const wchar_t* szFileName, bool dumpData = true)
printf(" RSize: %08X\n", cur->SizeOfRawData); printf(" RSize: %08X\n", cur->SizeOfRawData);
printf(" RAddr: %08X\n", cur->PointerToRawData); printf(" RAddr: %08X\n", cur->PointerToRawData);
} }
auto afterSectionHeadersData = pe.GetAfterSectionHeadersData();
printRegion("After Section Headers Data", afterSectionHeadersData);
} }
else else
printf("Pe::Parse failed (%d)!\n", parseError); printf("Pe::Parse failed (%s)!\n", pe.ErrorText(parseError));
} }
else else
puts("File::Read failed!"); puts("File::Read failed!");
@ -138,7 +141,8 @@ static void testCorkami()
int main() int main()
{ {
testCorkami(); testPeFile(L"C:\\test64.exe");
//testCorkami();
puts(""); puts("");
system("pause"); system("pause");
return 0; return 0;