编写windbg调试器扩展 入门篇2

    前面一篇是用sources和nmake组合编译生成调试器扩展,步骤比较繁琐,我相信读者应该更倾向于用IDE来编写代码。本篇有2个主题:1.将前面的代码移植到VS上,用IDE编译;2.调试生成的扩展命令。

1.移植代码到IDE

    这部分相对简单,所以放在开头。要用IDE代替nmake编译调试器扩展,只要把sources文件中的编译/链接选项复制到VS对应的选项中就可以了。

1.1.设置编译项:

    工程属性-C/C++-常规-附加包含目录中添加头文件的路径:C:\WinDDK\7600.16385.1\Debuggers\sdk\inc

1.2.设置链接项:

工程属性-链接器-输入-附加依赖项中添加库文件的路径:C:\WinDDK\7600.16385.1\Debuggers\sdk\lib\$(ARCH)\dbgeng.lib。对于运行在不同架构的调试器扩展要使用不同的ARCH,我的调试器扩展用于调试x86的程序,因此最终路径为:C:\WinDDK\7600.16385.1\Debuggers\sdk\lib\i386\dbgeng.lib.

上面的截图中"将模块添加到程序集",我在这里直接将exts/目录下的windbgExt.def文件添加进来。当然,你也可以不添加这项,直接在代码中声明导出函数即可。怎么选择取决于个人~

2.调试调试扩展

    写程序难免会出bug,出了bug就得通过调试器定位/解决。平时,我们都是用调试器附加到有问题的程序中调试代码;现在情况变了:windbg在加载扩展命令后变得岌岌可危,如何应对新问题?其实很简单:另起炉灶,新开一个windbg实例,attach到加载了扩展命令的有问题的windbg实例上,就能把新问题变成与调试普通代码一样了。扩展命令本身是Dll程序,通过windbg调用LoadLibrary加载,因此,调试扩展命令可以再细分为两种类型:1.调试Dll入口函数;2.调试其他导出函数,下面仍以demo程序dbgexts.dll为例分类讨论。为了加以区分,我们先做如下约定:加载扩展命令的windbg叫做调试器A,调试有问题的windbg的windbg叫做调试器B。

2.1.调试扩展命令入口函数

    在调试器A加载调试器扩展前,先运行调试器B,并使调试器B attach调试器A上。然后在调试器B中启用加载Dll事件,这样一旦调试器A加载了扩展命令dbgexts,调试器B就会捕捉到调试事件并中断。
以下输出来源于调试器B:
0:002> |.        ;查看当前进程
.  0	id: 2324	attach	name: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\windbg.exe
0:002> sxe ld dbgexts    ;启用Dll加载事件
0:007> lm        ;查看调试器A中已加载的模块(至少没加载dbgexts.dll)
start    end        module name
012a0000 01331000   windbg     (pdb symbols)          C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\sym\windbg.pdb\CC6E30603ED243FBB418BC2ED0F2FDC71\windbg.pdb
60d60000 6113b000   ext        (deferred)             
61d40000 621bc000   dbgeng     (deferred)             
64f60000 6509e000   dbghelp    (deferred)             
67050000 67109000   exts       (deferred)
...      
以下输出来源于调试器A:
0:004> .chain
Extension DLL chain:
    dbghelp: image 10.0.10586.15, API 10.0.6, built Fri Nov 20 12:39:22 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\dbghelp.dll]
    ext: image 10.0.10586.15, API 1.0.0, built Fri Nov 20 12:39:52 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\winext\ext.dll]
    exts: image 10.0.10586.15, API 1.0.0, built Fri Nov 20 12:39:08 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\WINXP\exts.dll]
    uext: image 10.0.10586.15, API 1.0.0, built Fri Nov 20 12:38:53 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\winext\uext.dll]
    ntsdexts: image 10.0.10586.15, API 1.0.0, built Fri Nov 20 13:08:00 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\WINXP\ntsdexts.dll]
从上面的输出可以看到目前调试器A尚未加载调试器扩展dbgExts.dll。
    调试器A一旦执行了.load命令,调试器B就会中断。这是加载符号,设置断点的好时机:
以下输出来源于调试器B:
0:001> .sympath+ C:\WinDDK\7600.16385.1\Debuggers\sdk\samples\exts\objchk_win7_x86\i386
Symbol search path is: SRV*;C:\Users\Administrator\Desktop\studio\windbgExt\Debug;
0:001> .reload
Reloading current modules
.....................................................
0:001> bl
 0 e 71981898     0001 (0001)  0:**** dbgexts!DebugExtensionInitialize+0x8
根据网上的资料介绍,调试器扩展的初始化函数原型为:
HRESULT
CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
于是我在这下了断点,并等待中断,按下F5以后很快就会中断到这个函数。

再次F5,调试器A才会从.load命令中返回。
以下输出来源于调试器A:
0:004> .load C:\WinDDK\7600.16385.1\Debuggers\sdk\samples\exts\objchk_win7_x86\i386\dbgexts.dll
Extension dll detected a break connected to X86
00 01c9fb64 7763ec87 ntdll!DbgBreakPoint
0:004> .chain
Extension DLL chain:
    C:\WinDDK\7600.16385.1\Debuggers\sdk\samples\exts\objchk_win7_x86\i386\dbgexts.dll: image 6.1.7600.16385, API 1.0.0, built Wed Aug 09 23:24:43 2017
        [path: C:\WinDDK\7600.16385.1\Debuggers\sdk\samples\exts\objchk_win7_x86\i386\dbgexts.dll]
    dbghelp: image 10.0.10586.15, API 10.0.6, built Fri Nov 20 12:39:22 2015
        [path: C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\dbghelp.dll]
    ext: image 10.0.10586.15, API 1.0.0, built Fri Nov 20 12:39:52 2015
对比前面调试器A运行.chain的输出,可以看到现在调试器A已经加载了dbgexts扩展。当然,这也可以从调试器B中获得信息:
以下输出来源于调试器B:
0:003> lml
start    end        module name
012a0000 01331000   windbg     (pdb symbols)          C:\Users\Administrator\Desktop
...
71980000 71989000   dbgexts    (private pdb symbols)  C:\Users\Administrator\Desktop\DevTools\windbg v10\x86\sym\dbgexts.pdb\C92C6D4B2699410CB2A62310F29351D41\dbgexts.pdb

2.2.调试其他导出函数

    调试自定义导出函数相对简单,前面已经加载了调试符号,只要在相应函数入口加断点即可,这里不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值