反汇编基础、OllyDbg简介和界面、基本操作、初级TraceMe练习
? ? 以下使用的練習示例是《Windows程序設計》第五版第一章的HelloMsg.exe;以及《加密與解密》第三版附帶的RebPE.exe;
?
一 反匯編基礎
1 字節順序
字節存儲順序
? ? 和CPU有關;微處理器的存放順序有正序(Big-Endian),逆序(Little-Endian);Intel逆序,Power-PC正序;
? ? 正序:高位字節存入低地址,低位字節存入高地址;
? ? 逆序:反之;
十進制7869,十六進制是1EBD;
看一下此數在emu8086中的存放;Intel逆序;低位字節存入低地址,高位字節存入高地址;
1E是高位字節,BD是低位字節;
1E存入01001單元,BD存入01000單元,逆序;
2 調試符號
Windows調試基礎 - 符號
? ? 當應用程序被鏈接以后,代碼被逐一地翻譯為一個個的地址。
? ? 使用vs或者windbg等微軟的調試工具進行調試的時候,可以方便地使用變量名來查看內存、可以使用函數名稱來下斷點、可以指定某個文件的某一行來下斷點。
? ? 這一切背后,是符號在指導調試器工作,pdb或者dbg文件。
? (.NET自己有元數據,符號不需要元數據已有的信息)。
? ? 程序運行的時候,計算機只需要逐條執行指令即可。而與源代碼對應的關系是完全不需要知道的。這就給調試帶來了困難。
? ? 無論什么編譯都有自己的一套用于對應代碼和可執行程序。各種編譯器都有自己保存類似這種對應關系的辦法,有的直接嵌入可執行文件,有的則是獨立出來的。
? ? 而微軟的編譯器則是獨立產生了這種文件,它就被成為符號文件。
? ? 符號文件一般都是pdb文件。
? ? pdb文件,根據微軟官方的解釋,包含有: 全局變量;局部變量;函數名及入口點;FPO記錄;源代碼行號。
3?調試寄存器機制
利用調試寄存器機制
? ? Win操作系統提供了兩種層次的進程控制和修改機制:
? ? ? ? 跨進程內存存取機制;
? ? ? ? Debug API 監控目標進程運行信息;
? ? 這兩種是運行在“操作系統”層次之上的。
? ? 自386以后,Intel公司已經在其CPU內部集成了Dr0-Dr7一共8個調試寄存器;并且對EFLAGS標志寄存器的功能也進行了擴展,使其也具有一部分調試的能力。
? ? 調試信息通知機制。
? ? 作為接收方,不能直接接收DrX調試寄存器發出來的中斷/異常信息,Windows已經將這個調試信息包裝到了Debug API 體系中,每當DrX調試信息被觸發時,ExceptionRecord.ExceptionCode部分都被設置成EXCEPTION_SINGLE_STEP,只需要在Debug API 循環中接受這個消息就可以達到目的。
? ? 自Win2000起,CreateProcess后,沒有辦法在目標進程的入口點地址處中斷,常見的解決辦法有兩種。
? ? 1 利用Single Step機制
? ? 2 利用ntdll.ntcontinue作為跳板
?
二 OllyDbg 簡介和界面
1
OllyDbg,簡稱OD;www.ollydbg.de;
結合了動態調試和靜態分析;
調試Ring 3級程序的首選工具;
可識別大量被C和Windows頻繁使用的函數,并能將其參數注釋出;
開放插件接口,功能變得越來越強;
當前默認窗口是CPU窗口,調試的大部分操作在這個窗口中進行;它包含5個面板窗口:反匯編面板,寄存器面板,信息面板,數據面板,堆棧面板;
2
OllyDbg的配置
? ? 配置在菜單Options里,有界面選項、調試選項,配置保存在ollydbg.ini文件里;
? ? Options-Appearance-Directories,設置UDD文件和插件的路徑;
? ? UDD文件是OllyDbg的工程文件,保存當前調試的一些狀態,斷點、注釋等;
? ? 將插件復制到目錄,主菜單會出現“Plugin”菜單項;
? ? 顏色:可根據喜好設置;
? ? 調試設置:一般按默認;異常(Exceptions),可以設置讓OllyDbg忽略或不忽略哪些異常;可以全選;
? ? 加載符號文件
? ? 可以讓OllyDbg以函數名顯示DLL中的函數。
? ? 例如MFC42.DLL是以序號輸出函數,在OllyDbg顯示的是序號,如果加載MFC42.DLL調試符號,則以函數名顯示相關輸出函數;
加載程序
? ? OllyDbg可以兩種方式加載目標調試程序:通過CreateProcess創建進程;利用DebugActiveProcess函數將調試器捆綁到一個正在運行的進程上;
三 工具條打開窗口
?
綠色一排按鈕用于打開各種窗口;
L:打開日志窗口;
E:打開可執行模塊窗口;
M:打開內存映射窗口;
W:打開窗口列表;指被反匯編的程序所包含的窗口;
T:打開線程窗口;查看被反匯編的程序所包含的線程;
C:打開CPU窗口;默認打開;
R:打開搜索結果窗口;
...:打開運行跟蹤窗口;
K:打開調用堆棧窗口;
四 常見問題和UDD目錄
?
OllyDbg常見問題
1 跟蹤程序時亂碼
? ? 這是因為OllyDbg將一段代碼當成數據;沒有進行反匯編識別;右鍵快捷菜單,執行 Analysis/Analyse code (分析/分析代碼);
? ? 不行,則執行菜單 Analysis/Remove analysis from module (分析/從模塊中刪除分析);或在UDD目錄中刪除相應的.udd文件;
2 快速回到當前領空
? ? 如果查看代碼翻頁到其他地方,想快速回到當前CPU所在的指令上,雙擊寄存器面板中的EIP或單擊
3 修改EIP
? ? 將光標移到需要的地址;執行右鍵菜單 New origin here (此處新建EIP);
4 在反匯編窗口鍵入匯編代碼,輸入 push E000,提示 未知標識符
? ? 不能識別E是字母還是數字;輸入 push 0E000;
啟動函數
在編寫Win32 應用程序時,都必須在源碼里實現一個WinMain函數;但Windows程序執行并不是從WinMain函數開始;首先被執行的是啟動函數相關代碼,這段代碼是編譯器生成的。
對于VC++程序,它調用的是C/C++運行時啟動函數,該函數負責對C/C++運行庫進行初始化。
對一個程序跟蹤調試后;退出時,此處調試情況默認保存在安裝目錄下,xxxx.udd文件中;
時間長了安裝目錄會亂;按圖2,設置新的UDD目錄;
?
五 運行代碼到指定地址情況1
?
裝載程序;
在CPU窗口右擊,選擇 轉到-表達式;
輸入欲運行代碼到的地址;假設要運行到004011B4;點擊 跟隨表達式;
光標定位到004011B4;
打F4,(F4是運行到光標,Execute till cursor),程序運行到004011B4停住;
六 運行代碼到指定地址情況2
?
裝載程序;
在CPU窗口右擊,選擇 轉到-表達式;
輸入欲運行代碼到的地址;假設要運行到00413033;點擊 跟隨表達式;
光標定位到00413033;
打F4,(F4是運行到光標,Execute till cursor),程序運行到75E305A0停住;
?
?
七 設置函數斷點
加載程序;
在反匯編代碼窗口右擊;選擇 搜索 - 名稱;
名稱窗口列出此程序調用的API函數;雙擊要下斷點的API函數;
反匯編代碼窗口定位到調用該API函數處;
按F2設置斷點;
八 對函數設置斷點以跟蹤
?
要跟蹤程序的C代碼如下;
#include <windows.h>
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
? ? ? ? ? ? ? ? ? ? PSTR szCmdLine, int iCmdShow)
{
? ? ?MessageBox (NULL, TEXT ("Hello, Windows 98!"), TEXT ("HelloMsg"), 0) ;
? ? ?return 0 ;
}
裝載程序;先練習跟蹤MessageBox函數;
打Ctrl+G,彈出對話框;輸入MessageBox;
點擊 跟隨表達式 按鈕;提示要選定一個匹配項;系統dll中以MessageBox打頭的函數有多個;
后綴A是ASCII版本;后綴W是寬字符版本;
此處選定MessageBoxA;
確定;自動定位到75231F70處;看CPU窗口第四列,此處是USER32.MessageBoxA函數的地址;
打F2在此行下一個斷點;可以點擊B按鈕,查看已經對此程序下的斷點;有2個,一個是前次下的;
現在只跟蹤MessageBoxA,禁用另一個斷點;在斷點上右擊彈出菜單即可禁用;
打F9運行程序;中斷在75231F70處;
九 反匯編單步步進和單步步過
?
OllyDbg
? ? F7,單步步進,遇到Call跟進;
? ? F8,單步步過,遇到Call跳過;
加載HelloMsg.exe;
停留在004011C0;這是一條Call語句;Call的地址是004027BC;
打F7,代碼運行到地址004027BC處;
重新加載程序;停留在004011C0;
打F8,程序運行到下一條,地址004011C5處;沒有跟進Call;
十 反匯編從call中返回
?
加載程序;停留在004011C0;
打F7單步步進,跳到004027BC;
執行數次F7,程序運行到004027C1;
現在想從此call中返回;打Ctrl+F9,執行到返回(Execute till return);OllyDbg會停在遇到的第一個返回命令(RET、RETF、IRET);在此是 00402851;
十一 對代碼段設置斷點
?
Ollydbg可以對代碼段設置斷點;
加載程序;
按 Alt+M 打開內存模板;對代碼段,此處是.text區塊,按F2鍵,設置內存訪問斷點;
運行程序;中斷在圖2;
十二 反匯編從系統地址空間返回應用程序領空
?
運行程序;按前述進入到系統地址空間,76F805A0;
看右側寄存器窗口,此地址處是系統dll,KERNEL32.dll;
打F7往前走幾步;運行到76F805A8;
Windows程序的內存布局中,7XXXXXXX通常是系統地址空間;0040XXXX通常是應用程序地址;
現在想返回應用程序地址空間;打Alt+F9;
程序返回到00402443;
十三 初級TraceMe練習
?
Win32 API 的GetDlgItemTextA函數獲取窗口上控件的文本;跟蹤此函數有可能獲取到密碼;
這是根據《加密與解密》第三版第2章所做的練習;使用的示例程序是原書附帶的TraceMe.exe;
?
操作細節只有2個地方和原書不一樣;
一個是ollydbg,右擊eax寄存器查看數據窗口時,非漢化版本的菜單是 Follow in Dump ,漢化版的菜單是 在轉儲跟隨 ;
一個是1.x版本,改變一條指令為nop空指令,是手動輸入nop;2.x版本已經在右鍵菜單中集成此功能,無需手動輸入nop;
ollydbg版本不同,生成的反匯編注釋略有差別;
1 裝載程序;
2 對 GetDlgItemTextA 函數設置斷點;
3 在程序窗口輸入用戶名pediy,隨便輸入個密碼;點 check 按鈕;
4 程序中斷在 GetDlgItemTextA 函數地址處;此處是 752468C0;
5 打Alt+F9回到調用函數的地方;004011B6;
先禁用 GetDlgItemTextA 斷點;
6 為了方便反復跟蹤;在004011AE處下一個斷點;
API 函數基本采用__stdcall調用約定:函數入口參數按從右到左的順序入棧,由被調用者清理棧中參數,返回值放在eax寄存器中;調用API前的push指令,這些push指令將參數放進堆棧以傳給API調用;
C代碼中的子程序采用C調用約定:函數入口參數按從右到左的順序入棧,由調用者清理棧中的參數;
GetDlgItemTextA函數,第一個參數是對話框句柄,第二個參數是控件標識(id),第三個參數是文本緩沖區指針,第四個參數是最大字符數;
7 push 51 ...... push esi,這四句是把調用GetDlgItemTextA需要的參數壓入堆棧;
8 打F8,使程序運行到004011B0停住;在寄存器窗口右擊EAX,在菜單選擇 在轉儲跟隨;
9,10 EAX內容為 0019F790,數據窗口定位到0019F790;此時數據窗口沒有什么有價值的;ASCII是些亂碼;
11 打F8,執行完CALL EDI一句;即調用了GetDlgItemTextA函數;獲取了用戶在對話框輸入的內容;
此時用戶輸入的用戶名,字符串pediy,出現在數據窗口;
12 004011E5 到 004011F5,這段是序列號的判斷核心,最后一句跳轉語句不跳轉,即可注冊成功;
13 使程序運行到004011F5停住;
14 此時可以在寄存器窗口,Z標志,右擊,選擇菜單 切換,改變Z標志的值為1或0,來判斷;
15,16 或者;右擊004011F5,選擇如圖15菜單;把此句跳轉指令改為NOP,空指令;
17 改為空指令后,判斷語句失效;隨便輸入的密碼注冊成功;
TraceMe先進行到此;密碼尚未破解;下回再搞;
總結
以上是生活随笔為你收集整理的反汇编基础、OllyDbg简介和界面、基本操作、初级TraceMe练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超图开发要点摘录
- 下一篇: Matlab简单系统仿真示例1