GT-2975 (Closes #674): Corrections, formatting, and certification

Pulled-from: Paul Moran <paul@paulsapps.com>
This commit is contained in:
ghizard 2019-07-17 09:40:38 -04:00
parent 81b0f31f03
commit 5621f6965e
13 changed files with 264 additions and 284 deletions

View file

@ -2,6 +2,7 @@
Module.manifest||GHIDRA||||END|
build.gradle||GHIDRA||||END|
src/global/docs/README_PDB.html||GHIDRA||||END|
src/pdb/.editorconfig||GHIDRA||||END|
src/pdb/README.txt||GHIDRA||||END|
src/pdb/pdb.sln||GHIDRA||||END|
src/pdb/pdb.vcxproj||GHIDRA||||END|

View file

@ -30,7 +30,7 @@ void fatal( const char * msg )
}
void checkErr(HRESULT hResult) {
if (SUCCEEDED(hResult)) {
if (hResult == S_OK) {
return;
}
switch (hResult) {

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,11 +17,10 @@
#include <atlcomcli.h>
#include <comutil.h>
std::wstring findMangledName(PDBApiContext& ctx, IDiaSymbol& pFunction) {
const DWORD rva = getRVA(pFunction);
std::wstring findMangledName(PDBApiContext& ctx, IDiaSymbol& function) {
const DWORD rva = getRVA(function);
CComPtr<IDiaSymbol> pSymbol;
const HRESULT hr = ctx.Session().findSymbolByRVA(rva, SymTagPublicSymbol, &pSymbol);
if (SUCCEEDED(hr)) {
if (ctx.Session().findSymbolByRVA(rva, SymTagPublicSymbol, &pSymbol) == S_OK) {
const DWORD tag = getTag(*pSymbol);
if (tag == SymTagPublicSymbol) {//do not delete
const DWORD address = getRVA(*pSymbol);
@ -31,19 +29,16 @@ std::wstring findMangledName(PDBApiContext& ctx, IDiaSymbol& pFunction) {
}
}
}
return getName(pFunction);
return getName(function);
}
void findNameInNamespace(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol& pnamespace )
void findNameInNamespace(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol& myNamespace )
{
BSTR temp = NULL;
if (FAILED(pnamespace.get_name(&temp))) {
bstr_t bstrNamespace;
if (FAILED(myNamespace.get_name(bstrNamespace.GetAddress()))) {
fatal("Namespace get_name failed");
}
bstr_t bstrNamespace;
bstrNamespace.Attach(temp);
const std::wstring strNamespace(bstrNamespace.GetBSTR(), bstrNamespace.length());
const std::wstring fullName = strNamespace + L"::" + name;
@ -53,33 +48,35 @@ void findNameInNamespace(PDBApiContext& ctx, const std::wstring& name, IDiaSymbo
}
long cnt = 0;
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // Found a name.
if ( pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0 ) { // Found a name.
printNameFromScope(ctx.Global(), *pEnum );
}
}
void findNameInEnum( const std::wstring& name, IDiaSymbol& penumeration )
void findNameInEnum( const std::wstring& name, IDiaSymbol& enumeration )
{
CComPtr<IDiaEnumSymbols> pEnum;
if ( FAILED( penumeration.findChildren( SymTagData, name.c_str(), nsRegularExpression, &pEnum ) ) ) {
if ( FAILED( enumeration.findChildren( SymTagData, name.c_str(), nsRegularExpression, &pEnum ) ) ) {
fatal( "Enumeration findChildren failed" );
}
long cnt = 0;
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // Found a name.
printNameFromScope( penumeration, *pEnum );
if ( pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0 ) { // Found a name.
printNameFromScope( enumeration, *pEnum );
}
}
void findNameInClass( const std::wstring& name, IDiaSymbol& pclass )
// 20190716: TODO: Investigate... This function appears to be only called by
// itself and by findCppNameInScope, which currently appears to be unused.
void findNameInClass( const std::wstring& name, IDiaSymbol& myClass )
{
{
CComPtr<IDiaEnumSymbols> pEnum;
if (FAILED(pclass.findChildren(SymTagNull, name.c_str(), nsCaseSensitive, &pEnum))) {
if (FAILED(myClass.findChildren(SymTagNull, name.c_str(), nsCaseSensitive, &pEnum))) {
fatal("Class findChildren failed");
}
long cnt = 0;
if (pEnum != NULL && SUCCEEDED(pEnum->get_Count(&cnt)) && cnt > 0) { // Found a name.
printNameFromScope(pclass, *pEnum);
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found a name.
printNameFromScope(myClass, *pEnum);
}
}
@ -87,14 +84,14 @@ void findNameInClass( const std::wstring& name, IDiaSymbol& pclass )
// Check out the enumerations.
CComPtr<IDiaEnumSymbols> pEnum;
CComPtr<IDiaSymbol> pSym;
if (FAILED(pclass.findChildren(SymTagEnum, NULL, nsNone, &pEnum))) {
if (FAILED(myClass.findChildren(SymTagEnum, NULL, nsNone, &pEnum))) {
fatal("Class findChildren for enums failed");
}
long cnt = 0;
if (pEnum != NULL && SUCCEEDED(pEnum->get_Count(&cnt)) && cnt > 0) { // Found an enum.
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found an enum.
DWORD celt;
while (SUCCEEDED(pEnum->Next(1, &pSym, &celt)) && celt == 1) {
while (pEnum->Next(1, &pSym, &celt) == S_OK && celt == 1) {
findNameInEnum(name, *pSym);
pSym = 0;
}
@ -105,17 +102,17 @@ void findNameInClass( const std::wstring& name, IDiaSymbol& pclass )
// Check out the base classes.
CComPtr<IDiaEnumSymbols> pEnum;
if (FAILED(pclass.findChildren(SymTagBaseClass, NULL, nsNone, &pEnum))) {
if (FAILED(myClass.findChildren(SymTagBaseClass, NULL, nsNone, &pEnum))) {
fatal("Class findChildren for base classes failed");
}
long cnt = 0;
if (pEnum != NULL && SUCCEEDED(pEnum->get_Count(&cnt)) && cnt > 0) { // Found a base class.
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found a base class.
DWORD celt;
CComPtr<IDiaSymbol> pSym;
while (SUCCEEDED(pEnum->Next(1, &pSym, &celt)) && celt == 1) {
while (pEnum->Next(1, &pSym, &celt) == S_OK && celt == 1) {
CComPtr<IDiaSymbol> pClass;
if (pSym->get_type(&pClass) == S_OK) {
if (pSym->get_type(&pClass) != S_OK ) {
fatal("Getting class for a base type failed");
}
if (pClass) {
@ -127,7 +124,9 @@ void findNameInClass( const std::wstring& name, IDiaSymbol& pclass )
}
}
void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol& pScope )
// 20190716: TODO: Investigate... This code appears to be unused. Also see
// note on function findNameInClass.
void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol& scope )
{
// while ( scope ) {
// Scan the scope for a symbol.
@ -138,7 +137,7 @@ void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol
// }
printf( "Finding name \"%S\" in ", name.c_str() );
printScopeName( pScope );
printScopeName( scope );
printf( "\n" );
DWORD celt;
@ -146,13 +145,13 @@ void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol
CComPtr<IDiaSymbol> pSym;
CComPtr<IDiaSymbol> pParent;
CComPtr<IDiaSymbol> pscope;
for ( pscope = &pScope; pscope != NULL; ) {
for ( pscope = &scope; pscope != NULL; ) {
CComPtr<IDiaEnumSymbols> pEnum;
// Local data search
if ( FAILED( pscope->findChildren( SymTagNull, name.c_str(), nsCaseSensitive, &pEnum ) ) ) {
fatal( "Local scope findChildren failed" );
}
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // Found a name.
if ( pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0 ) { // Found a name.
printNameFromScope( *pscope, *pEnum );
}
pEnum = 0;
@ -160,8 +159,8 @@ void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol
if ( FAILED( pscope->findChildren( SymTagUsingNamespace, NULL, nsNone, &pEnum ) ) ) {
fatal( "Namespace findChildren failed" );
}
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // Found a namespace.
while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
if ( pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0 ) { // Found a namespace.
while ( pEnum->Next( 1, &pSym, &celt ) == S_OK && celt == 1 ) {
findNameInNamespace( ctx, name, *pSym );
pSym = 0;
}
@ -169,12 +168,12 @@ void findCppNameInScope(PDBApiContext& ctx, const std::wstring& name, IDiaSymbol
pEnum = 0;
// Check if this is a member function.
DWORD tag = SymTagNull;
if ( SUCCEEDED( pscope->get_symTag( &tag ) ) && tag == SymTagFunction && SUCCEEDED( pscope->get_classParent( &pParent ) ) && pParent != NULL ) {
if ( pscope->get_symTag( &tag ) == S_OK && tag == SymTagFunction && pscope->get_classParent( &pParent ) == S_OK && pParent != NULL ) {
findNameInClass( name, *pParent );
}
pParent = NULL;
// Move to lexical parent.
if ( SUCCEEDED( pscope->get_lexicalParent( &pParent ) ) && pParent != NULL ) {
if ( pscope->get_lexicalParent( &pParent ) == S_OK && pParent != NULL ) {
pscope = pParent;
}
else {

View file

@ -16,16 +16,16 @@
*/
#include "iterate.h"
static void iterateEnumMembers(IDiaSymbol& pSymbol) {
static void iterateEnumMembers(IDiaSymbol& symbol) {
DWORD celt = 0;
CComPtr<IDiaEnumSymbols> pEnum;
CComPtr<IDiaSymbol> pMember;
pSymbol.findChildren(SymTagNull, NULL, nsNone, &pEnum);
symbol.findChildren(SymTagNull, NULL, nsNone, &pEnum);
if (pEnum == NULL) {
return;
}
while (1) {
if (FAILED(pEnum->Next( 1, &pMember, &celt ))) {
if (pEnum->Next( 1, &pMember, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -48,7 +48,7 @@ void iterateEnums(PDBApiContext& ctx) {
}
printf("%S<enums>\n", indent(4).c_str());
while ( 1 ) {
if (FAILED(pEnum->Next( 1, &pSymbol, &celt ))) {
if (pEnum->Next( 1, &pSymbol, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -70,16 +70,16 @@ void iterateEnums(PDBApiContext& ctx) {
printf("%S</enums>\n", indent(4).c_str());
}
static void iterateMembers(IDiaSymbol& pSymbol) {
static void iterateMembers(IDiaSymbol& symbol) {
DWORD celt = 0;
CComPtr<IDiaEnumSymbols> pEnum;
pSymbol.findChildren(SymTagNull, NULL, nsNone, &pEnum);
symbol.findChildren(SymTagNull, NULL, nsNone, &pEnum);
if (pEnum == NULL) {
return;
}
while (1) {
CComPtr<IDiaSymbol> pMember;
if (FAILED(pEnum->Next(1, &pMember, &celt))) {
if (pEnum->Next(1, &pMember, &celt) != S_OK ) {
break;
}
if (celt != 1) {
@ -107,7 +107,7 @@ void iterateDataTypes(PDBApiContext& ctx) {
while (1) {
CComPtr<IDiaSymbol> pSymbol;
if (FAILED(pEnum->Next(1, &pSymbol, &celt))) {
if ( pEnum->Next(1, &pSymbol, &celt) != S_OK ) {
break;
}
if (celt != 1) {
@ -148,7 +148,7 @@ void iterateTypedefs(PDBApiContext& ctx) {
printf("%S<typedefs>\n", indent(4).c_str());
while ( 1 ) {
CComPtr<IDiaSymbol> pSymbol;
if (FAILED(pEnum->Next( 1, &pSymbol, &celt ))) {
if (pEnum->Next( 1, &pSymbol, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -175,7 +175,7 @@ void iterateClasses(PDBApiContext& ctx) {
printf("%S<classes>\n", indent(4).c_str());
while ( 1 ) {
CComPtr<IDiaSymbol> pSymbol;
if (FAILED(pEnum->Next( 1, &pSymbol, &celt ))) {
if (pEnum->Next( 1, &pSymbol, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -206,6 +206,8 @@ void iterateClasses(PDBApiContext& ctx) {
printf("%S</classes>\n", indent(4).c_str());
}
// This method still leaks memory--seemingly in the pEnum->Next() for
// certain symbol types (e.g., tag == 32 (inline))
void dumpFunctionStackVariables( PDBApiContext& ctx, DWORD rva )
{
CComPtr<IDiaSymbol> pBlock;
@ -221,7 +223,7 @@ void dumpFunctionStackVariables( PDBApiContext& ctx, DWORD rva )
CComPtr<IDiaSymbol> pSymbol;
DWORD tag;
DWORD celt;
while ( pEnum != NULL && SUCCEEDED( pEnum->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
while (pEnum != NULL && pEnum->Next(1, &pSymbol, &celt) == S_OK && celt == 1) {
pSymbol->get_symTag( &tag );
if ( tag == SymTagData ) {
printf("%S<stack_variable name=\"%S\" kind=\"%S\" offset=\"0x%x\" datatype=\"%S\" length=\"0x%I64x\" />\n",
@ -241,7 +243,7 @@ void dumpFunctionStackVariables( PDBApiContext& ctx, DWORD rva )
fatal( "Annotation findChildren failed" );
}
pSymbol = NULL;
while ( pValues != NULL && SUCCEEDED( pValues->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
while ( pValues != NULL && pValues->Next( 1, &pSymbol, &celt ) == S_OK && celt == 1 ) {
//TODO
//CComVariant value;
//if ( pSymbol->get_value( &value ) != S_OK ) {
@ -260,36 +262,37 @@ void dumpFunctionStackVariables( PDBApiContext& ctx, DWORD rva )
}
// Move to lexical parent.
CComPtr<IDiaSymbol> pParent;
if ( SUCCEEDED( pBlock->get_lexicalParent( &pParent ) ) && pParent != NULL ) {
if ( pBlock->get_lexicalParent( &pParent ) == S_OK ) {
pBlock = pParent;
}
else {
break;
//fatal( "Finding lexical parent failed." );
}
};
}
void dumpFunctionLines( IDiaSymbol& pSymbol, IDiaSession& pSession )
void dumpFunctionLines( IDiaSymbol& symbol, IDiaSession& session )
{
ULONGLONG length = 0;
DWORD isect = 0;
DWORD offset = 0;
pSymbol.get_addressSection( &isect );
pSymbol.get_addressOffset( &offset );
pSymbol.get_length( &length );
symbol.get_addressSection( &isect );
symbol.get_addressOffset( &offset );
symbol.get_length( &length );
if ( isect == 0 || length <= 0 ) {
return;
}
CComPtr<IDiaEnumLineNumbers> pLines;
if (FAILED(pSession.findLinesByAddr( isect, offset, static_cast<DWORD>( length ), &pLines ))) {
if (session.findLinesByAddr( isect, offset, static_cast<DWORD>( length ), &pLines ) != S_OK ) {
return;
}
DWORD celt = 0;
while ( 1 ) {
CComPtr<IDiaLineNumber> pLine;
if (FAILED(pLines->Next( 1, &pLine, &celt ))) {
if (pLines->Next( 1, &pLine, &celt ) != S_OK) {
break;
}
if (celt != 1) {
@ -302,10 +305,8 @@ void dumpFunctionLines( IDiaSymbol& pSymbol, IDiaSession& pSession )
CComPtr<IDiaSourceFile> pSrc;
pLine->get_sourceFile( &pSrc );
BSTR temp = NULL;
pSrc->get_fileName(&temp);
bstr_t sourceFileName;
sourceFileName.Attach(temp);
pSrc->get_fileName(sourceFileName.GetAddress());
DWORD addr = 0;
pLine->get_relativeVirtualAddress( &addr );
@ -315,7 +316,7 @@ void dumpFunctionLines( IDiaSymbol& pSymbol, IDiaSession& pSession )
DWORD end = 0;
pLine->get_lineNumberEnd( &end );
printf("%S<line_number source_file=\"%S\" start=\"0x%x\" end=\"0x%x\" addr=\"0x%x\" /> \n",
printf("%S<line_number source_file=\"%ws\" start=\"0x%x\" end=\"0x%x\" addr=\"0x%x\" /> \n",
indent(12).c_str(), sourceFileName.GetBSTR(), start, end, addr);
}
}
@ -330,7 +331,7 @@ void iterateFunctions(PDBApiContext& ctx) {
}
printf("%S<functions>\n", indent(4).c_str());
while ( 1 ) {
if (FAILED(pEnum->Next( 1, &pSymbol, &celt ))) {
if (pEnum->Next( 1, &pSymbol, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -339,6 +340,7 @@ void iterateFunctions(PDBApiContext& ctx) {
const DWORD tag = getTag(*pSymbol);
if (tag != SymTagFunction) {//do not delete
pSymbol = 0;
continue;
}
@ -360,7 +362,7 @@ void iterateSymbolTable(IDiaEnumSymbols * pSymbols) {
DWORD celt = 0;
while ( 1 ) {
CComPtr<IDiaSymbol> pSymbol;
if (FAILED(pSymbols->Next( 1, &pSymbol, &celt ))) {
if (pSymbols->Next( 1, &pSymbol, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
@ -378,7 +380,7 @@ void iterateSymbolTable(IDiaEnumSymbols * pSymbols) {
printf("tag=\"%S\" ", getTagAsString(*pSymbol).c_str());
printf("kind=\"%S\" ", getKindAsString(*pSymbol).c_str());
printf("index=\"0x%x\" ", getIndex(*pSymbol));
printf("undecorated=\"%ws\" ", getUndecoratedName(*pSymbol).c_str());
printf("undecorated=\"%S\" ", getUndecoratedName(*pSymbol).c_str());
printf("value=\"%S\" ", getValue(*pSymbol).c_str());
printf("datatype=\"%S\" ", getTypeAsString(*pSymbol).c_str());
printf(" />\n");
@ -386,17 +388,12 @@ void iterateSymbolTable(IDiaEnumSymbols * pSymbols) {
}
void iterateSourceFiles(IDiaEnumSourceFiles * pSourceFiles) {
HRESULT hr = S_OK;
DWORD celt = 0;
CComPtr<IDiaSourceFile> pSourceFile;
while ( SUCCEEDED( hr = pSourceFiles->Next( 1, &pSourceFile, &celt ) ) && celt == 1 ) {
BSTR temp = NULL;
pSourceFile->get_fileName( &temp );
while ( pSourceFiles->Next( 1, &pSourceFile, &celt ) == S_OK && celt == 1 ) {
bstr_t name;
name.Attach(temp);
DWORD id = 0;
pSourceFile->get_uniqueId( &id );
if ( name.GetAddress() != NULL ) {
if( (pSourceFile->get_fileName( name.GetAddress() ) == S_OK) && (pSourceFile->get_uniqueId( &id ) == S_OK) ) {
printf("%S<source_file name=\"%ws\" id=\"0x%x\" /> \n", indent(12).c_str(), name.GetBSTR(), id);
}
pSourceFile = NULL;
@ -411,10 +408,9 @@ void iterateSourceFiles(IDiaEnumSourceFiles * pSourceFiles) {
* information in the segment map.
*/
void iterateSegments(IDiaEnumSegments * pSegments) {
HRESULT hr = S_OK;
DWORD celt = 0;
CComPtr<IDiaSegment> pSegment;
while ( SUCCEEDED( hr = pSegments->Next( 1, &pSegment, &celt ) ) && celt == 1 ) {
while ( pSegments->Next( 1, &pSegment, &celt ) == S_OK && celt == 1 ) {
DWORD rva = 0;
DWORD seg = 0;
pSegment->get_addressSection( &seg );
@ -429,21 +425,21 @@ void iterateSegments(IDiaEnumSegments * pSegments) {
* that is, a contiguous block of memory contributed
* to the image by a compiland.
*/
void iterateSections(PDBApiContext& ctx, IDiaEnumSectionContribs& pSecContribs) {
void iterateSections(PDBApiContext& ctx, IDiaEnumSectionContribs& secContribs) {
DWORD celt = 0;
CComPtr<IDiaSymbol> pSym ;
CComPtr<IDiaSectionContrib> pSecContrib;
while ( 1 ) {
if (pSecContribs.Next( 1, &pSecContrib, &celt ) < 0 ) {
if (secContribs.Next( 1, &pSecContrib, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
break;
}
DWORD rva = 0;
if (SUCCEEDED(pSecContrib->get_relativeVirtualAddress( &rva ))) {
if (FAILED(ctx.Session().findSymbolByRVA( rva, SymTagNull, &pSym )) ) {
if (pSecContrib->get_relativeVirtualAddress( &rva ) == S_OK) {
if (ctx.Session().findSymbolByRVA( rva, SymTagNull, &pSym ) != S_OK ) {
pSym = NULL;
}
}
@ -453,7 +449,7 @@ void iterateSections(PDBApiContext& ctx, IDiaEnumSectionContribs& pSecContribs)
pSecContrib->get_addressSection( &isect );
pSecContrib->get_addressOffset( &offset );
pSecContrib = NULL;
if (FAILED(ctx.Session().findSymbolByAddr( isect, offset, SymTagNull, &pSym )) ) {
if (ctx.Session().findSymbolByAddr( isect, offset, SymTagNull, &pSym ) != S_OK ) {
pSym = NULL;
}
}
@ -478,23 +474,18 @@ void iterateInjectedSource(IDiaEnumInjectedSources * pInjectedSrcs) {
CComPtr<IDiaInjectedSource> pInjectedSrc;
while ( 1 ) {
const HRESULT hr = pInjectedSrcs->Next( 1, &pInjectedSrc, &celt );
if (FAILED(hr)) {
if (pInjectedSrcs->Next( 1, &pInjectedSrc, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
break;
}
BSTR fileNameTemp = NULL;
pInjectedSrc->get_filename(&fileNameTemp);
bstr_t filename;
filename.Attach(fileNameTemp);
pInjectedSrc->get_filename(filename.GetAddress());
BSTR objectNameTemp = NULL;
pInjectedSrc->get_objectFilename(&objectNameTemp);
bstr_t objectname;
objectname.Attach(objectNameTemp);
pInjectedSrc->get_objectFilename(objectname.GetAddress());
DWORD crc;
pInjectedSrc->get_crc(&crc);
@ -508,6 +499,8 @@ void iterateInjectedSource(IDiaEnumInjectedSources * pInjectedSrcs) {
objectname.GetBSTR(),
crc,
length);
pInjectedSrc = NULL;
}
}
@ -521,8 +514,7 @@ void iterateFrameData(IDiaEnumFrameData * pEnumFrameData) {
while ( 1 ) {
CComPtr<IDiaFrameData> pFrameData;
const HRESULT hr = pEnumFrameData->Next( 1, &pFrameData, &celt );
if (FAILED(hr)) {
if (pEnumFrameData->Next( 1, &pFrameData, &celt ) != S_OK) {
break;
}
if (celt != 1) {
@ -532,32 +524,27 @@ void iterateFrameData(IDiaEnumFrameData * pEnumFrameData) {
}
}
int iterateTables(PDBApiContext& ctx, bool printAll) {
void iterateTables(PDBApiContext& ctx, bool printAll) {
printf("%S<tables>\n", indent(4).c_str());
HRESULT hr = S_OK;
DWORD celt = 0;
CComPtr<IDiaEnumTables> pTables;
hr = ctx.Session().getEnumTables( &pTables );
if ( FAILED(hr) ) {
return hr;
if ( ctx.Session().getEnumTables( &pTables ) != S_OK ) {
return;
}
while ( 1 ) {
CComPtr<IDiaTable> pTable;
if (FAILED(pTables->Next( 1, &pTable, &celt ))) {
if (pTables->Next( 1, &pTable, &celt ) != S_OK ) {
break;
}
if (celt != 1) {
break;
}
BSTR nameTemp;
pTable->get_name( &nameTemp );
bstr_t name;
name.Attach(nameTemp);
pTable->get_name( name.GetAddress() );
printf("%S<table name=\"%ws\">\n", indent(8).c_str(), name.GetBSTR() );
@ -568,30 +555,28 @@ int iterateTables(PDBApiContext& ctx, bool printAll) {
CComPtr<IDiaEnumInjectedSources> pInjectedSrcs;
CComPtr<IDiaEnumFrameData> pEnumFrameData;
if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pSymbols) ) ) ) {
if ( pTable->QueryInterface(IID_PPV_ARGS(&pSymbols) ) == S_OK ) {
iterateSymbolTable(pSymbols);
}
else if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pSourceFiles) ) ) ) {
else if ( pTable->QueryInterface(IID_PPV_ARGS(&pSourceFiles) ) == S_OK ) {
iterateSourceFiles(pSourceFiles);
}
else if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pSegments)) ) ) {
else if ( pTable->QueryInterface(IID_PPV_ARGS(&pSegments)) == S_OK ) {
iterateSegments(pSegments);
}
else if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pSecContribs) ) ) ) {
else if ( pTable->QueryInterface(IID_PPV_ARGS(&pSecContribs) ) == S_OK ) {
if (printAll) {
iterateSections(ctx, *pSecContribs);
}
}
else if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pInjectedSrcs) ) ) ) {
else if ( pTable->QueryInterface(IID_PPV_ARGS(&pInjectedSrcs) ) == S_OK ) {
iterateInjectedSource(pInjectedSrcs);
}
else if ( SUCCEEDED( pTable->QueryInterface(IID_PPV_ARGS(&pEnumFrameData) ) ) ) {
else if ( pTable->QueryInterface(IID_PPV_ARGS(&pEnumFrameData) ) == S_OK ) {
iterateFrameData(pEnumFrameData);
}
printf("%S</table>\n", indent(8).c_str());
}
printf("%S</tables>\n", indent(4).c_str());
return 0;
}

View file

@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pdb.h"
#include "iterate.h"
#include <signal.h>
@ -23,8 +22,8 @@ void segvHandler(int /*sig*/) {
exit(1); // Just die - prevents OS from popping-up a dialog
}
int wmain(int argc, wchar_t ** argv) {
if ( (argc < 2) || (argc > 5) ) {
void doAllWork(int argc, wchar_t ** argv) {
if ((argc < 2) || (argc > 5)) {
printf("USAGE:\n");
printf("\tValidation: %S <input pdb file> <guid OR signature> <age> [-fulloutput]\n", argv[0]);
printf("\tNo Validation: %S <input pdb file> [-fulloutput]\n", argv[0]);
@ -43,23 +42,28 @@ int wmain(int argc, wchar_t ** argv) {
std::unique_ptr<PDBApiContext> pbdApiContext;
if (argc <= 3) { // argc is either 2 or 3
if ( (argc == 3) && (wcscmp(argv[2], L"-fulloutput") == 0) ) {
if ((argc == 3) && (wcscmp(argv[2], L"-fulloutput") == 0)) {
doPrintAll = true;
}
pbdApiContext = std::make_unique<PDBApiContext>(std::wstring(argv[1]), L"", L"");
} else { // argc is either 4 or 5
if ( (argc == 5) && (wcscmp(argv[4], L"-fulloutput") == 0) ) {
}
else { // argc is either 4 or 5
if ((argc == 5) && (wcscmp(argv[4], L"-fulloutput") == 0)) {
doPrintAll = true;
}
pbdApiContext = std::make_unique<PDBApiContext>(std::wstring(argv[1]), std::wstring(argv[2]), std::wstring(argv[3]));
}
iterateEnums(*pbdApiContext);
iterateDataTypes(*pbdApiContext);
iterateTypedefs(*pbdApiContext);
iterateClasses(*pbdApiContext);
iterateFunctions(*pbdApiContext);
iterateTables(*pbdApiContext, doPrintAll);
iterateFunctions(*pbdApiContext); // still leaks
iterateTables(*pbdApiContext, doPrintAll); // still leaks.
}
int wmain(int argc, wchar_t ** argv) {
// Doing work in separate method so that we can do memory snapshot profiling in main
// before and after the call to doAllWork().
doAllWork(argc, argv);
return 0;
}

View file

@ -78,10 +78,10 @@ int PDBApiContext::init(const std::wstring& szFilename, const std::wstring& szSi
}
checkErr(hr);
if (FAILED(pSource->openSession( &pSession ))) {
if (pSource->openSession( &pSession ) != S_OK) {
fatal("Unable to open session\n");
}
if (FAILED(pSession->get_globalScope( &pGlobal ))) {
if (pSession->get_globalScope( &pGlobal ) != S_OK) {
fatal("Unable to get global scope\n");
}
@ -99,12 +99,12 @@ int PDBApiContext::init(const std::wstring& szFilename, const std::wstring& szSi
int maxGUIDStrLen = 64;
std::wstring guidStr(maxGUIDStrLen, L'\0');
if (SUCCEEDED(pGlobal->get_guid( &currGUID ))) {
if (pGlobal->get_guid( &currGUID ) == S_OK) {
if (StringFromGUID2(currGUID, &guidStr[0], maxGUIDStrLen) <= 0) {
fatal("Unable to convert GUID\n");
}
if (FAILED(pGlobal->get_age( &currAge ))) {
if (pGlobal->get_age( &currAge ) != S_OK) {
fatal("Unable to get PDB age\n");
}
} else {

View file

@ -106,22 +106,20 @@ std::wstring printVariant( VARIANT & v ) {
}
}
void printBound( IDiaSymbol& pBound ) {
void printBound( IDiaSymbol& bound ) {
DWORD tag = 0;
BSTR nameTemp = NULL;
DWORD kind = 0;
pBound.get_symTag( &tag );
pBound.get_locationType( &kind );
bound.get_symTag( &tag );
bound.get_locationType( &kind );
bstr_t name;
if ( tag == SymTagData && kind == LocIsConstant ) {
//TODO
//CComVariant v;
//pBound->get_value( &v );
//printVariant( v );
}
else if ( pBound.get_name( &nameTemp ) == S_OK ) {
bstr_t name;
name.Attach(nameTemp);
else if ( bound.get_name( name.GetAddress()) == S_OK ) {
printf( "%ws", name.GetBSTR() );
}
}
@ -171,7 +169,7 @@ std::wstring printType( IDiaSymbol * pType, const std::wstring& suffix ) {
DWORD id = 0;
DWORD rec = 0;
GUID guid = GUID_NULL;
if (pType->get_guid(&guid) == S_OK) {
if ( pType->get_guid(&guid) == S_OK ) {
const int maxGUIDStrLen = 64 + 1;
std::vector<wchar_t> guidStr(maxGUIDStrLen);
if (StringFromGUID2(guid, guidStr.data(), maxGUIDStrLen) > 0) {
@ -200,14 +198,14 @@ void printScopeName( IDiaSymbol& pscope ) {
printf("<scope name=\"%S\" tag=\"%S\" />\n", getName( pscope ).c_str(), getTagAsString( pscope ).c_str());
}
void printNameFromScope( IDiaSymbol& pscope, IDiaEnumSymbols& pEnum ) {
void printNameFromScope( IDiaSymbol& scope, IDiaEnumSymbols& myEnum ) {
CComPtr<IDiaSymbol> pSym;
DWORD celt = 0;
while ( SUCCEEDED( pEnum.Next( 1, &pSym, &celt ) ) && celt == 1 ) {
wprintf( L"\t%s %s found in ", getTagAsString(*pSym).c_str(), getName(*pSym).c_str() );
printScopeName( pscope );
wprintf( L"\n" );
while ( myEnum.Next( 1, &pSym, &celt ) == S_OK && celt == 1 ) {
printf( "\t%S %S found in ", getTagAsString(*pSym).c_str(), getName(*pSym).c_str() );
printScopeName( scope );
printf( "\n" );
pSym = 0;
}
}

View file

@ -174,11 +174,9 @@ const static std::wstring BASIC_TYPE_STRINGS [] = {
L"char32_t"
};
std::wstring getName(IDiaSymbol& pSymbol) {
BSTR temp = NULL;
if (SUCCEEDED(pSymbol.get_name(&temp))) {
std::wstring getName(IDiaSymbol& symbol) {
bstr_t name;
name.Attach(temp);
if (symbol.get_name(name.GetAddress()) == S_OK) {
const std::wstring wstrName = std::wstring(name.GetBSTR(), name.length());
if (wstrName.empty()) {
return escapeXmlEntities(L"NONAME");
@ -186,20 +184,20 @@ std::wstring getName(IDiaSymbol& pSymbol) {
if (wstrName.find(L"unnamed-tag") != std::wstring::npos) {
DWORD symIndexId = 0;
if (FAILED(pSymbol.get_symIndexId(&symIndexId))) {
if (symbol.get_symIndexId(&symIndexId) != S_OK) {
symIndexId = 0;
}
const size_t length = 20; // length of: "<unnamed_NNNN>\0" + 1 extra
std::vector<wchar_t> str(20);
std::vector<wchar_t> str(length);
swprintf_s(str.data(), length, L"<unnamed_%04x>", symIndexId);
return escapeXmlEntities(str.data());
}
DWORD locType = 0;
ULONGLONG len = 0;
if (SUCCEEDED(pSymbol.get_locationType(&locType)) &&
if (symbol.get_locationType(&locType) == S_OK &&
locType == LocIsBitField &&
SUCCEEDED(pSymbol.get_length(&len))) {
symbol.get_length(&len) == S_OK) {
const size_t length = wstrName.length() + 4 + 32; // length of: name + ":0x\0" + wag_hex_numeric_str_len
std::vector<wchar_t> str(length);
swprintf_s(str.data(), length, L"%ws:0x%I64x", wstrName.c_str(), len);
@ -211,89 +209,87 @@ std::wstring getName(IDiaSymbol& pSymbol) {
return std::wstring();
}
std::wstring getUndecoratedName(IDiaSymbol& pSymbol) {
BSTR temp = NULL;
if (pSymbol.get_undecoratedName(&temp) == S_OK) {
// May also return S_FALSE which is not failure, however in this case there is no name
std::wstring getUndecoratedName(IDiaSymbol& symbol) {
bstr_t name;
name.Attach(temp);
if (symbol.get_undecoratedName(name.GetAddress()) == S_OK) {
// May also return S_FALSE which is not failure, however in this case there is no name
return escapeXmlEntities(std::wstring(name.GetBSTR(), name.length()));
}
return L"";
}
DWORD getRVA(IDiaSymbol& pSymbol) {
DWORD getRVA(IDiaSymbol& symbol) {
DWORD rva = 0;
pSymbol.get_relativeVirtualAddress( &rva );
symbol.get_relativeVirtualAddress( &rva );
return rva;
}
ULONGLONG getLength(IDiaSymbol& pSymbol) {
ULONGLONG getLength(IDiaSymbol& symbol) {
ULONGLONG len = 0;
pSymbol.get_length( &len );
symbol.get_length( &len );
return len;
}
DWORD getTag(IDiaSymbol& pSymbol) {
DWORD getTag(IDiaSymbol& symbol) {
DWORD tag = 0;
pSymbol.get_symTag( &tag );
symbol.get_symTag( &tag );
return tag;
}
std::wstring getTagAsString(IDiaSymbol& pSymbol) {
const DWORD tag = getTag(pSymbol);
std::wstring getTagAsString(IDiaSymbol& symbol) {
const DWORD tag = getTag(symbol);
if (tag > _countof(SYMBOL_TAG_STRINGS)) {
return L"";
}
return SYMBOL_TAG_STRINGS[tag];
}
DWORD getKind(IDiaSymbol& pSymbol) {
DWORD getKind(IDiaSymbol& symbol) {
DWORD kind = 0;
pSymbol.get_dataKind( &kind );
symbol.get_dataKind( &kind );
return kind;
}
DWORD getUdtKind(IDiaSymbol& pSymbol) {
DWORD getUdtKind(IDiaSymbol& symbol) {
DWORD kind = 0;
pSymbol.get_udtKind( &kind );
symbol.get_udtKind( &kind );
return kind;
}
std::wstring getKindAsString(IDiaSymbol& pSymbol) {
const DWORD tag = getTag(pSymbol);
std::wstring getKindAsString(IDiaSymbol& symbol) {
const DWORD tag = getTag(symbol);
if (tag == SymTagUDT) {
const DWORD kind = getUdtKind(pSymbol);
const DWORD kind = getUdtKind(symbol);
if (kind < _countof(UDT_KIND_STRINGS)) {
return UDT_KIND_STRINGS[kind];
}
return L"";
}
const DWORD dataKind = getKind(pSymbol);
const DWORD dataKind = getKind(symbol);
if (dataKind < _countof(DATA_KIND_STRINGS)) {
return DATA_KIND_STRINGS[dataKind];
}
return L"";
}
LONG getOffset(IDiaSymbol& pSymbol) {
LONG getOffset(IDiaSymbol& symbol) {
LONG offset = 0;
pSymbol.get_offset( &offset );
symbol.get_offset( &offset );
return offset;
}
DWORD getIndex(IDiaSymbol& pSymbol) {
DWORD getIndex(IDiaSymbol& symbol) {
DWORD index = 0;
pSymbol.get_symIndexId( &index );
symbol.get_symIndexId( &index );
return index;
}
std::wstring getValue(IDiaSymbol& pSymbol) {
if (getKind(pSymbol) == DataIsConstant) {
std::wstring getValue(IDiaSymbol& symbol) {
if (getKind(symbol) == DataIsConstant) {
VARIANT value;
HRESULT hr = pSymbol.get_value( &value );
if (hr == S_OK) {
value.vt = VT_EMPTY;
if (symbol.get_value( &value ) == S_OK) {
return printVariant( value );
}
}
return L"";
}
/*
BSTR getBaseTypeName(IDiaSymbol * pSymbol) {
BSTR getBaseTypeName(IDiaSymbol * symbol) {
IDiaSymbol * pBaseType;
if (pType->get_type( &pBaseType ) != 0) {
return NULL;
@ -310,17 +306,17 @@ BSTR getBaseTypeName(IDiaSymbol * pSymbol) {
}
*/
CComPtr<IDiaSymbol> getType(IDiaSymbol& pSymbol) {
CComPtr<IDiaSymbol> getType(IDiaSymbol& symbol) {
CComPtr<IDiaSymbol> pBaseType;
if (SUCCEEDED(pSymbol.get_type( &pBaseType ))) {
if (symbol.get_type( &pBaseType ) == S_OK) {
return pBaseType;
}
return NULL;
}
std::wstring getTypeAsString(IDiaSymbol& pSymbol) {
std::wstring getTypeAsString(IDiaSymbol& symbol) {
std::wstring typeStr ;
CComPtr<IDiaSymbol> pType;
if (SUCCEEDED(pSymbol.get_type( &pType ))) {
if (symbol.get_type( &pType ) == S_OK) {
typeStr = printType( pType, L"" );
}
else {
@ -329,19 +325,19 @@ std::wstring getTypeAsString(IDiaSymbol& pSymbol) {
return typeStr;
}
static DWORD getBaseType(IDiaSymbol& pSymbol) {
if (getTag(pSymbol) == SymTagBaseType) {
static DWORD getBaseType(IDiaSymbol& symbol) {
if (getTag(symbol) == SymTagBaseType) {
DWORD baseType = btNoType;
if (FAILED(pSymbol.get_baseType(&baseType))) {
if (symbol.get_baseType(&baseType) != S_OK) {
return btNoType;
}
return baseType;
}
return btNoType;
}
std::wstring getBaseTypeAsString(IDiaSymbol& pSymbol) {
const ULONGLONG len = getLength(pSymbol);
const DWORD bt = getBaseType(pSymbol);
std::wstring getBaseTypeAsString(IDiaSymbol& symbol) {
const ULONGLONG len = getLength(symbol);
const DWORD bt = getBaseType(symbol);
switch(bt) {
case btInt:
switch(len) {

View file

@ -23,6 +23,7 @@ std::wstring indent(size_t nSpaces) {
std::wstring escapeXmlEntities(const std::wstring& str) {
std::wstring escaped;
// Setting initial space; string operators will get more if needed.
escaped.reserve(str.length() * 2);
for (int i = 0 ; i < str.length(); ++i) {

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,6 +27,6 @@ void iterateEnums(PDBApiContext& ctx);
void iterateTypedefs(PDBApiContext& ctx);
void iterateClasses(PDBApiContext& ctx);
void iterateFunctions(PDBApiContext& ctx);
int iterateTables(PDBApiContext& ctx, bool printAll);
void iterateTables(PDBApiContext& ctx, bool printAll);
#endif

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.