• Windbg命令学习14(dv)




    以下以自己的控件库skinhgy为例,windbg启动

    1.dv(display Local variable)

    dv 命令显示当前作用域的所有局部变量的名字和值。

    0:000> x Simple1Demo!CSimple1DemoApp::InitInstance
    00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void)
    0:000> bp 00640080 
    0:000> bl
     0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance
    0:000> g
    ModLoad: 62c20000 62c29000   C:\WINDOWS\system32\LPK.DLL
    ModLoad: 73fa0000 7400b000   C:\WINDOWS\system32\USP10.dll
    ModLoad: 5adc0000 5adf7000   C:\WINDOWS\system32\uxtheme.dll
    Breakpoint 0 hit
    eax=0062c312 ebx=7ffdd000 ecx=00b24d28 edx=00a765dc esi=0342f76e edi=0342f6f2
    eip=00640080 esp=0012fedc ebp=0012fefc iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    Simple1Demo!CSimple1DemoApp::InitInstance:
    00640080 55              push    ebp
    0:000> dv
               this = 0x0012fecc
                dlg = class CSimple1DemoDlg
          InitCtrls = struct tagINITCOMMONCONTROLSEX
          nResponse = -16843010
    


    我的代码是这样的:

    BOOL CSimple1DemoApp::InitInstance()
    {
    	INITCOMMONCONTROLSEX InitCtrls;
    	InitCtrls.dwSize = sizeof(InitCtrls);
    
    	InitCtrls.dwICC = ICC_WIN95_CLASSES;
    	InitCommonControlsEx(&InitCtrls);
    
    	CWinAppEx::InitInstance();
    
    	AfxEnableControlContainer();
    
    	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
    
    	m_hDll = LoadLibrary(TEXT("SkinHgy.dll"));
    	if (m_hDll)
    	{
    #ifdef UNICODE
    		SkinLoadFileSkin = (fun_SkinLoadFileSkin)GetProcAddress(m_hDll, "SkinLoadFileSkinW");
    #else
    		SkinLoadFileSkin = (fun_SkinLoadFileSkin)GetProcAddress(m_hDll, "SkinLoadFileSkinA");
    #endif
    		if (SkinLoadFileSkin)
    		{
    
    			TCHAR wcPath[MAX_PATH] = {0};
    			::GetModuleFileName(NULL, wcPath, MAX_PATH);
    			CString szSkinPath = wcPath;
    			szSkinPath = szSkinPath.Left(szSkinPath.ReverseFind('\\'));
    			szSkinPath += TEXT("\\skin\\skin.xml");
    
    			SkinLoadFileSkin(szSkinPath);
    		}
    	}
    
    	m_bDragFull = IsDragFullWindows();
    	if (m_bDragFull)
    	{
    		::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, FALSE, NULL, 0);
    	}
    
    	CSimple1DemoDlg dlg;
    	m_pMainWnd = &dlg;
    	INT_PTR nResponse = dlg.DoModal();
    	if (nResponse == IDOK)
    	{
    
    	}
    	else if (nResponse == IDCANCEL)
    	{
    
    	}
    
    	return FALSE;
    }
    


    我们可以看到,的确显示的四个局部变量,当然,出现的顺序可能并不一致,

    /i 使得输出中显示变量的类型:局部、全局、参数、函数或未知:
    0:000> dv /i
    prv local             this = 0x0012fecc
    prv local              dlg = class CSimple1DemoDlg
    prv local        InitCtrls = struct tagINITCOMMONCONTROLSEX
    prv local        nResponse = -16843010

    数据结构和陌生的数据类型不会完整显示,而只显示他们的类型名。要显示整个结构或结构中的特定成员,使用dt (Display Type)命令。

    0:000> dt InitCtrls
    Local var @ 0x12feb0 Type tagINITCOMMONCONTROLSEX
       +0x000 dwSize           : 0xb1c238
       +0x004 dwICC            : 4
    

    贴一下tagINITCOMMONCONTROLSEX的定义:

    typedef struct tagINITCOMMONCONTROLSEX {
        DWORD dwSize;             // size of this structure
        DWORD dwICC;              // flags indicating which classes to be initialized
    } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;

    我们继续F10单步调试,到了系统函数COMCTL32!InitCommonControlsEx中,F11进入,这时再dv

    0:000> t
    eax=0012feb0 ebx=7ffdd000 ecx=00b24d28 edx=00a765dc esi=0012f7c0 edi=0012fecc
    eip=77184088 esp=0012f7b8 ebp=0012fed8 iopl=0         nv up ei pl nz na po nc
    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
    COMCTL32!InitCommonControlsEx:
    77184088 8bff            mov     edi,edi
    0:000> dv
    Unable to enumerate locals, HRESULT 0x80004005
    Private symbols (symbols.pri) are required for locals.
    Type ".hh dbgerr005" for details.
    


    显示不了local,这是因为dv命令是显示当前函数的局部变量,而当前函数是系统的函数(比如ntdll!DbgBreakPoint),那么因为没有系统模块的私有符号,所以会出错。
    建议你切换到0号线程(~0s),然后使用单步或者gu命令执行到CSimple1Demo模块中的函数,然后再用dv命令

    我们dt this看看:

    0:000> dt this
    Local var @ 0x12fec0 Type CSimple1DemoApp*
    0x0012fecc 
       +0x000 __VFN_table : 0x0012fed8 
       =00a85844 CObject::classCObject : CRuntimeClass
       =00a78d54 CCmdTarget::classCCmdTarget : CRuntimeClass
       =00a78d18 CCmdTarget::_commandEntries : [1] AFX_OLECMDMAP_ENTRY
       =00a78d24 CCmdTarget::commandMap : AFX_OLECMDMAP
       =00a78c8c CCmdTarget::_dispatchEntries : [1] AFX_DISPMAP_ENTRY
       =00b1c484 CCmdTarget::_dispatchEntryCount : 0xffffffff
       =00b1c488 CCmdTarget::_dwStockPropMask : 0xffffffff ......................未完
    

    我们可以看到,第一个就是指向虚表的指针:__VFN_table

    补充点小细节,用dt /f <addr>可以用它来查看任何地方的任何代码处有些什么参数和局部变量。它会关闭对值得显示并隐含/V。/f 必须是最后一个标志

    0:000> dv /i /v /f VerifyTxSignDemo!WinMain
    prv param  @ebp+0x08       hInstance
    prv param  @ebp+0x0c   hPrevInstance
    prv param  @ebp+0x10       lpCmdLine
    prv param  @ebp+0x14        nCmdShow

    也可以使用通配符,注意用双引号

    0:000> dv /f  VerifyTxSignDemo!WinMain "*cmd*"
    @ebp+0x10       lpCmdLine
    @ebp+0x14        nCmdShow


     

  • 相关阅读:
    is 和 == 的区别,utf和gbk的转换,join用法
    python字典的整理信息
    poj分类
    cloud computing
    POJ1007 关于STL排序方法 动态数组的创建 和向量的使用
    math类
    研究生考试感想
    4.11
    重看设计模式 观察者模式
    子串计算 2010北京大学复试机试题
  • 原文地址:https://www.cnblogs.com/hgy413/p/3693516.html
Copyright © 2020-2023  润新知