之前我曾提供了匯出stl map和set內容的windbg擴充套件指令庫,並給出了使用方法。授人以魚不如授人以漁,下面的文章將以開發乙個匯出cmap容器內容的windbg擴充套件指令cmap為例,介紹如果開發乙個windbg的擴充套件指令庫。
1. windbg擴充套件指令
windbg自身提供豐富的擴充套件指令,使得它的除錯功能十分強大。通常,我看到的以!開頭的指令就是擴充套件指令,而這些擴充套件指令大多由windbg安裝目錄下winext、winxp等子目錄中的dll匯出。
有時候我們也需要開發自己的擴充套件指令,用以方便地完成特殊的除錯任務。例如,我們很可能需要匯出乙個儲存了大量資料cmap容器的內容,開發乙個自己的cmap匯出指令會很方便地解決問題。
開發乙個擴充套件指令,實質上就是要按照debug engine定義的開發規範,開發乙個匯出了擴充套件指令的擴充套件dll。擴充套件dll可以分為3類,在windbg目錄下sdk\sample中提供了對應的簡單示例:
2. engextcpp擴充套件指令開發
engextcpp擴充套件指令是按照c++的語法進行開發,下面的內容將主要介紹如何開發這種型別的指令。在windbg官方幫助文件中有名為engextcpp extension design guide的專題對engextcpp擴充套件指令的開發做了一定的介紹,不一定適用,但是可以參考其中的基本概念。
2.1 建立完整的engextcpp工程
按照windbg官方幫助文件提供的開發方案,擴充套件外掛程式需要在ddk環境編譯,顯然比較麻煩。而且按照它的方法,我用ddk沒有成功編譯過它所提供的示例**。事實上,在vc環境中照樣能夠開發出擴充套件指令。下面就以在vs2008中開發乙個匯出cmap內容的
擴充套件指令cmap
為例,說明主要的過程。 1)
建立乙個空白的win32 dll工程。 2)
向工程新增
engextcpp.hpp和engextcpp.cpp兩個現有檔案,檔案所在路徑位於windbg安裝目錄下
sdk\sample\inc。按照windbg幫助文件的說明,以及官方示例**的內容顯示,原本我們只需要包含標頭檔案
engextcpp.hpp,並連線engextcpp.lib靜態庫就能完成開發,但是事實上直接使用靜態庫在連線過程中會出現錯誤,並不能成功編譯,所以我
選擇了直接包含engextcpp.cpp原始檔的方法,而不去連線engextcpp.lib。
3)向工程中新增乙個新建的cpp檔案,命名為mtlkit.cpp。這個檔案的內容就是我們實現擴充套件指令
cmap
我們需要自己開發的**,其內容如下:
4)新增乙個新建的def檔案,命名為mtlkit.def。這個檔案定義擴充套件dll中需要匯出的介面,也就是支援的擴充套件指令名字。其內容如下:
5)按照實際情況配置工程屬性。
c++編譯配置中,程式檔案的包含路徑中要新增上windbg sdk的原始碼所在目錄,也就是
engextcpp.hpp和engextcpp.cpp兩個檔案的所在目錄。
連線配置中,新增模組定義檔名稱mtlkit.def,以表明需要使用def檔案。
6)最後還要注意工程常規屬性裡面要選擇多位元組集和靜態使用mfc庫。當然,根據自己的需要這些設定是可以調整的。
7)至此,乙個完整的windbg engextcpp擴充套件dll工程就建立起來了,只需要只需編譯就能得到,乙個名為mtlkit.dll的動態庫檔案。之後只要將mtlkit.dll拷貝到windbg安裝目錄下的winext子目錄中,我們就能在windbg中使用cmap指令了。使用方法可以是!mtlkit.cmap,也可以先用.load mtlkit載入動態庫,之後就能直接使用!cmap指令了。
最後需要注意的是,以上編譯得到的是32位dll,只能在32位的windbg上使用,64位windbg需要載入64位的擴充套件dll才能正常使用。
2.2 engextcpp開發**規則
下面以mtlkit.cpp的內容為例,介紹
engextcpp擴充套件指令開發
基本的規則。
包含標頭檔案
#include
要使用engextcpp框架所提供的介面,顯然需要包含它提供的標頭檔案。
類宣告的規矩
class ext_class : public extextension
;// ext_declare_globals must be used to instantiate
// the framework's assumed globals.
ext_declare_globals();
我們自定義的類通常會繼承engextcpp框架所定義的
extextension類,在這個類的內部將實現擴充套件指令的所有功能。自定義類的類名通常必須是ext_class,因為
engextcpp框架在實現時,宣告了一些變數,而這些變數固定使用了
ext_class這樣乙個符號。可以參看ext_declare_globals()巨集的定義。
類名ext_class實際上也是乙個巨集,定義在檔案engextcpp.hpp中,具體的定義為:
#ifndef ext_class
#define ext_class extension
#endif
也就是說,我們自定義類的真實名字預設情況下是extension。如果我們需要改變真實類名,則需要在#include 之前,對ext_class進行#define操作,否則可能無效或報錯。
自定義類中的函式宣告同普通的c++類基本一致。唯一不同的是擴充套件指令必須用ext_command_method巨集申明為public方法。
public:
ext_command_method(cmap);
上面的**,宣告了乙個叫做cmap的public方法,cmap方法是用ext_command_method巨集宣告的,因此它就是乙個擴充套件指令。
指令函式實現的規矩
相應的,用ext_command_method巨集宣告的函式,其實現也不同於普通的c++類函式,實現時必須用ext_command巨集引導:
ext_command(cmap,
"\n-description: \n"
"- dump the content of a specific cmap (vc9).\n"
"-usage:"
" directly use the name of a map variate, eg."
" !cmap nameofmapvar",
"")
ext_command巨集的原型為:
ext_command( _name, _desc, _args );
_name:指令的名稱
_desc:指令的描述資訊
_args:指令引數的描述資訊
(指定windbg指令後面引數的屬性,如引數是數字還是字串等等,可以參考windbg幫助文件中的主題
parsing extension arguments)
.def檔案說明
def檔案最後一行的cmap就是我們擴充套件指令的名字,同時也是自定義類中匯出函式名字。必須把
cmap
新增到def檔案中,宣告cmap函式是mtlkit.dll中的乙個匯出函式才能在windbg中呼叫cmap指令。另外,def檔案中help等4個匯出函式的名稱是由開發庫預設匯出的介面。
**簡單說明
outunfold函式:由於變數可能不是基本資料型別,而是複雜的類,在匯出類的時候就需要按層次展開類中的結構。outunfold函式指定展開的層數,對資料內容做輸出。
dumpcmap函式:根據cmap的儲存結構,匯出其中的key以及key對應的value。cmap實際上是乙個hash表,具體的實現可以參考它的原始碼。
extremotetyped類:
乙個由engextcpp框架提供的很方便的類,在偵錯程式成功引導程式符號表的情況下,extremotetyped
可以根據符號資訊對一段給定的記憶體做解析,使我們可以方便提取記憶體中資料的內容、資料型別等資訊。具體情況可以參考windbg幫助文件的說明,也可以分析它的原始碼對它做進一步了解。
為了避免windbg版本差異引起不必要的問題,我已經將乙個windbg資源新增到了工程檔案中,可在此基礎上學習開發,並直接在其中使用開發出的擴充套件庫。
3.參考文件
以下都是windbg官方幫助文件中的主題,對於學習windbg擴充套件指令開發都有幫助。
(1)introduction
(2)parsin
g extension
arguments
(3)engextcpp extension design guide
(4)using debugger extension commands
(5)wdbgexts extension design guide
(6)dbgeng extension design guide
Windbg指令碼和擴充套件工具開篇
好長一段時間沒寫文章了,最近一直忙於為專案的可調式性做一些指令碼和擴充套件工具,鑑於對windbg強大威力的震撼,以及相對較少的資料,筆者決定寫一系列關於如何開發windbg指令碼和擴充套件命令的文章,您的支援是我最大的動力,希望本系列文章對您有所幫助。那麼乙個完整的windbg script是什麼...
Windbg指令碼和擴充套件工具開篇
好長一段時間沒寫文章了,最近一直忙於為專案的可調式性做一些指令碼和擴充套件工具,鑑於對windbg強大威力的震撼,以及相對較少的資料,筆者決定寫一系列關於如何開發windbg指令碼和擴充套件命令的文章,您的支援是我最大的動力,希望本系列文章對您有所幫助。那麼乙個完整的windbg script是什麼...
Windbg指令碼和擴充套件工具開篇
好長一段時間沒寫文章了,最近一直忙於為專案的可調式性做一些指令碼和擴充套件工具,鑑於對windbg強大威力的震撼,以及相對較少的資料,筆者決定寫一系列關於如何開發windbg指令碼和擴充套件命令的文章,您的支援是我最大的動力,希望本系列文章對您有所幫助。那麼乙個完整的windbg script是什麼...