BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
DebugDirWrapper.cpp
Go to the documentation of this file.
2#include <QtGlobal>
3
4using namespace pe;
5/*
6typedef struct _IMAGE_DEBUG_DIRECTORY {
7 DWORD Characteristics;
8 DWORD TimeDateStamp;
9 WORD MajorVersion;
10 WORD MinorVersion;
11 DWORD Type;
12 DWORD SizeOfData;
13 DWORD AddressOfRawData;
14 DWORD PointerToRawData;
15} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
16
17*/
18
20{
21 const size_t dirSize = this->getSize();
22 const size_t entriesCount = dirSize / sizeof(IMAGE_DEBUG_DIRECTORY);
23 if (cntr >= entriesCount) {
24 return false;
25 }
26
27 DebugDirEntryWrapper* dbgEntry = new DebugDirEntryWrapper(m_PE, this, cntr);
28 if (!dbgEntry || !dbgEntry->getPtr()) {
29 delete dbgEntry;
30 return false;
31 }
32 entries.push_back(dbgEntry);
33 return true;
34}
35
37{
38 for (auto itr = entries.begin(); itr != entries.end(); ++itr) {
39 DebugDirEntryWrapper* dbgEntry = dynamic_cast<DebugDirEntryWrapper*>(*itr);
40 if (!dbgEntry) continue;
41
42 bool isOk = false;
43 uint64_t typeVal = dbgEntry->getNumValue(DebugDirEntryWrapper::TYPE, &isOk);
44 if (isOk && typeVal == pe::DT_REPRO) {
45 return true;
46 }
47 }
48 return false;
49}
50//---
51
53{
54 if (this->getDebugStruct()) {
56 this->entries.push_back(cvWrapper);
57 }
58 return true;
59}
60
62{
63 return debugDir();
64}
65
67{
68 if (!getPtr()) return 0;
69 return sizeof(IMAGE_DEBUG_DIRECTORY);
70}
71
72void* DebugDirEntryWrapper::getFieldPtr(size_t fId, size_t subField)
73{
74 IMAGE_DEBUG_DIRECTORY* d = debugDir();
75 if (d == NULL) return NULL;
76
77 switch (fId) {
78 case CHARACTERISTIC: return &d->Characteristics;
79 case TIMESTAMP: return &d->TimeDateStamp;
80 case MAJOR_VER: return &d->MajorVersion;
81 case MINOR_VER: return &d->MinorVersion;
82 case TYPE: return &d->Type;
83 case DATA_SIZE: return &d->SizeOfData;
84 case RAW_DATA_ADDR: return &d->AddressOfRawData;
85 case RAW_DATA_PTR: return &d->PointerToRawData;
86 }
87 return this->getPtr();
88}
89
91{
92 switch (fieldId) {
93 case CHARACTERISTIC: return "Characteristics";
94 case TIMESTAMP: return (dbgRootDir && dbgRootDir->isRepro()) ? "ReproChecksum" :"TimeDateStamp";
95 case MAJOR_VER: return "MajorVersion";
96 case MINOR_VER: return "MinorVersion";
97 case TYPE: return "Type";
98 case DATA_SIZE: return "SizeOfData";
99 case RAW_DATA_ADDR: return "AddressOfRawData";
100 case RAW_DATA_PTR: return "PointerToRawData";
101 }
102 return getName();
103}
104
106{
107 switch (fieldId) {
108 case RAW_DATA_ADDR: return Executable::RVA;
109 case RAW_DATA_PTR: return Executable::RAW;
110 }
112}
113
115{
116 switch (type) {
117 case pe::DT_UNKNOWN : return "unknown";
118 case pe::DT_COFF : return "COFF";
119 case pe::DT_CODEVIEW : return "Visual C++ (CodeView)";
120 case pe::DT_FPO : return "Frame pointer omission";
121 case pe::DT_MISC : return "DBG file";
122 case pe::DT_EXCEPTION : return "A copy of .pdata section";
123 case pe::DT_FIXUP : return "Reserved";
124 case pe::DT_OMAP_TO_SRC : return "mapping from an RVA in image to an RVA in source image";
125 case pe::DT_OMAP_FROM_SRC : return "mapping from an RVA in source image to an RVA in image";
126 case pe::DT_BORLAND : return "Borland";
127 case pe::DT_RESERVED10 : return "Reserved";
128 case pe::DT_CLSID : return "CLSID";
129 case pe::DT_VC_FEATURE : return "VC Feature";
130 case pe::DT_POGO : return "POGO";
131 case pe::DT_ILTCG : return "ILTCG";
132 case pe::DT_MPX : return "MPX";
133 case pe::DT_REPRO : return "REPRO";
134 }
135 return "<Unknown>";
136}
137
139{
140 if (fieldId != TYPE) return "";
141
142 IMAGE_DEBUG_DIRECTORY* d = debugDir();
143 if (d == NULL) return NULL;
144
145 return translateType(d->Type);
146}
147
149{
150 IMAGE_DEBUG_DIRECTORY* d = this->debugDir();
151 if (d == NULL) return NULL;
152 if (d->Type != DT_CODEVIEW) {
153 return NULL;
154 }
155 offset_t rva = d->PointerToRawData;
156 size_t dirSize = d->SizeOfData;
157 return m_Exe->getContentAt(rva, Executable::RAW, dirSize);
158}
159
161{
162 BYTE* debugStr = getDebugStruct();
163 IMAGE_DEBUG_DIRECTORY* d = debugDir();
164 if (!debugStr || !d) return NULL;
165 if (d->SizeOfData < sizeof(DEBUG_RSDSI)) {
166 return NULL;
167 }
168 DEBUG_RSDSI* rdsi = (DEBUG_RSDSI*)debugStr;
169 if (rdsi->dwSig == CV_SIGNATURE_RSDS) {
170 return rdsi;
171 }
172 return NULL;
173}
174
176{
177 BYTE* debugStr = getDebugStruct();
178 IMAGE_DEBUG_DIRECTORY* d = debugDir();
179 if (!debugStr || !d) return NULL;
180 if (d->SizeOfData < sizeof(DEBUG_NB10)) {
181 return NULL;
182 }
183 DEBUG_NB10* nb = (DEBUG_NB10*)debugStr;
184 if (nb->cvHdr.CvSignature == CV_SIGNATURE_NB10) {
185 return nb;
186 }
187 return NULL;
188}
189//-------------------------
190
192{
193 DEBUG_RSDSI* rdsi = parentDir->getRDSI();
194 if (rdsi) {
195 return rdsi;
196 }
197 return parentDir->getNB10();
198}
199
201{
202 IMAGE_DEBUG_DIRECTORY* d = parentDir->debugDir();
203 if (d == NULL) return 0;
204 return d->SizeOfData;
205}
206
207void* DebugDirCVEntryWrapper::getFieldPtr(size_t fId, size_t subField)
208{
209 DEBUG_RSDSI* rdsi = parentDir->getRDSI();
210 if (rdsi) {
211 switch (fId) {
212 case F_CVDBG_SIGN: return &rdsi->dwSig;
213 case F_CVDBG_GUID: return &rdsi->guidSig;
214 case F_CVDBG_AGE: return &rdsi->age;
215 case F_CVDBG_PDB: return &rdsi->szPdb;
216 }
217 return rdsi;
218 }
219 DEBUG_NB10* dbg = parentDir->getNB10();
220 if (dbg) {
221 switch (fId) {
222 case F_CVDBG_SIGN: return &dbg->cvHdr.CvSignature;
223 case F_CVDBG_GUID: return &dbg->Signature;
224 case F_CVDBG_AGE: return &dbg->Age;
225 case F_CVDBG_PDB: return &dbg->PdbFileName;
226 }
227 return dbg;
228 }
229 return NULL;
230}
231
233{
234 DEBUG_RSDSI* rdsi = parentDir->getRDSI();
235 if (rdsi) {
236 QString chunk4 = "";
237 for (size_t i = 0; i < sizeof(rdsi->guidSig.Data4); i++) {
238 QString out;
239#if QT_VERSION >= 0x050000
240 out = QString().asprintf("%02X", rdsi->guidSig.Data4[i]);
241#else
242 out = QString().sprintf("%02X", rdsi->guidSig.Data4[i]);
243#endif
244 chunk4 += out;
245 }
246 QString chunk5 = "";
247 for (size_t i = 0; i < sizeof(rdsi->guidSig.Data5); i++) {
248 QString out;
249#if QT_VERSION >= 0x050000
250 out = QString().asprintf("%02X", rdsi->guidSig.Data5[i]);
251#else
252 out = QString().sprintf("%02X", rdsi->guidSig.Data5[i]);
253#endif
254 chunk5 += out;
255 }
256 QString out;
257#if QT_VERSION >= 0x050000
258 out = QString().asprintf("%08X-%04X-%04X-",
259 rdsi->guidSig.Data1,
260 rdsi->guidSig.Data2,
261 rdsi->guidSig.Data3);
262#else
263 out = QString().sprintf("%08X-%04X-%04X-",
264 rdsi->guidSig.Data1,
265 rdsi->guidSig.Data2,
266 rdsi->guidSig.Data3);
267#endif
268 return "{" + out + chunk4 + "-" + chunk5 + "}";
269 }
270
271 DEBUG_NB10* dbg = parentDir->getNB10();
272 if (dbg) {
273 QString out;
274#if QT_VERSION >= 0x050000
275 out = QString().asprintf("%04X", dbg->Signature);
276#else
277 out = QString().sprintf("%04X", dbg->Signature);
278#endif
279 return out;
280 }
281 return "";
282}
283
285{
286 DEBUG_RSDSI* rdsi = (DEBUG_RSDSI*)this->getPtr();
287 if (!rdsi) return "";
288
289 QString out;
290#if QT_VERSION >= 0x050000
291 out = QString().asprintf("%.4s", (char*)&rdsi->dwSig);
292#else
293 out = QString().sprintf("%.4s", (char*)&rdsi->dwSig);
294#endif
295 return out;
296}
297
299{
300 switch (fId) {
301 case F_CVDBG_SIGN: return "CvSig";
302 case F_CVDBG_GUID: return "Signature";
303 case F_CVDBG_AGE: return "Age";
304 case F_CVDBG_PDB: return "PDB";
305 }
306 return "";
307}
308
310{
311 DEBUG_RSDSI* rdsi = parentDir->getRDSI();
312 DEBUG_NB10* dbg = parentDir->getNB10();
313 if (!rdsi && !dbg) return "";
314
315 char *pdb = NULL;
316 if (rdsi) pdb = (char*)rdsi->szPdb;
317 if (dbg) pdb = (char*)dbg->PdbFileName;
318
319 switch (fId) {
320 case F_CVDBG_SIGN: return getSignature();
321 case F_CVDBG_GUID: return getGuidString();
322 case F_CVDBG_PDB: return pdb ? pdb : "";
323 }
324 return "";
325}
uint32_t bufsize_t
uint64_t offset_t
QString translateFieldContent(size_t fieldId)
virtual QString getFieldName(size_t fieldId)
QString getSignature()
@ F_CVDBG_SIGN
@ F_CVDBG_GUID
@ F_CVDBG_AGE
@ F_CVDBG_PDB
virtual void * getPtr()
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
QString getGuidString()
virtual bufsize_t getSize()
pe::DEBUG_RSDSI * getRDSI()
bool wrap()
virtual QString getName()
DebugDirWrapper * dbgRootDir
QString translateFieldContent(size_t fieldId)
virtual QString getFieldName(size_t fieldId)
virtual void * getPtr()
@ RAW_DATA_PTR
@ MINOR_VER
@ CHARACTERISTIC
@ TYPE
@ MAJOR_VER
@ DATA_SIZE
@ TIMESTAMP
@ RAW_DATA_ADDR
virtual bufsize_t getSize()
IMAGE_DEBUG_DIRECTORY * debugDir()
friend class DebugDirCVEntryWrapper
pe::DEBUG_NB10 * getNB10()
virtual void * getFieldPtr(size_t fieldId, size_t subField)
BYTE * getDebugStruct()
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
QString translateType(int type)
friend class DebugDirEntryWrapper
virtual bool loadNextEntry(size_t cntr)
virtual bufsize_t getSize()
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
std::vector< ExeNodeWrapper * > entries
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65