mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
GT-2975 (Closes #674): Corrections, formatting, and certification
Pulled-from: Paul Moran <paul@paulsapps.com>
This commit is contained in:
parent
81b0f31f03
commit
5621f6965e
13 changed files with 264 additions and 284 deletions
|
@ -30,7 +30,7 @@ void fatal( const char * msg )
|
|||
}
|
||||
|
||||
void checkErr(HRESULT hResult) {
|
||||
if (SUCCEEDED(hResult)) {
|
||||
if (hResult == S_OK) {
|
||||
return;
|
||||
}
|
||||
switch (hResult) {
|
||||
|
|
|
@ -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,81 +48,85 @@ 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 ) ) ) {
|
||||
CComPtr<IDiaEnumSymbols> 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))) {
|
||||
fatal("Class findChildren failed");
|
||||
}
|
||||
long cnt = 0;
|
||||
if (pEnum != NULL && SUCCEEDED(pEnum->get_Count(&cnt)) && cnt > 0) { // Found a name.
|
||||
printNameFromScope(pclass, *pEnum);
|
||||
}
|
||||
}
|
||||
{
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
if (FAILED(myClass.findChildren(SymTagNull, name.c_str(), nsCaseSensitive, &pEnum))) {
|
||||
fatal("Class findChildren failed");
|
||||
}
|
||||
long cnt = 0;
|
||||
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found a name.
|
||||
printNameFromScope(myClass, *pEnum);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Check out the enumerations.
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaSymbol> pSym;
|
||||
if (FAILED(pclass.findChildren(SymTagEnum, NULL, nsNone, &pEnum))) {
|
||||
fatal("Class findChildren for enums failed");
|
||||
}
|
||||
{
|
||||
// Check out the enumerations.
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaSymbol> pSym;
|
||||
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.
|
||||
DWORD celt;
|
||||
while (SUCCEEDED(pEnum->Next(1, &pSym, &celt)) && celt == 1) {
|
||||
findNameInEnum(name, *pSym);
|
||||
pSym = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
long cnt = 0;
|
||||
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found an enum.
|
||||
DWORD celt;
|
||||
while (pEnum->Next(1, &pSym, &celt) == S_OK && celt == 1) {
|
||||
findNameInEnum(name, *pSym);
|
||||
pSym = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Check out the base classes.
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
{
|
||||
// Check out the base classes.
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
|
||||
if (FAILED(pclass.findChildren(SymTagBaseClass, NULL, nsNone, &pEnum))) {
|
||||
fatal("Class findChildren for base classes failed");
|
||||
}
|
||||
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.
|
||||
DWORD celt;
|
||||
CComPtr<IDiaSymbol> pSym;
|
||||
while (SUCCEEDED(pEnum->Next(1, &pSym, &celt)) && celt == 1) {
|
||||
CComPtr<IDiaSymbol> pClass;
|
||||
if (pSym->get_type(&pClass) == S_OK) {
|
||||
fatal("Getting class for a base type failed");
|
||||
}
|
||||
if (pClass) {
|
||||
findNameInClass(name, *pClass);
|
||||
}
|
||||
pSym = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
long cnt = 0;
|
||||
if (pEnum != NULL && pEnum->get_Count(&cnt) == S_OK && cnt > 0) { // Found a base class.
|
||||
DWORD celt;
|
||||
CComPtr<IDiaSymbol> pSym;
|
||||
while (pEnum->Next(1, &pSym, &celt) == S_OK && celt == 1) {
|
||||
CComPtr<IDiaSymbol> pClass;
|
||||
if (pSym->get_type(&pClass) != S_OK ) {
|
||||
fatal("Getting class for a base type failed");
|
||||
}
|
||||
if (pClass) {
|
||||
findNameInClass(name, *pClass);
|
||||
}
|
||||
pSym = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,21 +137,21 @@ 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;
|
||||
long cnt = 0;
|
||||
CComPtr<IDiaSymbol> pSym;
|
||||
CComPtr<IDiaSymbol> pParent;
|
||||
CComPtr<IDiaSymbol> pscope;
|
||||
for ( pscope = &pScope; pscope != NULL; ) {
|
||||
CComPtr<IDiaSymbol> pParent;
|
||||
CComPtr<IDiaSymbol> pscope;
|
||||
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 {
|
||||
|
|
|
@ -16,22 +16,22 @@
|
|||
*/
|
||||
#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) {
|
||||
break;
|
||||
}
|
||||
std::wstring name = getName(*pMember);
|
||||
std::wstring name = getName(*pMember);
|
||||
std::wstring value = getValue(*pMember);
|
||||
printf("%S<member name=\"%S\" value=\"%S\" />\n", indent(12).c_str(), name.c_str(), value.c_str());
|
||||
pMember = 0;
|
||||
|
@ -41,14 +41,14 @@ static void iterateEnumMembers(IDiaSymbol& pSymbol) {
|
|||
void iterateEnums(PDBApiContext& ctx) {
|
||||
DWORD celt = 0;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaSymbol> pSymbol;
|
||||
CComPtr<IDiaSymbol> pSymbol;
|
||||
ctx.Global().findChildren(SymTagEnum, NULL, nsNone, &pEnum);
|
||||
if (pEnum == NULL) {
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
|
@ -140,7 +140,7 @@ void iterateDataTypes(PDBApiContext& ctx) {
|
|||
|
||||
void iterateTypedefs(PDBApiContext& ctx) {
|
||||
DWORD celt = 0;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
ctx.Global().findChildren(SymTagTypedef, NULL, nsNone/*nsfCaseInsensitive|nsfUndecoratedName*/, &pEnum);
|
||||
if (pEnum == NULL) {
|
||||
return;
|
||||
|
@ -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) {
|
||||
|
@ -167,7 +167,7 @@ void iterateTypedefs(PDBApiContext& ctx) {
|
|||
|
||||
void iterateClasses(PDBApiContext& ctx) {
|
||||
DWORD celt = 0;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
ctx.Global().findChildren(SymTagUDT, NULL, nsNone/*nsfCaseInsensitive|nsfUndecoratedName*/, &pEnum);
|
||||
if (pEnum == NULL) {
|
||||
return;
|
||||
|
@ -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,27 +206,29 @@ 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;
|
||||
CComPtr<IDiaSymbol> pBlock;
|
||||
if ( FAILED(ctx.Session().findSymbolByRVA( rva, SymTagBlock, &pBlock ) ) ) {
|
||||
fatal( "Failed to find symbols by RVA" );
|
||||
}
|
||||
for ( ; pBlock != NULL; ) {
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
// Local data search
|
||||
if ( FAILED( pBlock->findChildren( SymTagNull, NULL, nsNone, &pEnum ) ) ) {
|
||||
fatal( "Local scope findChildren failed" );
|
||||
}
|
||||
CComPtr<IDiaSymbol> pSymbol;
|
||||
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",
|
||||
indent(12).c_str(),
|
||||
getName(*pSymbol).c_str(),
|
||||
getName(*pSymbol).c_str(),
|
||||
getKindAsString(*pSymbol).c_str(),
|
||||
getOffset(*pSymbol),
|
||||
getTypeAsString(*pSymbol).c_str(),
|
||||
|
@ -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 ) {
|
||||
|
@ -259,53 +261,52 @@ void dumpFunctionStackVariables( PDBApiContext& ctx, DWORD rva )
|
|||
break;
|
||||
}
|
||||
// Move to lexical parent.
|
||||
CComPtr<IDiaSymbol> pParent;
|
||||
if ( SUCCEEDED( pBlock->get_lexicalParent( &pParent ) ) && pParent != NULL ) {
|
||||
CComPtr<IDiaSymbol> pParent;
|
||||
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 ))) {
|
||||
CComPtr<IDiaEnumLineNumbers> 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) {
|
||||
break;
|
||||
}
|
||||
|
||||
CComPtr<IDiaSymbol> pComp;
|
||||
CComPtr<IDiaSymbol> pComp;
|
||||
pLine->get_compiland( &pComp );
|
||||
|
||||
CComPtr<IDiaSourceFile> pSrc;
|
||||
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,22 +316,22 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
void iterateFunctions(PDBApiContext& ctx) {
|
||||
DWORD celt = 0;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaSymbol> pSymbol;
|
||||
CComPtr<IDiaEnumSymbols> pEnum;
|
||||
CComPtr<IDiaSymbol> pSymbol;
|
||||
ctx.Global().findChildren(SymTagFunction, NULL, nsNone, &pEnum);
|
||||
if (pEnum == NULL) {
|
||||
return;
|
||||
}
|
||||
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,10 +340,11 @@ void iterateFunctions(PDBApiContext& ctx) {
|
|||
|
||||
const DWORD tag = getTag(*pSymbol);
|
||||
if (tag != SymTagFunction) {//do not delete
|
||||
pSymbol = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
const DWORD address = getRVA(*pSymbol);
|
||||
const DWORD address = getRVA(*pSymbol);
|
||||
|
||||
printf("%S<function name=\"%S\" address=\"0x%x\" length=\"0x%I64x\">\n", indent(8).c_str(), findMangledName(ctx, *pSymbol).c_str(), address, getLength(*pSymbol));
|
||||
|
||||
|
@ -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 );
|
||||
CComPtr<IDiaSourceFile> pSourceFile;
|
||||
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 ) {
|
||||
CComPtr<IDiaSegment> pSegment;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -475,26 +471,21 @@ void iterateSections(PDBApiContext& ctx, IDiaEnumSectionContribs& pSecContribs)
|
|||
*/
|
||||
void iterateInjectedSource(IDiaEnumInjectedSources * pInjectedSrcs) {
|
||||
DWORD celt = 0;
|
||||
CComPtr<IDiaInjectedSource> pInjectedSrc;
|
||||
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,66 +524,59 @@ 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;
|
||||
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() );
|
||||
|
||||
CComPtr<IDiaEnumSymbols> pSymbols;
|
||||
CComPtr<IDiaEnumSourceFiles> pSourceFiles;
|
||||
CComPtr<IDiaEnumSegments> pSegments;
|
||||
CComPtr<IDiaEnumSectionContribs> pSecContribs;
|
||||
CComPtr<IDiaEnumInjectedSources> pInjectedSrcs;
|
||||
CComPtr<IDiaEnumFrameData> pEnumFrameData;
|
||||
CComPtr<IDiaEnumSymbols> pSymbols;
|
||||
CComPtr<IDiaEnumSourceFiles> pSourceFiles;
|
||||
CComPtr<IDiaEnumSegments> pSegments;
|
||||
CComPtr<IDiaEnumSectionContribs> pSecContribs;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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,12 +22,12 @@ 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]);
|
||||
printf("\nThe -fulloutput parameter must be specified in order for 'Sections' information to be output in the XML file.\n");
|
||||
printf("\nThe -fulloutput parameter must be specified in order for 'Sections' information to be output in the XML file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -37,8 +37,8 @@ std::wstring printVariant( VARIANT & v ) {
|
|||
return L"null";
|
||||
}
|
||||
|
||||
const int blen = 100;
|
||||
wchar_t variant[blen] = {};
|
||||
const int blen = 100;
|
||||
wchar_t variant[blen] = {};
|
||||
switch( v.vt ) {
|
||||
case VT_ARRAY://Indicates a SAFEARRAY pointer.
|
||||
swprintf_s(variant, blen, L"%I64d", (ULONGLONG) v.parray);//TODO
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +132,7 @@ std::wstring printType( IDiaSymbol * pType, const std::wstring& suffix ) {
|
|||
DWORD tag = getTag(*pType);
|
||||
|
||||
if ( tag == SymTagPointerType ) {
|
||||
CComPtr<IDiaSymbol> pBaseType;
|
||||
CComPtr<IDiaSymbol> pBaseType;
|
||||
if ( pType->get_type( &pBaseType ) == S_OK ) {
|
||||
return printType(pBaseType, suffix + L" *");
|
||||
}
|
||||
|
@ -148,7 +146,7 @@ std::wstring printType( IDiaSymbol * pType, const std::wstring& suffix ) {
|
|||
}
|
||||
|
||||
if ( tag == SymTagArrayType ) {
|
||||
CComPtr<IDiaSymbol> pBaseType = getType( *pType );
|
||||
CComPtr<IDiaSymbol> pBaseType = getType( *pType );
|
||||
if ( pBaseType == NULL ) {
|
||||
return L"";
|
||||
}
|
||||
|
@ -158,7 +156,7 @@ std::wstring printType( IDiaSymbol * pType, const std::wstring& suffix ) {
|
|||
lenElem = lenArray;
|
||||
}
|
||||
const size_t strLen = suffix.length() + 64 + 3; // length of suffix + wag_for_numeric_value + "[]\0"
|
||||
std::vector<wchar_t> str(strLen);
|
||||
std::vector<wchar_t> str(strLen);
|
||||
swprintf_s(str.data(), strLen, L"%s[%I64d]", suffix.c_str(), lenArray / lenElem);
|
||||
return printType(pBaseType, str.data());
|
||||
}
|
||||
|
@ -170,27 +168,27 @@ std::wstring printType( IDiaSymbol * pType, const std::wstring& suffix ) {
|
|||
if ( tag == SymTagCustomType ) {
|
||||
DWORD id = 0;
|
||||
DWORD rec = 0;
|
||||
GUID guid = GUID_NULL;
|
||||
if (pType->get_guid(&guid) == S_OK) {
|
||||
GUID guid = GUID_NULL;
|
||||
if ( pType->get_guid(&guid) == S_OK ) {
|
||||
const int maxGUIDStrLen = 64 + 1;
|
||||
std::vector<wchar_t> guidStr(maxGUIDStrLen);
|
||||
std::vector<wchar_t> guidStr(maxGUIDStrLen);
|
||||
if (StringFromGUID2(guid, guidStr.data(), maxGUIDStrLen) > 0) {
|
||||
return guidStr.data();
|
||||
return guidStr.data();
|
||||
}
|
||||
}
|
||||
else if ( pType->get_oemId( &id ) == S_OK && pType->get_oemSymbolId( &rec ) == S_OK ) {
|
||||
const size_t strLen = 256; // wag_for_2_hex_numbers "0xNNNNN:0xNNNNN"
|
||||
wchar_t str[strLen] = {};
|
||||
wchar_t str[strLen] = {};
|
||||
if (str != NULL) {
|
||||
swprintf_s(str, L"0x%x:0x%x", id, rec);
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
if ( !name.empty() ) {
|
||||
return name + suffix;
|
||||
return name + suffix;
|
||||
}
|
||||
|
||||
return L"Undefined";
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,19 +54,19 @@ const static std::wstring SYMBOL_TAG_STRINGS [] = {
|
|||
L"Thunk",
|
||||
L"CustomType",
|
||||
L"ManagedType",
|
||||
L"Dimension",
|
||||
L"CallSite",
|
||||
L"InlineSite",
|
||||
L"BaseInterface",
|
||||
L"VectorType",
|
||||
L"MatrixType",
|
||||
L"HLSLType",
|
||||
L"Caller",
|
||||
L"Callee",
|
||||
L"Export",
|
||||
L"HeapAllocationSite",
|
||||
L"CoffGroup",
|
||||
L"Inlinee",
|
||||
L"Dimension",
|
||||
L"CallSite",
|
||||
L"InlineSite",
|
||||
L"BaseInterface",
|
||||
L"VectorType",
|
||||
L"MatrixType",
|
||||
L"HLSLType",
|
||||
L"Caller",
|
||||
L"Callee",
|
||||
L"Export",
|
||||
L"HeapAllocationSite",
|
||||
L"CoffGroup",
|
||||
L"Inlinee",
|
||||
L""
|
||||
};
|
||||
|
||||
|
@ -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))) {
|
||||
bstr_t name;
|
||||
name.Attach(temp);
|
||||
std::wstring getName(IDiaSymbol& symbol) {
|
||||
bstr_t name;
|
||||
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) {
|
||||
std::wstring getUndecoratedName(IDiaSymbol& symbol) {
|
||||
bstr_t name;
|
||||
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
|
||||
bstr_t name;
|
||||
name.Attach(temp);
|
||||
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> pBaseType;
|
||||
if (SUCCEEDED(pSymbol.get_type( &pBaseType ))) {
|
||||
CComPtr<IDiaSymbol> getType(IDiaSymbol& symbol) {
|
||||
CComPtr<IDiaSymbol> pBaseType;
|
||||
if (symbol.get_type( &pBaseType ) == S_OK) {
|
||||
return pBaseType;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
std::wstring getTypeAsString(IDiaSymbol& pSymbol) {
|
||||
std::wstring typeStr ;
|
||||
CComPtr<IDiaSymbol> pType;
|
||||
if (SUCCEEDED(pSymbol.get_type( &pType ))) {
|
||||
std::wstring getTypeAsString(IDiaSymbol& symbol) {
|
||||
std::wstring typeStr ;
|
||||
CComPtr<IDiaSymbol> pType;
|
||||
if (symbol.get_type( &pType ) == S_OK) {
|
||||
typeStr = printType( pType, L"" );
|
||||
}
|
||||
else {
|
||||
|
@ -329,20 +325,20 @@ 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);
|
||||
switch(bt) {
|
||||
std::wstring getBaseTypeAsString(IDiaSymbol& symbol) {
|
||||
const ULONGLONG len = getLength(symbol);
|
||||
const DWORD bt = getBaseType(symbol);
|
||||
switch(bt) {
|
||||
case btInt:
|
||||
switch(len) {
|
||||
case 1: return L"char";
|
||||
|
@ -359,7 +355,7 @@ std::wstring getBaseTypeAsString(IDiaSymbol& pSymbol) {
|
|||
case 8: return L"__uint64";
|
||||
}
|
||||
break;
|
||||
case btFloat:
|
||||
case btFloat:
|
||||
switch(len) {
|
||||
case 4: return L"float";
|
||||
case 8: return L"double";
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue