Windbg调试之句柄泄露
1、首先,用C++写一个句柄泄露的样例程序:
#include "stdafx.h"
#include <windows.h>
void fun1(void);
void fun2(void);
void fun3(void);
void fun4(void);
int main(int argc, char* argv[])
{
while(1)
{
fun1(); 孝凤
fun2();
Sleep(100);
}
return 0;
}
void fun1(void)
{
fun3();
}
void fun2(void)
{
fun4();
}
void fun3(void)
{
HANDLE hEvent;
hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
CloseHandle(hEvent);
}
void fun4(void)
{
HANDLE hEvent2;
hEvent2 = CreateEvent(NULL,TRUE,TRUE,NULL);//这里只打开但是没关闭句柄
}
2、其次,进行菌选晃Windbg的调试,运行上面的程序,接着打开Windbg,点击”Attach to a Process”,如下所示:

3、选择刚刚运帮摸行的程序,如下所示:

4、接着打开Windbg安装目录下的gflags.exe工具,如下所示:

5、出现如下窗口:

6、这里设置勾上application verifiwer,该工具主要用来对程序做一些稳定性的检测,本次调试主要用于保存栈的相关信息,同时设置stack backtrace即栈的大小为10。关于具体gflags.exe的详细使用可以查看windbg帮助,如下所示:

7、设置完毕,此时切换到Windbg的界面上去,让程序运行起来,如下所示:

8、此时可以查看任务管理器里该进程的句柄信息,会发现该进程的句柄数目一直在增加,如下所示:

9、在windbg中用ctrl+break命令中断进程运行,笔记本则是Fn+Esc命令中断进程运行,用!htrace -enable命令开启句柄检测;htrace提供了进行句柄相关检测的命令,可查看windbg帮助,如下所示:

10、同时用g命令让程序运行,如下所示:

11、再次中断进程,使用!htrace -snapshot命令,获得此时进程句柄的镜像,并用g命令再次让程序运行,如下所示:

12、第三次中断进程运行,我们再使用!htrace -diff命令获得当前句柄状态与上一步 snapshot镜像句柄的差异,如下所示:

13、通过上面可以发现:新增很多打开的句柄,平常情况下这些打开的句柄有可能不是泄露,需要具体分析,但是本次示例程序太简单,所以刚好所有打开的句柄都属于泄露的。
使用lsa 传递指定位置对应的代码,lsa test!fun4+0x0000002e,如下所示:
