OllyDBG - 第五章 | 訊息斷點及RUN追蹤
教學文章提到,這個目的程式,使用OllyDBG - 第二章 | 字串參考、OllyDBG - 第三章 | 函數參考,兩種方法都可以容易找到斷點。
註:我這邊是沒有去實際操作是否可以使用
字串參考
和函數參考
就可以找到,有時間再試試看。
這篇文章主要是要說訊息斷點
和RUN追蹤
。
檔案下載
目的程式:
cycle.7z
解壓縮密碼:
1 | morosedog |
使用PEid檢驗
檢驗顯示是使用MASM32/TASM32[Overlay]
編寫。
開啟cycle.EXE
使用並分析
- 開啟 cycle.EXE
- 輸入
Name
和serial
Morose
、12345678
- 點擊「Check」按鈕
- 沒有反應
分析:看來要輸入正確,然後按下「Check」才會有反應
前言
在設訊息斷點前,有兩個內容我們要簡單瞭解一下:
訊息是幹什麼的
- Windows 的中文翻譯就是「視窗」,而 Windows 上面的套用程式也都是通過視窗來與使用者互動的。
- 現在就有一個問題,套用程式是如何知道使用者做了什麼樣的操作的?這裡就要用到訊息了。
- Windows 是個基於訊息的系統,它在套用程式開始執行後,為該程式建立一個「訊息佇列」,用來存放該程式可能建立的各種不同視窗的資訊。
- 比如你建立視窗、點擊按鈕、搬移滑鼠等等,都是通過訊息來完成的。
- 通俗的說,Windows 就像一個中間人,你要幹什麼事是先知會它,然後它才通過傳遞訊息的模式知會套用程式作出相應的操作。
- 說到這,又有個問題了,在 Windows 下有多個程式都在執行,那我點了某個按鈕,或把某個視窗最大化,Windows 知道我是點的哪個嗎?
- 這裡就要說到另一個內容:識別碼(handle)了。識別碼一般是個 32 位的數,表示一個對象。
- Windows 通過使用識別碼來標識它代表的對象。比如你點擊某個按鈕,Windows 就是通過識別碼來判斷你是點擊了那一個按鈕,然後傳送相應的訊息知會程式。
RUN追蹤是幹什麼的:
簡單的說,RUN追蹤就是把被除錯程式執行過的指令儲存下來,讓你可以檢視被除錯程式執行期間干了哪些事。RUN追蹤會把位址、暫存器的內容、訊息以及已知的操作數記錄到RUN追蹤緩沖區中,你可以通過檢視RUN追蹤的記錄來瞭解程式執行了那些指令。在這還要注意一個緩沖區大小的問題,如果執行的指令太多,緩沖區滿了的話,就會自動丟棄前面老的記錄。
設定RUN追蹤,可以點選選項
-> 除錯選項
-> 追蹤
開啟設定視窗
使用OllyDBG分析
- 啟動
OllyDBG
- 按下快捷鍵
F3
- 選擇
cycle.EXE
- 在入口點地址後面加上註解 (良好的註解有助於分析)
F9
運行程式- 輸入
Name
和serial
Morose
、12345678
- 先不要點擊「Check」按鈕
- 點擊選單上的
檢視
->視窗
(或是點擊「W」圖的按鈕)
- 會開啟
Windwos
視窗
- 分析
Windwos
內容 (行號為我自己加入的,用於方便表示)- 1 表示父視窗
- 2 看到類別為
Button
,標題為Check
,所以這個代表Chekc
的那顆按鈕 - 3、4 看到類別為
Edit
,可以判定為兩個輸入框 - 5、6 看到類別為
Static
,可以判斷為兩個標籤,分別為Name
和Serial
- 7、8 看到類別為
Button
,標題為About
;為什麼會有兩個,我的猜測是點擊About
後裡面還有一個確定
的按鈕 - 9、10 這個我不做解釋,怕解釋錯了⋯這邊暫時不需要知道。
注意:控制碼(句柄),每次重開程式後都會不一樣。
行號 | 控制碼 | 標題 | 父視窗 | WinProc | ID | 樣式 | 擴充樣式 | 緒程 | ClsProc | 類別 |
---|---|---|---|---|---|---|---|---|---|---|
1 | 00120274 | CycleCrackme | Topmost | 94C80A44 | 00010100 | 主 | 76AFAF83 | #32770 | ||
2 | 00070268 | Check | 00120274 | 00000066 | 50010000 | 00000004 | 主 | 76B058F1 | Button | |
3 | 00090234 | 00120274 | 000003E8 | 50010080 | 00000204 | 主 | 76B0167B | Edit | ||
4 | 000B0230 | 00120274 | 000003E9 | 50010080 | 00000204 | 主 | 76B0167B | Edit | ||
5 | 000B0244 | Name | 00120274 | 0000FFFF | 50020000 | 00000004 | 主 | 76B05164 | Static | |
6 | 000B025C | Serial | 00120274 | 0000FFFF | 50020000 | 00000004 | 主 | 76B05164 | Static | |
7 | 000B0260 | About | 00120274 | 00000067 | 50010000 | 00000004 | 主 | 76B058F1 | Button | |
8 | 000B0278 | About | 00120274 | 00000003 | 50010000 | 00000004 | 主 | 76B058F1 | Button | |
9 | 000D027C | Default IME | 00120274 | 8C000000 | 主 | 76B04411 | IME | |||
10 | 000F01C8 | MSCTFIME UI | 000D027C | 8C000000 | 主 | FFFF01DB | MSCTFIME UI |
- 針對
Chekc
按鈕的控制碼(句柄)右鍵 - 選擇
在ClassProc 上設訊息斷點
- 會開啟
在ClassProc 上設訊息斷點
視窗
- 點擊
訊息
下拉選單 - 會看到訊息真不少
註:這麼多訊息我們選哪個呢?註冊是個按鈕,我們就在按下按鈕再鬆開時讓程式中斷。
查一下 MSDN,我們知道這個訊息應該是WM_LBUTTON_UP
,看字面意思也可以知道是左鍵鬆開時的訊息 - 選擇
202 WM_LBUTTON_UP
- 按下
確定
,消息斷點就設定完畢
- 這邊會發現三個按鈕都被下了斷點
- 回到
OllyDBG
中 - 點擊選單上的
除錯
->開啟或清除RUN追蹤
註:第一次點這個選單是開啟RUN追蹤,在開啟的情況下點擊就是清除RUN追蹤的記錄,對RUN追蹤熟悉時還可以設定條件
- 保證目前在我們除錯的程式領空
- 在反匯編視窗中點擊右鍵選擇
RUN追蹤
->加入所有函數過程的入口
- 可以看到
OllyDBG
把識別出的函數過程都在前面加了灰色條
- 回到
cycle
程式,點擊「Check」按鈕 - 斷點到
76B058F1 > 8BFF mov edi,edi
- 此時要打開記憶體映射視窗
- 點擊選單上的
檢視
->記憶體
(或是點擊「M」圖的按鈕)
- 會開啟
Memory map
視窗
- 選中
00401000
,並設定斷點
為什麼在00401000
上設定斷點?
看完上面的圖我們應該瞭解為什麼在00401000
處的代碼段下斷點了
- 按下
F9
- 跳到中斷點,而且可以發現回到程式領空
註:當然在 401000 處所在的段不是絕對的,我們主要是要看程式的代碼段在什麼位置,其實在上面圖中
OllyDBG
記憶體視窗的「包括」欄中我們就可以看得很清楚了
- 按下
F9
- 選單檢視->RUN 追蹤
- 點擊選單上的
檢視
->RUN 追蹤
(或是點擊「…」圖的按鈕)
- 會開啟
Run trace
視窗
- 選中隨便一條
cycle
- 點擊右鍵選擇
統計模組
- 會開啟
統計用於 cycle
視窗 - 關心計數為
1
的地址 - 隨便對其中一點左鍵兩下就會跳到反匯編對應的相關代碼處
- 這邊就點
00401082
- 跳轉到
00401082 |> \837D 10 67 cmp dword ptr ss:[ebp+10],67
- 看不懂組合語言的情況下,看不到什麼關鍵的
- 繼續點另外一個計數為
1
的地址 - 這邊點
0040111F
- 跳轉到
0040111F |> \C3 retn
- 首先
retn
我猜是返回指令,所以假設為最後一個動作 - 我們往上看匯編可以看到一些熟悉的東西
- 所以我將斷點設定在
004010BE |. 6A 11 push 11 ; /Count = 11 (17.)
- 按下
Alt + B
開啟Breakpoints
視窗 - 將其它的斷點停用
76B058F1 USER32 Log "<WinProc>" mov edi,edi
停用
- 點擊選單上的
除錯
->關閉 RUN 追蹤
- 回到
cycle
程式,點擊「Check」按鈕 - 斷點到
004010BE |. 6A 11 push 11 ; /Count = 11 (17.)
- 我們就可以開始分析了
分段分析
(以下在本人對組合語言不懂的情況下分析,所以以下為不負責任分析,如有錯誤請鞭小力一點)
- 分析過程中,會發現斷點到
cmp ecx,11
後jnz short 0040111F
就跳到ret
了。
1 | 00401100 |> \83F9 11 cmp ecx,11 ; 比較注冊碼的長度是否為十進制的17 |
- 下斷點在
00401100 |> \83F9 11 cmp ecx,11 ; 比較注冊碼的長度是否為十進制的17
- 在執行下次分析之前我們先把註冊碼輸入為17位
- 回到
cycle
程式,輸入12345678901234567
點擊「Check」按鈕 - 這次可以發現成功過了
cmp ecx,11
這段 - 繼續向下分析 (看到call那些都還先不要進去)
- 當執行到
0040111A |> /E8 47000000 call 00401166
發現無法再按F8
往下 - 回到
cycle
程式,會發現跳出Please enter a valid serial for your name!
(分析到這邊我就沒再繼續分析了,只是大概有個感覺,在對組合語言更熟後我會再重新分析過一次)
- 以下是參考教學文章中所註解的 (因為我還不熟組合語言)
(這邊以下看不懂也沒關係,不要氣餒,目前先盡量了解OD工具的功能和使用…因為我也很多問號)
1 | 004010BC |. /74 61 je short 0040111F |
這邊是教學說的內容:
1 | 寫到這準備追蹤算法時,才發現這個 crackme 還是挺複雜的,具體算法我就不寫了,實在沒那麼多時間詳細追蹤。有興趣的可以跟一下,註冊碼是17位,使用者名採用複製的模式延伸到 16 位,如我輸入「CCDebuger」,延伸後就是「CCDebugerCCDebug」。大致是先取延伸後使用者名的前 8 位和註冊碼的前 8 位,把使用者名的前四位和後四位分別與註冊碼的前四位和後四位進行運算,算完後再把延伸後使用者名的後 8 位和註冊碼的後 8 位分兩部分,再與前面使用者名和註冊碼的前 8 位計算後的值進行異或計算,最後結果等於 0 就成功。註冊碼的第 17 位我尚沒有找到有何用處。對於新手來說,可能這個 crackme 的難度大了一點。沒關係,我們主要是學習 OllyDBG 的使用,方法掌握就可以了。 |
總結
這個CrackMe真的有難度,我有嘗試著追蹤進去關鍵的Call,發現非常的複雜⋯一堆組合語言就殺死我了。看來在寫個一兩張了解OllyDBG後,要認真把組合語言學習過一遍。不過在這邊實作過程慢慢看得懂一些組合語言了。
註:以上參考了
看雪論壇 的 OllyDBG 入门系列(五)-消息断点及 RUN 跟踪