您的位置:首页 > 其它

显示EXEDLL或PDB文件中指定函数的Parameter和local variables信息

2006-11-14 09:54 393 查看
显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息

//============================================================================
// LFVars : A small tool used to display function symbol informaton from EXE, DLL or PDB files
// L(ist)F(untion)Vars: list function parameters and local variabls.
// Author : zyq654321 --- Oct, 2004
// Comment: This is only a sample code to show you how to dump symbol information,
// you can improve it and your advise is appreciated.
#include <windows.h>
#include <TCHAR.h>
#define _NO_CVCONST_H // We should define the constant in order to ...
#include <dbghelp.h>
#include <stdio.h>

#pragma comment( lib, "dbghelp.lib" )

BOOL CALLBACK LFVarsCallback( SYMBOL_INFO* pSymInfo, ULONG SymbolSize, PVOID UserContext )
{
if( pSymInfo != 0 )
{
// Increase the counter of found local variables and parameters
if( UserContext != 0 )
*(int*)UserContext += 1;
// list parameters or variables
_tprintf(_T("Name: %s /n"),pSymInfo->Name);
_tprintf(_T(" Type: %s "),
(pSymInfo->Flags & SYMFLAG_PARAMETER) ? "Function Parameter" :
( (pSymInfo->Flags & SYMFLAG_LOCAL)? "Local Variable": "Unknown"));
TCHAR tcsReg[10];
switch(pSymInfo->Register)
{
case 17:
_tcscpy(tcsReg,_T("[EAX]"));
break;
case 18:
_tcscpy(tcsReg,_T("[ECX]"));
break;
case 19:
_tcscpy(tcsReg,_T("[EDX]"));
break;
case 20:
_tcscpy(tcsReg,_T("[EBX]"));
break;
case 21:
_tcscpy(tcsReg,_T("[ESP]"));
break;
case 22:
_tcscpy(tcsReg,_T("[EBP]"));
break;
case 23:
_tcscpy(tcsReg,_T("[ESI]"));
break;
case 24:
_tcscpy(tcsReg,_T("[EDI]"));
break;
default:
_tcscpy(tcsReg,_T("Unknown"));
break;
}
_tprintf( _T("Register: %s "), tcsReg );
UINT uMax = 0xFFFFFFFF;
_tprintf( _T("Address(Offset): %c0x%X "),
(LONG)pSymInfo->Address >= 0? ' ' : '-',
(LONG)pSymInfo->Address >= 0? pSymInfo->Address : (uMax - pSymInfo->Address + 1));
_tprintf( _T("Size: %d /n"), pSymInfo->Size);

//ShowSymbolDetails( *pSymInfo );
}

return TRUE; // Continue enumeration
}

int main( int argc, const TCHAR* argv[] )
{
if(argc < 3)
{
goto FAILED_PARAM;
}

// Set debug options
DWORD dwOpn = SymGetOptions();
dwOpn |= SYMOPT_DEBUG;
SymSetOptions(dwOpn);

// Initilaize the symbol handle for the current process
if(!SymInitialize( GetCurrentProcess(),
NULL,
FALSE ))
{
_tprintf(_T("Failed when SymInitialize():%d/n"), GetLastError());
return 0;
}

if( argv[1] == NULL || argv[2] == NULL)
{
goto FAILED_PARAM;
}

//------------------------------------------------------------------------
// Set initial parameters
TCHAR pszExt[MAX_PATH];
_tsplitpath( argv[1], NULL, NULL, NULL, pszExt );
DWORD64 dw64Base = 0; // if the image is a .pdb file, dw64Base cannot be zero.
// if the value is zero, the library obtains the load address
// from the symbol file.
DWORD dwFileSize = 0; // if the image is a .pdb file, dwFileSize cannot be zero.
// if the value is zero, the library obtains the size
// from the symbol file.

_tcslwr(pszExt);
if(_tcsicmp(pszExt, _T(".pdb")) == 0)
{
// this is a .pdb file, and so we should set the load address and file size;
dw64Base = 0x10000000;
// get the file size
HANDLE hFile = CreateFile( argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
if( INVALID_HANDLE_VALUE == hFile )
{
_tprintf(_T("Failed when open %s: %d"), argv[1], GetLastError());
goto FAILED_PARAM;
}
if( INVALID_FILE_SIZE == ( dwFileSize = GetFileSize(hFile, NULL) ))
{
_tprintf(_T("Failed when read the size of %s: %d"), argv[1], GetLastError());
goto FAILED_PARAM;
}
CloseHandle(hFile);
}

//------------------------------------------------------------------------
// Load symbol table
_tprintf(_T("Load %s...../n"), argv[1]);
DWORD64 dw64ModAddress = SymLoadModule64( GetCurrentProcess(),
NULL,
argv[1],
NULL,
dw64Base,
dwFileSize);

if( dw64ModAddress == 0 )
{
_tprintf(_T("Failed when SymLoadModule64(): %d /n"), GetLastError());
return 0;
}
_tprintf(_T("Load Address: %I64x /n"), dw64ModAddress);

//------------------------------------------------------------------------
// Display the function parameters and local variables according to the
// specified function name.
SYMBOL_INFO symInfo;
symInfo.SizeOfStruct = sizeof(SYMBOL_INFO);
if(! SymFromName( GetCurrentProcess(),
argv[2],
&symInfo) )
{
_tprintf( _T("Failed When SymFromName(): %d /n"), GetLastError() );
goto FAILED_AFTER_LOAD;
}

// We only need functon symbol
if( symInfo.Tag != SymTagFunction )
{
_tprintf( _T("Invalid Function Name or Not Found./n") );
goto FAILED_AFTER_LOAD;
}

// List funtion's parameters and its local variables
IMAGEHLP_STACK_FRAME stackFrm;
stackFrm.InstructionOffset = symInfo.Address;
if(!SymSetContext( GetCurrentProcess(),
&stackFrm,
0 ))
{
_tprintf( _T("Failed when SymSetContext: %d /n"), GetLastError() );
goto FAILED_AFTER_LOAD;
}

int nVarsCnt = 0;
if(!SymEnumSymbols( GetCurrentProcess(),
0,
0,
LFVarsCallback,
&nVarsCnt ) )
{
_tprintf( _T("Failed when SymEnumSymbols(): %d /n"), GetLastError() );
goto FAILED_AFTER_LOAD;
}

_tprintf( _T("%d function parmeters and local variables had been listed./n"), nVarsCnt );


FAILED_AFTER_LOAD:
//------------------------------------------------------------------------
// Unload symbols table
if(!SymUnloadModule64( GetCurrentProcess(), dw64ModAddress ))
{
_tprintf( _T("Failed when SymUnloadModule64() : %d /n"), GetLastError() );
}

if(!SymCleanup(GetCurrentProcess()))
{
_tprintf(_T("Failed when SymCleanup(): %d /n"), GetLastError());
return 0;
}


return 0;

FAILED_PARAM:
_tprintf(_T("Failed Parameter!/n"));
_tprintf(_T("Usage: LFVars -filename -function_name/n"));
_tprintf(_T("filename: a EXE, DLL or PDB file/n"));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: