天天看點

windbg調試執行個體(4)--句柄洩露

    如果你不喜歡英文,那就可以看下面我蹩腳的解釋了。

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);//這裡隻打開但是沒關閉句柄

代碼非常簡單,明眼人一看就能看出哪裡有問題,那麼程式編譯後用windbg怎麼調出來呢? 

2、windbg調試

1)找到windbgs安裝目錄下的gflags.exe工具,該工具可用來打開windows自帶的一些調試選項,具體gflags.exe的詳細使用可以檢視windbg幫助;

這裡我們設定勾上application verifiwer,該工具主要可用來對程式做一些穩定性的檢測,本次調試主要用于儲存棧的相關資訊。同時設定stack backtrace即棧的大小為10.

2)運作windbg,打開第一步編譯的程式,并使其跑起來;此時你檢視任務管理器中的句柄資訊,會發行相應程序句柄一直在增加。

3)windbg用ctrl+break指令中斷程序運作,用!htrace -enable指令開啟句柄檢測;htrace提供了進行句柄相關檢測的指令,可檢視windbg幫助。

同時用g指令讓程式運作。

4)再次中斷程序,使用!htrace -snapshot指令,獲得此時程序句柄的鏡像。并再次讓程式運作。

5)第三次中斷程序運作,我們再使用!htrace -diff指令獲得目前句柄狀态與第4步 snapshot鏡像句柄的差異;

我們可以發現:新增很多打開的句柄,平常情況下這些打開的句柄有可能不是洩露,需要具體分析,但是本次示例程式太簡單,是以剛好所有打開的句柄都屬于洩露的。

6)我們使用lsa 傳遞指定位置對應的代碼,lsa  handlew2!fun4+0x0000002e

到這裡,我們就找到了洩露句柄的函數,真是神奇啊。