快乐小胖兔的一窟

用自己的方式过一生 --- zyq654321

VC知识库BLOG 首页 新随笔 联系 聚合 登录
  23 Posts :: 0 Stories :: 95 Comments :: 2 Trackbacks

公告

Welcome you

留言簿(4)

随笔分类

随笔档案

文章档案

相册

网站联接

BLOG友情链接

搜索

最新评论

阅读排行榜

评论排行榜

       上次写了列出EXE,DLLPDB文件中的符号信息,这次再贴一段代码。举例说明如何列举一指定函数的局部信息,即函数的参数和局部变量信息。呵呵,本人即不爱说废话,又怕打字太累。^_^,开门见山,来看下面代码吧。Enjoy!

//============================================================================

// 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;

}

呵呵,举了两个例子代码后。真正的有用的应该是如何建立自己的dubegging过程。空了,偶会整理一下,贴点更爽的例子。

 

 

posted on 2004-11-16 06:46 HERCULES BLOG 阅读(3184) 评论(7)  编辑 收藏

Feedback

# 收藏!!!!!!!!!!!!!!!!! 2004-11-16 09:04 开心小生
谢谢老大

# re: 源码例子:显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息 2004-11-16 21:38 周星星
dbghelp.h这个文件在哪里?

# re: 周** 2004-11-16 22:11 zyq654321
请看我的上上一篇文章。要下载最新的debugging tools for windows

# re: 源码例子:显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息 2004-12-16 22:58 flying
我运行时是用的user32.dll 的 MessageBoxW函数,总是在这里就出错了,请问一下为什么?谢谢!
// We only need functon symbol

if( symInfo.Tag != SymTagFunction )

{

_tprintf( _T("Invalid Function Name or Not Found.\n") );

goto FAILED_AFTER_LOAD;

}



# re: 源码例子:显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息 2005-03-22 11:37 zhangzhijun
你好
我想请教你一些关于dbghelp.dll使用方面的问题
我的联系方式有QQ41902243 MSN zzj5385@hotmail.com
谢谢

# 显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息[TrackBack] 2006-03-04 14:03 eaglenet
上次写了列出EXE,DLL或PDB文件中的符号信息,这次再贴一段代码。举例说明如何列举一指定函数的局部信息,即函数的参数和局部变量信息。呵呵,本人即不爱说废话,又怕打字太累。^_^,开门见山,来看下面代码吧。Enjoy!

eaglenet引用了该文章,地址:http://blog.csdn.net/eaglenet/archive/2006/03/04/615262.aspx

# re: 源码例子:显示EXE,DLL或PDB文件中指定函数的Parameter和local variables信息 2008-08-08 14:18 核动力机器人
无法通过

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]