界面構成
啟動程序。未打開調試文件時,空白狀態如下:
如上圖所示幾個部分:
1、反匯編窗口:顯示被調試程序的反匯編代碼,標題欄上的地址、HEX 數據、反匯編、注釋可以通過在窗口中右擊出現的菜單 界面選項->隱藏標題 或 顯示標題 來進行切換是否顯示。用鼠標左鍵點擊注釋標簽可以切換注釋顯示的方式。
2、寄存器窗口:顯示當前所選線程的 CPU 寄存器內容。同樣點擊標簽 寄存器 (FPU) 可以切換顯示寄存器的方式。
3、信息窗口:顯示反匯編窗口中選中的第一個命令的參數及一些跳轉目標地址、字串等。
4、數據窗口:顯示內存或文件的內容。右鍵菜單可用於切換顯示方式。
5、堆棧窗口:顯示當前線程的堆棧。
6、菜單窗口:顧名思義,一些命令以及操作、顯示等都在這里。
7、命令行窗口:用來下斷點等相關命令。
除了直接啟動 OllyDBG 來調試外,我們還可以把 OllyDBG 添加到資源管理器右鍵菜單,這樣我們就可以直接在 .exe 及 .dll 文件上點右鍵選擇“用Ollydbg打開”菜單來進行調試。要把 OllyDBG 添加到資源管理器右鍵菜單,只需點菜單 選項->添加到瀏覽器,將會出現一個對話框,先點擊“添加 Ollydbg 到系統資源管理器菜單”,再點擊“完成”按鈕即可。要從右鍵菜單中刪除也很簡單,還是這個對話框,點擊“從系統資源管理器菜單刪除 Ollydbg”,再點擊“完成”就行了。
OllyDBG 支持插件功能,插件的安裝也很簡單,只要把下載的插件(一般是個 DLL 文件)復制到 OllyDBG 安裝目錄下的 PLUGIN 目錄中就可以了,OllyDBG 啟動時會自動識別。要注意的是 OllyDBG 1.10 對插件的個數有限制,最多不能超過 32 個,否則會出錯。建議插件不要添加的太多。
到這里基本配置就完成了,OllyDBG 把所有配置都放在安裝目錄下的 ollydbg.ini 文件中。
打開文件后的狀態如下
打開要測試的文件:文件-打開,或第一個文件夾打開圖標,或按 F3 - 彈出“打開32位.EXE文件”對話框[Open 32-bit .EXE file],您可以選擇可執行文件,並可以輸入運行參數。
下邊是已經打開TraceMe.exe后的界面。
A區域為反匯編代碼區
B區為寄存器區
C區為 Dump經轉儲而產生的那些數據,內存映像區
D區為Stack of pila 堆棧中轉區
反匯編CUP代碼窗口詳解如下:
-
反匯編窗口
OllyDbg在這里顯示反匯編代碼,我們將要以OllyDbg的默認配置調試分析你打開的程序。 調試選項可以在Options->Debugging options里更改。
-
寄存器
第二個重要的窗口——寄存器窗口
-
堆棧窗口
默認情況下,它顯示ESP寄存器指向的信息(也是最重要的),但是你可以改變它的顯示模式來顯示來自涉及EBP的信息。這需要在這個窗口上點擊右鍵,選擇GO to EBP。再次點擊右鍵選擇Go to ESP,回到先前窗口。
-
數據窗口(dump)
默認的模式是最常用的,我們還可以改變它以顯示反匯編代碼(Disassemble),文本(Text)和其它格式(Short,Long,Float)。
現在我們了解了OllyDbg的最主要的四個窗口。還有一些窗口沒有直接顯示,可以通過菜單或控制面板上的圖標按鈕訪問。
1 匯編程序地址 2 機器碼 3 反匯編語句(語法表達式) 4 注釋信息窗口
(內存地址\ 十六進制(偏移值)\ 反匯編代碼 \ 注釋)
5 FPU寄存器信息 6 Flag軍旗指向。你要在匯編里改那條跳轉指令, 使程序執行到那里時執行同等你改Z flag的效果。 比如說把JMP改成jz, JZ改成nop等。
7 中轉數據倉庫地址 8 HEX二進制代碼 9 文本ASC代碼 10、11 堆棧窗口:顯示ESP寄存器指向的信息(也是最重要的)
12 CUP執行情況反饋 14 直接輸入匯編指令窗口 15 程序運行狀態顯示
16 快捷命令圖標 17 程序運行、暫停、中止狀態信息。
A、代碼窗口(OllyDbg幫助文件自稱反匯編窗口),顯示被調試程序的代碼。他有四個列
1、地址/Address(虛擬地址)。在代碼窗口(地址行,不是列標題)雙擊時完成動作。●地址(Address)列:顯示相對被雙擊地址的地址,再次雙擊返回標准地址模式;
2、HEX數據/HEX dump(機器碼)。●HEX數據(HEX dump)列:設置或取消無條件斷點,按F2鍵也能設置斷點;
3、/Disassembly(反匯編)。●反匯編(Disassembly)列:調試編輯器,可直接修改匯編代碼;
4、注釋/Comment(注釋)●注釋(Comment)列:允許增加或編輯注釋。最后一列注釋(Comment)顯示相關API參數或運行簡表,非常有用,有點類似於IDA Pro。
代碼窗口允許瀏覽、分析、搜索和修改代碼,保存改變到可執行文件,設置斷點等。相關彈出式菜單包括100多項。
B、信息窗口(Information window)
動態跟蹤時,與指令相關的各寄存器的值、API函數調用提示、跳轉提示等信息顯示。
C、數據窗口
以十六進制或內存方式顯示文件在內容中的數據,類似於softICE的數據窗口。要顯示數據可單擊右鍵"轉到→表達式(Go to→expression)"或按Ctrl+G鍵打開地址窗口,輸入地址。
D、寄存器(Registers window)
顯示CPU各寄存器的值,支持浮點(FPU)、MMX,3DNow!寄存器,可以單擊鼠標右鍵切換。
E、堆棧窗口(Stack window)
堆棧窗口非常重要,各API函數、子程序等都利用它傳遞參數、變量等。OllyDbg堆棧窗口功能強大。如果傳遞的參數都是字符串,OllyDbg會在注釋里直接將其顯示出來,再也不用像SoftICE那樣經常用D命令查看內存數據了。
F、其他窗口
OD 快捷方式
按鈕1=F3,打開被調試的exe文件。按鈕2=CTRL+F2,重新加載被調試的程序。按鈕3=ALT+F2,關閉被測試的文件。
1=F9運行,2=F12暫停,3=F7單步入,4=F8單步過,5=CTRL+F11跟蹤步入,6=CTRL+F12跟蹤步過
7=CTRL+F9 執行到返回,8=轉到反匯編窗口的地址
l : log 查看OD運行的日志信息
e :被調試exe程序所加載的所有模塊的信息(加載基址,大小,入口(OEP),名稱,版本,路徑)
OEP:(Original Entry Point)
m :程序的內存映射視圖(memory map)
t :線程信息
w :窗口windows信息
h :handles 句柄表
c :顯示CPU窗口(反匯編窗口)ALT+c
/ :P,顯示補丁(Patches)信息 CTRL+P
k :調用堆棧 ALT+K
b :軟件斷點列表 Alt+B
r :顯示參考(數據引用等) references
... : RUN跟蹤軌跡,run trace
s: 源碼source顯示窗口
OD快捷方式
F2:斷點,CTRL+F2 重加載程序!
F3 打開要操作的程序。
F4: 運行到光標處
F7: 單步
F8: 步過
*** 后撤一步:小鍵盤上的頭號(-)
F9: 運行,SHIFT+F9(次數為程序運行的次數-1次
Shift+F9 - 與F9相同,但是如果被調試程序發生異常而中止,調試器會首先嘗試執行被調試程序指定的異常處理(請參考忽略Kernel32中的內存非法訪問)。
Ctrl+F9 - 執行直到返回,跟蹤程序直到遇到返回,在此期間不進入子函數也不更新CPU數據。因為程序是一條一條命令執行的,所以速度可能會慢一些。按Esc鍵,可以停止跟蹤。
Alt+F9 - 執行直到返回到用戶代碼段,跟蹤程序直到指令所屬於的模塊不在系統目錄中,在此期間不進入子函數也不更新CPU數據。因為程序是一條一條執行的,所以速度可能會慢一些。按Esc鍵,可以停止跟蹤。
————————————————
Ctrl+A :分析代碼(函數,參數...)
Ctrl+G : 跳轉到
Ctrl+X : 復制地址
Ctrl+E :修改內存
Ctrl+B :二進制搜索
Ctrl+F :指令搜索(單條指令)
Ctrl+S :指令搜索(多條指令)
Ctrl+F9 :運行到返回(ret指令位置)
Ctrl+F12: 重啟調試
Ctrl+Shift+x :復制二進制數據
調試中我們經常要用到的快捷鍵有這些:
F2:設置斷點,只要在光標定位的位置(上圖中灰色條)按F2鍵即可,再按一次F2鍵則會刪除斷點。
F4:運行到選定位置。作用就是直接運行到光標所在位置處暫停。
F7:單步步入。功能同單步步過(F8)類似,區別是遇到 CALL 等子程序時會進入其中,進入后首先會停留在子程序的第一條指令上。
F8:單步步過。每按一次這個鍵執行一條反匯編窗口中的一條指令,遇到 CALL 等子程序不進入其代碼。
F9:運行。按下這個鍵如果沒有設置相應斷點的話,被調試的程序將直接開始運行。
CTR+F9:執行到返回。此命令在執行到一個 ret (返回指令)指令時暫停,常用於從系統領空返回到我們調試的程序領空。
ALT+F9:執行到用戶代碼。可用於從系統領空快速返回到我們調試的程序領空。
上面提到的幾個快捷鍵對於一般的調試基本上已夠用了。要開始調試只需設置好斷點,找到你感興趣的代碼段再按 F8 或 F7 鍵來一條條分析指令功能就可以了。
http://pan.baidu.com/s/1dDGO8GL
第一章-OD的各個窗口介紹
第二章-數制系統
第三章-寄存器
第四章-匯編指令
第五章-數學指令
第六章-比較和條件跳轉指令
第七章-call,ret
第八章-循環,字符串指令和尋址方式
第九章-基本概念
第十章-斷點
第十一章-硬件斷點與條件斷點
第十二章-消息斷點
第十三章-硬編碼序列號尋蹤-Part1
第十四章-硬編碼序列號尋蹤-Part2
第十五章-硬編碼序列號尋蹤-Part3
第十六章-序列號生成算法分析-Part1
第十七章-序列號生成算法分析-Part2
第十八章-序列號生成算法分析-Part3
第十九章-OllyDbg反調試之IsDebuggerPresent
第二十章-OllyDbg反調試之檢測OD進程名
第二十一章-OllyDbg反調試之檢測OD進程名,窗口類名,窗口標題名
第二十二章-OllyDbg反調試之UnhandledExceptionFilter,ZwQueryInformationProcess
第二十三章-OllyDbg反調試之ProcessHeap,NTGlobalFlag,OutputDebugStringA
第二十四章-OllyDbg反調試之綜合練習
第二十五章-異常處理
第二十六章-Visual Basic程序的破解-Part1
第二十七章-Visual Basic程序的破解-Part2
第二十八章-Visual Basic程序的破解-Part3
第二十九章-P-CODE-Part1
第三十章-P-CODE-Part2
第三十一章-脫殼簡介
第三十二章-OEP尋蹤
第三十三章-神馬是IAT,如何修復
第三十四章-手脫UPX,修復IAT
第三十五章-手脫ASPack V2.12
第三十六章-IAT重定向
第三十七章-論IAT重定向之修復
第三十八章-手脫Yoda's Crypter v1.3
第三十九章-何謂stolen bytes
第四十章-OllyDbg腳本的編寫
第四十一章-神馬是AntiDump
第四十二章-ACProtect V1.09脫殼(尋找OEP,繞過硬件斷點的檢測,修復Stolen code)
第四十三章-ACProtect V1.09脫殼(編寫腳本修復IAT)
第四十四章-ACProtect V1.09脫殼(修復AntiDump)
第四十五章-ReCrypt v0.80脫殼
第四十五章補充章節-ReCrypt v0.80脫殼(續)
第四十六章-Patrick的CrackMe-Part1
第四十七章-Patrick的CrackMe-Part2
第四十八章-PeSpin V1.3.04脫殼-Part1
第四十九章-PeSpin V1.3.04脫殼-Part2
第五十章-再談ReCrypt v.0.80脫殼(調戲OutputDebugString)
第五十一章-ASProtect v2.3.04.26脫殼-Part1
第五十二章-ASProtect v2.3.04.26脫殼-Part2
第五十三章-TPPpack脫殼
第五十四章-EXECryptor v2.2.50.a脫殼-Part1
第五十五章-EXECryptor v2.2.50.a脫殼-Part2
第五十六章-EXECryptor v2.2.50.b脫殼
第五十七章-EXECryptor v2.2.50.c/d/e/f/g脫殼
第五十八章-EXECryptor v2.2.50.h脫殼
百度網盤下載:
http://pan.baidu.com/s/1dDGO8GL
詳細介紹
運行環境:OllyDbg 可以以在任何采用奔騰處理器的 Windows 95、98、ME、NT 或是 XP(未經完全測試)操作系統中工作,但我們強烈建議您采用300-MHz以上的奔騰處理器以達到最佳效果。還有,OllyDbg 是極占內存的,因此如果您需要使用諸如追蹤調試[Trace]之類的擴展功能話,建議您最好使用128MB以上的內存。
* 目前測試 OllyDbg 可以運行在任意Windows x86架構的平台下。
支持的處理器 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:幾乎所有支持 ASCⅡ 的操作同時也支持 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 個中斷。
監視與監察器:每個監視都是一個表達式並能實時顯示表達式的值。您可以使用寄存器、常數、地址表達式、布爾值以及任何復雜代數運算,您還可以比較ASCⅡ和UNICODE
字符串。監察器[inspectors]是一種包含了兩個的索引序列的監視[Watches],它以二維表的形式呈現,可以對數組和結構進行解碼分析。
Heap walk.:在基於Win95的系統中,OllyDbg 可以列出所有的已分配的堆。
句柄:在基於NT的系統中,OllyDbg 可列出被調試程序的所有系統句柄。
執行:.您可以單步執行、步入子程序或者步過子程序。您也可以執行程序直到函數返回時、執行到指定地址處,還可以自動執行。當程序運行時,您仍然可以操縱程序並能夠查看內存、設置斷點甚至修改代碼。您也可以任意的暫停或重啟被調試的程序。
Hit跟蹤:.Hit跟蹤可以顯示出目前已執行的指令或函數過程,幫助您檢驗代碼的各個分支。Hit跟蹤會在指定指令到達之前設置斷點,而在這個指令執行后,會把這個斷點清除掉。
譯者注:Hit在英文中是"擊中"的意思,指令如果運行了就表示這個指令被"擊中"了,沒有執行的指令就是"未擊中",這樣我們就很容易看出被調試程序哪些部分運行了,而哪些沒有運行。
Run跟蹤:Run跟蹤可以單步執行程序,它會在一個很大的循環緩沖區中模擬運行程序。這個模擬器包含了除了SSE指令集以外的所以寄存器、標志、線程錯誤、消息、已經函數的參數。您可以保存命令,這樣可以非常方便地調試自修改代碼(譯者注:比如加殼程序)。您可以設置條件中斷,條件包括地址范圍、表達式、命令。您可以將Run
跟蹤信息保存到一個文件中,這樣就可以對比兩次運行的差別。Run跟蹤可以回溯分析已執行過的上百萬條命令的各種細節。
OllyDbg完全支持 UNICODE,幾乎所有對 ASCⅡ字符串的操作都可以同樣應用於 UNICODE。
匯編指令都是很相似的。您經常會搞不清自己是不是已經跟蹤過某一段代碼。在 OllyDbg 中您可以加入自己的標簽[labels]和注釋[comments]。這些極大地方便了調試。注意一旦您注釋了某個DLL,以后每次加載這個DLL時,注釋和標簽都有效----盡管您在調試不同的程序。
OllyDbg可以跟蹤標准的棧幀[stack frames](由PUSH EBP; MOV EBP,ESP所創建的)。現代編譯器有禁止產生標准棧框架的選項,在這種情況下分配棧[stack walk
]是不可能的。當程序運行到已知的函數時,棧窗口[stack window]解析它的參數,調用棧[Call stack]窗口顯示到達當前位置所調用函數的序列。
現代的面向對象應用程序廣泛地使用了一種叫做結構化異常處理[Structured Exception Handling,SEH]的技術。SEH窗口[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位擴展操作系統無法實現某些必需的調試功能。
函數[Procedure](或 函數/參數[Procedure / arguments])顯示了被調用函數的地址,在某些情況下,OllyDbg並不能保證該地址是正確的並會添加如下標記之一:
找到的入口點不可靠
可能[Maybe] OllyDbg無法找到精確的入口點,報告的地址是用啟發式算法猜測的。
包含[Includes] OllyDbg無法找到入口點,僅知道該函數包含顯示的地址
通過按例標題欄上的按鈕或從菜單中選擇"隱藏/顯示參數[Hide/Show arguments]",可以在顯示或隱藏函數的參數之間切換。
調用來自[Called from]用於顯示調用該函數的命令地址。最后一欄是框架[Frame]這一欄默認是隱藏的,如果框架指針的值(寄存器EBP)已知的話,則該欄用於顯示這個值。
當調用函數經過分析[analyzed].后,棧移動會更可靠並且迅速。十六,調用樹[Call tree]
調用樹(快捷鍵:在反匯編窗口中Ctrl+K)利用分析[Analysis]的結果來找出指定函數過程直接或間接調用的函數列表,同時列出指定函數過程被調用的地址。為了避免由此可能造成的副作用。調用樹會判斷選定函數是否明確地是遞歸的。"明確地"意味着它不會跟蹤目標未知的調用,比如CALL EAX。如果函數過程中有未知調用,調用樹將會添加標記"未知目標"。
某些函數調用將會添加如下注釋之一:
當自解壓選項[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跟蹤將暫停。條件包括:
當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 這個函數名是通用函數名,實事上,這個函數有處理 ASCⅡ 的 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 函數。
函數 MessageBoxW 不會修改參數。如果您調用的函數更新了內存,比如函數 GetWindowName,修改的字節將會在數據區里高亮。注意:EAX 返回值為1,表示成功。
不幸的是,您不能通過這種方式調試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 ; ASCⅡ "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 "FⅨED_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_DECORATⅣE"
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語言中一樣,OllyDbg不會嘗試解碼這樣的參數。如果函數的參數為空,則按functionname(void)對待
OllyDbg 僅支持32位的參數。某些參數已經預定義好了:
INT ;以十六進制和帶符號整數兩種格式顯示值
UINT ;以十六進制和無符號整數兩種格式顯示值
HEX ;以十六進制格式顯示值
BOOL TRUE 或 FALSE
CHAR ASCⅡ 字符
WCHAR UNICODE字符
FLOAT 32位浮點數
ERRCODE 系統錯誤代碼(像由函數GetLastError()報告的)
ADDR,PTR ;地址(特殊情況:NULL)
ASCⅡ ASCⅡ 串指針
UNICODE UNICODE 串指針
FORMAT 在類似函數printf()(不包括wscanfW()!)使用的 ASCⅡ 格式串
WFORMAT 類似函數wsprintfW()(不包括scanf()!)使用的 UNICODE 格式串
RECT RECT(矩形)結構指針
MESSAGE MSG(ASCⅡ 窗口消息)結構指針
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 - 以 ASCⅡ 字符形式顯示域內容。
域若是一個枚舉類型,則可以使用IF序列,如果必要的話還可以在IF序列后跟關鍵字 TRYxxx 與 ELSExxx:
IF 十六進制值 "文本" - 如果域等於十六進制值,則將文本作為輸出字符串;
TRYASCⅡ - 如果域是一個指向ASCⅡ串的指針,則顯示這個串;
TRYUNICODE - 如果域是一個指向UNICODE串的指針,則顯示這個串;
TRYORDINAL - 如果域是一序號(有16位均為0),則會顯示為序號("#"后跟整數);
OTHERWISE - 如果前面IF語句為真,則停止解碼,否則繼續解碼;
ELSEINT - 如果前面所有的 IF 和 TRYxxx 語句均失敗,則以帶符號十進制數形式(帶小數點)顯示這個域;
ELSEHEX -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以十六進制形式顯示這個域;
ELSECHAR -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以 ASCⅡ 字符形式顯示這個域;
ELSEWCHAR -如果前面所有的 IF 和 TRYxxx 語句均為失敗,則以 UNICODE 字符形式顯示這個域。
如果域是一個二進制位集,則可以使用BIT序列,如果必要的話可以后面跟關鍵字 BITZ 與 BITHEX :
BIT 十六進制掩碼 "文本" - 如果值與十六進制掩碼按位與(AND)的結果不是0,則將文本做為輸出串;
BITZ十六進制掩碼 "文本" - 如果值與十六進制掩碼按位與(AND)的結果是0,則將文本做為輸出串;
BITHEX十六進制掩碼 - 如果值與十六進制掩碼按位與(AND)的結果不是0,則將結果以十六進制形式顯示。
常見問題
怎樣保存ollydbg的調試信息以便下次使用?
調試菜單->;選擇符號路徑 然后在彈出的對話框設置路徑即可。注意調試文件為udd格式,,當被調試文件路徑發生變化時調試信息不再可用,,比如:你在C盤有一個文件用ollydby調試並加入注視或斷點后,,把這個文件移到別的路徑下,再用ollydbg打開調試信息注視和斷點不被顯示。
注意:斷點和注釋窗口只能查看到當前模塊的斷點和注釋,且當前被ollydbg分析為代碼的斷點和注釋才能被看到。