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

LFVars是一款小型工具,用于从EXE、DLL或PDB文件中显示指定函数的参数和局部变量信息。通过调用Windows API函数,LFVars能够加载符号表,并枚举目标函数的所有参数及局部变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//============================================================================
// 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;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值