1、首先,用C++老揉孟阼写一个句柄泄露的样例程序:#include "stdafx.h"#include 媪青怍牙<windows.h>voidfun1(void);voidfun2(void);voidfun3(void);voidfun4(void);intmain(intargc,char*argv[]){while(1){fun1();fun2();Sleep(100);}return0;}voidfun1(void){fun3();}voidfun2(void){fun4();}voidfun3(void){HANDLEhEvent;hEvent=CreateEvent(NULL,TRUE,TRUE,NULL);CloseHandle(hEvent);}voidfun4(void){HANDLEhEvent2; hEvent2=CreateEvent(NULL,TRUE,TRUE,NULL);//这里只打开但是没关闭句柄}
2、其次,进行Windbg的调试,运行上面的程序,接着打开Windbg,点击”Attach to a Process”,如下所示:
3、选择刚刚运行的程序,如下所示:
4、接着打开Windbg安装目录下的gflags.exe工具,如下所示:
5、出现如下窗口:
6、这里设置勾上appl坡纠课柩ication 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嗒扬柰旦传递指定位置对应的代码,lsatest!fun4+0x0000002e,如下所示: