主要介紹
軟體
名稱,一個新的動態追蹤工具,將IDA與SoftIce結合起來的思想,Ring 3級調試器,非常容易上手,己代替SoftICE成為當今最為流行的調試解密工具了.同時還支持外掛程式擴展功能,是目前最強大的調試工具.
相關條目
追蹤調試器流行工具外掛程式
一,什麼是 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 ,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 = "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預編譯類型
常見問題
怎樣保存ollydbg的調試信息以便下次使用?
調試選單->;選擇符號路徑 然後在彈出的對話框設定路徑即可。注意調試檔案為udd格式,,當被調試檔案路徑發生變化時調試信息不再可用,,比如:你在C糟有一個檔案用ollydby調試並加入注視或斷點後,,把這個檔案移到別的路徑下,再用ollydbg打開調試信息注視和斷點不被顯示。
注意:斷點和注釋視窗只能查看到當前模組的斷點和注釋,且當前被ollydbg分析為代碼的斷點和注釋才能被看到。