📄 dia2dump.cpp
字号:
} else if ( pType->get_oemId( &id ) == S_OK && pType->get_oemSymbolId( &rec ) == S_OK ) {
printf( "%x:%x", id, rec );
}
DWORD len = 0;
if ( pType->get_types( 0, &len, NULL ) == S_OK && len > 0 ) {
IDiaSymbol** psyms = new IDiaSymbol*[ len ];
pType->get_types( len, &len, psyms );
for ( DWORD i = 0; i < len; ++i ) {
printf( " <" );
printBasicType( psyms[i] );
printf( ">" );
psyms[i]->Release();
}
delete [] psyms;
}
len = 0;
if ( pType->get_dataBytes( 0, &len, NULL ) == S_OK && len > 0 ) {
BYTE* pdata = new BYTE[ len ];
pType->get_dataBytes( len, &len, pdata );
printf( "<data" );
for ( DWORD i = 0; i < len; ++i ) {
printf( " %02x", pdata[i] );
}
printf( " data>" );
delete [] pdata;
}
} else {
printf( "Type_%d",tag);
}
}
void dumpFunctionLines( IDiaSymbol* pSymbol, IDiaSession* pSession )
{
ULONGLONG length = 0;
DWORD isect = 0;
DWORD offset = 0;
pSymbol->get_addressSection( &isect );
pSymbol->get_addressOffset( &offset );
pSymbol->get_length( &length );
if ( isect != 0 && length > 0 ) {
CComPtr< IDiaEnumLineNumbers > pLines;
if ( SUCCEEDED( pSession->findLinesByAddr( isect, offset, static_cast<DWORD>( length ), &pLines ) ) ) {
CComPtr< IDiaLineNumber > pLine;
DWORD celt;
bool firstLine = true;
while ( SUCCEEDED( pLines->Next( 1, &pLine, &celt ) ) && celt == 1 ){
DWORD offset;
DWORD seg;
DWORD linenum;
CComPtr< IDiaSymbol > pComp;
CComPtr< IDiaSourceFile > pSrc;
pLine->get_compiland( &pComp );
pLine->get_sourceFile( &pSrc );
pLine->get_addressSection( &seg );
pLine->get_addressOffset( &offset );
pLine->get_lineNumber( &linenum );
printf( "\tline %d at 0x%x:0x%x\n", linenum, seg, offset );
pLine = NULL;
if ( firstLine ) {
// sanity check
CComPtr< IDiaEnumLineNumbers > pLinesByLineNum;
if ( SUCCEEDED( pSession->findLinesByLinenum( pComp, pSrc, linenum, 0, &pLinesByLineNum ) ) ) {
CComPtr< IDiaLineNumber > pLine;
DWORD celt;
while ( SUCCEEDED( pLinesByLineNum->Next( 1, &pLine, &celt ) ) && celt == 1 ){
DWORD offset;
DWORD seg;
DWORD linenum;
pLine->get_addressSection( &seg );
pLine->get_addressOffset( &offset );
pLine->get_lineNumber( &linenum );
printf( "\t\tfound line %d at 0x%x:0x%x\n", linenum, seg, offset );
pLine = NULL;
}
}
firstLine = false;
}
}
}
}
}
wchar_t* szTags[] = {
L"",
L"Executable (Global)",
L"Compiland",
L"CompilandDetails",
L"CompilandEnv",
L"Function",
L"Block",
L"Data",
L"Constant",
L"Label",
L"PublicSymbol",
L"UDT",
L"Enum",
L"FunctionType",
L"PointerType",
L"ArrayType",
L"BaseType",
L"Typedef",
L"BaseClass",
L"Friend",
L"FunctionArgType",
L"FuncDebugStart",
L"FuncDebugEnd",
L"UsingNamespace",
L"VTableShape",
L"VTable",
L"Custom",
L"Thunk",
L"CustomType",
L""
};
bool fTagScopes[] = {
false,
true,
true,
false,
false,
true,
true,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
};
wchar_t* szDataKinds[] = {
L"Unknown",
L"Local",
L"Static Local",
L"Parameter",
L"Object Pointer",
L"File Static",
L"Global",
L"Member",
L"Static Member",
L"Constant"
};
wchar_t* symbolTagName( DWORD tag )
{
if ( tag > SymTagNull && tag < SymTagMax )
return szTags[ tag ];
assert( false );
return L"Error!";
}
bool isScopeSym( DWORD tag )
{
if ( tag > SymTagNull && tag < SymTagMax )
return fTagScopes[ tag ];
assert( false );
return false;
}
void printScopeName( IDiaSymbol* pscope )
{
DWORD tag;
BSTR name;
if ( pscope->get_symTag( &tag ) != S_OK )
Fatal( "Internal error, getting SymTag" );
if ( pscope->get_name( &name ) != S_OK )
Fatal( "Internal error, getting name" );
if ( name == NULL ) {
wprintf( szTags[ tag ] );
return;
}
wprintf( L"%ws (%ws)", name, szTags[ tag ] );
freeString( name );
}
void PrintNameFromScope( wchar_t* name, IDiaSymbol* pscope, IDiaEnumSymbols* pEnum )
{
CComPtr< IDiaSymbol> pSym;
DWORD celt;
while ( SUCCEEDED( pEnum->Next( 1, &pSym, &celt ) ) && celt == 1 ) {
DWORD tag;
BSTR bstr;
if ( pSym->get_symTag( &tag ) != S_OK )
Fatal( "Internal error, no SymTag" );
if ( pSym->get_name( &bstr ) != S_OK )
Fatal( "Internal error, no name" );
// tagtype name found in name or scopeTag
wprintf( L"\t%ws %ws found in ", szTags[ tag ], bstr );
printScopeName( pscope );
wprintf( L"\n" );
freeString( bstr );
pSym = 0;
}
}
void FindNameInNamespace( wchar_t* name, IDiaSymbol* pnamespace )
{
wchar_t *buf = NULL;
BSTR szNamespace;
pnamespace->get_name( &szNamespace );
buf = new wchar_t[ wcslen( name ) + wcslen( szNamespace ) + 3];
wsprintfW( buf, L"%s::%s", szNamespace, name );
freeString( szNamespace );
CComPtr< IDiaEnumSymbols > pEnum;
if ( FAILED( pglobal->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) )
Fatal( "Namespace findChildren failed" );
long cnt = 0;
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // found a name!
PrintNameFromScope( name, pglobal, pEnum );
}
delete [] buf;
}
void FindNameInEnum( wchar_t* name, IDiaSymbol* penumeration )
{
CComPtr< IDiaEnumSymbols > pEnum;
if ( FAILED( penumeration->findChildren( SymTagData, name, nsRegularExpression, &pEnum ) ) )
Fatal( "Enumeration findChildren failed" );
long cnt = 0;
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // found a name!
PrintNameFromScope( name, penumeration, pEnum );
}
}
void FindNameInClass( wchar_t* name, IDiaSymbol* pclass )
{
CComPtr< IDiaEnumSymbols > pEnum;
if ( FAILED( pclass->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) )
Fatal( "Class findChildren failed" );
long cnt = 0;
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // found a name!
PrintNameFromScope( name, pclass, pEnum );
}
pEnum = 0;
// check out the enumerations
CComPtr< IDiaSymbol > pSym;
if ( FAILED( pclass->findChildren( SymTagEnum, NULL, nsNone, &pEnum ) ) )
Fatal( "Class findChildren for enums failed" );
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;
}
}
pEnum = 0;
// check out the base classes
if ( FAILED( pclass->findChildren( SymTagBaseClass, NULL, nsNone, &pEnum ) ) )
Fatal( "Class findChildren for base classes failed" );
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // found a base class!
DWORD celt;
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;
}
}
}
void FindCppNameInScope( wchar_t* name, IDiaSymbol* pScope )
{
// while ( scope ) {
// Scan the scope for a symbol.
// If any namespaces, then scan for name in namespace.
// If scope is a member function then
// scan class parent for member with name.
// scope = scope.parent;
// }
wprintf( L"Finding name \"%ws\" in ", name );
printScopeName( pScope );
wprintf( L"\n" );
DWORD celt;
long cnt = 0;
CComPtr< IDiaSymbol > pSym;
CComPtr< IDiaSymbol > pParent;
CComPtr< IDiaSymbol > pscope;
for ( pscope = pScope; pscope != NULL; ) {
CComPtr< IDiaEnumSymbols > pEnum;
// local data search
if ( FAILED( pscope->findChildren( SymTagNull, name, nsCaseSensitive, &pEnum ) ) )
Fatal( "Local scope findChildren failed" );
if ( pEnum != NULL && SUCCEEDED( pEnum->get_Count(&cnt) ) && cnt > 0 ) { // found a name!
PrintNameFromScope( name, pscope, pEnum );
}
pEnum = 0;
// look into any namespaces
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 ) {
FindNameInNamespace( name, pSym );
pSym = 0;
}
}
pEnum = 0;
// is this a member function?
DWORD tag = SymTagNull;
if ( SUCCEEDED( pscope->get_symTag( &tag ) )
&& tag == SymTagFunction
&& SUCCEEDED( pscope->get_classParent( &pParent ) )
&& pParent != NULL ) {
FindNameInClass( name, pParent );
}
pParent = NULL;
// move to lexical parent
if ( SUCCEEDED( pscope->get_lexicalParent( &pParent ) )
&& pParent != NULL ) {
pscope = pParent;
} else {
pscope = NULL;
}
pParent = NULL;
};
}
void dumpLocalVars( DWORD rva )
{
CComPtr< IDiaSymbol > pBlock;
if ( FAILED( psession->findSymbolByRVA( rva, SymTagBlock, &pBlock ) ) ) {
Fatal( "Failed to find symbols by RVA" );
}
CComPtr< IDiaSymbol > pscope;
for ( ; pBlock != NULL; ) {
CComPtr< IDiaEnumSymbols > pEnum;
// local data search
if ( FAILED( pBlock->findChildren( SymTagNull, NULL, nsNone, &pEnum ) ) )
Fatal( "Local scope findChildren failed" );
CComPtr< IDiaSymbol > pSymbol;
DWORD tag;
DWORD celt;
while ( pEnum != NULL && SUCCEEDED( pEnum->Next( 1, &pSymbol, &celt ) ) && celt == 1 ) {
pSymbol->get_symTag( &tag );
if ( tag == SymTagData ) {
BSTR name;
DWORD kind;
pSymbol->get_name( &name );
pSymbol->get_dataKind( &kind );
if ( name != NULL )
wprintf( L"\t%s (%s)\n", name, szDataKinds[ kind ] );
}
pSymbol = NULL;
}
pBlock->get_symTag( &tag );
if ( tag == SymTagFunction ) // stop when at function scope
break;
// move to lexical parent
CComPtr< IDiaSymbol > pParent;
if ( SUCCEEDED( pBlock->get_lexicalParent( &pParent ) )
&& pParent != NULL ) {
pBlock = pParent;
} else {
Fatal( "Finding lexical parent failed." );
}
};
}
DWORD PrintNameAddr( IDiaSymbol* pSym )
{
DWORD rva;
if ( pSym->get_relativeVirtualAddress( &rva ) != S_OK )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -