MCPcopy Create free account
hub / github.com/ThirteenAG/WidescreenFixesPack / ExtractEmbeddedPDB

Function ExtractEmbeddedPDB

source/EmbedPDB/main.cpp:87–193  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

85}
86
87std::optional<std::vector<uint8_t>> ExtractEmbeddedPDB(const fs::path& filePath, bool forceScan)
88{
89 std::ifstream file(filePath, std::ios::binary | std::ios::ate);
90 if (!file) return {};
91
92 auto fileSize = file.tellg();
93 if (fileSize < 32) return {};
94
95 // --- Fast path: check the very end of the file ---
96 file.seekg(fileSize - std::streamoff(32));
97 std::array<uint8_t, 32> tail{};
98 file.read(reinterpret_cast<char*>(tail.data()), 32);
99
100 if (std::equal(kMagic.begin(), kMagic.end(), tail.begin() + 16))
101 {
102 uint64_t originalSize = *reinterpret_cast<uint64_t*>(tail.data());
103 uint64_t compressedSize = *reinterpret_cast<uint64_t*>(tail.data() + 8);
104
105 if (compressedSize == 0 || compressedSize > static_cast<uint64_t>(fileSize) - 32)
106 return {};
107
108 file.seekg(fileSize - std::streamoff(32) - std::streamoff(compressedSize));
109 std::vector<uint8_t> compressed(compressedSize);
110 file.read(reinterpret_cast<char*>(compressed.data()), compressedSize);
111
112 std::vector<uint8_t> decompressed;
113 if (DecompressData(compressed, originalSize, decompressed))
114 return decompressed;
115 }
116
117 // --- Signed PE path: check just before the Authenticode certificate ---
118 uint64_t secOffset = GetPESecurityOffset(file, fileSize);
119 if (secOffset >= 32)
120 {
121 // Signing tools may insert alignment padding (up to 7 bytes) before
122 // the certificate, so scan a small 64-byte window before it.
123 constexpr std::streamoff kScanWindow = 64;
124 auto scanStart = std::max(std::streamoff(0), std::streamoff(secOffset) - kScanWindow);
125 auto scanLen = static_cast<size_t>(std::streamoff(secOffset) - scanStart);
126
127 if (scanLen >= 32)
128 {
129 file.seekg(scanStart);
130 std::vector<uint8_t> buf(scanLen);
131 file.read(reinterpret_cast<char*>(buf.data()), scanLen);
132
133 if (file.good())
134 {
135 for (size_t pos = scanLen - 16; pos >= 16; --pos)
136 {
137 if (std::equal(kMagic.begin(), kMagic.end(), buf.begin() + pos))
138 {
139 uint64_t originalSize = *reinterpret_cast<uint64_t*>(buf.data() + pos - 16);
140 uint64_t compressedSize = *reinterpret_cast<uint64_t*>(buf.data() + pos - 8);
141
142 auto trailerFileOff = scanStart + std::streamoff(pos - 16);
143 if (compressedSize > 0 && compressedSize <= static_cast<uint64_t>(trailerFileOff))
144 {

Callers 1

ProcessFileFunction · 0.85

Calls 2

DecompressDataFunction · 0.85
GetPESecurityOffsetFunction · 0.85

Tested by

no test coverage detected