mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-04-26 12:24:32 +00:00
Populate Rich header version strings (#94)
This commit is contained in:
parent
ea3970c9a0
commit
bd68ba418f
261
dump-pe/main.cpp
261
dump-pe/main.cpp
@ -229,11 +229,12 @@ int printSymbols(void *N,
|
||||
|
||||
int printRich(void *N, rich_entry r) {
|
||||
static_cast<void>(N);
|
||||
|
||||
std::cout << std::dec;
|
||||
std::cout << std::setw(10) << "ProdId:" << std::setw(7) << r.ProductId;
|
||||
std::cout << std::setw(10) << "Build:" << std::setw(7) << r.BuildNumber;
|
||||
std::cout << std::setw(10) << "Name:" << std::setw(20)
|
||||
<< GetRichProductName(r.ProductId, r.BuildNumber);
|
||||
std::cout << std::setw(10) << "Name:" << std::setw(40)
|
||||
<< GetRichProductName(r.BuildNumber) << " "
|
||||
<< GetRichObjectType(r.ProductId);
|
||||
std::cout << std::setw(10) << "Count:" << std::setw(7) << r.Count << "\n";
|
||||
return 0;
|
||||
}
|
||||
@ -282,10 +283,13 @@ int printSecs(void *N,
|
||||
|
||||
#define DUMP_FIELD(x) \
|
||||
std::cout << "" #x << ": 0x"; \
|
||||
std::cout << std::hex << static_cast<std::uint64_t>(p->peHeader.nt.x) << "\n";
|
||||
std::cout << std::hex << static_cast<std::uint64_t>(p->peHeader.x) << "\n";
|
||||
#define DUMP_DEC_FIELD(x) \
|
||||
std::cout << "" #x << ": "; \
|
||||
std::cout << std::dec << static_cast<std::uint64_t>(p->peHeader.nt.x) << "\n";
|
||||
std::cout << std::dec << static_cast<std::uint64_t>(p->peHeader.x) << "\n";
|
||||
#define DUMP_BOOL_FIELD(x) \
|
||||
std::cout << "" #x << ": "; \
|
||||
std::cout << std::boolalpha << static_cast<bool>(p->peHeader.x) << "\n";
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 2 || (argc == 2 && std::strcmp(argv[1], "--help") == 0)) {
|
||||
@ -303,120 +307,153 @@ int main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Print Rich header info
|
||||
if (p->peHeader.rich.isPresent) {
|
||||
std::cout << "Rich header: present\n";
|
||||
IterRich(p, printRich, NULL);
|
||||
} else {
|
||||
std::cout << "Rich header: not present\n";
|
||||
}
|
||||
// print out some things
|
||||
DUMP_FIELD(Signature);
|
||||
DUMP_FIELD(FileHeader.Machine);
|
||||
DUMP_FIELD(FileHeader.NumberOfSections);
|
||||
DUMP_DEC_FIELD(FileHeader.TimeDateStamp);
|
||||
DUMP_FIELD(FileHeader.PointerToSymbolTable);
|
||||
DUMP_DEC_FIELD(FileHeader.NumberOfSymbols);
|
||||
DUMP_FIELD(FileHeader.SizeOfOptionalHeader);
|
||||
DUMP_FIELD(FileHeader.Characteristics);
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
DUMP_FIELD(OptionalHeader.Magic);
|
||||
DUMP_DEC_FIELD(OptionalHeader.MajorLinkerVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader.MinorLinkerVersion);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfCode);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfInitializedData);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfUninitializedData);
|
||||
DUMP_FIELD(OptionalHeader.AddressOfEntryPoint);
|
||||
DUMP_FIELD(OptionalHeader.BaseOfCode);
|
||||
DUMP_FIELD(OptionalHeader.BaseOfData);
|
||||
DUMP_FIELD(OptionalHeader.ImageBase);
|
||||
DUMP_FIELD(OptionalHeader.SectionAlignment);
|
||||
DUMP_FIELD(OptionalHeader.FileAlignment);
|
||||
DUMP_DEC_FIELD(OptionalHeader.MajorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader.MinorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader.Win32VersionValue);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfImage);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfHeaders);
|
||||
DUMP_FIELD(OptionalHeader.CheckSum);
|
||||
DUMP_FIELD(OptionalHeader.Subsystem);
|
||||
DUMP_FIELD(OptionalHeader.DllCharacteristics);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfStackReserve);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfStackCommit);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfHeapReserve);
|
||||
DUMP_FIELD(OptionalHeader.SizeOfHeapCommit);
|
||||
DUMP_FIELD(OptionalHeader.LoaderFlags);
|
||||
DUMP_DEC_FIELD(OptionalHeader.NumberOfRvaAndSizes);
|
||||
} else {
|
||||
DUMP_FIELD(OptionalHeader64.Magic);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.MajorLinkerVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.MinorLinkerVersion);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfCode);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfInitializedData);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfUninitializedData);
|
||||
DUMP_FIELD(OptionalHeader64.AddressOfEntryPoint);
|
||||
DUMP_FIELD(OptionalHeader64.BaseOfCode);
|
||||
DUMP_FIELD(OptionalHeader64.ImageBase);
|
||||
DUMP_FIELD(OptionalHeader64.SectionAlignment);
|
||||
DUMP_FIELD(OptionalHeader64.FileAlignment);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.MajorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.MinorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.Win32VersionValue);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfImage);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfHeaders);
|
||||
DUMP_FIELD(OptionalHeader64.CheckSum);
|
||||
DUMP_FIELD(OptionalHeader64.Subsystem);
|
||||
DUMP_FIELD(OptionalHeader64.DllCharacteristics);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfStackReserve);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfStackCommit);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfHeapReserve);
|
||||
DUMP_FIELD(OptionalHeader64.SizeOfHeapCommit);
|
||||
DUMP_FIELD(OptionalHeader64.LoaderFlags);
|
||||
DUMP_DEC_FIELD(OptionalHeader64.NumberOfRvaAndSizes);
|
||||
}
|
||||
if (p != NULL) {
|
||||
// Print DOS header
|
||||
DUMP_FIELD(dos.e_magic);
|
||||
DUMP_FIELD(dos.e_cp);
|
||||
DUMP_FIELD(dos.e_crlc);
|
||||
DUMP_FIELD(dos.e_cparhdr);
|
||||
DUMP_FIELD(dos.e_minalloc);
|
||||
DUMP_FIELD(dos.e_maxalloc);
|
||||
DUMP_FIELD(dos.e_ss);
|
||||
DUMP_FIELD(dos.e_sp);
|
||||
DUMP_FIELD(dos.e_csum);
|
||||
DUMP_FIELD(dos.e_ip);
|
||||
DUMP_FIELD(dos.e_cs);
|
||||
DUMP_FIELD(dos.e_lfarlc);
|
||||
DUMP_FIELD(dos.e_ovno);
|
||||
DUMP_FIELD(dos.e_res[0]);
|
||||
DUMP_FIELD(dos.e_res[1]);
|
||||
DUMP_FIELD(dos.e_res[2]);
|
||||
DUMP_FIELD(dos.e_res[3]);
|
||||
DUMP_FIELD(dos.e_oemid);
|
||||
DUMP_FIELD(dos.e_oeminfo);
|
||||
DUMP_FIELD(dos.e_res2[0]);
|
||||
DUMP_FIELD(dos.e_res2[1]);
|
||||
DUMP_FIELD(dos.e_res2[2]);
|
||||
DUMP_FIELD(dos.e_res2[3]);
|
||||
DUMP_FIELD(dos.e_res2[4]);
|
||||
DUMP_FIELD(dos.e_res2[5]);
|
||||
DUMP_FIELD(dos.e_res2[6]);
|
||||
DUMP_FIELD(dos.e_res2[7]);
|
||||
DUMP_FIELD(dos.e_res2[8]);
|
||||
DUMP_FIELD(dos.e_res2[9]);
|
||||
DUMP_FIELD(dos.e_lfanew);
|
||||
// Print Rich header info
|
||||
DUMP_BOOL_FIELD(rich.isPresent);
|
||||
if (p->peHeader.rich.isPresent) {
|
||||
DUMP_FIELD(rich.DecryptionKey);
|
||||
DUMP_FIELD(rich.Checksum);
|
||||
DUMP_BOOL_FIELD(rich.isValid);
|
||||
IterRich(p, printRich, NULL);
|
||||
}
|
||||
// print out some things
|
||||
DUMP_FIELD(nt.Signature);
|
||||
DUMP_FIELD(nt.FileHeader.Machine);
|
||||
DUMP_FIELD(nt.FileHeader.NumberOfSections);
|
||||
DUMP_DEC_FIELD(nt.FileHeader.TimeDateStamp);
|
||||
DUMP_FIELD(nt.FileHeader.PointerToSymbolTable);
|
||||
DUMP_DEC_FIELD(nt.FileHeader.NumberOfSymbols);
|
||||
DUMP_FIELD(nt.FileHeader.SizeOfOptionalHeader);
|
||||
DUMP_FIELD(nt.FileHeader.Characteristics);
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
DUMP_FIELD(nt.OptionalHeader.Magic);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.MajorLinkerVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.MinorLinkerVersion);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfCode);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfInitializedData);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfUninitializedData);
|
||||
DUMP_FIELD(nt.OptionalHeader.AddressOfEntryPoint);
|
||||
DUMP_FIELD(nt.OptionalHeader.BaseOfCode);
|
||||
DUMP_FIELD(nt.OptionalHeader.BaseOfData);
|
||||
DUMP_FIELD(nt.OptionalHeader.ImageBase);
|
||||
DUMP_FIELD(nt.OptionalHeader.SectionAlignment);
|
||||
DUMP_FIELD(nt.OptionalHeader.FileAlignment);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.MajorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.MinorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.Win32VersionValue);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfImage);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfHeaders);
|
||||
DUMP_FIELD(nt.OptionalHeader.CheckSum);
|
||||
DUMP_FIELD(nt.OptionalHeader.Subsystem);
|
||||
DUMP_FIELD(nt.OptionalHeader.DllCharacteristics);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfStackReserve);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfStackCommit);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfHeapReserve);
|
||||
DUMP_FIELD(nt.OptionalHeader.SizeOfHeapCommit);
|
||||
DUMP_FIELD(nt.OptionalHeader.LoaderFlags);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader.NumberOfRvaAndSizes);
|
||||
} else {
|
||||
DUMP_FIELD(nt.OptionalHeader64.Magic);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.MajorLinkerVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.MinorLinkerVersion);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfCode);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfInitializedData);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfUninitializedData);
|
||||
DUMP_FIELD(nt.OptionalHeader64.AddressOfEntryPoint);
|
||||
DUMP_FIELD(nt.OptionalHeader64.BaseOfCode);
|
||||
DUMP_FIELD(nt.OptionalHeader64.ImageBase);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SectionAlignment);
|
||||
DUMP_FIELD(nt.OptionalHeader64.FileAlignment);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.MajorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.MinorOperatingSystemVersion);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.Win32VersionValue);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfImage);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfHeaders);
|
||||
DUMP_FIELD(nt.OptionalHeader64.CheckSum);
|
||||
DUMP_FIELD(nt.OptionalHeader64.Subsystem);
|
||||
DUMP_FIELD(nt.OptionalHeader64.DllCharacteristics);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfStackReserve);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfStackCommit);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfHeapReserve);
|
||||
DUMP_FIELD(nt.OptionalHeader64.SizeOfHeapCommit);
|
||||
DUMP_FIELD(nt.OptionalHeader64.LoaderFlags);
|
||||
DUMP_DEC_FIELD(nt.OptionalHeader64.NumberOfRvaAndSizes);
|
||||
}
|
||||
|
||||
#undef DUMP_FIELD
|
||||
#undef DUMP_DEC_FIELD
|
||||
|
||||
std::cout << "Imports: "
|
||||
<< "\n";
|
||||
IterImpVAString(p, printImports, NULL);
|
||||
std::cout << "Relocations: "
|
||||
<< "\n";
|
||||
IterRelocs(p, printRelocs, NULL);
|
||||
std::cout << "Symbols (symbol table): "
|
||||
<< "\n";
|
||||
IterSymbols(p, printSymbols, NULL);
|
||||
std::cout << "Sections: "
|
||||
<< "\n";
|
||||
IterSec(p, printSecs, NULL);
|
||||
std::cout << "Exports: "
|
||||
<< "\n";
|
||||
IterExpVA(p, printExps, NULL);
|
||||
|
||||
// read the first 8 bytes from the entry point and print them
|
||||
VA entryPoint;
|
||||
if (GetEntryPoint(p, entryPoint)) {
|
||||
std::cout << "First 8 bytes from entry point (0x";
|
||||
|
||||
std::cout << std::hex << entryPoint << "):"
|
||||
std::cout << "Imports: "
|
||||
<< "\n";
|
||||
for (std::size_t i = 0; i < 8; i++) {
|
||||
std::uint8_t b;
|
||||
if (!ReadByteAtVA(p, i + entryPoint, b)) {
|
||||
std::cout << " ERR";
|
||||
} else {
|
||||
std::cout << " 0x" << std::hex << static_cast<int>(b);
|
||||
IterImpVAString(p, printImports, NULL);
|
||||
std::cout << "Relocations: "
|
||||
<< "\n";
|
||||
IterRelocs(p, printRelocs, NULL);
|
||||
std::cout << "Symbols (symbol table): "
|
||||
<< "\n";
|
||||
IterSymbols(p, printSymbols, NULL);
|
||||
std::cout << "Sections: "
|
||||
<< "\n";
|
||||
IterSec(p, printSecs, NULL);
|
||||
std::cout << "Exports: "
|
||||
<< "\n";
|
||||
IterExpVA(p, printExps, NULL);
|
||||
|
||||
// read the first 8 bytes from the entry point and print them
|
||||
VA entryPoint;
|
||||
if (GetEntryPoint(p, entryPoint)) {
|
||||
std::cout << "First 8 bytes from entry point (0x";
|
||||
std::cout << std::hex << entryPoint << "):"
|
||||
<< "\n";
|
||||
for (std::size_t i = 0; i < 8; i++) {
|
||||
std::uint8_t b;
|
||||
if (!ReadByteAtVA(p, i + entryPoint, b)) {
|
||||
std::cout << " ERR";
|
||||
} else {
|
||||
std::cout << " 0x" << std::hex << static_cast<int>(b);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
std::cout << "\n";
|
||||
std::cout << "Resources: "
|
||||
<< "\n";
|
||||
IterRsrc(p, printRsrc, NULL);
|
||||
|
||||
DestructParsedPE(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "Resources: "
|
||||
<< "\n";
|
||||
IterRsrc(p, printRsrc, NULL);
|
||||
|
||||
DestructParsedPE(p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -359,7 +359,9 @@ struct rich_header {
|
||||
std::vector<rich_entry> Entries;
|
||||
std::uint32_t EndSignature;
|
||||
std::uint32_t DecryptionKey;
|
||||
std::uint32_t Checksum;
|
||||
bool isPresent;
|
||||
bool isValid;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -157,6 +157,7 @@ uint64_t bufLen(bounded_buffer *b);
|
||||
struct parsed_pe_internal;
|
||||
|
||||
typedef struct _pe_header {
|
||||
dos_header dos;
|
||||
rich_header rich;
|
||||
nt_header_32 nt;
|
||||
} pe_header;
|
||||
@ -170,8 +171,8 @@ typedef struct _parsed_pe {
|
||||
// Resolve a Rich header product id / build number pair to a known
|
||||
// product name
|
||||
typedef std::pair<std::uint16_t, std::uint16_t> ProductKey;
|
||||
const std::string &GetRichProductName(std::uint16_t prodId,
|
||||
std::uint16_t buildNum);
|
||||
const std::string &GetRichObjectType(std::uint16_t prodId);
|
||||
const std::string &GetRichProductName(std::uint16_t buildNum);
|
||||
|
||||
// get parser error status as integer
|
||||
std::uint32_t GetPEErr();
|
||||
|
@ -123,20 +123,347 @@ struct parsed_pe_internal {
|
||||
std::vector<symbol> symbols;
|
||||
};
|
||||
|
||||
// The mapping of Rich header product id / build number pairs
|
||||
// to strings
|
||||
static const std::map<ProductKey, const std::string> ProductMap = {
|
||||
{std::make_pair(static_cast<std::uint16_t>(1),
|
||||
static_cast<std::uint16_t>(0)),
|
||||
"Imported Functions"}};
|
||||
// String representation of Rich header object types
|
||||
static const std::string kProdId_C = "[ C ]";
|
||||
static const std::string kProdId_CPP = "[C++]";
|
||||
static const std::string kProdId_RES = "[RES]";
|
||||
static const std::string kProdId_IMP = "[IMP]";
|
||||
static const std::string kProdId_EXP = "[EXP]";
|
||||
static const std::string kProdId_ASM = "[ASM]";
|
||||
static const std::string kProdId_LNK = "[LNK]";
|
||||
static const std::string kProdId_UNK = "[ ? ]";
|
||||
|
||||
// Mapping of Rich header Product ID to object type string
|
||||
// Source: https://github.com/dishather/richprint/blob/master/comp_id.txt
|
||||
static const std::map<std::uint16_t, std::string> ProductIdMap = {
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0000), kProdId_UNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0002), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0004), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0006), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x000A), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x000B), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x000F), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0015), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0016), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0019), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x001C), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x001D), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x003D), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x003F), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0040), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0045), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x005A), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x005C), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x005D), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x005E), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x005F), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0060), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x006D), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x006E), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0078), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x007A), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x007B), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x007C), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x007D), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0083), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0084), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0091), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0092), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0093), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0094), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0095), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x009A), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x009B), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x009C), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x009D), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x009E), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00AA), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00AB), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00C9), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CA), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CB), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CC), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CD), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CE), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00CF), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00DB), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00DC), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00DD), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00DE), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00DF), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00E0), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00E1), kProdId_CPP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x00FF), kProdId_RES)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0100), kProdId_EXP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0101), kProdId_IMP)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0102), kProdId_LNK)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0103), kProdId_ASM)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0104), kProdId_C)},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0105), kProdId_CPP)}};
|
||||
|
||||
// Mapping of Rich header build number to version strings
|
||||
static const std::map<std::uint16_t, const std::string> ProductMap = {
|
||||
// Source: https://github.com/dishather/richprint/blob/master/comp_id.txt
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0000), "Imported Functions")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0684),
|
||||
"VS97 v5.0 SP3 cvtres 5.00.1668")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x06B8),
|
||||
"VS98 v6.0 cvtres build 1720")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x06C8),
|
||||
"VS98 v6.0 SP6 cvtres build 1736")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x1C87),
|
||||
"VS97 v5.0 SP3 link 5.10.7303")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5E92),
|
||||
"VS2015 v14.0 UPD3 build 24210")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5E95),
|
||||
"VS2015 UPD3 build 24213")},
|
||||
|
||||
// http://bytepointer.com/articles/the_microsoft_rich_header.htm
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0BEC),
|
||||
"VS2003 v7.1 Free Toolkit .NET build 3052")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0C05),
|
||||
"VS2003 v7.1 .NET build 3077")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0FC3),
|
||||
"VS2003 v7.1 | Windows Server 2003 SP1 DDK build 4035")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x1C83), "MASM 6.13.7299")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x178E),
|
||||
"VS2003 v7.1 SP1 .NET build 6030")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x1FE8),
|
||||
"VS98 v6.0 RTM/SP1/SP2 build 8168")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x1FE9),
|
||||
"VB 6.0/SP1/SP2 build 8169")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x20FC), "MASM 6.14.8444")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x20FF),
|
||||
"VC++ 6.0 SP3 build 8447")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x212F),
|
||||
"VB 6.0 SP3 build 8495")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x225F),
|
||||
"VS 6.0 SP4 build 8799")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2263), "MASM 6.15.8803")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x22AD),
|
||||
"VB 6.0 SP4 build 8877")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2304),
|
||||
"VB 6.0 SP5 build 8964")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2306),
|
||||
"VS 6.0 SP5 build 8966")},
|
||||
// {std::make_pair(static_cast<std::uint16_t>(0x2346), "MASM 6.15.9030
|
||||
// (VS.NET 7.0 BETA 1)")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2346),
|
||||
"VS 7.0 2000 Beta 1 build 9030")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2354),
|
||||
"VS 6.0 SP5 Processor Pack build 9044")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2426),
|
||||
"VS2001 v7.0 Beta 2 build 9254")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x24FA),
|
||||
"VS2002 v7.0 .NET build 9466")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2636),
|
||||
"VB 6.0 SP6 / VC++ build 9782")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x26E3),
|
||||
"VS2002 v7.0 SP1 build 9955")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x520D),
|
||||
"VS2013 v12.[0,1] build 21005")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x521E),
|
||||
"VS2008 v9.0 build 21022")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x56C7),
|
||||
"VS2015 v14.0 build 22215")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x59F2),
|
||||
"VS2015 v14.0 build 23026")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5BD2),
|
||||
"VS2015 v14.0 UPD1 build 23506")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5D10),
|
||||
"VS2015 v14.0 UPD2 build 23824")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5E97),
|
||||
"VS2015 v14.0 UPD3.1 build 24215")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x7725),
|
||||
"VS2013 v12.0 UPD2 build 30501")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x766F),
|
||||
"VS2010 v10.0 build 30319")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x7809),
|
||||
"VS2008 v9.0 SP1 build 30729")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x797D),
|
||||
"VS2013 v12.0 UPD4 build 31101")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x9D1B),
|
||||
"VS2010 v10.0 SP1 build 40219")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x9EB5),
|
||||
"VS2013 v12.0 UPD5 build 40629")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC497),
|
||||
"VS2005 v8.0 (Beta) build 50327")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC627),
|
||||
"VS2005 v8.0 | VS2012 v11.0 build 50727")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC751),
|
||||
"VS2012 v11.0 Nov CTP build 51025")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC7A2),
|
||||
"VS2012 v11.0 UPD1 build 51106")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xEB9B),
|
||||
"VS2012 v11.0 UPD2 build 60315")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xECC2),
|
||||
"VS2012 v11.0 UPD3 build 60610")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xEE66),
|
||||
"VS2012 v11.0 UPD4 build 61030")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5E9A),
|
||||
"VS2015 v14.0 build 24218")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x61BB),
|
||||
"VS2017 v14.1 build 25019")},
|
||||
|
||||
// https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x2264),
|
||||
"VS 6 [SP5,SP6] build 8804")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x23D8), "Windows XP SP1 DDK")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x0883),
|
||||
"Windows Server 2003 DDK")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x08F4),
|
||||
"VS2003 v7.1 .NET Beta build 2292")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x9D76),
|
||||
"Windows Server 2003 SP1 DDK (for AMD64)")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x9E9F),
|
||||
"VS2005 v8.0 Beta 1 build 40607")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC427),
|
||||
"VS2005 v8.0 Beta 2 build 50215")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0xC490),
|
||||
"VS2005 v8.0 build 50320")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x50E2),
|
||||
"VS2008 v9.0 Beta 2 build 20706")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x501A),
|
||||
"VS2010 v10.0 Beta 1 build 20506")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x520B),
|
||||
"VS2010 v10.0 Beta 2 build 21003")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5089),
|
||||
"VS2013 v12.0 Preview build 20617")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x515B),
|
||||
"VS2013 v12.0 RC build 20827")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x527A),
|
||||
"VS2013 v12.0 Nov CTP build 21114")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x63A3),
|
||||
"VS2017 v15.3.3 build 25507")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x63C6),
|
||||
"VS2017 v15.4.4 build 25542")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x63CB),
|
||||
"VS2017 v15.4.5 build 25547")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x7674),
|
||||
"VS2013 v12.0 UPD2 RC build 30324")},
|
||||
|
||||
// https://walbourn.github.io/visual-studio-2015-update-2/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x5D6E),
|
||||
"VS2015 v14.0 UPD2 build 23918")},
|
||||
|
||||
// https://walbourn.github.io/visual-studio-2017/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x61B9),
|
||||
"VS2017 v15.[0,1] build 25017")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x63A2),
|
||||
"VS2017 v15.2 build 25019")},
|
||||
|
||||
// https://walbourn.github.io/vs-2017-15-5-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x64E6),
|
||||
"VS2017 v15 build 25830")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x64E7),
|
||||
"VS2017 v15.5.2 build 25831")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x64EA),
|
||||
"VS2017 v15.5.[3,4] build 25834")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x64EB),
|
||||
"VS2017 v15.5.[5,6,7] build 25835")},
|
||||
|
||||
// https://walbourn.github.io/vs-2017-15-6-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6610),
|
||||
"VS2017 v15.6.[0,1,2] build 26128")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6611),
|
||||
"VS2017 v15.6.[3,4] build 26129")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6613),
|
||||
"VS2017 v15.6.6 build 26131")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6614),
|
||||
"VS2017 v15.6.7 build 26132")},
|
||||
|
||||
// https://devblogs.microsoft.com/visualstudio/visual-studio-2017-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6723),
|
||||
"VS2017 v15.1 build 26403")},
|
||||
|
||||
// https://walbourn.github.io/vs-2017-15-7-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x673C),
|
||||
"VS2017 v15.7.[0,1] build 26428")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x673D),
|
||||
"VS2017 v15.7.2 build 26429")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x673E),
|
||||
"VS2017 v15.7.3 build 26430")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x673F),
|
||||
"VS2017 v15.7.4 build 26431")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6741),
|
||||
"VS2017 v15.7.5 build 26433")},
|
||||
|
||||
// https://walbourn.github.io/visual-studio-2019/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6B74),
|
||||
"VS2019 v16.0.0 build 27508")},
|
||||
|
||||
// https://walbourn.github.io/vs-2017-15-8-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6866),
|
||||
"VS2017 v15.8.0 build 26726")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6869),
|
||||
"VS2017 v15.8.4 build 26729")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x686A),
|
||||
"VS2017 v15.8.9 build 26730")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x686C),
|
||||
"VS2017 v15.8.5 build 26732")},
|
||||
|
||||
// https://walbourn.github.io/vs-2017-15-9-update/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x698F),
|
||||
"VS2017 v15.9.[0,1] build 27023")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6990),
|
||||
"VS2017 v15.9.2 build 27024")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6991),
|
||||
"VS2017 v15.9.4 build 27025")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6992),
|
||||
"VS2017 v15.9.5 build 27026")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6993),
|
||||
"VS2017 v15.9.7 build 27027")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6996),
|
||||
"VS2017 v15.9.11 build 27030")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6997),
|
||||
"VS2017 v15.9.12 build 27031")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6998),
|
||||
"VS2017 v15.9.14 build 27032")},
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x699A),
|
||||
"VS2017 v15.9.16 build 27034")},
|
||||
|
||||
// https://walbourn.github.io/visual-studio-2019/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6B74),
|
||||
"VS2019 v16.0.0 RTM build 27508")},
|
||||
|
||||
// https://walbourn.github.io/vs-2019-update-1/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6C36),
|
||||
"VS2019 v16.1.2 UPD1 build 27702")},
|
||||
|
||||
// https://walbourn.github.io/vs-2019-update-2/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6D01),
|
||||
"VS2019 v16.2.3 UPD2 build 27905")},
|
||||
|
||||
// https://walbourn.github.io/vs-2019-update-3/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x6DC9),
|
||||
"VS2019 v16.3.2 UPD3 build 28105")},
|
||||
|
||||
// https://walbourn.github.io/visual-studio-2013-update-3/
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x7803),
|
||||
"VS2013 v12.0 UPD3 build 30723")},
|
||||
|
||||
// experimentation
|
||||
{std::make_pair(static_cast<std::uint16_t>(0x685B),
|
||||
"VS2017 v15.8.? build 26715")},
|
||||
};
|
||||
|
||||
static const std::string kUnknownProduct = "<unknown>";
|
||||
|
||||
// Resolve a Rich header product id / build number pair to a known
|
||||
// product name
|
||||
const std::string &GetRichProductName(std::uint16_t prodId,
|
||||
std::uint16_t buildNum) {
|
||||
auto it = ProductMap.find(std::make_pair(prodId, buildNum));
|
||||
// Returns a stringified Rich header object type given a product id
|
||||
const std::string &GetRichObjectType(std::uint16_t prodId) {
|
||||
|
||||
auto it = ProductIdMap.find(prodId);
|
||||
if (it != ProductIdMap.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return kProdId_UNK;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a stringified Rich header product name given a build number
|
||||
const std::string &GetRichProductName(std::uint16_t buildNum) {
|
||||
|
||||
auto it = ProductMap.find(buildNum);
|
||||
if (it != ProductMap.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
@ -836,6 +1163,41 @@ bool readNtHeader(bounded_buffer *b, nt_header_32 &header) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// zero extends its first argument to 32 bits and then performs a rotate left
|
||||
// operation equal to the second arguments value of the first argument’s bits
|
||||
static inline std::uint32_t rol(std::uint32_t val, std::uint32_t num) {
|
||||
return ((val << num) & 0xffffffff) | (val >> (32 - num));
|
||||
}
|
||||
|
||||
std::uint32_t calculateRichChecksum(const bounded_buffer *b, pe_header &p) {
|
||||
|
||||
// First, calculate the sum of the DOS header bytes each rotated left the
|
||||
// number of times their position relative to the start of the DOS header e.g.
|
||||
// second byte is rotated left 2x using rol operation
|
||||
std::uint32_t checksum = 0;
|
||||
|
||||
for (uint8_t i = 0; i < RICH_OFFSET; i++) {
|
||||
|
||||
// skip over dos e_lfanew field at offset 0x3C
|
||||
if (i >= 0x3C && i <= 0x3F) {
|
||||
continue;
|
||||
}
|
||||
checksum += rol(b->buf[i], i);
|
||||
}
|
||||
|
||||
// Next, take summation of each Rich header entry by combining its ProductId
|
||||
// and BuildNumber into a single 32 bit number and rotating by its count.
|
||||
for (rich_entry entry : p.rich.Entries) {
|
||||
std::uint32_t num =
|
||||
static_cast<std::uint32_t>((entry.ProductId << 16) | entry.BuildNumber);
|
||||
checksum += rol(num, entry.Count & 0x1F);
|
||||
}
|
||||
|
||||
checksum += RICH_OFFSET;
|
||||
|
||||
return checksum;
|
||||
}
|
||||
|
||||
bool readRichHeader(bounded_buffer *rich_buf,
|
||||
std::uint32_t key,
|
||||
rich_header &rich_hdr) {
|
||||
@ -914,30 +1276,62 @@ bool readRichHeader(bounded_buffer *rich_buf,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readDosHeader(bounded_buffer *file, dos_header &dos_hdr) {
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
READ_WORD(file, 0, dos_hdr, e_magic);
|
||||
READ_WORD(file, 0, dos_hdr, e_cblp);
|
||||
READ_WORD(file, 0, dos_hdr, e_cp);
|
||||
READ_WORD(file, 0, dos_hdr, e_crlc);
|
||||
READ_WORD(file, 0, dos_hdr, e_cparhdr);
|
||||
READ_WORD(file, 0, dos_hdr, e_minalloc);
|
||||
READ_WORD(file, 0, dos_hdr, e_maxalloc);
|
||||
READ_WORD(file, 0, dos_hdr, e_ss);
|
||||
READ_WORD(file, 0, dos_hdr, e_sp);
|
||||
READ_WORD(file, 0, dos_hdr, e_csum);
|
||||
READ_WORD(file, 0, dos_hdr, e_ip);
|
||||
READ_WORD(file, 0, dos_hdr, e_cs);
|
||||
READ_WORD(file, 0, dos_hdr, e_lfarlc);
|
||||
READ_WORD(file, 0, dos_hdr, e_ovno);
|
||||
READ_WORD(file, 0, dos_hdr, e_res[0]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res[1]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res[2]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res[3]);
|
||||
READ_WORD(file, 0, dos_hdr, e_oemid);
|
||||
READ_WORD(file, 0, dos_hdr, e_oeminfo);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[0]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[1]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[2]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[3]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[4]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[5]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[6]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[7]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[8]);
|
||||
READ_WORD(file, 0, dos_hdr, e_res2[9]);
|
||||
READ_DWORD(file, 0, dos_hdr, e_lfanew);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getHeader(bounded_buffer *file, pe_header &p, bounded_buffer *&rem) {
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// start by reading MZ
|
||||
std::uint16_t tmp = 0;
|
||||
std::uint32_t curOffset = 0;
|
||||
if (!readWord(file, curOffset, tmp)) {
|
||||
PE_ERR(PEERR_READ);
|
||||
return false;
|
||||
}
|
||||
if (tmp != MZ_MAGIC) {
|
||||
// read the DOS header
|
||||
readDosHeader(file, p.dos);
|
||||
|
||||
if (p.dos.e_magic != MZ_MAGIC) {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the offset to the NT headers
|
||||
std::uint32_t offset;
|
||||
if (!readDword(file, _offset(dos_header, e_lfanew), offset)) {
|
||||
PE_ERR(PEERR_READ);
|
||||
return false;
|
||||
}
|
||||
curOffset += offset;
|
||||
// get the offset to the NT headers
|
||||
std::uint32_t offset = p.dos.e_lfanew;
|
||||
std::uint32_t curOffset = offset;
|
||||
|
||||
// read rich header
|
||||
std::uint32_t dword;
|
||||
@ -983,6 +1377,24 @@ bool getHeader(bounded_buffer *file, pe_header &p, bounded_buffer *&rem) {
|
||||
deleteBuffer(richBuf);
|
||||
}
|
||||
|
||||
// Split the DOS header into a separate buffer which
|
||||
// starts at offset 0 and has length 0x80
|
||||
bounded_buffer *dosBuf = splitBuffer(file, 0, RICH_OFFSET);
|
||||
if (dosBuf == nullptr) {
|
||||
return false;
|
||||
}
|
||||
// Calculate checksum
|
||||
p.rich.Checksum = calculateRichChecksum(dosBuf, p);
|
||||
if (p.rich.Checksum == p.rich.DecryptionKey) {
|
||||
p.rich.isValid = true;
|
||||
} else {
|
||||
p.rich.isValid = false;
|
||||
}
|
||||
if (dosBuf != nullptr) {
|
||||
deleteBuffer(dosBuf);
|
||||
}
|
||||
|
||||
// Rich header not present
|
||||
} else {
|
||||
p.rich.isPresent = false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user