[爆卦]windbg指令是什麼?優點缺點精華區懶人包

為什麼這篇windbg指令鄉民發文收入到精華區:因為在windbg指令這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者purpose (purpose)看板C_and_CPP標題[分享] WinDbg 調試 MFC...


腦筋亂,標題取得不太好,見諒。

場景是,想對某個 MFC 程式 myapp.exe 用 WinDbg 來做 Debug。

這個 MFC 程式是有原始碼,有 PDB 檔 (VC++ Build 專案時自動生出來的),目標只是
想把中斷點設定在,按下某個按鈕後的回應函數。

不過問題是,OllyDbg 跟 Visual C++ 畫面都比 WinDbg 精美無數倍,
到底為什麼要用 WinDbg 自討苦吃?有很多人推崇 WinDbg 說它很強大,是有什麼功能
WinDbg 還能比另外兩套突出?

說 WinDbg 強,根本就是 莫名其妙,指鹿為馬,令人驚嘆 XD!

XDDDDDDDDDDDDDDDD
XXXXXXXXXXXXXXXXD

太智障了!
_______________________________________

WinDbg 有三大強處:1. 符號查詢 2. Display Type 3. 外掛
_______________________________________

莫名其妙 X

所謂的符號就是指姓名,可能是 typedef 資料型態名稱、函數名稱、
全域變數的名稱,以及 class/struct/union ...等名稱。

現代的 Visual C++ 在 Build 專案,產生 .exe/.dll 時都會輸出 PDB 檔,這個
PDB 檔裡面包含了無數的符號名稱,以及符號的位址。

比如
符號名 = foo, 型態 = function, 位址 = blah.dll 內第 200~300 位元組

符號名 = Point, 型態 = struct, 成員為 {int x, int y}

不管是 VC、OD、WinDbg 或各大 Windows 界當紅 Debugger 都可以從 PDB 抓出
符號資訊來用,但是 WinDbg 是其中當之無愧的最強者。

以對 myapp.exe 這個 MFC 程式下中斷點為例,最方便一定是用 VC 開專案,去找出
該按鈕,點兩下就能進入該按鈕的處理函數並下中斷點。

而 WinDbg 它沒有 Resource Editor,所以不能跟 VC 做同樣的事。
但可以利用匈牙利命名法、VC 預設取名慣例,再使用 WinDbg 的超強符號查詢
來找出目標函數的名稱。

0:000> 用 WinDbg 執行 X myapp!C*

因為 MFC 用匈牙利命名法,每個類別名字開頭都是 CXX, CYY 之類,
所以這樣就能列出所有位於 myapp.exe 範圍內的 MFC 類別。

另外 MFC 精靈預設幫我們取的按鈕點擊處理函數,名稱都是 OnXX, OnYY
所以就進一步這樣篩選

0:000> 用 WinDbg 執行 X myapp!C*::On*

通常 myapp.pdb 是我們自己產生的,所以每個符號的資訊都是充分描述,不像微軟
公開的 PDB 只有寫符號名稱跟位址,其他都不講。

0:000> 用 WinDbg 執行 X /f myapp!C*

上面這個指令的 /f 是指列出所有 myapp.exe 內,符號名稱開頭為 C 且符號型態
只會是 function 者。同理 /d 是只有資料。而 /t 是列出符號時順便顯示
該符號的型態為何。而 /v 是囉唆 (verbose) 模式,就是該符號的一切資訊皆印出。

不管怎樣,用 X myapp!C*::On* 指令可以得到所有訊息處理函數,不管你知不知道
真正的函數名稱是什麼,不必開 Visual C++,隨便挑一個函數出來下中斷點就好。

當下了中斷點後,讓 WinDbg 恢復 myapp.exe 運行,然後就亂點按鈕,當該中斷點
被觸發時,因為 myapp.pdb 檔裡面會記載該函數的原始碼絕對路徑,以及此函數是
位於該 src.cpp 裡的第幾行這些 PDB (Program Debug Database) 都會記載。

所以 WinDbg 一旦觸發中斷點成功,就會自動打開原始碼,這時候就可以
當作 Visaul C++ 來用,直接到原始碼視窗裡,自己找目標來下中斷點。

那 myapp.pdb 是記載 myapp.exe 的所有符號資訊,可是一開始 WinDbg 怎麼知道
這個 myapp.pdb 檔放在哪?其實不管用 Debug 組態或 Release 組態,VC 都會在
myapp.exe 的 header裡面記錄 myapp.pdb 的絕對路徑,所以才抓得到。

補充:
使用 X 指令是「以名找名」,用不完整只有模糊的名稱
來搜尋出可能的目標符號名。找出來的符號至少至少都會說明其「位址」。

┌可以將 X 指令視為: 名字 -> 位址
└可將 LN 指令視為相反的: 位址 -> 名字

┌ X: eXamine
└LN: List Near (Symbol)

只能用完全精確的位址,才能查出符號名就太遜了,隨便丟個垃圾位址加上 LN
後,WinDbg 都能攀親帶故地去搜尋,找出位址在那附近的符號,猜出嫌疑犯來。

指鹿為馬 D

所謂的 D,完整來說應該是 Display Type,也就是 DT 指令才是正主兒 XD!

0:000> 用 WinDbg 執行 DT _PEB

會印出 _PEB 這個 struct 資料型態的完整宣告。
同樣,只能印出 struct 宣告沒什麼好強的,WinDbg 可以指鹿為馬

0:000> 用 WinDbg 執行 DT _PEB 0x12345678

其中 0x12345678 是隨便找來的位址,用 DT 指令硬讓他解讀成 _PEB 型態。
實際在哪些狀況派得上用場,一時也不好說。

反正 WinDbg 新手就記住這是 WinDbg 獨家且拿手的好戲,有天會用到就對了。

令人驚嘆 !

這爛梗寫到這,很多人都猜得到了,WinDbg 第三強大功能就是一堆外掛 Extensions,
這些外掛提供的功能往往 VC 不會有 (可是 OD 這個素人太受歡迎,外掛也不少)。

微軟對 OS 內部最瞭解,偷藏步那是想當然爾,每當使用者回報微軟的產品有什麼
漏洞、問題時,微軟的工程師們,大多也都是用 WinDbg 來偵錯,而不會用 VC 的。

所以 WinDbg 外掛寫出來,他們本是要自己工作用的,有免費公開出來給大眾,
當然就不能錯過了。

WinDbg 所有的外掛指令都是用 ! 開頭的,所以「令人驚嘆」由此而來。

舉例來說,想要處理程式的 Handle Leak 議題時,就可以用 !htrace 外掛,
這方面網路上很多教學,小弟新手就不多說了。


2011/09/10 AM 10:20 補充

WinDbg 包含在「Debugging Tools for Windows」這套軟體裡面,官方網址:
http://msdn.microsoft.com/en-us/windows/hardware/gg581067

OllyDbg 官方網址:http://www.ollydbg.de/

不管是 WinDbg 或 OllyDbg 都是針對已經撰寫好的 .EXE 或 .DLL 進行處理,
第一步是用這些軟體載入目標 .EXE,接著看是要單步執行 (Step) 或下中斷點,
使程式停在特定的運行時間點。

WinDbg 的一般用途就是純偵錯,找出程式問題用。
而 OllyDbg 針對「逆向工程」、「PEDIY」...等,有特別強化過。

逆向工程就是當你沒有該程式的原始碼,但是又想要知道某些關鍵區段,對方到底是
怎麼寫,於是 OllyDbg 特別擅長從這些程式的 Binary 中,反組譯出組合語言來,
加以分析,並且用很舒服的畫面呈現。在 UI 上,以 OllyDbg 進行逆向工程,會遠比
WinDbg 甚至比 Visual Studio 等更加好看。

當然目前 OD 的勁敵,商業軟體 IDA Pro 也有獨冠全球的功能,
比如「程式流程圖」、「反編譯出C語言原始碼」。

OD 是免費的,太受大家推崇,所以很多變種的版本,我現在用的主要是大陸人的改版
OllyICE,不過提到這些變種版時,大家還是習慣講成 OllyDbg。

至於 PEDIY 是好聽的說法,所謂的 PE 是 .EXE 或 .DLL 等檔案的格式。
而 PEDIY 最有趣的兩個部份,破解商業軟體的授權限制。第二是「增加」、「修改」
程式的既有功能。

你不需要有程式的原始碼,直接從成品的 .EXE 進行修改,然後將修改後的 .EXE 從
記憶體裡面另外存成新的 .EXE,以後就能重複使用,這個過程也有人用 DUMP 傾印
來稱呼他。

而一個程式的授權限制,往往會有一個相當於 if else 的來判斷你的序號正不正確,
使用 OD 把這個關鍵的判斷區域直接永遠改成 return true 之類的修改,術語上
稱為「爆破」。如果是用逆向功能方式解出程式判斷序號的邏輯,則可以製作出
所謂的「算號器」是為 keygen.exe。

對於 OD 的 PEDIY,讓許多原作者深惡痛覺,因此有了防護技術,主要為「加殼」,
這裡的殼對應的英文是 shell,當然 shell 這個字的意思很多很多,不再贅述。

殼主要有兩大種類,一個叫「壓縮殼」,其中最有名的叫做 UPX,是免費軟體。
連知名的 nirsoft 都會在其公佈的每套軟體使用 UPX 去壓縮,使執行檔從比如
上百K變成幾十KB的大小。而壓縮殼的壓縮功能多多少少會妨害到逆向工程、PEDIY 的
進行,因此碰到這種狀況時,必須先進行「脫殼」的動作,使程式回到加殼之前的狀態。

當然 UPX 是壓縮殼裡面比較友善的,任何人使用 UPX 主程式,就能自行脫掉 UPX 殼。

另外一種殼的種類為「加密殼」,也是各大商業軟體的主要保護手段。
使用加密殼後,防護 PEDIY 與逆向工程的能力會大幅提高,至少像我這種肉腳,看到
喜歡的軟體沒人破解,想自己爆破卻碰到加密殼時,往往都是束手無策。

對於 .EXE/.DLL 檔,判斷其有無加殼或使用何種殼的最著名軟體為 PEiD,也有人說
PEiD 可以用來判斷你的執行檔是用何種語言來寫。這是因為有時會分析出該檔
是用 VC 或用 Delphi 所建立,才有此一說。

PEiD 自己 google 就可以找到,也是免費的軟體。

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 124.8.133.39
※ 編輯: purpose 來自: 124.8.133.39 (09/10 02:49)

錯字改完,不改了。
之後有新的東西一律於文末補充,原文不再更動
※ 編輯: purpose 來自: 124.8.133.39 (09/10 02:50)
purincess:我只會用windbg看windows的crash dump QQ 09/10 03:06
tropical72:purpose 大強到我褲子都掉下來了.. 09/10 03:11
purpose:詞不達意,文筆很差,給點批評吧大大們 09/10 03:14
fon909:推,windbg的footprint較小,可以remote debug以及kernel 09/10 09:48
fon909:mode debug,題外話,"調試"是什麼意思呢? 09/10 09:50
tropical72:這用語常見於對岸,私以為 debug & trace 屬之。 09/10 10:03
purpose:是的,Debug在台灣翻成偵錯,大陸人大多講「調試」 09/10 10:19
※ 編輯: purpose 來自: 124.8.137.218 (09/10 10:47)
fon909:原來是這個意思,我看到一些對岸用詞常無法理解 09/10 12:34
fon909:試想"調試"怎會聯想到debug&trace? 太難望文生義了:( 09/10 12:38
loveme00835:有時候他們講的調試實際上代表testing...不同東西 09/10 12:39
fon909:不過語言差異無關技術高低以及熱心,大推原PO的補充:) 09/10 12:40
Bencrie:debug 不是叫除錯嗎 XD 09/11 11:17
purpose:是,而 VC 繁體中文版也翻成偵錯。用原文 Debug 時,比較 09/11 11:25
purpose:有想像空間,比較能腦補,用台灣用法時,會太狹窄。很多時 09/11 11:25
purpose:候,進行 Debug 從來也不是要找"錯",而是要破解要逆向... 09/11 11:26
VictorTom:推; 話說小弟跟OD不熟, 不知道OD能不能像WinDbg做live 09/11 20:12
VictorTom:debug(trace/break/watch...etc), 尤其是可以從user 09/11 20:12
VictorTom:mode的call stack一路串到kernel mode去(如果知道kernel 09/11 20:13
VictorTom:要停哪XD); 話說, WinDbg還可以local debug....XD 09/11 20:13
VictorTom:不過, de到C#寫的東西就很頭痛, 用VC都不能remote...Orz 09/11 20:14
purpose:OD沒聽過,倒是除了WinDbg還聽說一套叫syser好像可以。而 09/11 20:32
purpose:IDA 5.4以後甚至可以搭配WinDbg了,連結在這: 09/11 20:33
purpose:http://www.hexblog.com/?p=92 09/11 20:33

你可能也想看看

搜尋相關網站