標籤: 暫無標籤

OLLYDBG是一個新的動態追蹤工具,將IDA與SoftICE結合起來的思想,Ring 3級調試器,非常容易上手,己代替SoftICE成為當今最為流行的調試解密工具了.同時還支持插件擴展功能,是目前最強大的調試工具.

1 OLLYDBG -主要介紹

軟體

OLLYDBGOLLYDBG
名稱,一個新的動態追蹤工具,將IDA與SoftIce結合起來的思想,Ring 3級調試器,非常容易上手,己代替SoftICE成為當今最為流行的調試解密工具了.同時還支持插件擴展功能,是目前最強大的調試工具.

 

 

 

2 OLLYDBG -相關條目

追蹤 調試器 流行 工具 插件

一,什麼是 OllyDbg?

OllyDbg 是一種具有可視化界面的 32 位彙編-分析調試器。它的特別之處在於可以在沒有源代碼時解決問題,並且可以處理其它編譯器無法解決的難題。

Version 1.10 是最終的發布版本。 這個工程已經停止,我不再繼續支持這個軟體了。但不用擔心:全新打造的 OllyDbg 2.00 不久就會面世!

運行環境: OllyDbg 可以以在任何採用奔騰處理器的 Windows 95、98、ME、NT 或是 XP(未經完全測試)操作系統中工作,但我們強烈建議您採用300-MHz以上的奔騰處理器以達到最佳效果。還有,OllyDbg 是極占內存的,因此如果您需要使用諸如追蹤調試[Trace]之類的擴展功能話,建議您最好使用128MB以上的內存。

支持的處理器: OllyDbg 支持所有 80x86、奔騰、MMX、3DNOW!、Athlon 擴展指令集、SSE指令集以及相關的數據格式,但是不支持SSE2指令集。

配置: 有多達百餘個選項用來設置 OllyDbg 的外觀和運行。

數據格式: OllyDbg 的數據窗口能夠顯示的所有數據格式:HEX、ASCII、UNICODE、 16/32位有/無符號/HEX整數、32/64/80位浮點數、地址、反彙編(MASM、IDEAL或是HLA)、pe文件頭或線程數據塊。

幫助: 此文件中包含了關於理解和使用 OllyDbg 的必要的信息。如果您還有 Windows API 幫助文件的話(由於版權的問題 win32.HLP 沒有包括在內),您可以將它掛在 OllyDbg 中,這樣就可以快速獲得系統函數的相關幫助。

啟動: 您可以採用命令行的形式指定可執行文件、也可以從菜單中選擇,或直接拖放到OllyDbg中,或者重新啟動上一個被調試程序,或是掛接[Attach]一個正在運行的程序。OllyDbg支持即時調試。OllyDbg根本不需要安裝,可直接在軟盤中運行!

調試DLLs: 您可以利用OllyDbg調試標準動態鏈接庫 (DLLs)。OllyDbg 會自動運行一個可執行程序。這個程序會載入鏈接庫,並允許您調用鏈接庫的輸出函數。

源碼級調試: OllyDbg 可以識別所有 Borland 和 Microsoft 格式的調試信息。這些信息包括源代碼、函數名、標籤、全局變數、靜態變數。有限度的支持動態(棧)變數和結構。

代碼高亮: OllyDbg 的反彙編器可以高亮不同類型的指令(如:跳轉、條件跳轉、入棧、出棧、調用、返回、特殊的或是無效的指令)和不同的操作數(常規[general]、
FPU/SSE、段/系統寄存器、在棧或內存中的操作數,常量)。您可以定製個性化高亮方案。

線程: OllyDbg 可以調試多線程程序。因此您可以在多個線程之間轉換,掛起、恢復、終止線程或是改變線程優先順序。並且線程窗口將會顯示每個線程的錯誤(就像調用 GETLASTERROR 返回一樣)。

分析:OllyDbg 的最大特點之一就是分析。它會分析函數過程、循環語句、選擇語句、表[tables]、常量、代碼中的字元串、欺騙性指令[tricky constructs]、API調用、函數中參數的數目,import表等等。. 這些分析增加了二進位代碼的可讀性,減少了出錯的可能性,使得我們的調試工作更加容易。

Object掃描。 OllyDbg 可以掃描Object文件/庫(包括 OMF 和 COFF 格式),解壓代碼段[code segments]並且對其位置進行定向。

Implib掃描。 由於一些DLL文件的輸出函數使用的索引號,對於人來說,這些索引號沒有實際含義。如果您有與DLL相應的輸入庫[import library],OllyDbg 就可以將序號轉換成符號名稱。

完全支持Unicode: 幾乎所有支持 ASCII 的操作同時也支持 UNICODE,反之亦然。

名稱: OllyDbg 可以根據 Borland 和 Microsoft 格式的調試信息,顯示輸入/輸出符號及名稱。Object 掃描器可以識別庫函數。其中的名稱和註釋您可任意添加。如果DLL中的某些函數是通過索引號輸出的,則您可通過掛接輸入庫[import library]來恢復原來的函數名稱。不僅如此,OllyDbg還能識別大量的常量符號名(如:窗口消息、錯誤代碼、位域[bit fields]…)並能夠解碼為已知的函數調用。

已知函數:OllyDbg 可以識別 2300 多個 C 和 Windows API 中的常用函數及其使用的參數。您可以添加描述信息、預定義解碼。您還可以在已知函數設定 Log 斷點並可以對參數進行記錄。

函數調用: OllyDbg 可以在沒有調試信息或函數過程使用非標準的開始部分[prolog]和結尾部分[epilog]的情況下,對遞歸調用進行回溯。
譯者註:
004010D0   push  EBP              \
004010D1   mov   ebp,esp       |
004010D3   sub   esp,10h       |prolog
004010D6   push  ebx               |
004010D7   push  esi               |
004010D8   push  edi              /
……
004010C5   pop   edi              \ 
004010C6   pop   esi               |
004010C7   pop   ebx              |epilog
004010C8   mov   esp,ebp       |

004010CA   pop   ebp              |
004010CB   ret                     /

棧:在棧窗口中,OllyDbg 能智能識別返回地址和棧框架[Stack Frames]。並會留下一些先前的調用。如果程序停在已知函數上,堆棧窗口將會對其參數進行分析解碼。

譯者註:棧框架[Stack Frames]是指一個內存區域,用於存放函數參數和局部變數。

SEH 鏈: 跟蹤棧並顯示結構化異常句柄鏈。全部鏈會顯示在一個單獨的窗口中。

搜索:方法真是太多了!可精確、模糊搜索命令或命令序列,搜索常數,搜索二進位、文本字元串,搜索全部命令地址,搜索全部常量或地址域[address range],搜索所有能跳到選定地址的跳轉,搜索所有調用和被調用的函數,搜索所有參考字元串,在不同模塊中搜索所有調用、搜索函數名稱,在全部已分配的內存中搜索二進位序列。如果搜索到多個結果,您可以對其進行快速操作。

窗口:OllyDbg 能夠列出關於調試程序中的各種窗口,並且可以在窗口、類甚至選定的消息上設置斷點。

資源:如果 Windows API 函數使用了參考資源串,OllyDbg 可以顯示它。其支持顯示的類型僅限於附帶資源[attached resources]的列表、數據顯示及二進位編輯、。

斷點: OllyDbg 支持各種斷點:一般斷點、條件斷點、記錄斷點(比如記錄函數參數到記錄窗口)、內存讀寫斷點、硬體斷點(只適用於ME/NT/2000)等。在Hit跟蹤情況下,可以在模塊的每條命令上都設置INT3斷點。在使用500-MHZ處理器的 Windows NT 中,OllyDbg 每秒可以處理高達 5000 個中斷。

監視與監察器:每個監視都是一個表達式並能實時顯示錶達式的值。您可以使用寄存器、常數、地址表達式、布爾值以及任何複雜代數運算,您還可以比較ASCII和UNICODE
字元串。監察器[inspectors]是一種包含了兩個的索引序列的監視[Watches],它以二維表的形式呈現,可以對數組和結構進行解碼分析。 

Heap walk.:在基於Win95的系統中,OllyDbg 可以列出所有的已分配的堆。

句柄:在基於NT的系統中,OllyDbg 可列出被調試程序的所有系統句柄。

執行:.您可以單步執行、步入子程序或者步過子程序。您也可以執行程序直到函數返回時、執行到指定地址處,還可以自動執行。當程序運行時,您仍然可以操縱程序並能夠查看內存、設置斷點甚至修改代碼。您也可以任意的暫停或重啟被調試的程序。

Hit跟蹤:.Hit跟蹤可以顯示出目前已執行的指令或函數過程,幫助您檢驗代碼的各個分支。Hit跟蹤會在指定指令到達之前設置斷點,而在這個指令執行后,會把這個斷點清除掉。

譯者註:Hit在英文中是「擊中」的意思,指令如果運行了就表示這個指令被「擊中」了,沒有執行的指令就是「未擊中」,這樣我們就很容易看出被調試程序哪些部分運行了,而哪些沒有運行。

Run跟蹤: Run跟蹤可以單步執行程序,它會在一個很大的循環緩衝區中模擬運行程序。這個模擬器包含了除了SSE指令集以外的所以寄存器、標誌、線程錯誤、消息、已經函數的參數。您可以保存命令,這樣可以非常方便地調試自修改代碼(譯者註:比如加殼程序)。您可以設置條件中斷,條件包括地址範圍、表達式、命令。您可以將Run
跟蹤信息保存到一個文件中,這樣就可以對比兩次運行的差別。Run跟蹤可以回溯分析已執行過的上百萬條命令的各種細節。

統計: 統計[Profiler]可以在跟蹤時計算某些指令出現的次數。因此您就能了解代碼的哪一部分被頻繁執行。

補丁: 內置彙編器能夠自動找到修改過的代碼段。二進位編輯器則會以ASCII、UNICODE或者十六進位的形式同步顯示修改後的數據。修改後的數據同其它數據一樣,能夠進行複製-粘貼操作。原來的數據會自動備份,以便數據恢復時使用。您可以把修改的部分直接複製到執行文件中,OllyDbg會自動修正。OllyDbg還會記錄以前調試過程中使用的所有補丁。您可以通過空格鍵實現補丁的激活或者禁止。

自解壓文件: 當調試自解壓文件時,您往往希望跳過解壓部分,直接停在程序的原始入口點。OllyDbg的自解壓跟蹤將會使您實現這一目的。如果是加保護的自解壓段,自解壓跟蹤往往會失敗。而一旦OllyDbg找到了入口點,它將會跳過解壓部分,並準確的到達入口點。

插件:您可以把自己的插件添加到 OllyDbg 中,以增加新的功能。OllyDbg 的插件能夠訪問幾乎所有重要的數據的結構、能夠在 OllyDbg 的窗口中添加菜單和快捷鍵,能夠使用100個以上的插件API函數。插件API函數有詳細的說明文檔。默認安裝已經包含了兩個插件:命令行插件和書籤插件。

udd:OllyDbg 把所有程序或模塊相關的信息保存至單獨的文件中,並在模塊重新載入時繼續使用。這些信息包括了標籤、註釋、斷點、監視、分析數據、條件等等

 

更多:這裡介紹的功能,僅僅是 OllyDbg 的部分功能。因為其具有如此豐富的功能,以至於 OllyDbg 能成為非常方便的調試器!
2005-9-6 15:25 乾龍二,一般原理[General principles]

我希望您能對80x86系列處理器的內部結構有所了解,同時具有一定的編寫彙編程序的能力。對於Microsoft Windows方面的知識,您也要熟悉。

OllyDbg是運行在Windows 95、Windows 98、Windows ME、Windows NT 和 Windows 2000系統下的一個單進程、多線程的分析代碼級調試工具。它可以調試PE格式的執行文件及動態鏈接庫,並可以對其打補丁。「代碼級」意味著您可以直接與比特、位元組或處理器指令打交道。OllyDbg 僅使用已公開的 Win32 API 函數,因此它可以在所有 Windows 操作系統及後繼版本中使用。但是由於我沒有對 XP 系統進行徹底測試,因此不能保證 OllyDbg 功能的充分發揮。注意:OllyDbg 不支持對 .NET 程序的調試。

OllyDbg不是面向編譯器的。它沒有特別的規則規定必須是哪一個編譯器產生的代碼。因此,OllyDbg可以非常好的處理通過編譯器生成的代碼,或是直接用彙編寫入的代碼。

OllyDbg可以并行調試程序。您無須暫停執行程序,就可以瀏覽代碼和數據,設置斷點、停止或恢複線程,甚至直接修改內存。(這可以視為一種軟體調試的模式,與之相對的硬體模式則是當進程在運行時調試器被阻滯,反之亦然)。假使所需的操作比較複雜,OllyDbg會讓進程終止一小段時間,但是這種暫停對於用戶來說是透明的。

有時進程會發生非法操作。您可以把OllyDbg設置成即時[just-in-time]調試器,它會掛接出錯程序,並停在程序產生異常的地方。

通過OllyDbg,您可以調試單獨的DLL[standalone DLLs]文件。操作系統不能直接運行 DLL 文件,因此 OllyDbg 將一個可以載入 DLL 的小程序壓縮到資源里,這個程序允許您調用最多10個參數的輸出函數。

OllyDbg是完全面向模塊[module-oriented]的。模塊[Module]包括可執行文件(擴展名通常為.EXE)和在啟動時載入或需要時動態載入的動態鏈接庫(擴展名通常為.DLL
)。在調試期間,您可以設置斷點[breakpoints]、定義新的標籤[labels]、註釋[comment]彙編指令,當某個模塊從內存中卸載[unload]時,調試器會把這些信息保存在文件中,文件名就是模塊的名稱,擴展名為.UDD(表示 用戶自定義文件[User-Defined Data])當OllyDbg下一次載入該模塊時,它會自動恢復所有的調試信息,而不管是哪一個程序使用這個模塊。假設您正在調試程序Myprog1,這個程序使用了Mydll。您在 Mydll 中設置了一些斷點,然後您開始調試Myprog2,這個程序同樣使用了Mydll。這時您會發現,所有 Mydll 中的斷點依然存在,即使 Mydll 載入到不同的位置!

一些調試器把被調試進程的內存當作一個單一的(並且大部分是空的)大小為2 ^32位元組的區域。OllyDbg採用了與之不同的技術:在這裡,內存由許多獨立的塊組成,任何對內存內容的操作都被限制在各自的塊內。在大多數情況下,這種方式工作得很好並且方便了調試。但是,如果模塊包含好幾個可執行段[executable sections],您將不能一次看到全部代碼,然而這種情況是非常少見的。

OllyDbg 是一個很佔用內存的程序[memory-hungry application]。它在啟動時就需要 3 MB,並且當您第一次裝載被調試的程序時還需要一到兩兆的內存。每一次的分析、備份、跟蹤或者文件數據顯示都需要佔用一定的內存。因此當您調試一個很大的項目,發現程序管理器顯示有 40 或 60 兆內存被佔用時,請不要驚慌。

為了有效地調試一些不帶源碼的程序,您必須首先理解它是如何工作的。OllyDbg 包含的大量特性可以使這種理解變得非常容易。

首先,OllyDbg包含一個內置的代碼分析器。分析器遍歷整個代碼,分出指令和數據,識別出不同的數據類型和過程,分析出標準API函數(最常用的大約有1900個)的參數並且試著猜出未知函數的參數數目。您也可以加入自己的函數說明[your own function descriptions]。它標記出程序入口點和跳轉目的地,識別出跳轉表[table-driven switches]和指向字元串的指針,加入一些註釋,甚至標示出跳轉的方向等等。在分析結果的基礎上,調用樹[call tree]顯示哪些函數被指定過程調用(直接或間接)並且識別出遞歸調用、系統調用和葉子過程[leaf procedures]。如果需要的話,您可以設置解碼提示[decoding hints]來幫助分析器解析那些不明確的代碼或數據。

OllyDbg還包含Object掃描器[Object Scanner]。如果您有庫文件[libraries]或目標文件[object files],掃描器會在被調試的程序中定位這些庫函數。在全部函數調用中,對標準函數的調用占很重要的一部分(據我估計可達70%)。如果您知道正要被調用的函數的功能,您就不必把注意力集中在這個函數上,可以簡單地單步步過[
step over]這個call。分析器知道400多個標準C函數,比如fopen和memcpy。然而我必須承認當前版本的OllyDbg不能定位很短的函數(比一個return命令多不了多少的)或相似的函數(只在重定位上有不同)。

Object掃描器[Object scanner]也能夠識別輸入庫[import libraries]。如果某個DLL是按序號輸出的,您不會看到函數名,只會發現一堆無意義的神秘數字。這種DLL的開發者通常會提供一個輸入庫來實現函數符號名與序號間的對應。讓OllyDbg使用這個輸入庫,它就會恢復原始的函數符號名。

面向對象的語言(如C++),使用了一種叫做名稱修飾[name mangling]的技術,把函數類型和參數都加入函數名中。OllyDbg 可以解碼[demangle]這種函數名,使程序更易讀。

譯者註:C++的名稱修飾是編譯器將函數的名稱轉變成為一個唯一的字元串的過程,這個字元串會對函數的類、其命名空間、其參數表,以及其他等等進行編碼。C++的名稱修飾適用於靜態成員函數,也適用於非靜態成員函數。靜態函數的名稱修飾的一個好處之一,是能夠在不同的類里使用同一個名稱來聲明兩個或者更多的靜態成員函數----而不會發生名稱上的衝突。

OllyDbg完全支持 UNICODE,幾乎所有對 ASCII 字元串的操作都可以同樣應用於 UNICODE。

彙編指令都是很相似的。您經常會搞不清自己是不是已經跟蹤過某一段代碼。在 OllyDbg 中您可以加入自己的標籤[labels]和註釋[comments]。這些極大地方便了調試。注意一旦您註釋了某個DLL,以後每次載入這個DLL時,註釋和標籤都有效----儘管您在調試不同的程序。

OllyDbg可以跟蹤標準的棧幀[stack frames](由PUSH EBP; MOV EBP,ESP所創建的)。現代編譯器有禁止產生標準棧框架的選項,在這種情況下分配棧[stack walk
]是不可能的。當程序運行到已知的函數時,棧窗口[stack window]解析它的參數,調用棧[Call stack]窗口顯示到達當前位置所調用函數的序列。

現代的面向對象應用程序廣泛地使用了一種叫做結構化異常處理[Structured Exception Handling,SHE]的技術。SHE窗口[SEH window] 可以顯示異常處理鏈。

多種不同的搜索[search]選項可以讓您找到二進位代碼或數據、命令或命令序列、常量或字元串、符號名或在 Run跟蹤中的一條記錄。

對於任何地址或常量,OllyDbg 可以找出參考[referencing]到該地址或常量的全部命令的列表。然後您可以在這個列表裡找出對您來說是重要的參考。舉例來說,某個函數可能被直接調用,或者經過編譯器優化后把地址放入寄存器間接調用,或者把地址壓入堆棧作為一個參數----沒問題,OllyDbg 會找出所有這樣的地方。它甚至能找到並列出所有和某個指定的位置有關的跳轉。(真的?哦,天哪!……)

OllyDbg 支持所有標準類型的斷點[breakpoints]----非條件和條件斷點、內存斷點(寫入或訪問)、硬體斷點或在整個內存塊上下斷點(后兩項功能只在Window ME,NT,2000,XP中有效)。條件表達式可以非常複雜(「當 [ESP+8] 的第 2 位被設置,並且 123456 位置處的字[word]小於10,或者 EAX 指向一個以「ABC」開頭的 UNICODE 字串,但跳過前10次斷點而在第11次中斷」)。您可以設定一條或多條指令,當程序暫停時由OllyDbg傳遞給插件插件[plugins]。除了暫停,您還可以記錄某個表達式的值(可以帶有簡短的說明),或者記錄 OllyDbg 已知的函數的參數。在Athlon 2600+、Windows2000 環境下,OllyDbg 可以每秒處理多達 25000 個條件斷點。

另一個有用的特性是跟蹤。OllyDbg 支持兩種方式的跟蹤:hit和run。在第一種情況下,它對指定範圍內的每條指令上設置斷點(比如在全部可執行代碼中)。當到達設斷的指令后,OllyDbg 清除斷點並且把該指令標記為hit。這種方法可以用來檢測某段代碼是否被執行。Hit跟蹤速度驚人的快,在一個很短時間的啟動后程序幾乎達到了全速(譯者註:這應該是與不進行調試時速度相比而言)。因為INT3斷點可能對數據有災難性的影響,所以我建議不要使用模糊識別過程。當代碼沒有被分析時Hit跟蹤是不可以使用的。

Run跟蹤[Run trace] 是一步一步地執行程序,同時記錄精確的運行歷史和所有寄存器的內容、已知的參數和可選的指令(當代碼是自修改時會有幫助)。當然,這需要大量的內存(每個指令需要15至50個位元組,取決於調試的模式)但是可以精確地回溯和分析。您可以只在選定的一段代碼甚至是一條指令中進行Run跟蹤,或者您可以跳過無關緊要的代碼。對於每個地址,OllyDbg能夠計算這個地址在Run跟蹤日誌中出現的次數,雖然會導致執行緩慢但是可以得到代碼執行的統計。比如說,某命令讓您在每個已識別的過程入口處進行Run跟蹤,那麼統計[profile]就會給您每個過程被調用的次數。在到達某條指令、某個地址範圍或指令計數器達到某一數值時Run跟蹤可以自動地暫停[pause]。

在多線程程序里OllyDbg可以自動管理線程[threads],如果您單步調試或跟蹤程序,它會自動恢復當前線程而掛起其它線程。如果您運行程序,OllyDbg 會恢復先前的線程狀態。

您可以為內存塊建立快照(叫做備份)。OllyDbg會高亮顯示所有的改動。您可以把備份保存到文件或從文件中讀取出來,從而發現兩次運行的不同之處。您可以查看備份,搜索下一處改動,恢復全部或選定的改動。補丁管理器[Patch manager]記錄了上次應用到程序中的所有補丁,在下次調試時可以再次應用它們。

您可以很容易地把您的補丁加在可執行文件上。OllyDbg 會自動進行修正。

您不能在帶有 Win32 的16位 Windows 下使用 OllyDbg。這種32位擴展操作系統無法實現某些必需的調試功能。

您既不能調試 DOS 程序也不能調試16位 NE(New Executable)格式文件,我也沒有打算在未來的版本中支持這些。安息吧,古老而美好的命令提示符!
三,反彙編器[Disassembler]

反彙編器識別所有的標準80x86、保護、FPU、MMX和3DNow!指令集(包括Athlon擴展的MMX指令集)。但它不識別ISSI命令,儘管計劃要在下個版本中支持這種命令。某些過時或者未公開的命令,像LOADALL,也不支持。

反彙編器可以正確解碼16位地址。但它假設所有的段都是32位的(段屬性使用32位)。這對於PE[Portable Executable]格式文件總是真的。OllyDbg不支持16位的NE
[New Executables]格式。

如果您熟悉MASM或者TASM,那麼反彙編的代碼對於您沒有任何問題。但是,一些特例也是存在的。以下命令的解碼與Intel的標準不同:


AAD (ASCII Adjust AX Before Division) -
該命令的解碼后的一般形式為:AAD imm8

AAM (ASCII Adjust AX After Multiply) -
該命令(非十進位數)的一般解碼形式為:AAM imm8

SLDT (Store Local Descriptor Table register) -
操作數總被解碼為16位。這個命令的32位形式會在目的操作數的低16位中存儲段選擇器,並保留高16位不變。

SALC (Sign-extend Carry bit to AL, undocumented) -
OllyDbg 支持這個未公開指令。

PINSRW (Insert Word From Integer Register, Athlon extension to MMX) -
在AMD的官方文檔中,這個命令的內存形式使用了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) -

在這些命令中,第一個操作數是MMX寄存器,第二個或者是128位XMM寄存器或者是64位內存區域。為了方便處理,內存操作數也被解碼為128位。


有些指令的助記符要依賴操作數的大小:


不分大小的形式       明確的16位形式       明確的32位形式
PUSHA       PUSHAW       PUSHAD
POPA       POPAW       POPAD
LOOP       LOOPW       LOOPD
LOOPE       LOOPWE       LOOPDE
LOOPNE       LOOPWNE       LOOPDNE
PUSHF       PUSHFW       PUSHFD
POPF       POPFW       POPFD
IRET       IRETW       IRETD
您可以改變解碼大小敏感助記符[decoding of size-sensitive mnemonics].。根據選項,反彙編器從三種可能中選擇之一進行解碼。這個選項也會影響彙編器的默認處理方式。

解碼MMX和3DNow!指令總是開啟的,儘管您的處理器並不支持這些指令。四,分析器[Analysis]

OllyDbg 整合了一個快速而強大的代碼分析器。您可以從快捷菜單,或者在CPU窗口的反彙編面板中按 Ctrl+A ,或者在可執行模塊中選擇「分析全部模塊[Analyze all modules]」,來使用它。

分析器有很高的啟發性。它能區分代碼和數據,標記入口和跳轉目的地址,識別轉換表[switch tables],ASCII 和 UNICODE 串,定位函數過程,循環,高階轉換[
high-level switches]並且能解碼標準API函數的參數(示例[example])。OllyDbg 的其他部分也廣泛的使用了分析后的數據。

這是如何實現的?我將為您揭開這一神秘面紗。第一遍,OllyDbg反彙編代碼段中所有可能的地址,並計算調用的每個目的地址的個數。當然,很多調用是假的,但不可能兩個錯誤的調用都指向了相同的命令,當然如果有三個的話,就更不可能了。因此如果有三個或者更多的調用指向了相同的地址,我可以肯定的說這個地址是某個頻繁使用的子程序的入口。從定位的入口出發,我繼續跟蹤所有的跳轉和函數調用,等等。按這種方法,我可能準確定位99.9% 的命令。但是,某些位元組並不在這個鏈條上。我再用20多種高效的啟發方法(最簡單的方法,比如「直接訪問前64K內存是不允許的,像在MOV [0],EAX中」)來探測他們

有時,分析器在您感興趣的地方分析錯誤。有兩種解決方法:或者從選中的部分移除分析(快捷鍵退格鍵),這樣 OllyDbg 將使用默認的解碼(反彙編)方式;或者設置
解碼提示[decoding hints]並重新分析。注意:在某些情況下,當分析器認為您的提示是不合適的,或者有衝突,則可能忽略您的設置。

探測程序的函數過程也很簡單。在分析器眼中看來,程序只是一個連綿不斷的代碼,從一個入口開始,可能達到(至少從理論上)所有的命令(除了NOP以及類似的用於填充間隙的命令)。您可能指定三個識別級別。嚴格的函數過程要求有準確的一個入口,並且至少有一個返回。在啟發級別下,分析器只要求過程有一個入口。而如果您選擇模糊模式,差不多連貫的代碼都會被識別為單獨的過程。現代編譯器進行全局代碼優化,有可能把一個過程分成幾個部份。在這種情況下,模糊模式非常有用。但是也會誤識別的機率也就更高。

同樣地,循環是一個封閉的連續的命令序列,並有一個到開始處的跳轉作為一個入口,還有若干個出口。循環與高級操作命令 do, while 和 for 相對應。OllyDbg 能夠識別任何複雜的嵌套循環。他們會在反彙編欄[Disassembly]中用長而粗括弧標記。如果入口不是循環的第一個命令,OllyDbg會用一個小三角進行標記。

為了實現一個轉換[switch], 許多編譯器,讀取轉換變數[switch variable]到寄存器中,然後減它,像如下的代碼序列:

     MOV edX,
     SUB EDX,100
     JB DEFAULTCASE
     JE CASE100        ; Case 100
     DEC EDX
     JNE DEFAULTCASE
     ...               ; Case 101

這個序列可能還包含一到兩階的轉換表、直接比較、優化和其他元素。如果在比較或跳轉的很深處,這就很難知道哪是一個分支[Case]。OllyDbg 會幫助您,它會標記所有的分支,包括默認的,甚至嘗試分析每個分支的含義,如'A'、WM_PAINT 或者 EXCEPTION_ACCESS_VIOLATION。如果命令序列沒有修改寄存器(也就是僅僅由比較組成),那麼這可能不是轉換,而很有可能是選擇嵌套:

     if (i==0) {...}
     else if (i==5) {...}
     else if (i==10) {...}

如果需要OllyDbg將選擇嵌套解碼成選擇語句,請在分析1[Analysis1]中設置相關選項。

OllyDbg包含多達1900條常用API函數,這些都作為內部預處理資源。這個列表包含了KERNEL32, GDI32, USER32, ADVAPI32, COMDLG32, SHELL32, VERSION, SHLWAPI, COMCTL32, WINSOCK, WS2_32 和 MSVCRT。您可以添加自己的函數描述[add your own descriptions]。如果分析器遇到的調用,使用了已知的函數名(或者跳轉到這樣的函數),它將在調用之前立即解碼PUSH命令。因此,您只需略微一看就能明白函數調用的含義。OllyDbg還包含了大約400多種的標準C函數。如果您有原始的庫文件,我推薦您在分析前掃描目標文件。這樣OllyDbg將能解碼這些C函數的參數。

如果選項「猜測未知函數的參數個數」開啟,分析器將會決定這個調用函數過程使用的長度為雙字的參數個數。並且標記他們為參數1[Arg1],參數2[ Arg2],等等。注意:無論如何,寄存器參數是無法識別的,所以不會增加參數的數目。分析器使用了一種比較安全的方法。例如,它不能識別的沒有參數的函數過程,或者該過程POP
命令直接做返回前的寄存器恢復,而不銷毀參數。然而,識別出來的函數參數數目通常非常高,這大大加大了代碼的可讀性。

分析器能夠跟蹤整型寄存器的內容。現代優化編譯器,特別是奔騰系列,頻繁地使用寄存器讀取常量和地址,或使用盡量少的使用內存。如果某個常量讀取到寄存器中,分析器會注意它,並嘗試解碼函數和其參數。分析器還能完成簡單的算術計算,甚至可以跟蹤壓棧和出棧。

分析器不能區分不同類的名稱[different kinds of names]. 。如果您將某些函數指定為已知的名稱,OllyDbg將會解碼所有到該地址的調用。這是幾個預定義的特殊名稱
WinMain, DllEntryPoint and WinProc。您可能使用這些標籤標記主程序、DLL的的入口以及窗口過程(注意:OllyDbg不檢查用戶自定義的標籤是否唯一)。另外,假定預定義參數assume predefined arguments是一種更好的方法

不幸的是,沒有一般規則能夠做到100%的準確分析。在某些情況下,例如當模塊包含了P-Code或代碼段中包換了大量的數據,分析器可能將一些數據解釋成代碼。如果統計分析顯示代碼部分很可能是壓縮包或者經過加密了,分析器會發出警告。如果您想使用Hit跟蹤[Hit trace],我建議您不要使用模糊分析[fuzzy analysis],因為設置斷點的地方可能正是數據部分。

自解壓文件[Self-extractable files] 通常有一個自提取器,在「正式」代碼段之外。如果您選擇自解壓選項[SFX option]中的「擴展代碼段,包含提取器[Extend code section to include self-extractor]」,OllyDbg將會擴展代碼段,形式上允許分析它,並可以使用Hit跟蹤[Hit] trace和Run跟蹤[Run trace]。
2005-9-6 15:27 乾龍五,Object掃描器[Object scanner]

掃描器將特定的目標文件或者目標庫(包括OMF和COFF兩種格式),提取出代碼段,然後將這些段定位在當前模塊的代碼節[Code section]中.如果段定位好了,掃描器將從目標文件中的調試信息提取名稱(也就是所謂的庫標籤[library labels])。這極大的增加了代碼與數據的可讀性.

掃描器並不會對已識別的目標文件進行標籤匹配,所以它不能識別非常小或相似的函數(比如:兩個函數只是在重定位有區別)。因此要經常檢查掃描器發送到登陸窗口的警告列表!六,Implib掃描器 [Implib scanner]

某些DLL的輸出符號僅僅是一個序號。許多符號都是井號加數字(比如:MFC42.#1003),這非常不便於理解。幸運的是,軟體零售商提供了輸入連接庫(implibs),它與序號符號名相關。

使用implib掃描器的方法:從主菜單中選擇調試[Debug]|選擇輸入鏈接庫[Select import libraries]。當您載入應用程序時,OllyDbg會讀取鏈接庫並從內置表格[
internal tables]中提取符號名。每次遇到序號符號,而對應的鏈接庫已經註冊到OllyDbg中時,這個序號符號會被替換。七,如何開始調試[How to start debugging session]

最簡單的方法是:運行 OllyDbg,點擊菜單上的文件[File]|打開[Open],選擇您想調試的程序。如果程序需要命令行參數,您可以在對話框底部的輸入欄中,輸入參數或者選擇以前調試時輸入過的一條參數。

OllyDbg 能夠調試獨立的DLL[stand-alone DLLs]。在這種情況下,OllyDbg 會創建並運行一個小的應用程序來載入鏈接庫並根據您的需要調用輸出函數。

如果您想重新啟動上一次調試的程序,只要按一下 Ctrl+F2(這是重啟程序的快捷鍵),這樣 OllyDbg 會以同樣的參數運行這個程序。另一種做法是在菜單中選擇文件[File],從歷史列表中選擇程序。您也可以在 Windows 資源管理器中將可執行文件或 DLL 文件拖拽到 OllyDbg 中。

當然,您可以在 OllyDbg 啟動時,運行指定帶有運行參數的被調試程序。例如:您可以在桌面創建一個 OllyDbg 的快捷方式,右擊並選擇「屬性」,在「快捷方式」中的「目標」中添加調試的程序的全路徑。這樣,您每次雙擊快捷方式時,OllyDbg 將自動運行被調試程序。注意:DLL文件不支持這種方式。

您可以把正在運行的進程掛接到 OllyDbg 中。在菜單中打開 文件[File]|掛接[Attach],從進程列表中選擇要掛接的進程。注意:在您關閉 OllyDbg 的同時,這個進程也會被關閉。不要掛接系統進程,否則可能會導致整個操作系統的崩潰。(事實上在大多數情況下,操作系統禁止您掛接敏感進程)。

OllyDbg 可以作為即時[just-in-time]調試器。這需要在系統註冊表中註冊。在菜單中選擇選項[Options]|即時調試[Just-in-time debugging] 並在彈出的對話框中單擊按鈕「設置OllyDbg為即時調試器」[Make OllyDbg just-in-time debugger]。今後,如果某個應用程序發生了非法操作,系統將提示您是否用 OllyDbg 調試這個程序。操作系統會啟動 OllyDbg 並直接停在發生異常的地方。如果您選擇了「掛接時不詢問」[attaching without confirmation],則在即時調試時OllyDbg不會彈出詢問對話框。如果想恢復成以前的即時調試器[Restore old just-in-time debuger],按相應的按鈕即可。

另一種方法是把 OllyDbg 添加到與可執行文件關聯的快捷菜單中(這個想法是 Jochen Gerster 提出的)。在主菜單中,選擇選項[Options]|添加到資源管理器中[Add to Explorer]。以後您可以在所有的文件列表中,右擊可執行文件或DLL,在快捷菜單中選擇OllyDbg。這個功能會創建四個註冊表鍵值:


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程序是由微軟的中間語言這種偽指令組成的,或是on-the-fly to native ?6 commands編譯的。

注意:如果您運行的是Windows NT、2000 或XP操作系統,您應該擁有管理員許可權以
八,CPU 窗口[CPU window]

對於用戶來說,CPU窗口在OllyDbg中是最重要的窗口。您調試自己程序的絕大部分操作都要在這個窗口中進行。它包括以下五個面板(這五個面板的大小都是可以調節的):


反彙編[Disassembler]
信息[Information]
數據[Dump]
寄存器[Registers]
棧[Stack]

按TAB鍵,可以切換到下一個CPU面板中(順時針方向)。

按Shift+TAB,可以切換到前一個CPU面板(逆時針方向)。九,斷點[Breakpoints]

OllyDbg支持數種不同類型的斷點:

- 一般斷點[Ordinary breakpoint], 將您想中斷的命令的第一個位元組,用一個特殊命令INT3(調試器陷阱)來替代。您可以在反彙編窗口中選中要設斷點的指令行並按下 F2 鍵就可以設定一個此類型的斷點。也可以在快捷菜單中設置。再次按下 F2 鍵時,斷點將被刪除。注意,程序將在設斷指令被執行之前中斷下來。

INT3斷點的設置數量是沒有限制的。當您關閉被調試程序或者調試器的時候,OllyDbg將自動把這些斷點保存到硬碟中,永遠不要試圖在數據段或者指令的中間設置這種斷點,如果您試圖在代碼段以外設置斷點,OllyDbg將會警告。您可以在安全選項[Security options]中永遠關閉這個提示,在某些情況下調試器會插入自帶的臨時INT3
斷點。

- 條件斷點[Conditional breakpoint] (快捷鍵 Shift+F2) 是一個帶有條件表達式的普通INT3斷點。當調試器遇到這類斷點時,它將計算表達式的值,如果結果非零或者表達式無效,將暫停被調試程序,當然,由條件為假的斷點引起的開銷是非常高的(主要歸因於操作系統的反應時間)。在Windows NT、奔騰Ⅱ/450處理器環境下
OllyDbg每秒最多處理2500個條件為假的斷點。條件斷點的一個典型使用情況就是在windows消息上設置斷點(比如 WM_PAINT)。為此,您可以將偽變數 MSG 同適當的參數說明聯合使用。如果窗口被激活,參考一下後面的消息斷點描述。

- 條件記錄斷點 [Conditional logging breakpoint] (Shift+F4)是一種條件斷點,每當遇到此類斷點或者滿足條件時,它將記錄已知函數表達式或參數的值。例如,您可以在一些窗口過程函數上設置記錄斷點並列出對該函數的所有調用。或者只對接收到的WM_COMMAND消息標識符設斷,或者對創建文件的函數(CreateFile)設斷,並且記錄以只讀方式打開的文件名等,記錄斷點和條件斷點速度相當,並且從記錄窗口中瀏覽上百條消息要比按上百次F9輕鬆的多,您可以為表達式選擇一個預先定義好的解釋說明。

您可以設置通過的次數 - 每次符合暫停條件時,計數器就會減一。如果通過計數在減一前,不等於零,OllyDbg就會繼續執行。如果一個循環執行100次(十進位),在循環體內設置一個斷點,並設置通過次數為99(十進位)。OllyDbg將會在最後一次執行循環體時暫停。

另外,條件記錄斷點允許您傳遞一個或多個命令給插件[plugins]。例如,您需要使用命令行插件改變一個寄存器的內容,然後繼續執行程序。

- 消息斷點[Message breakpoint]和條件記錄斷點基本相同,除了OllyDbg會自動產生一個條件,這個條件允許在窗口過程的入口處設置某些消息(比如WM_PSINT)斷點,您可以在窗口[Windows]中設置它。

- 跟蹤斷點[Trace breakpoint] 是在每個選中命令上設置的一種特殊的INT3斷點。如果您設置了Hit跟蹤[hit trace] ,斷點會在命令執行后移除,並在該地址處做一個標記。如果您使用的是Run跟蹤[run trace] ,OllyDbg會添加跟蹤數據記錄並且斷點仍然是保持激活狀態。

- 內存斷點[Memory breakpoint] OllyDbg每一時刻只允許有一個內存斷點。您可以在反彙編窗口、CPU窗口、數據窗口中選擇一部分內存,然後使用快捷菜單設置內存斷點。如果有以前的內存斷點,將被自動刪除。您有兩個選擇:在內存訪問(讀,寫,執行)時中斷,或內存寫入時中斷。設置此類斷點時,OllyDbg將會改變所選部分的內存塊的屬性。在與80x86兼容的處理器上將會有4096位元組的內存被分配並保護起來。即使您僅僅選擇了一個位元組,OllyDbg 也會將整個內存塊都保護起來。這將會引起大量的錯誤警告,請小心使用此類斷點。某些系統函數(特別是在Windows95/98下)在訪問受保護的內存時不但不會產生調試事件反而會造成被調試程序的崩潰。

- 硬斷點[Hardware breakpoint](僅在Windows ME,NT或2000下可用)在80x86兼容的處理器上,允許您設置4個硬體斷點。和內存斷點不同,硬體斷點並不會降低執行速度,但是最多只能覆蓋四個位元組。在單步執行或者跟蹤代碼時,OllyDbg能夠使用硬斷點代替INT3斷點。

- 內存訪問一次性斷點[Single-shot break on memory access] (僅在Windows NT或2000下可用)。您可以通過內存窗口的快捷菜單(或按F2),對整個內存塊設置該類斷點。當您想捕捉調用或返回到某個模塊時,該類斷點就顯得特別有用。中斷髮生以後,斷點將被刪除。

- 暫停Run跟蹤[Run trace pause] (快捷鍵:Ctrl+T)是在每一步Run跟蹤[run trace] 時都要檢查的一個條件集.您可以在EIP進入某個範圍或超出某個範圍時暫停,某個條件為真時暫停,或者命令與指定的模式匹配時暫停,或者當命令可疑的時候暫停。注意,這一選擇會極大的(高達20%)降低Run跟蹤的速度。

OllyDbg也可以在一些調試事件[debugging events]上暫停程序執行。比如載入或卸載DLL,啟動或終止線程,或者程序發出調試字元串的時候。

10,數據窗口[Dump]
數據窗口用於顯示內存或文件的內容。您可以從以下預處理格式[predefined formats]中選擇一種顯示方式:位元組[byte]、文本[text]、整數[integer]、浮點數[float
]、地址[address],反彙編[disassembly]、 PE頭[PE Header]。

所有的dump窗口支持備份[backup]、搜索和編輯操作。CPU 窗口[CPU window]的Dump面板允許您對可執行代碼的數據和可執行文件(.exe,或.dll)的內存映射做如下操作:定義標籤[labels]、設置 內存斷點[memory breakpoints], 查找參考[references]。數據菜單[Dump menu]只顯示與選中部分相關的命令。

如果 備份[backup]可用,則單擊第一個列標題欄,會在地址[Address]/備份[Backup] 兩種顯示模式之間切換。點擊其他列標題欄,會改變Dump模式。

像反彙編窗口一樣,數據窗口也保存了大量查看內存地址的歷史記錄。您可以通過「+」和「-」鍵來訪問您過去查看過的數據地址空間。

要翻動一位元組的數據,可以按住Ctrl l鍵並按上/下方向鍵。

可執行模塊窗口[Executable modules window]
可執行模塊窗口(快捷鍵:Alt+E)列出了當前被調試進程載入的所有可執行模塊。它也顯示了很多有用的信息,比如模塊大小、入口地址、模塊版本、以及可執行文件路徑等。一些信息,如以十進位顯示的模塊大小、入口地址的符號名、是否為系統模塊等,通常是被隱藏的。如果想看,可以增加相應欄的寬度。快捷菜單支持以下操作:

刷新[Actualize] - 重新掃描模塊並去除對新載入模塊的高亮顯示。在大多數情況下,OllyDbg會自動完成該操作。

查看內存[View memory] - 打開內存窗口,並定位到屬於該模塊鏡像的第一個內存塊處。

在CPU窗口中查看代碼[View code in CPU] (快捷鍵:回車鍵) - 在反彙編窗口中顯示模塊的可執行代碼。

跟進到入口[Follow entry] - 在反彙編窗口中跟進到模塊的入口處。

在CPU窗口中查看數據[Dump data in CPU] -在CPU窗口的數據面板中顯示模塊的數據段。塊代碼段。

顯示名稱[View names] (快捷鍵:Ctrl+N) -顯示當前模塊定義或使用的全部名稱[names](包括輸出表、引入表、鏈接庫、用戶自定義)。

標記為系統DLL[Mark as system DLL],
標記為非系統DLL[Mark as non-system DLL] - 將選中模塊標記為系統或非系統屬性。如果設置為系統屬性,則在Run跟蹤[Run trace] 時會直接執行(不進行跟蹤)這個模塊,從而大大加快跟蹤速度。默認情況下,所有駐留在系統目錄(通常在Windows 95/98下為c:\windows\system ,在WinNT/2000/XP下為c:\winnt\system32)的模塊都認為是系統模塊。

立即更新.udd文件[Update .udd file now] -向文件「.udd」寫入模塊相關的全部數據,udd文件保存了在調試期間設置的斷點、標籤、註釋、監視、分析等信息。當模塊卸載時OllyDbg會自動創建.udd文件。

查看可執行文件[View executable file] - 顯示可執行文件的全部內容。

查看全部資源[View all resources] - 以列表形式顯示模塊定義的全部資源,並帶有一個簡簡訊息。OllyDbg並不把資源當作單獨實體來支持。您可以提取[Dump]並以二進位的形式進行編輯。

查看資源字元串[View resource strings] -以列表形式顯示資源字元串及其標識符。

查看Run跟蹤的統計[View run trace profile] - 在此模塊中計算統計[profile] 。相關信息:Run跟蹤[Run trace].

分析全部模塊[Analyze all modules] -允許同時分析全部模塊。分析將從代碼中提取大量的有用信息;代碼經過分析后再進行調試,通常會非常快並且可靠。

滑鼠雙擊某一行,將會在反彙編窗口中顯示模塊的執行代碼。十,內存映射窗口[Memory map window]

內存映射窗口顯示了被調試程序分配的所有內存塊。因為沒有標準的方法來完成這項任務,所以OllyDbg可能會把一個大的內存塊分成幾個部分。然而,在大多數情況下,並非一定要精確處理。如果想查看由應用程序通過調用GlobalAlloc()和LocalAlloc()等申請的內存塊列表,請使用堆列表[Heap list]。

如果內存塊是可執行模塊的一個節,OllyDbg則會報告這個內存塊所包含的數據類型:代碼、數據、資源等。

Windows95/98是和WindowsNT/2000是有一些區別的。在Windows95/98下,OllyDbg是不能顯示被映射文件的名稱的。另外,Windows95/98不允許的訪存類型為讀和寫,然而,在WindowsNT/2000下,OllyDbg卻有擁有更多功能,包括執行訪問,寫複製[copy-on-write]以及監視標誌位。OllyDbg忽略寫複製[copy-on-write]屬性。

如果OllyDbg發現程序分配了新內存或者重新分配了已經存在的內存塊,它將在內存映射窗口中高亮顯示相應的記錄,去掉高亮度顯示,可以選擇快捷菜單中的刷新[
Actualize]項。

您可以按Alt+M來調用內存窗口。

以下是快捷菜單中可以選擇的菜單項:

刷新[Actualize] - 更新已分配內存的列表並去除對新內存塊的高亮顯示。

在反彙編窗口中查看[View in Disassembler] -在反彙編窗口中查看:在反彙編窗口中打開內存塊,這一選項僅在某些模塊的內存塊中包含可執行代碼或者自解壓器時可用。

在CPU數據窗口中查看[Dump in CPU] - 在CPU的數據窗口中顯示內存塊的內容。

數據窗口[Dump] - 在單獨窗口中顯示內存塊內容。如果內存塊的類型已知,則OllyDbg會自動選擇顯示格式。

查看全部資源[View all resources] - 如果內存塊包含資源數據,則列出所有資源及相關數據。OllyDbg並不把資源當作單獨實體來支持。您可以顯示其數據並以二進位的形式進行編輯。

查看資源字元串[View resource strings] - 如果內存塊包含資源數據,則列出全部資源字元串及其標識符。

搜索[Search] - 允許搜索所有的內存塊,從選擇處開始,搜索匹配的二進位串。如果找到,則OllyDbg將顯示該內存塊。內存映像窗口和數據窗口共享同一種搜索模式,所以您可以在彈出的數據窗口中立即繼續搜索該二進位串出現的下一位置。按Esc鍵可以關閉數據窗口。

搜索下一個[Search next](快捷鍵:Ctrl+L) - 繼續上次搜索。

設置訪問中斷[Set break-on-access] (快捷鍵:F2,僅在WindowsNT/2000下可用) - 保護整個內存塊。當中斷髮生后OllyDbg暫停被調試程序並清除斷點。這類斷點在您想捕捉調用或返回到某個模塊的時候特別有用。

清除訪問中斷[Remove break-on-access] (快捷鍵:F2) - 從內存塊中清除訪問中斷保護。

設置內存訪問斷點[Set memory breakpoint on access] - 在整個內存塊上設置斷點,每當該內存塊被訪問時程序都將中斷。OllyDbg只支持一個內存訪問斷點。在
Windows95/98下,當系統程序訪問含有內存斷點的內存塊時,可能會導致所被調試程序崩潰,因此,不到萬不得已,請不要設置這種斷點。

設置內存寫入斷點[Set memory breakpoint on write] - 在整個內存塊上設置斷點,每當該內存塊被寫入數據時程序都將中斷。在Windows95/98下,當系統程序訪問含有內存斷點的內存塊時,可能會導致所被調試程序崩潰,因此,不到萬不得已,請不要設置這種斷點。

清除內存斷點[Remove memory breakpoint] - 清除內存斷點。

清除自解壓內存斷點[Remove SFX memory breakpoint] - 停止搜索自解壓程序[self-extractable (SFX) program]的真實入口。這個搜索使用了特殊類型的內存斷點。

訪問設置[Set access] -設置整個內存塊的保護屬性,可選擇的有:


禁止訪問[No access]
只讀[Read only]
讀/寫[Read/write]
執行[Execute]
執行/讀[Execute/read]
完全訪問[Full access]

複製到剪切板[Copy to Clipboard]


整行[Whole line] -以多行文本(包括解釋)的方式把所選記錄複製到剪切板,如果複製時想排除某些列,可將該列的寬度置為最小(該欄剩餘的邊框將變灰)。

整個表格[Whole table] -以多行文本的方式將整個內存映像信息複製到剪切板,該文本的第一行為窗口標題("內存映射[Memory map]"), 第二行為列標題欄,後面幾行的內容為內存數據記錄。複製將保持列的寬度。如果複製時想排除某些列,可將該列的寬度置為最小(該欄剩餘的邊框將變灰)。十一,監視與監察器[Watches and inspectors]

監視[Watch] 窗口包含若干個表達式[expressions]。它在第二列里顯示這些表達式的值。OllyDbg 會把這些表達式保存到主模塊的.UDD文件中,因此它們在下一次調試時同樣有效。

監察器[inspector]是顯示若干變數、1/2維數組或是選定項目結構數組[selected items of array of structures]的獨立窗口。它的表達式與監視窗口中的基本相同,只是多包含了兩個參數:%A和%B。您可以指定這兩個參數的界限,OllyDbg 將會用所有可能的組合代替表達式中的%A和%B。從0開始一直到界限(不包含界限),並在表格中顯示結果。參數%B(列數)的界限不能超過16。

例如,如果您指定了表達式%A+%B,並且限定%A和%B的上限為3,您將獲得如下的表格:
十三,線程[Threads]

OllyDbg 以簡單而有效的線程管理為特色。如果您單步調試、跟蹤、執行到返回或者執行到所選,則線程管理器將停止除當前線程以外的所有線程。即使當前線程被掛起,它也會將其恢復。在這種情況下,如果您手動掛起或者恢複線程,動作將被延期。如果您運行被調試的應用程序,OllyDbg將恢復最初的線程狀態。(從調試器的角度來看,Hit跟蹤[hit trace]和自由運行是等效的)。

依據這種方案,線程窗口可能會有如下五種線程狀態:


激活[Active]       - 線程運行中,或被調試信息暫停t
掛起[suspended]       - 線程被掛起
跟蹤[Traced]       - 線程被掛起,但OllyDbg正在單步跟蹤此線程
暫停[Paused]       - 線程是活動的,但OllyDbg臨時將其掛起,並在跟蹤其它的線程
結束[Finished]       - 線程結束
.

線程窗口同時也顯示了最後的線程錯誤(GetlastError函數的返回值)並計算該線程以用戶模式和系統模式(僅NT/2000/XP)運行的時間。線程窗口還會高亮主線程的標識符。

以下在快捷菜單中可用:

刷新[Actualize] - 標記所有線程為舊的。

掛起[Suspend] - 掛起線程。

恢復[Resume] - 恢復先前掛起的線程。

設置優先順序[Set priority] - 調整進程中線程的優先順序。以下選項可用:

空閑[Idle]       - 進程中線程的最低優先順序
最低[Lowest]      
低[Low]      
標準[Normal]      
高[High]      
最高[Highest]      
時間臨界[Time critical]       - 最高優先順序
在CPU窗口打開[Open in CPU](雙擊)- 在CPU窗口中顯示所選線程的當前狀態。十四,複製到剪切板[Copy to clipboard]

整行[Whole line] -全部行--以多行文本的形式並帶註釋將所選記錄複製到剪切板。如果在複製時想排除某個欄目,可以將該欄的寬度置為最小(欄目的殘留部分將變灰)。

整個表格[Whole table] - 整個表格--以多行文本的形式將整個內存映象複製到剪切板,該文本的第一行包含窗口標題(「內存映射[Memory map]」),第二行是欄目標題,所有後繼行是內存數據記錄。複製將保持欄目的寬度。如果在複製時想排除某些欄目,可以將該欄的寬度置為最小(欄目的殘留部分將變灰)。十五,調用棧[Call stack]

調用棧窗口(快捷鍵:Alt+K)根據選定線程的棧,嘗試反向跟蹤函數調用順序並將其顯示出來,同時包含被調用函數的已知的或隱含的參數。如果調用函數創建了標準的堆棧框架(PUSH EBP; MOV EBP,ESP),則這個任務非常容易完成。現代的優化編譯器並不會為棧框架而操心,所以OllyDbg另闢蹊徑,採用了一個變通的辦法。例如,跟蹤代碼到下一個返回處,並計算其中全部的入棧、出棧,及 ESP 的修改。如果不成功,則嘗試另外一種辦法,這個辦法風險更大,速度也更慢:移動棧,搜索所有可能的返回地址,並檢查這個地址是否被先前的已分析的命令調用。如果還不行,則會採用啟髮式搜索。棧移動[Stack Walk]可能會非常慢。OllyDbg 僅在調用棧窗口打開時才會使用。

調用棧窗口包含5個欄目:地址[Address]、棧[Stack]、過程[Procedure],調用來自[Called from],框架[Frame]。地址[Adress]欄包含棧地址,棧[Stack]
欄顯示了相應的返回地址或參數值。

函數[Procedure](或 函數/參數[Procedure / arguments])顯示了被調用函數的地址,在某些情況下,OllyDbg並不能保證該地址是正確的並會添加如下標記之一:

?       找到的入口點不可靠
可能[Maybe]       OllyDbg無法找到精確的入口點,報告的地址是用啟髮式演算法猜測的。
包含[Includes]       OllyDbg無法找到入口點,僅知道該函數包含顯示的地址
通過按例標題欄上的按鈕或從菜單中選擇「隱藏/顯示參數[Hide/Show arguments]」,可以在顯示或隱藏函數的參數之間切換。

調用來自[Called from]用於顯示調用該函數的命令地址。最後一欄是框架[Frame]這一欄默認是隱藏的,如果框架指針的值(寄存器EBP)已知的話,則該欄用於顯示這個值。

當調用函數經過分析[analyzed].后,棧移動會更可靠並且迅速。十六,調用樹[Call tree]

調用樹(快捷鍵:在反彙編窗口中Ctrl+K)利用分析[Analysis]的結果來找出指定函數過程直接或間接調用的函數列表,同時列出指定函數過程被調用的地址。為了避免由此可能造成的副作用。調用樹會判斷選定函數是否明確地是遞歸的。「明確地」意味著它不會跟蹤目標未知的調用,比如CALL EAX。如果函數過程中有未知調用,調用樹將會添加標記「未知目標」。

某些函數調用將會添加如下註釋之一:


葉子[Leaf]       不調用其他函數
純函數[Pure]       不調用函數,不會產生副作用
單返回[RETN]       只有一個RETN 命令
系統[Sys]       系統動態鏈接庫中的函數。系統動態鏈接庫定義為保存在系統目錄下的動態鏈接庫。
如果想在調用樹上移動,可以雙擊「被調用[Called from]」或「調用/直接調用[Calls/Calls directly]」兩欄中的地址。調用樹窗口保存了移動記錄(快捷鍵「-」和「+」)。

如果被調試的程序包含幾個模塊,推薦您分析所有模塊。Call tree 不會試圖處理系統函數。十七,選項[Options]

外觀選項[Appearance options]

常規[General]
默認[Defaults]
對話框[Dialogs]
目錄[Directories]
字體[Fonts]
顏色[Colours]
代碼高亮[Code highlighting]

調試選項[Debugging options] (Alt+O)

安全[Security]
調試[Debug]
事件[Events]
異常[Exceptions]
跟蹤[Trace]
自解壓[SFX]
字元串[Strings]
地址[Addresses]
命令[Commands]
反彙編[Disasm]
CPU
寄存器[Registers]
棧[Stack]

分析1[Analysis 1]
分析2[Analysis 2]
分析3[Analysis 3]

即時調試[Just-in-time debugging]

添加到資源管理器[Add to Explorer]十八,搜索[Search]

OllyDbg 允許您使用以下的搜索方式:

符號名(標籤)[Symbolic name (label)]
二進位串[binary string]
常量[constant]
命令[command]
命令序列[sequence of commands]
模塊間調用[intermodular calls]
修改過的命令或數據[modified command or data]
自定義標籤[user-defined label]

自定義註釋[user-defined comment
文本字元串[text string]
Run跟蹤的記錄[record in run trace]
參考命令[referencing commands]
十九,自解壓文件[Self-extracting (SFX) files]

自解壓文件由提取程序和壓縮的原程序兩部分組成。當遇到自解壓文件(SFX)文件時,我們通常希望跳過解壓部分,而直接跳到原始程序的入口(真正的入口)。
OllyDbg 包含了幾個便於完成這一任務的功能。

通常提取程序的載入地址都在執行代碼之外。在這種情況下,OllyDbg 將這類文件均視作為自解壓文件(SFX)。

當自解壓選項[SFX options]要求跟蹤真正入口時,OllyDbg 在整個代碼節[Code section]設置內存斷點,最初這裡是空的,或者只包含壓縮數據。當程序試圖執行某個在這個保護區域的命令,而這些命令不是 RET 和 JMP 時,OllyDbg 會報告真正的入口。這就是提取工作的原理。

上面的方法非常慢。有另外一種比較快的方法。每次讀取數據發生異常時,OllyDbg 使這個4K內存區域變為可讀,而使原先可讀的區域變為無效。而每次發生寫數據異常時,
OllyDbg 使這個區域變為可寫,而使原先可寫的區域變為無效。當程序執行在保留的保護區域中的指令時,OllyDbg 報告真正的入口。但是,當真正的入口點在可讀或可寫區域內部時,報告的地址就可能有誤。

您可以糾正入口位置,選擇新的入口,從反彙編窗口的快捷菜單中選擇「斷點[Breakpoint]|設置真正的自解壓入口[Set real SFX entry here]」。如果相應的SFX選項是開啟的,OllyDbg下次可以迅速而可靠的跳過自提取程序。

注意:OllyDbg 在跟蹤採取了保護或者反調試技術的解壓程序時通常會失敗。  二十,單步執行與自動執行[Step-by-step execution and animation]

您可以通過按 F7(單步步入)或 F8(單步步過),對程序進行單步調試。這兩個單步執行操作的主要區別在於:如果當前的命令是一個子函數,按F7,將會進入子函數,並停在子函數的第一條命令上;而按 F8,將會一次運行完這個子函數。如果您單步步過的子函數中含有斷點或其他調試事件,執行將會被暫停,但 OllyDbg 會在子函數的后一條命令上,自動下一個斷點,而這個斷點您遲早會碰到。

如果被調試程序停在異常上,您可以跳過它,並轉到被調試程序建立的句柄處。只需簡單的 Shift 鍵和任何一個單步命令。

如果需要連續按F7、F8鍵上百次,您可以使用自動執行(Ctrl+F7或者Ctrl+F8)功能。在這種情況下,OllyDbg 將自動重複F7或者F8操作,並且實時更新所有的窗口。這個過程會在下面情況停止:


- 按 Esc 鍵或發出任何單步命令

- OllyDbg 遇到斷點

- 被調試程序發生異常

使用「+」和「-」按鍵,可以回朔以前的執行歷史[execution history].

注意:當執行停止時 OllyDbg 將會刷新大部分窗口。如果動態執行過程非常慢,可以嘗試關掉或最小化沒有用的窗口。

另外,更快捷的找到以前執行指令的辦法是Run跟蹤[run trace]。它將創建一個執行協議並告知您指定指令的執行時間和次數二一,Hit跟蹤[Hit trace]

Hit跟蹤能夠讓您辨別哪一部分代碼執行了,哪一部分沒有。OllyDbg的實現方法相當簡單。它將選中區域的每一條命令處均設置一個INT3斷點。當中斷髮生的時候,OllyDbg便把它去除掉,並把該命令標誌為命中[hit]。因為每個跟蹤斷點只執行一次,所以這種方法速度非常快。

在使用Hit跟蹤的時候,一定要注意不能在數據中設置斷點,否則應用程序極有可能崩潰。因此,您必須打開相關的菜單選項,以進行代碼分析[analyze]。我推薦您選擇嚴格或啟髮式函數識別[strict or heuristical procedure recognition]。如果選擇模糊[Fuzzy]的話,可能會產生很多難以容忍的錯誤,而且經常把本不是函數的代碼段識別成函數。

只要您在模塊中設置了跟蹤斷點,哪怕只設了一個,OllyDbg都會分配兩倍於代碼段大小的緩衝區。

注意:當您退出Hit跟蹤的時候,Run跟蹤也會同時退出。

[color=blue]Run 跟蹤[Run trace][/color]
Run跟蹤是一種反方向跟蹤程序執行的方式,可以了解以前發生的事件。您還可以使用Run跟蹤來了解運行的簡單統計[profile]。基本上,OllyDbg 是一步一步地執行被調試程序的,就像動畫[animation]演示一樣,但不會實時刷新窗口,最重要的是它能將地址、寄存器的內容、消息以及已知的操作數記錄到Run跟蹤緩衝區中。如果被調試的代碼是自修改的,您就能夠保存原始的命令。可以通過按Ctrl+F11(Run跟蹤步入,進入子函數)或者Ctrl+F12(Run跟蹤步過,一次執行完子函數)開始Run跟蹤,並用F12或者Esc鍵停止跟蹤。

您可以指定在Run跟蹤時執行每一步的條件集(快捷鍵:Ctrl+T)。如果條件符合,Run跟蹤將暫停。條件包括:


?當EIP在某個地址範圍內時暫停[Pause when EIP is in the address range];
?當EIP在某個地址範圍之外時暫停[Pause when EIP is outside the address range];
?當某個條件為真時暫停[Pause when some condition is true];
?當下一條指令可疑時暫停[Pause when next command is suspicious],比如: 可能為非法指令(根據在分析3[Analysis 3]中設定的規則而定),訪問不存在的內存,設置了單步陷阱標誌[single-step trap flag]或者越ESP界訪問棧。注意這個選項會明顯地(大約20%)減慢Run跟蹤的速度;

?當命令執行達到指定的次數(更確切的說,是添加到Run跟蹤的緩衝區裡面的命令數量)時暫停[Pause after specified number of commands is traced]。注意計數器不能自動歸零。也就是說,如果您設置指令次數為10,則在第10次執行到該命令時暫停,並不是該命令每執行10次就暫停一次。

?當下一條命令符合指定的樣式之一時暫停[Pause when next command matches one of the specified patterns]。您可以使用模糊命令和操作數[imprecise commands and operands]及匹配32位寄存器RA和RB,像R32一樣,這兩個寄存器可以替代任何通用32位寄存器,但是在同一條命令中其值是不能變的。而 RA 和 RB
在同一條命令中,則一定是不同的。例如,在程序中含有 XOR EAX,EAX; XOR ESI,EDX 兩條命令,兩條命令均符合樣式 XOR R32,R32;第一條命令符合樣式XOR RA,RA
;而等二條命令 XOR ESI,EDX 符合樣式XOR RA,RB。

毫無疑問,Run跟蹤需要足夠的內存,每條命令平均需要佔用16到35位元組,同時速度也非常慢。在500-MHZ處理器、Windows NT環境下,它每秒能跟蹤5000條指令。
Windows95更慢:每秒鐘僅2200條指令。但是在許多情況下,例如當一個程序跳轉到不存在的地址的時候,這是找到原因的唯一方法。您可以在Run跟蹤時將準線性命令序列(即序列尾部只有唯一出口)跳過。當OllyDbg遇到這些需跳過的命令序列時,會設置一個臨時斷點,然後跟進到序列中,並一次運行完。當然了,如果排除命令中返回或跳轉的地址在跟蹤範圍之外,將可能導致跟蹤發生錯誤;因此OllyDbg會檢查您想跳過的代碼塊,如果存在上述情況,會向您詢問。

在大多數情況下,您對跟蹤系統API代碼不感興趣。跟蹤選項總是跟過系統DLL[Always trace over system DLLs]允許您在 跟蹤/自動 模式下跟過API函數。如果模塊在系統目錄下,OllyDbg就假設該模塊是系統的。您可以在模塊[Modules]窗口中標記任意DLL是系統的或者非系統的。

為了使執行速度更快,您可以通過設置Run跟蹤斷點,先將Run跟蹤限制在選定的命令或代碼塊上,然後再運行程序。我把這種做法稱作「強迫Run跟蹤」。一般來說,刪除Run跟蹤斷點不會移除Hit跟蹤斷點。但如果您刪除了hit跟蹤斷點,同時您也移除了Run跟蹤斷點。


跟蹤命令會保存到跟蹤緩衝區中,這個緩衝區在跟蹤開始時自動創建。您可以在選項中指定它的大小(最高64MB)。這個緩衝區是循環隊列,當滿了的時候,會丟棄老的記錄。

您可以通過從OllyDbg主菜單中選擇「調試[Debug]|打開或者清除Run跟蹤[Open or clear run trace]」,來打開或者清除Run跟蹤緩衝區。在Run跟蹤緩衝區打開后,
OllyDbg 會記錄在執行過程中的所有暫停,甚至那些不是由Run跟蹤引起的暫停。例如,您可以通過按 F7 或者 F8 單步執行程序,然後通過使用+鍵和-鍵來反方向跟蹤程序的執行。注意:如果Run跟蹤緩衝區已經關閉,則用這些鍵瀏覽的是歷史[history]記錄。在您查看Run跟蹤記錄時,寄存器和信息面板會變灰,來強調它們所顯示的寄存器並不是實際的寄存器。跟蹤緩衝區並不保存棧頂或由寄存器所指向的內容。寄存器、信息和棧在Run跟蹤的時候使用實際的內存狀態來解釋寄存器的變化。

OllyDbg能夠記下每個指令在Run跟蹤緩衝區裡面出現的次數。在反彙編窗口快捷菜單中,選擇是「查看[View]|統計作為註釋[Profile as comments]」。這個命令使用統計取代了註釋欄。或者,如果列標題欄可見,則可以單擊它幾次直到它顯示統計信息。注意顯示出來的數字是動態的,而且不計算已經從跟蹤緩衝區中丟棄的指令。您還可以在單獨的統計窗口[Profile window]中,按觸發次數排序,來查看整個模塊的統計數據。

在反彙編窗口的快捷菜單中選擇「Run跟蹤[Run trace]|添加到所有函數入口處[Add entries of all procedures]」,這樣能夠檢查每個可識別的函數被調用的次數。另一個命令「Run跟蹤[Run trace]|添加到函數中所有的分支[Add branches in procedure]」會強行跟蹤此函數中所有識別的跳轉目的地址的內容。在這種情況下,統計功能能夠找到最頻繁執行的分支,您可以優化這部分的代碼,以提高速度。

在反彙編窗口中的某條命令上使用快捷菜單中選擇「搜索[Search for]|Run跟蹤的最新記錄[Last record in run trace]」用於查找該命令是否被執行過,如果執行過,最後一次執行在哪裡。


Run跟蹤窗口顯示跟蹤緩衝區的內容。對每個指令來說包括被指令改變的整數寄存器的內容(更準確的說是給定的記錄變成下一條記錄的變化)。如果您雙擊某條指令,窗口會選擇在跟蹤緩衝區里全部含有該命令的記錄,而且您可以通過按+和-鍵來快速的瀏覽;如果您在調試選項[Debugging options]中設置了 「跟蹤[Trace]|同步CPU和
Run跟蹤[synchronize CPU and Run trace]」,雙擊記錄則會跟進到對應的反彙編窗口中位置。

注意:當您退出Hit跟蹤時,您同時也強行退出了Run跟蹤。通用快捷鍵[Global shortcuts]

無論當前的OllyDbg窗口是什麼,這些快捷鍵均有效:


Ctrl+F2 - 重啟程序,即重新啟動被調試程序。如果當前沒有調試的程序,OllyDbg會運行歷史列表[history list]中的第一個程序。程序重啟后,將會刪除所有內存斷點和硬體斷點。
譯者註:從實際使用效果看,硬體斷點在程序重啟后並沒有移除。

Alt+F2 - 關閉,即關閉被調試程序。如果程序仍在運行,會彈出一個提示信息,詢問您是否要關閉程序。

F3 - 彈出「打開32位.EXE文件」對話框[Open 32-bit .EXE file],您可以選擇可執行文件,並可以輸入運行參數。

Alt+F5 - 讓OllyDbg總在最前面。如果被調試程序在某個斷點處發生中斷,而這時調試程序彈出一個總在最前面的窗口(一般為模式消息或模式對話框[modal message or dialog]),它可能會遮住OllyDbg的一部分,但是我們又不能移動最小化這個窗口。激活OllyDbg(比如按任務欄上的標籤)並按Alt+F5,OllyDbg將設置成總在最前面,會反過來遮住剛才那個窗口。如果您再按一下Alt+F5,OllyDbg會恢復到正常狀態。OllyDbg是否處於總在最前面狀態,將會保存,在下一次調試時依然有效。當前是否處於總在最前面狀態,會顯示在狀態欄中。

F7 - 單步步入到下一條命令,如果當前命令是一個函數[Call],則會停在這個函數體的第一條命令上。如果當前命令是是含有REP前綴,則只執行一次重複操作。

Shift+F7 - 與F7相同,但是如果被調試程序發生異常而中止,調試器會首先嘗試步入被調試程序指定的異常處理(請參考忽略Kernel32中的內存非法訪問)。

Ctrl+F7 - 自動步入,在所有的函數調用中一條一條地執行命令(就像您按住F7鍵不放一樣,只是更快一些)。當您執行其他一些單步命令,或者程序到達斷點,或者發生異常時,自動步入過程都會停止。每次單步步入,OllyDbg都會更新所有的窗口。所以為了提高自動步入的速度,請您關閉不必要成窗口,對於保留的窗口最好盡量的小。按Esc鍵,可以停止自動步入。

F8 - 單步步過到下一條命令。如果當前命令是一個函數,則一次執行完這個函數(除非這個函數內部包含斷點,或發生了異常)。如果當前命令是含有REP前綴,則會執行完重複操作,並停在下一條命令上。

Shift+F8 - 與F8相同,但是如果被調試程序發生異常而中止,調試器會首先嘗試步過被調試程序指定的異常處理(請參考忽略Kernel32中的內存非法訪問)。

Ctrl+F8 - 自動步過,一條一條的執行命令,但並不進入函數調用內部(就像您按住F8鍵不放一樣,只是更快一些)。當您執行其他一些單步命令,或者程序到達斷點,或者發生異常時,自動步過過程都會停止。每次單步步過,OllyDbg都會更新所有的窗口。所以為了提高自動步過的速度,請您關閉不必要成窗口,對於保留的窗口最好盡量的小。按Esc鍵,可以停止自動步過。

F9 - 讓程序繼續執行。

Shift+F9 - 與F9相同,但是如果被調試程序發生異常而中止,調試器會首先嘗試執行被調試程序指定的異常處理(請參考忽略Kernel32中的內存非法訪問)。

Ctrl+F9 - 執行直到返回,跟蹤程序直到遇到返回,在此期間不進入子函數也不更新CPU數據。因為程序是一條一條命令執行的,所以速度可能會慢一些。按Esc鍵,可以停止跟蹤。

Alt+F9 - 執行直到返回到用戶代碼段,跟蹤程序直到指令所屬於的模塊不在系統目錄中,在此期間不進入子函數也不更新CPU數據。因為程序是一條一條執行的,所以速度可能會慢一些。按Esc鍵,可以停止跟蹤。

Ctrl+F11 -Run跟蹤步入,一條一條執行命令,進入每個子函數調用,並把寄存器的信息加入到Run跟蹤的存儲數據中。Run跟蹤不會同步更新CPU窗口。

F12 - 停止程序執行,同時暫停被調試程序的所有線程。請不要手動恢複線程運行,最好使用繼續執行快捷鍵或菜單選項(像 F9)。

Ctrl+F12 - Run跟蹤 步過,一條一條執行命令,但是不進入子函數調用,,並把寄存器的信息加入到Run跟蹤的存儲數據中。Run跟蹤不會同步更新CPU窗口。

Esc - 如果當前處於自動運行或跟蹤狀態,則停止自動運行或跟蹤;如果CPU顯示的是跟蹤數據,則顯示真實數據。

Alt+B - 顯示斷點窗口。在這個窗口中,您可以編輯、刪除、或跟進到斷點處。

Alt+C - 顯示CPU窗口。

Alt+E - 顯示模塊列表[list of modules]。

Alt+K - 顯示調用棧[Call stack]窗口。

Alt+L - 顯示日誌窗口。

Alt+M - 顯示內存窗口。

Alt+O - 顯示選項對話框[Options dialog]

Ctrl+P - 顯示補丁窗口。

Ctrl+T - 打開 暫停 Run跟蹤 對話框

Alt+X - 關閉 OllyDbg。

大多數窗口都支持以下的鍵盤命令:


Alt+F3 - 關閉當前窗口。

Ctrl+F4 - 關閉當前窗口。

F5 - 最大化當前窗口或將當前窗口大小改為正常化。

F6 - 切換到下一個窗口。

Shift+F6 - 切換到前一個窗口。

F10 - 打開與當前窗口或面板相關的快捷菜單。

左方向鍵 - 顯示窗口左方一個位元組寬度的內容。

Ctrl+左方向鍵 - 顯示窗口左方一欄的內容。

右方向鍵 - 顯示窗口右方一個位元組寬度的內容

Ctrl+右方向鍵 - 顯示窗口右方一欄的內容


[color=blue]反彙編窗口中的快捷鍵[Disassembler shortcuts][/color]

當CPU窗口中的反彙編面板[Disassembler pane]處於激活狀態時,您可以使用以下快捷鍵:

回車鍵 - 將選中的命令添加到命令歷史[command history]中,如果當前命令是一個跳轉、函數或者是轉換表的一個部分,則進入到目的地址。

退格鍵 - 移除選中部分的自動分析信息。如果分析器將代碼誤識別為數據,這個快捷鍵就非常有用。請參考解碼提示[decoding hints].

Alt+退格鍵 - 撤消所選部分的修改,以備份數據的相應內容替換所選部分。僅當備份數據存在且與所選部分不同時可用。

Ctrl+F1 -如果API幫助文件已經選擇,將打開與首個選擇行內的符號名相關聯的幫助主題。

F2 -在首個選擇的命令上開關INT3 斷點[Breakpoint],也可以雙擊該行第二列。

Shift+F2 -在首個選擇命令設置條件斷點,參見忽略Kernel32中內存訪問異常[Ignore memory access violations in Kernel32]。

F4 -執行到所選行,在首個選擇的命令上設置一次性斷點,然後繼續執行調試程序,直到OllyDbg捕獲到異常或者停止在該斷點上。在程序執行到該命令之前,該一次性斷點一直有效。如有必要,可在斷點窗口[Breakpoints window]中刪除它。

Shift+F4 -設置記錄斷點(一種條件斷點,當條件滿足時一些表達式的值會記錄下來), 詳情參見斷點[Breakpoint]。

Ctrl+F5 -打開與首個選擇的命令相對應的源文件。

Alt+F7 -轉到上一個找到的參考。

Alt+F8 -轉到下一個找到參考。

Ctrl+A -分析當前模塊的代碼段。

Ctrl+B - 開始二進位搜索。

Ctrl+C -複製所選內容到剪貼板。複製時會簡單地按列寬截斷不可見內容,如果希望排除不需要的列,可把這些列的寬度調整到最小。

Ctrl+E -以二進位(十六進位)格式編輯所選內容。

Ctrl+F -開始命令搜索。

Ctrl+G -轉到某地址。該命令將彈出輸入地址或表達式的窗口。該命令不會修改 EIP。

Ctrl+J -列出所有的涉及到該位置的調用和跳轉,在您用這個功能之前,您必須使用分析代碼功能。

Ctrl+K - 查看與當前函數相關的調用樹[Call tree]。在您用這個功能之前,您必須使用分析代碼功能。

Ctrl+L - 搜索下一個,重複上一次的搜索內容。

Ctrl+N - 打開當前模塊的名稱(標籤)列表。

Ctrl+O - 掃描object文件。掃描Object文件。該命令會顯示掃描Object文件對話框,您可以在該對話框中選擇Object文件或者lib文件,並掃描這個文件,試圖找到在實際代碼段中用到的目標模塊。

Ctrl+R -搜索所選命令的參考。該命令掃描激活模塊的全部可執行代碼,以找到涉及到首個選中的命令的全部相關參考(包括:常量、跳轉及調用),您可以在參考中使用快捷鍵 Alt+F7 和 Alt+F8來瀏覽這些參考。為便於您使用,被參考的命令也包含在該列表中。

Ctrl+S -命令搜索。該命令顯示命令查找[Find command]對話框供您輸入彙編命令,並從當前命令開始搜索。

星號[asterisk](*) -轉到原始位置(激活線程的EIP處)。

Ctrl+星號(*) - 指定新的起始位置,設置當前所選線程的EIP為首個選擇位元組的地址。您可以在選擇EIP並撤消該操作。

加號[Plus](+) -如果run跟蹤[run trace] 沒有激活,則根據命令歷史[command history]跳到下一條運行過命令的地方;否則跳到Run跟蹤的下一個記錄。

Ctrl+加號 - 跳到前一個函數開始處。(注意只是跳到,並不執行)

減號[Minus](-) - 如果run跟蹤[run trace] 沒有激活,則根據命令歷史[command history]跳到前一條運行過命令的地方;否則跳到Run跟蹤的前一個記錄。

Ctrl+減號 - 跳到下一個函數開始處。(注意只是跳到,並不執行)

空格[Space] - 修改命令。您可在顯示對話框中以彙編語言修改實際指令或輸入新指令,這些指令將替換實際代碼,您也可以在想要修改的指令處雙擊滑鼠。

冒號[Colon](:) - 添加標籤。顯示添加標籤窗口[Add label]或修改標籤窗口[Change label],您可在此輸入與首個選擇的命令中的第一個位元組相關聯的標籤(符號名)。注意,在多種編程語言中,冒號可以是標籤的一部分。

分號[semicolon](;) - 添加註釋[comment]。顯示添加註釋窗口[Add label]或修改註釋窗口[Change label],您可在此輸入與首條所選命令的第一個位元組相關聯的註釋(註釋串會顯示在最後一列中)。注意,多種彙編語言使用分號作為註釋開始。您也可以在註釋列雙擊需要註釋的命令行。
插件[Plugins]

插件是一個DLL,存放在OllyDbg的目錄中,用於增加 OllyDbg 的功能。您可以從 OllyDbg 的主頁上([url]http://home.t-online.de/home/Ollydbg[/url])免費下載插件開發工具包
plug110.zip。

插件可以設置斷點,增加標籤和註釋,修改寄存器和內存。插件可以添加到主菜單和很多的窗口(比如反彙編窗口、內存窗口)的快捷菜單中,也可以攔截快捷鍵。插件還可以創建MDI(多文檔界面)窗口。插件還可以根據模塊信息和OllyDbg.ini文件,將自己數據寫到.udd文件中;並能讀取描述被調試程序的各種數據結構。插件API包含了多達170
個函數。

許多第三方插件都可以從Internet網上獲得,比如由網友TBD創建並維護的OllyDbg的論壇([url]http://ollydbg.win32asmcommunity.net[/url])。

安裝插件的方法:將DLL複製到插件目錄[plugin directory]中,然後重新啟動Ollydbg。默認情況下,這個插件目錄為ollydbg.exe文件所在的目錄。

現在的版本中已經包含了兩個「原始」插件: 書籤[bookmark] and 命令行[Command line]. 他們的源代碼都保存在plug110.zip.文件中。這些插件都是免費的,您可以任意修改或使用它們。

[color=blue]技巧提示[Tips and tricks][/color]

?OllyDbg 可以作為二進位編輯器使用。選擇視圖[View]→文件[File]並選定需要查看的文件。文件不能大於剩餘內存數量。

?假使您修改了內存中的執行文件,這時您想恢復修改的部分,但是您忘記哪裡被修改了,您可以把原始文件當作備份進行載入,這樣您就可以找到修改的部分了。

分析前,先掃描 OBJ 文件。這時 OllyDbg 會對已知 C 函數的參數進行解碼。

一些表格中包含了隱藏數據。可以通過增加列寬來顯示出來。

所有數據窗口(包括反彙編窗口),可以通過雙擊顯示相對的地址。

您可以通過 Ctrl +↑ 或 Ctrl+↓ 對數據窗口翻動一個位元組。

[color=darkblue]調試獨立的DLL[Debugging of stand-alone DLLs][/color]

打開DLL,也可以直接將其從資源管理器拖放到 OllyDbg 上。OllyDbg 會詢問您並將該文件的全路徑作為參數傳遞給loaddll.exe.。然後鏈接庫被載入並停在代碼的入口(
)。您可以設置斷點,運行或跟蹤啟動代碼,等等。在初始化完成後,應該程序會再次暫停。這次停在標籤名為 Firstbp 的位置,其在立即進入主消息循環之前。


現在,您可以調用DLL函數。從主菜單選擇「調試[Debug]|調用DLL輸出[Call DLL export]」。這時會彈出一個對話框。由於這個對話框是無模式對話框,因此您仍然能夠使用OllyDbg的全部功能,比如查看代碼、數據,查看斷點,修改內存等等。
選擇您想調用的函數。例如我們將開始使用 user32.dll 里的MessageBox 函數。注意loaddll.exe 已經使用了這個鏈接庫,因此會假定這個 DLL 已經初始化而不再調用入口。MessageBox 這個函數名是通用函數名,實事上,這個函數有處理 ASCII 的 MessageBoxA 和處理 Unicode 的MessageBoxW 兩種。我們繼續往下看:在我們選擇這個函數后,右邊的消息框中會出現 Number of arguments: 4(有四個參數)的字樣。OllyDbg 會根據函數尾部的RET 10語句來正確識別參數的數量。RET nnn
是使用PASCAL調用約定的函數的典型特徵。(參數被放入棧中,第一個參數會被最後一個壓入棧中,函數調用完畢后,參數會被遺棄)。大多數的 Windows API 函數都是
PASCAL形式的。

下一步,我們要設定棧中參數的個數。在這個例子中,不必做進行這個操作,因為OllyDbg已經知道了MessageBoxW函數的參數數量。但是,如果您願意的話,也可以單擊左邊的複選框,改變成您認為合適的參數數量

現在填寫參數列表。這個對話框中支持至多10個參數. 參數可以是任何有效的表達式,而不必使用寄存器。如果操作數指向了內存,則參數右邊的緩衝區窗口會顯示內存中的數據。Loaddll.exe 有10個大小為1K的緩衝區,這些緩衝區被標記為Arg1 .. Arg10,,您可以方便自由的使用它們。 另外,對話框還支持兩個偽變數:由loaddll.exe創建的父窗口句柄, 以及loaddll的實例句柄。為了方便您的使用,在您第一次使用調用輸出函數時,OllyDbg就已經將這兩個偽變數加到了歷史列表中去了。

MessageBoxW e函數需要4個參數:


?父窗口句柄。 這裡我們選擇 ;handle of owner window. Here, we simply select ;
?在消息框中UNICODE文本的地址。選擇Arg2並按回車。緩衝區窗口會以16進位的格式顯現內存中的緩衝區。這個緩衝區初始化全是0。點擊第一個位元組,並按快捷鍵
Ctrl+E(另外, 也可以從菜單中選擇「二進位[Binary]|編輯[Edit]」)。這時會出現一個對話框,在對話框中鍵入「Text in box」或者其他希望顯示的字元串;

?消息框標題的UNICODE文本的地址。選擇Arg3並在Unicode格式的內存中寫上「Box title」;
?消息框的風格。使用常量MB_xxx進行組合.OllyDbg 可以識別這些常量。在這裡我們鍵入:MB_OK|MB_ICONEXCLAMATION。

這裡不需要寄存器參數。

現在我們準備調用輸出函數。選項「在調用時隱藏[Hide on call]」意思是說,當函數運行時對話框將會從屏幕消失。當我們執行一個會運行很長時間的函數,或者設置了斷點的時候,這個選項非常的有用。您也可以手動關閉對話框。當函數執行完畢后,OllyDbg會重新自動打開。「調用輸出函數」對話框。選項「在調用后暫停[Pause after call]」意思是說,在執行完函數后,loaddll將會被暫停。

按「調用[Call]按鈕」后,OllyDbg 會自動備份所有的內存、校驗、參數、寄存器等信息。並隱藏對話框,然後調用 MessageBoxW 函數。和期望的一樣,消息框在屏幕中出現了:
[img]http://groups.msn.com/_Secure/0cgDvAt0gqCx*VnJiVlT79*fFmiyfIJrL1diSHtf7m4m3LNGaibFjk1iUQSsMo3d!8GXeH6em0*I9Mk21pTpPMxIYYOtm2HvNluWwbU*OK*oFBjq4eIf0ezBiGKAKJKdU67ObrqhBIK9jR!25g*3Ow5dP08iL4hVZNZyO0JeS8Bc/%E8%B0%E8%AF%E7%AC%E7%AB%E7DLL2.JPG?dc=4675538092381011503[/img]
函數 MessageBoxW 不會修改參數。如果您調用的函數更新了內存,比如函數 GetWindowName,修改的位元組將會在數據區里高亮。注意:EAX 返回值為1,表示成功。

其他的例子請訪問我的網站:
[url]http://home.t-online.de/home/Ollydbg/Loaddll.htm.[/url]

不幸的是,您不能通過這種方式調試OllyDbg的插件,插件關聯到ollydbg.exe文件,Windows系統不能在同一個應用程序里載入並運行兩個可執行文件。

[color=blue]解碼提示[Decoding hints][/color]
在某些情況下,分析器不能區分代碼和數據。讓我們看看下面的例子:


const char s[11] = "0123456789";
...
for (i=0x30; i內存中間碼

內存中間碼 = 中間碼| { 符號標誌 大小標誌 前綴} [表達式 ]

中間碼 = (表達式)| 一元操作符 內存中間碼 | 帶符號寄存器 | 寄存器 | FPU寄存器 | 段寄存器 | 整型常量 | 浮點常量 | 串常量 | 參數 | 偽變數

一元操作符 = ! | ~ | + |

帶符號寄存器 = 寄存器.

寄存器 = AL | BL | CL ... | AX | BX | CX ... | EAX | EBX | ECX ...

FPU寄存器 = ST | ST0 | ST1 ...

段寄存器 = CS | DS | ES | SS | FS | GS

整型常量 = . |  |  |

浮點常量 =

串常量 = ""

符號標誌 = SIGNED | UNSIGNED

大小標誌 = BYTE | CHAR | WORD | SHORT | DWORD | LONG | qword | FLOAT | DOUBLE | FLOAT10 | STRING | UNICODE

前綴 = 中間碼:

參數 = %A | %B       // 僅允許在監察器[inspector] 中使用

偽變數 = MSG       // 窗口消息中的代碼

這個語法並不嚴格。在解釋[WORD [EAX]]或類似的表達式時會產生歧義。可以理解為以寄存器EAX所指向地址的兩位元組內容為地址,所指向的雙字內容;也可以理解為以寄存器EAX所指向地址的四位元組內容為地址,所指向的兩位元組內容。而OllyDbg會將修飾符儘可能的放在地址最外面,所以在這種情況下,[WORD [EAX]] 等價於 WORD [[EAX]]。

默認情況下,BYTE、WORD 和 DWORD 都是無符號的,而CHAR、SHORT 和 LONG都是帶符號的。也可以使用明確的修飾符SIGNED 或 UNSIGNED。例如在二元操作時,如果一個操作數是浮點的,那麼另外一個就要轉成浮點數;或者如果一個是無符號膽,那麼另外一個要轉成無符號的。浮點類型不支持UNSIGNED。大小修飾符後面跟 MASM兼容關鍵字PTR(如:BYTE PTR)也允許的,也可以不要PTR。寄存器名和大小修飾符不區分大小寫。

您可以使用下面類C的運算符(0級最高):


優先順序       類型       運算符
0       一元運算符       ! ~ + -
1       乘除運算       * / %
2       加減運算       + -
3       位移動       >
4       比較        >=
5       比較       == !=
6       按位與       &
7       按位異或       ^
8       按位或       |
9       邏輯與       &&
10       邏輯或       ||
在計算時,中間結果以 DWORD 或 FLOAT10 形式保存。某些類型組合和操作是不允許的。例如:QWODRD 類型只能顯示;STRING 和 UNICODE 只能進行加減操作(像C語言里的指針)以及與 STRING、UNICODE 類型或串常量進行比較操作;您不能按位移動 浮點[FLOAT] 類型,等等。
自定義函數描述[Custom function descriptions]

概論[Introduction]

OllyDbg包含(做為內部資源)1900多種標準函數以及400多種標準C函數的名稱和參數。分析器[Analyzer] 用這些描述使被調試程序更加易懂。比較下面一個例子,分析器的函數CreateFont:


        PUSH OT.00469F2A               ; ASCII "Times New Roman"
        PUSH 12                          
        PUSH 2                          
        PUSH 0                         
        PUSH 0                          
        PUSH 0                          
        PUSH 0                       
        PUSH 0                          
        MOV EAX,DWORD PTR [49FA70]
        PUSH EAX
        PUSH 190                        
        PUSH 0                         

        PUSH 0                         
        PUSH 0                        
        PUSH 10                       
        CALL

這是分析后的:


        MOV EAX,DWORD PTR [49FA70]    
        PUSH OT.00469F2A               ; ?FaceName = "Times New Roman"
        PUSH 12                        ; ?PitchAndFamily = VARIABLE_PITCH|FF_ROMAN
        PUSH 2                         ; ?Quality = PROOF_QUALITY
        PUSH 0                         ; ?ClipPrecision = CLIP_DEFAULT_PRECIS
        PUSH 0                         ; ?OutputPrecision = OUT_DEFAULT_PRECIS
        PUSH 0                         ; ?CharSet = ANSI_CHARSET

        PUSH 0                         ; ?StrikeOut = FALSE
        PUSH 0                         ; ?Underline = FALSE
        PUSH EAX                       ; ?italic => TRUE
        PUSH 190                       ; ?Weight = FW_NORMAL
        PUSH 0                         ; ?Orientation = 0
        PUSH 0                         ; ?escapement = 0
        PUSH 0                         ; ?Width = 0
        PUSH 10                        ; ?Height = 10 (16.)

        CALL   ; ?CreateFontA

顯然,後面的代碼更容易理解。API函數CreateFont 有14個參數。分析器標記所有這些參數的名稱並解碼他們的值。如果寄存器跟蹤開啟,那麼分析器同時會解碼參數Italic
的值為地址49FA70處雙字長的內容。解碼使用參數的真實值,所以如果[49FA70]里的內容改變了,那麼參數Italic的值也會隨之改變。當EIP指向跳轉或調用該函數的命令,或指向入口時,OllyDbg也會在棧中對已知函數的參數進行解碼。

OllyDbg可以對像printf()這樣參數個數可變的函數進行參數解碼:

        PUSH EAX                       ; ?
        PUSH E8                        ; ? = E8 (232.)
        PUSH EBX                       ; ?
        PUSH Mymodule.004801D2         ; ?format = "Size %08X (%.*s) bytes"
        PUSH ESI                       ; ?s
        CALL Mymodule.sprintf          ; ?sprintf

您可以定義自己的函數。每次您打開某個應用程序時,OllyDbg都會重新設置函數參數表並用內嵌描述添充這個表。然後嘗試打開文件「\common.arg」和「\.arg」,這裡使用8.3格式(DOS)被調試程序文件名(不帶路徑和擴展名)。

下面看一個簡單的.arg文件實例:


        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 ""
          IF 00FFFFFF ""
          OTHERWISE
          TEXT "RGB("
          FIELD 000000FF
          UINT
          TEXT ","

          FIELD 0000FF00
          UINT
          TEXT ","
          FIELD 00FF0000
          UINT
          TEXT ")"
        END
        STDFUNC CreateHatchBrush
          "style" HS_X
          "colorref" COLORREF
        END

標準Windos API函數CreateHatchBrush(int style,int colorref) 有兩個參數。第一個必須是陰影風格[hatch style],第二個是常量由紅色、綠色、藍色組成,並用一個32
位整數的低三位元組表示。為了解碼這些參數,文件定義了兩個新的參數類型:HS_X 和 COLORREF。

陰影風格是一個簡單的枚舉類型,如0表示HS_HORIZONTAL(水平風格)、1表示HS_VERTICAL(垂直風格)。IF關鍵字比較參數與第一個操作數(注意:其總是十六進位的),如果相同則顯示第二個操作數里的文本。但萬一匹配失敗會如何?關鍵字ELSEINT 會然OllyDbg會將參數解釋為一個整數。

COLORREF 更複雜一些。首先嘗試解碼兩個廣泛使用的顏色值:黑(全0組成)與白(全0xFF組成)。如果匹配失敗,COLORREF嘗試解碼顏色為一個結構包含紅、綠、藍的亮度。FIELD會用第一個操作數與參數進行邏輯與操作。然後轉換結果為整數,並同時按位右移第一個操作及該整數,直到第一個操作數的二進位個位數字為1,這時整數按位右移的結果以無符號10進位顯示出來。這個例子做了三次這樣的操作,以分離出每個顏色成份。TEXT關鍵字用於無條件顯示文本。如果參數為00030201,那麼
COLORREF將其解碼為RGB(1.,2.,3.)。

大多斷API函數都會從棧中移除參數並保護寄存器EBX, EBP, ESI 和 EDI。聲明這樣的函數為STDFUNC,以告訴分析器該函數做了這樣的事情。否則請其描述為FUNCTION

萬一某個參數由多個域及比特值組成,比如上面提到的fdwPitchAndFamily ,我們該怎麼辦?請看下面這個例子:


        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

前兩個比特位(第0和等1位)表示傾斜度,必須一起解碼。我們使用 MASK 03 來提取這兩個比特並通過IF序列來解碼。增加了連接符「|」,分別提取第2和第3個比特位,並分別單獨解碼。最後提取剩餘部分並進行解碼。

OllyDbg 會移除生成串尾部的連接符「|」、空格、冒號、逗號、分號和等號。

目前版本的分析僅能夠解碼32位參數。如您不能解碼雙精度浮點或長雙精度浮點的函數參數。


格式描述

自定義解碼信息由函數描述和類型描述兩部分組成。函數描述部分非常的簡單:


FUNCTION|STDFUNC [模塊名]函數名
  
  ……
  
END

如果函數從棧中移除參數並保護寄存器EBX, EBP, ESI 和 EDI,請使用關鍵字STDFUNC。大多少函數都遵循這樣的規則。其他情況則聲明為FUNCTION。模塊(EXE 或 DLL)名是可選的。如果模塊名被忽略,OllyDbg會對嘗試匹配任何模塊。模塊名不區分大小寫。

函數名稱總是區分大小寫的。有針對UNICODE的函數必須使用後綴 A 或 W 加以區分,比如SetWindowTextA.。

參數的順序又C風格的參數使用慣例一致。而16位Windows和32位API函數也是按慣例使用。如果參數名由多個字組成,或者包含特殊字元,那麼請將其用兩個單引號引起來。與在C語言中一樣,省略號(叄┦且桓鎏厥獾募鍬加糜詒硎靜問 靠殺洹K 匭朐諍 枋齙淖詈蟆 llyDbg不會嘗試解碼這樣的參數。如果函數的參數為空,則按functionname(void)對待

OllyDbg 僅支持32位的參數。某些參數已經預定義好了:


INT              以十六進位和帶符號整數兩種格式顯示值
UINT              以十六進位和無符號整數兩種格式顯示值
HEX              以十六進位格式顯示值
BOOL              TRUE 或 FALSE
CHAR       ASCII 字元
WCHAR       UNICODE 字元
FLOAT       32位浮點數
ERRCODE       系統錯誤代碼(像由函數GetLastError()報告的)
ADDR, PTR              地址(特殊情況:NULL)
ASCII                      ASCII 串指針
UNICODE                    UNICODE 串指針
FORMAT       在類似函數printf()(不包括wscanfW()!)使用的 ASCII 格式串
WFORMAT       類似函數wsprintfW()(不包括scanf()!)使用的 UNICODE 格式串
RECT       RECT(矩形)結構指針
MESSAGE       MSG(ASCII 窗口消息)結構指針
WMESSAGE       MSG(UNICODE 窗口消息)結構指針
HANDLE              句柄(特殊情況:NULL, ERROR_INVALID_HANDLE)
HWND       窗口句柄
HMODULE       模塊句柄
RSRC_STRING                帶索引的資源串
NULL, DUMMY                       有參數,但解碼時跳過了
您不能重定義預定義類型。自定義類型允許您將參數分離成幾個域並分別解碼。類型描述有以下幾種格式:


TYPE 類型名
  [TEXT "任何文本"]
  []
 
 
  [TEXT "任何文本"]
  [PURGE]
  ...
 
 
 
  [TEXT "任何文本"]
END

類型名的程度限制在16個字元以內。 OllyDbg會無條件將"任何文本"作為生成的解碼。域選擇器提取一部分參數用於解碼。以下域選擇器,可以用於提取域:


MASK 十六進位掩碼 - 域等於參數同十六進位掩碼按位與(AND)的結果。

FIELD 十六進位掩碼 - 參數同十六進位掩碼按位與(AND)的數值,然後OllyDbg同時按位右移掩碼和計算的數值直到掩碼的二進位個位為1,這時數值按位右移的結果就是域的值。例如參數0xC250, FIELD F0,得到的結果是5。

SIGFIELD十六進位掩碼 -參數同十六進位掩碼按位與(AND)的數值,然後OllyDbg同時按位右移掩碼和計算的數值直到掩碼的二進位個位為1,這時數值按位右移的結果轉成帶符號32位數就是域的值。例如參數0xC250 ,SIGFIELD FF00,得到的結果是0xFFFFFFC2。

簡單域的解碼會一次顯示整個域的內容:


HEX - 以十六進位形式顯示域內容;

INT - 以帶符號十進位形式顯示域內容(帶小數點);

UINT -以無符號十進位形式顯示域內容(帶小數點);

CHAR - 以 ASCII 字元形式顯示域內容。

域若是一個枚舉類型,則可以使用IF序列,如果必要的話還可以在IF序列後跟關鍵字 TRYxxx 與 ELSExxx:


IF 十六進位值 "文本" - 如果域等於十六進位值,則將文本作為輸出字元串;

TRYASCII - 如果域是一個指向ASCII串的指針,則顯示這個串;

TRYUNICODE - 如果域是一個指向UNICODE串的指針,則顯示這個串;

TRYORDINAL - 如果域是一序號(有16位均為0),則會顯示為序號(「#」後跟整數);

OTHERWISE - 如果前面IF語句為真,則停止解碼,否則繼續解碼;


ELSEINT - 如果前面所有的 IF 和 TRYxxx 語句均失敗,則以帶符號十進位數形式(帶小數點)顯示這個域;

ELSEHEX -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以十六進位形式顯示這個域;

ELSECHAR -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以 ASCII 字元形式顯示這個域;

ELSEWCHAR -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以 UNICODE 字元形式顯示這個域。

如果域是一個二進位位集,則可以使用BIT序列,如果必要的話可以後面跟關鍵字 BITZ 與 BITHEX :

BIT 十六進位掩碼 "文本" - 如果值與十六進位掩碼按位與(AND)的結果不是0,則將文本做為輸出串;

BITZ十六進位掩碼 "文本" - 如果值與十六進位掩碼按位與(AND)的結果是0,則將文本做為輸出串;

BITHEX十六進位掩碼 - 如果值與十六進位掩碼按位與(AND)的結果不是0,則將結果以十六進位形式顯示。

特殊關鍵字 PURGE 會從輸出串尾部移除以下幾種符號:


空格       ' '
逗號       ','
或       '|'
冒號       ':'
等於       '='
這會讓某些解碼情況變的簡單。關鍵字END是類型定義結尾標記並會自動運行PURGE命令。


預編譯類型

OllyDbg在預編譯資源時,已經包含150多種類型描述。以下列出了一部分。您可以在自定義文件中直接使用這些類型:


LANG_X - 操作系統語言ID(0 - 未知、 9 - 語言、 C - 法語,等等)

GENERIC_X - 訪問類型(GENERIC_READ, GENERIC_WRITE...)

FILE_SHARE_X - 共享類型(FILE_SHARE_READ, FILE_SHARE_WRITE)

CREATEFILE_X - 文件創建模式(CREATE_NEW, OPEN_EXISTING...)

FILE_ATTRIBUTE_X - 文件屬性(READONLY, SYSTEM, DELETE_ON_CLOSE...)

RT_AXX - 資源類型(RT_CURSOR, RT_GROUP_ICON, ASCII string...)

RT_WXX - 資源類型(RT_CURSOR, RT_GROUP_ICON, UNICODE string...)

coord - 坐標結構 "(X=xxx,Y=yyy)"

STD_IO_X - 標準句柄(STD_INPUT_HANDLE, STD_ERROR_HANDLE...)

GMEM_X - 全局內存類型(GMEM_FIXED, GPTR...)

LMEM_X - 局部內存類型(LMEM_FIXED, LPTR...)

FSEEK_X - 文件查找類型(FILE_BEGIN, FILE_CURRENT...)

OF_X - 文件模式(fOF_READ, OF_SHARE_COMPAT, OF_VERIFY...)

O_X - 文件創建模式(O_RDONLY, O_BINARY, SH_COMPAT...)

SEMAPHORE_X - 信號量類型(SEMAPHORE_ALL_ACCESS, SYNCHRONIZE...)

SLEEP_TIMEOUT - 超時(INFINITE 或時間)

ROP - 一些標準柵格運算標誌代碼(ROP)(SRCCOPY, MERGEPAINT...)

COLORREF - RGB 顏色值("", "RGB(rr.,gg.,bb.)"...)

WS_X - 窗口風格(WS_OVERLAPPED, WS_POPUP...)

WS_EX_X - 擴展窗口風格(WS_EX_DLGMODALFRAME, WS_EX_TOPMOST...)

MF_X - 菜單標誌(MF_BYPOSITION, MF_ENABLED...)

WM_X - ASCII窗口消息類型(WM_CREATE, WM_KILLFOCUS, CB_SETCURSEL...)

WM_W - UNICODE窗口消息類型(WM_CREATE, WM_KILLFOCUS, CB_SETCURSEL...)

VK_X - 虛擬鍵盤代碼(VK_LBUTTON, VK_TAB, VK_F10...)

MB_X - message box style (MB_OK, MB_ICONHAND...)

HKEY_X - 預定義註冊表句柄(HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE...)

還有更多的預編譯類型。如果常量在它文件被定義為ABC_ xxxxxxxx,那麼一般就有ABC_X預編譯類型

 

上一篇[神木出雲]    下一篇 [方灘鄉]

相關評論

同義詞:暫無同義詞