資源:如果 Windows API 函數使用了參考資源串,OllyDbg 可以顯示它。其支持顯示的類(lèi)型僅限于附帶資源[attached resources]的列表、數據顯示及二進(jìn)制編輯、。
斷點(diǎn): OllyDbg 支持各種斷點(diǎn):一般斷點(diǎn)、條件斷點(diǎn)、記錄斷點(diǎn)(比如記錄函數參數到記錄窗口)、內存讀寫(xiě)斷點(diǎn)、硬件斷點(diǎn)(只適用于ME/NT/2000)等。在Hit跟蹤情況下,可以在模塊的每條命令上都設置INT3斷點(diǎn)。在使用500-MHZ處理器的 Windows NT 中,OllyDbg 每秒可以處理高達 5000 個(gè)中斷。
Run 跟蹤: Run跟蹤可以單步執行程序,它會(huì )在一個(gè)很大的循環(huán)緩沖區中模擬運行程序。這個(gè)模擬器包含了除了SSE指令集以外的所以寄存器、標志、線(xiàn)程錯誤、消息、已經(jīng)函數的參數。您可以保存命令,這樣可以非常方便地調試自修改代碼(譯者注:比如加殼程序)。您可以設置條件中斷,條件包括地址范圍、表達式、命令。您可以將Run 跟蹤信息保存到一個(gè)文件中,這樣就可以對比兩次運行的差別。Run跟蹤可以回溯分析已執行過(guò)的上百萬(wàn)條命令的各種細節。
OllyDbg 是運行在Windows 95、Windows 98、Windows ME、Windows NT 和 Windows 2000系統下的一個(gè)單進(jìn)程、多線(xiàn)程的分析代碼級調試工具。它可以調試PE格式的執行文件及動(dòng)態(tài)鏈接庫,并可以對其打補丁?!按a級”意味著(zhù)您可以直接與比特、字節或處理器指令打交道。OllyDbg 僅使用已公開(kāi)的 Win32 API 函數,因此它可以在所有 Windows 操作系統及后繼版本中使用。但是由于我沒(méi)有對 XP 系統進(jìn)行徹底測試,因此不能保證 OllyDbg 功能的充分發(fā)揮。注意:OllyDbg 不支持對 .NET 程序的調試。
首先,OllyDbg包含一個(gè)內置的代碼分析器。分析器遍歷整個(gè)代碼,分出指令和數據,識別出不同的數據類(lèi)型和過(guò)程,分析出標準API函數(最常用的大約有 1900個(gè))的參數并且試著(zhù)猜出未知函數的參數數目。您也可以加入自己的函數說(shuō)明[your own function descriptions]。它標記出程序入口點(diǎn)和跳轉目的地,識別出跳轉表[table-driven switches]和指向字符串的指針,加入一些注釋?zhuān)踔翗耸境鎏D的方向等等。在分析結果的基礎上,調用樹(shù)[call tree]顯示哪些函數被指定過(guò)程調用(直接或間接)并且識別出遞歸調用、系統調用和葉子過(guò)程[leaf procedures]。如果需要的話(huà),您可以設置解碼提示[decoding hints]來(lái)幫助分析器解析那些不明確的代碼或數據。
AAD (ASCII Adjust AX Before Division) - 該命令的解碼后的一般形式為:AAD imm8
AAM (ASCII Adjust AX After Multiply) - 該命令(非十進(jìn)制數)的一般解碼形式為:AAM imm8
SLDT (Store Local Descriptor Table register) - 操作數總被解碼為16位。這個(gè)命令的32位形式會(huì )在目的操作數的低16位中存儲段選擇器,并保留高16位不變。
SALC (Sign-extend Carry bit to AL, undocumented) - OllyDbg 支持這個(gè)未公開(kāi)指令。
PINSRW (Insert Word From Integer Register, Athlon extension to MMX) - 在A(yíng)MD的官方文檔中,這個(gè)命令的內存形式使用了16位內存操作數;然而寄存器形式需要32位寄存器,但只使用了低16位。為了方便處理,反匯編器解碼寄存器為16 位形式。而匯編器兩種形式都支持。
CVTPS2PI and CVTTPS2PI (Convert Packed Single-Precision Floating to Packed Doubleword, Convert with Truncation Packed Single-Precision Floating to Packed Doubleword) -
同樣地,循環(huán)是一個(gè)封閉的連續的命令序列,并有一個(gè)到開(kāi)始處的跳轉作為一個(gè)入口,還有若干個(gè)出口。循環(huán)與高級操作命令 do, while 和 for 相對應。OllyDbg 能夠識別任何復雜的嵌套循環(huán)。他們會(huì )在反匯編欄[Disassembly]中用長(cháng)而粗括號標記。如果入口不是循環(huán)的第一個(gè)命令,OllyDbg會(huì )用一個(gè)小三角進(jìn)行標記。
OllyDbg 可以作為即時(shí)[just-in-time]調試器。這需要在系統注冊表中注冊。在菜單中選擇選項[Options]|即時(shí)調試[Just-in-time debugging] 并在彈出的對話(huà)框中單擊按鈕“設置OllyDbg為即時(shí)調試器”[Make OllyDbg just-in-time debugger]。今后,如果某個(gè)應用程序發(fā)生了非法操作,系統將提示您是否用 OllyDbg 調試這個(gè)程序。操作系統會(huì )啟動(dòng) OllyDbg 并直接停在發(fā)生異常的地方。如果您選擇了“掛接時(shí)不詢(xún)問(wèn)”[attaching without confirmation],則在即時(shí)調試時(shí)OllyDbg不會(huì )彈出詢(xún)問(wèn)對話(huà)框。如果想恢復成以前的即時(shí)調試器[Restore old just-in-time debuger],按相應的按鈕即可。
另一種方法是把 OllyDbg 添加到與可執行文件關(guān)聯(lián)的快捷菜單中(這個(gè)想法是 Jochen Gerster 提出的)。在主菜單中,選擇選項[Options]|添加到資源管理器中[Add to Explorer]。以后您可以在所有的文件列表中,右擊可執行文件或DLL,在快捷菜單中選擇OllyDbg。這個(gè)功能會(huì )創(chuàng )建四個(gè)注冊表鍵值:
HKEY_CLASSES_ROOT\exefile\shell\Open with OllyDbg HKEY_CLASSES_ROOT\exefile\shell\Open with OllyDbg\command HKEY_CLASSES_ROOT\dllfile\shell\Open with OllyDbg HKEY_CLASSES_ROOT\dllfile\shell\Open with OllyDbg\command
OllyDbg能夠調試控制臺程序(基于文字的)。
OllyDbg不能調試.NET應用程序。.NET程序是由微軟的中間語(yǔ)言這種偽指令組成的,或是on-the-fly to native ?6 commands編譯的。
標記為系統DLL[Mark as system DLL], 標記為非系統DLL[Mark as non-system DLL] - 將選中模塊標記為系統或非系統屬性。如果設置為系統屬性,則在Run跟蹤[Run trace]時(shí)會(huì )直接執行(不進(jìn)行跟蹤)這個(gè)模塊,從而大大加快跟蹤速度。默認情況下,所有駐留在系統目錄(通常在Windows 95/98下為c:\windows\system ,在WinNT/2000/XP下為c:\winnt\system32)的模塊都認為是系統模塊。
監察器[inspector]是顯示若干變量、1/2維數組或是選定項目結構數組[selected items of array of structures]的獨立窗口。它的表達式與監視窗口中的基本相同,只是多包含了兩個(gè)參數:%A和%B。您可以指定這兩個(gè)參數的界限,OllyDbg 將會(huì )用所有可能的組合代替表達式中的%A和%B。從0開(kāi)始一直到界限(不包含界限),并在表格中顯示結果。參數%B(列數)的界限不能超過(guò)16。
Hit 跟蹤能夠讓您辨別哪一部分代碼執行了,哪一部分沒(méi)有。OllyDbg的實(shí)現方法相當簡(jiǎn)單。它將選中區域的每一條命令處均設置一個(gè)INT3斷點(diǎn)。當中斷發(fā)生的時(shí)候,OllyDbg便把它去除掉,并把該命令標志為命中[hit]。因為每個(gè)跟蹤斷點(diǎn)只執行一次,所以這種方法速度非???。
在使用 Hit跟蹤的時(shí)候,一定要注意不能在數據中設置斷點(diǎn),否則應用程序極有可能崩潰。因此,您必須打開(kāi)相關(guān)的菜單選項,以進(jìn)行代碼分析[analyze]。我推薦您選擇嚴格或啟發(fā)式函數識別[strict or heuristical procedure recognition]。如果選擇模糊[Fuzzy]的話(huà),可能會(huì )產(chǎn)生很多難以容忍的錯誤,而且經(jīng)常把本不是函數的代碼段識別成函數。
Run 跟蹤[Run trace] Run 跟蹤是一種反方向跟蹤程序執行的方式,可以了解以前發(fā)生的事件。您還可以使用Run跟蹤來(lái)了解運行的簡(jiǎn)單統計[profile]?;旧?,OllyDbg 是一步一步地執行被調試程序的,就像動(dòng)畫(huà)[animation]演示一樣,但不會(huì )實(shí)時(shí)刷新窗口,最重要的是它能將地址、寄存器的內容、消息以及已知的操作數記錄到Run跟蹤緩沖區中。如果被調試的代碼是自修改的,您就能夠保存原始的命令??梢酝ㄟ^(guò)按Ctrl+F11(Run跟蹤步入,進(jìn)入子函數)或者 Ctrl+F12(Run跟蹤步過(guò),一次執行完子函數)開(kāi)始Run跟蹤,并用F12或者Esc鍵停止跟蹤。
當EIP在某個(gè)地址范圍內時(shí)暫停[Pause when EIP is in the address range]; 當EIP在某個(gè)地址范圍之外時(shí)暫停[Pause when EIP is outside the address range]; 當某個(gè)條件為真時(shí)暫停[Pause when some condition is true]; 當下一條指令可疑時(shí)暫停[Pause when next command is suspicious],比如:可能為非法指令(根據在分析3[Analysis 3]中設定的規則而定),訪(fǎng)問(wèn)不存在的內存,設置了單步陷阱標志[single-step trap flag]或者越ESP界訪(fǎng)問(wèn)棧。注意這個(gè)選項會(huì )明顯地(大約20%)減慢Run跟蹤的速度;
當命令執行達到指定的次數(更確切的說(shuō),是添加到Run跟蹤的緩沖區里面的命令數量)時(shí)暫停[Pause after specified number of commands is traced]。注意計數器不能自動(dòng)歸零。也就是說(shuō),如果您設置指令次數為10,則在第10次執行到該命令時(shí)暫停,并不是該命令每執行10次就暫停一次。
當下一條命令符合指定的樣式之一時(shí)暫停[Pause when next command matches one of the specified patterns]。您可以使用模糊命令和操作數[imprecise commands and operands]及匹配32位寄存器RA和RB,像R32一樣,這兩個(gè)寄存器可以替代任何通用32位寄存器,但是在同一條命令中其值是不能變的。而 RA 和 RB 在同一條命令中,則一定是不同的。例如,在程序中含有 XOR EAX,EAX; XOR ESI,EDX 兩條命令,兩條命令均符合樣式 XOR R32,R32;第一條命令符合樣式XOR RA,RA ;而等二條命令 XOR ESI,EDX 符合樣式XOR RA,RB。
在大多數情況下,您對跟蹤系統API代碼不感興趣。跟蹤選項總是跟過(guò)系統DLL[Always trace over system DLLs]允許您在跟蹤/自動(dòng)模式下跟過(guò)API函數。如果模塊在系統目錄下,OllyDbg就假設該模塊是系統的。您可以在模塊[Modules]窗口中標記任意DLL是系統的或者非系統的。
您可以通過(guò)從OllyDbg主菜單中選擇“調試[Debug]|打開(kāi)或者清除Run跟蹤[Open or clear run trace]”,來(lái)打開(kāi)或者清除Run跟蹤緩沖區。在Run跟蹤緩沖區打開(kāi)后, OllyDbg 會(huì )記錄在執行過(guò)程中的所有暫停,甚至那些不是由Run跟蹤引起的暫停。例如,您可以通過(guò)按 F7 或者 F8 單步執行程序,然后通過(guò)使用+鍵和-鍵來(lái)反方向跟蹤程序的執行。注意:如果Run跟蹤緩沖區已經(jīng)關(guān)閉,則用這些鍵瀏覽的是歷史[history]記錄。在您查看Run跟蹤記錄時(shí),寄存器和信息面板會(huì )變灰,來(lái)強調它們所顯示的寄存器并不是實(shí)際的寄存器。跟蹤緩沖區并不保存棧頂或由寄存器所指向的內容。寄存器、信息和棧在Run跟蹤的時(shí)候使用實(shí)際的內存狀態(tài)來(lái)解釋寄存器的變化。
OllyDbg能夠記下每個(gè)指令在Run跟蹤緩沖區里面出現的次數。在反匯編窗口快捷菜單中,選擇是“查看[View]|統計作為注釋?zhuān)跴rofile as comments]”。這個(gè)命令使用統計取代了注釋欄?;蛘?,如果列標題欄可見(jiàn),則可以單擊它幾次直到它顯示統計信息。注意顯示出來(lái)的數字是動(dòng)態(tài)的,而且不計算已經(jīng)從跟蹤緩沖區中丟棄的指令。您還可以在單獨的統計窗口[Profile window]中,按觸發(fā)次數排序,來(lái)查看整個(gè)模塊的統計數據。
在反匯編窗口的快捷菜單中選擇“Run跟蹤[Run trace]|添加到所有函數入口處[Add entries of all procedures]”,這樣能夠檢查每個(gè)可識別的函數被調用的次數。另一個(gè)命令“Run跟蹤[Run trace]|添加到函數中所有的分支[Add branches in procedure]”會(huì )強行跟蹤此函數中所有識別的跳轉目的地址的內容。在這種情況下,統計功能能夠找到最頻繁執行的分支,您可以?xún)?yōu)化這部分的代碼,以提高速度。
在反匯編窗口中的某條命令上使用快捷菜單中選擇“搜索[Search for]|Run跟蹤的最新記錄[Last record in run trace]”用于查找該命令是否被執行過(guò),如果執行過(guò),最后一次執行在哪里。
Run 跟蹤窗口顯示跟蹤緩沖區的內容。對每個(gè)指令來(lái)說(shuō)包括被指令改變的整數寄存器的內容(更準確的說(shuō)是給定的記錄變成下一條記錄的變化)。如果您雙擊某條指令,窗口會(huì )選擇在跟蹤緩沖區里全部含有該命令的記錄,而且您可以通過(guò)按+和-鍵來(lái)快速的瀏覽;如果您在調試選項[Debugging options]中設置了 “跟蹤[Trace]|同步CPU和 Run跟蹤[Synchronize CPU and Run trace]”,雙擊記錄則會(huì )跟進(jìn)到對應的反匯編窗口中位置。
在我們選擇這個(gè)函數后,右邊的消息框中會(huì )出現 Number of arguments: 4(有四個(gè)參數)的字樣。OllyDbg 會(huì )根據函數尾部的RET 10語(yǔ)句來(lái)正確識別參數的數量。RET nnn 是使用PASCAL調用約定的函數的典型特征。(參數被放入棧中,第一個(gè)參數會(huì )被最后一個(gè)壓入棧中,函數調用完畢后,參數會(huì )被遺棄)。大多數的 Windows API 函數都是 PASCAL形式的。
現在我們準備調用輸出函數。選項“在調用時(shí)隱藏[Hide on call]”意思是說(shuō),當函數運行時(shí)對話(huà)框將會(huì )從屏幕消失。當我們執行一個(gè)會(huì )運行很長(cháng)時(shí)間的函數,或者設置了斷點(diǎn)的時(shí)候,這個(gè)選項非常的有用。您也可以手動(dòng)關(guān)閉對話(huà)框。當函數執行完畢后,OllyDbg會(huì )重新自動(dòng)打開(kāi)?!罢{用輸出函數”對話(huà)框。選項“在調用后暫停[Pause after call]”意思是說(shuō),在執行完函數后,loaddll將會(huì )被暫停。
INFO Simple .ARG file that decodes CreateHatchBrush TYPE HS_X IF 0 "HS_HORIZONTAL" IF 1 "HS_VERTICAL" IF 2 "HS_FDIAGONAL" IF 3 "HS_BDIAGONAL" IF 4 "HS_CROSS" IF 5 "HS_DIAGCROSS" ELSEINT END TYPE COLORREF IF 0 "<BLACK>" IF 00FFFFFF "<WHITE>" OTHERWISE TEXT "RGB(" FIELD 000000FF UINT TEXT ","
FIELD 0000FF00 UINT TEXT "," FIELD 00FF0000 UINT TEXT ")" END STDFUNC CreateHatchBrush "style" HS_X "colorref" COLORREF END
TYPE FF_PITCH MASK 03 IF 00 "DEFAULT_PITCH" IF 01 "FIXED_PITCH" IF 02 "VARIABLE_PITCH" ELSEHEX TEXT "|" MASK 0C BIT 04 "4|" BIT 08 "8|" MASK FFFFFFF0 IF 00 "FF_DONTCARE" IF 10 "FF_ROMAN" IF 20 "FF_SWISS" IF 30 "FF_MODERN" IF 40 "FF_SCRIPT" IF 50 "FF_DECORATIVE" ELSEHEX END