Skip to content

Commit

Permalink
Merge branch 'debug_refact' (Issue #12)
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Aug 29, 2022
2 parents f76bec6 + 758d0ad commit 0825ed7
Show file tree
Hide file tree
Showing 3 changed files with 286 additions and 4 deletions.
50 changes: 48 additions & 2 deletions parser/include/bearparser/pe/DebugDirWrapper.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "DataDirEntryWrapper.h"
#include "pe_undoc.h"

class DebugDirWrapper : public DataDirEntryWrapper
{
Expand Down Expand Up @@ -39,9 +40,54 @@ class DebugDirWrapper : public DataDirEntryWrapper
QString translateType(int type);
QString translateFieldContent(size_t fieldId);

private:
protected:
BYTE* getDebugStruct();
pe::DEBUG_RSDSI* getRDSI();
pe::DEBUG_NB10* getNB10();

IMAGE_DEBUG_DIRECTORY* debugDir();

void clear() {}
friend class DebugDirCVEntryWrapper;
};


class DebugDirCVEntryWrapper : public ExeNodeWrapper
{
public:
// fields :
enum FieldID {
NONE = FIELD_NONE,
F_CVDBG_SIGN,
F_CVDBG_GUID,
F_CVDBG_AGE,
F_CVDBG_PDB,
FIELD_COUNTER
};

DebugDirCVEntryWrapper(Executable* pe, DebugDirWrapper *_parentDir)
: ExeNodeWrapper(pe, _parentDir, 0)
{
this->parentDir = _parentDir;
}

// full structure boundaries
virtual void* getPtr();
virtual bufsize_t getSize();

virtual QString getName() { return "CodeView Info"; }
virtual size_t getFieldsCount() { return getPtr() ? FIELD_COUNTER : 0; }
virtual size_t getSubFieldsCount() { return 1; }

// specific field boundaries
virtual void* getFieldPtr(size_t fieldId, size_t subField = FIELD_NONE);
virtual QString getFieldName(size_t fieldId);
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField) { return Executable::NOT_ADDR; }

QString translateFieldContent(size_t fieldId);

//this wrapper only:
QString getGuidString();
QString getSignature();
private:
DebugDirWrapper* parentDir;
};
51 changes: 51 additions & 0 deletions parser/include/bearparser/pe/pe_undoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,57 @@ typedef struct _IMAGE_RICH_HEADER {
RICH_SIGNATURE richSign;
} IMAGE_RICH_HEADER, *PIMAGE_RICH_HEADER;


///---

//Debug Directory type: CodeView
#pragma pack (1)

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

#define CV_SIGNATURE_RSDS 0x53445352
#define CV_SIGNATURE_NB10 0x3031424E

typedef struct _RSDSI_GUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[2];
BYTE Data5[6];
} RSDSI_GUID;


// CodeView header
struct CV_HEADER
{
DWORD CvSignature; // NBxx
LONG Offset; // Always 0 for NB10
};

typedef struct _DEBUG_NB10
{
CV_HEADER cvHdr;
DWORD Signature; // seconds since 01.01.1970
DWORD Age; // an always-incrementing value
BYTE PdbFileName[1]; // zero terminated string with the name of the PDB file
} DEBUG_NB10, *PDEBUG_NB10;

typedef struct _DEBUG_RSDSI
{
/*000*/ DWORD dwSig;
/*004*/ RSDSI_GUID guidSig;
/*014*/ DWORD age;
/*018*/ BYTE szPdb[1];
/*324*/
} DEBUG_RSDSI, *PDEBUG_RSDSI;

#define RSDSI_SIZE sizeof (RSDSI)

#pragma pack () //#pragma pack (1)


}; //namespace pe

#include "../win_hdrs/poppack.h"
189 changes: 187 additions & 2 deletions parser/pe/DebugDirWrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "pe/DebugDirWrapper.h"
#include <QtGlobal>

using namespace pe;
/*
typedef struct _IMAGE_DEBUG_DIRECTORY {
DWORD Characteristics;
Expand All @@ -19,24 +21,29 @@ IMAGE_DEBUG_DIRECTORY* DebugDirWrapper::debugDir()
offset_t rva = getDirEntryAddress();

BYTE *ptr = m_Exe->getContentAt(rva, Executable::RVA, sizeof(IMAGE_DEBUG_DIRECTORY));
if (ptr == NULL) return NULL;
if (!ptr) return NULL;

return (IMAGE_DEBUG_DIRECTORY*) ptr;
}

bool DebugDirWrapper::wrap()
{
if (this->getDebugStruct()) {
DebugDirCVEntryWrapper *cvWrapper = new DebugDirCVEntryWrapper(m_Exe, this);
this->entries.push_back(cvWrapper);
}
return true;
}


void* DebugDirWrapper::getPtr()
{
return debugDir();
}

bufsize_t DebugDirWrapper::getSize()
{
if (getPtr() == NULL) return 0;
if (!getPtr()) return 0;
return sizeof(IMAGE_DEBUG_DIRECTORY);
}

Expand Down Expand Up @@ -122,3 +129,181 @@ QString DebugDirWrapper::translateFieldContent(size_t fieldId)
return translateType(d->Type);
}

BYTE* DebugDirWrapper::getDebugStruct()
{
IMAGE_DEBUG_DIRECTORY* d = debugDir();
if (d == NULL) return NULL;
if (d->Type != DT_CODEVIEW) {
return NULL;
}
offset_t rva = d->PointerToRawData;
size_t dirSize = d->SizeOfData;
return m_Exe->getContentAt(rva, Executable::RAW, dirSize);
}

DEBUG_RSDSI* DebugDirWrapper::getRDSI()
{
BYTE* debugStr = getDebugStruct();
IMAGE_DEBUG_DIRECTORY* d = debugDir();
if (!debugStr || !d) return NULL;
if (d->SizeOfData < sizeof(DEBUG_RSDSI)) {
return NULL;
}
DEBUG_RSDSI* rdsi = (DEBUG_RSDSI*)debugStr;
if (rdsi->dwSig == CV_SIGNATURE_RSDS) {
return rdsi;
}
return NULL;
}

pe::DEBUG_NB10* DebugDirWrapper::getNB10()
{
BYTE* debugStr = getDebugStruct();
IMAGE_DEBUG_DIRECTORY* d = debugDir();
if (!debugStr || !d) return NULL;
if (d->SizeOfData < sizeof(DEBUG_NB10)) {
return NULL;
}
DEBUG_NB10* nb = (DEBUG_NB10*)debugStr;
if (nb->cvHdr.CvSignature == CV_SIGNATURE_NB10) {
return nb;
}
return NULL;
}
//-------------------------

void* DebugDirCVEntryWrapper::getPtr()
{
DEBUG_RSDSI* rdsi = parentDir->getRDSI();
if (rdsi) {
return rdsi;
}
return parentDir->getNB10();
}

bufsize_t DebugDirCVEntryWrapper::getSize()
{
IMAGE_DEBUG_DIRECTORY* d = parentDir->debugDir();
if (d == NULL) return 0;
return d->SizeOfData;
}

void* DebugDirCVEntryWrapper::getFieldPtr(size_t fId, size_t subField)
{
DEBUG_RSDSI* rdsi = parentDir->getRDSI();
if (rdsi) {
switch (fId) {
case F_CVDBG_SIGN: return &rdsi->dwSig;
case F_CVDBG_GUID: return &rdsi->guidSig;
case F_CVDBG_AGE: return &rdsi->age;
case F_CVDBG_PDB: return &rdsi->szPdb;
}
return rdsi;
}
DEBUG_NB10* dbg = parentDir->getNB10();
if (dbg) {
switch (fId) {
case F_CVDBG_SIGN: return &dbg->cvHdr.CvSignature;
case F_CVDBG_GUID: return &dbg->Signature;
case F_CVDBG_AGE: return &dbg->Age;
case F_CVDBG_PDB: return &dbg->PdbFileName;
}
return dbg;
}
return NULL;
}

QString DebugDirCVEntryWrapper::getGuidString()
{
DEBUG_RSDSI* rdsi = parentDir->getRDSI();
if (rdsi) {
QString chunk4 = "";
for (size_t i = 0; i < sizeof(rdsi->guidSig.Data4); i++) {
QString out;
#if QT_VERSION >= 0x050000
out = QString().asprintf("%02X", rdsi->guidSig.Data4[i]);
#else
out = QString().sprintf("%02X", rdsi->guidSig.Data4[i]);
#endif
chunk4 += out;
}
QString chunk5 = "";
for (size_t i = 0; i < sizeof(rdsi->guidSig.Data5); i++) {
QString out;
#if QT_VERSION >= 0x050000
out = QString().asprintf("%02X", rdsi->guidSig.Data5[i]);
#else
out = QString().sprintf("%02X", rdsi->guidSig.Data5[i]);
#endif
chunk5 += out;
}
QString out;
#if QT_VERSION >= 0x050000
out = QString().asprintf("%08X-%04X-%04X-",
rdsi->guidSig.Data1,
rdsi->guidSig.Data2,
rdsi->guidSig.Data3);
#else
out = QString().sprintf("%08X-%04X-%04X-",
rdsi->guidSig.Data1,
rdsi->guidSig.Data2,
rdsi->guidSig.Data3);
#endif
return "{" + out + chunk4 + "-" + chunk5 + "}";
}

DEBUG_NB10* dbg = parentDir->getNB10();
if (dbg) {
QString out;
#if QT_VERSION >= 0x050000
out = QString().asprintf("%04X", dbg->Signature);
#else
out = QString().sprintf("%04X", dbg->Signature);
#endif
return out;
}
return "";
}

QString DebugDirCVEntryWrapper::getSignature()
{
DEBUG_RSDSI* rdsi = (DEBUG_RSDSI*)this->getPtr();
if (!rdsi) return "";

QString out;
#if QT_VERSION >= 0x050000
out = QString().asprintf("%.4s", (char*)&rdsi->dwSig);
#else
out = QString().sprintf("%.4s", (char*)&rdsi->dwSig);
#endif
return out;
}

QString DebugDirCVEntryWrapper::getFieldName(size_t fId)
{
switch (fId) {
case F_CVDBG_SIGN: return "CvSig";
case F_CVDBG_GUID: return "Signature";
case F_CVDBG_AGE: return "Age";
case F_CVDBG_PDB: return "PDB";
}
return "";
}

QString DebugDirCVEntryWrapper::translateFieldContent(size_t fId)
{
DEBUG_RSDSI* rdsi = parentDir->getRDSI();
DEBUG_NB10* dbg = parentDir->getNB10();
if (!rdsi && !dbg) return "";

char *pdb = NULL;
if (rdsi) pdb = (char*)rdsi->szPdb;
if (dbg) pdb = (char*)dbg->PdbFileName;

switch (fId) {
case F_CVDBG_SIGN: return getSignature();
case F_CVDBG_GUID: return getGuidString();
case F_CVDBG_PDB: return pdb ? pdb : "";
}
return "";
}

0 comments on commit 0825ed7

Please sign in to comment.