OllyDBG - 第三章 | 函數參考
這篇的重點講解怎樣使用 OllyDBG 中的函數參考(即名稱參考)功能。
檔案下載
目的程式:
crackhead.7z
解壓縮密碼:
1 | morosedog |
使用PEid檢驗
檢驗顯示是使用MASM32/TASM32
編寫。
開啟CrackHead.exe
使用並分析
- 開啟 CrackHead.exe
- 乍看一下好像沒什麼東西,左上角有一個
shit
- 點擊
shit
- 可以看到有
About
、Greets
、Try It
- 我們都點點看,點到
Try It
,發現會跳出類似輸入註冊碼的地方 - 內容已經填了
12345666
- 點擊「Check It」按鈕
- 沒反應
- 在輸入框內改輸入其他字符,會發現僅可輸入數字
- 輸入
987654321
- 點擊「Check It」按鈕
- 依舊沒反應
分析:看來要輸入正確的數字,然後按下「Check It」才會有反應
使用OllyDBG分析
- 啟動
OllyDBG
- 按下快捷鍵
F3
- 選擇
CrackHead.exe
- 在入口點地址後面加上註解 (良好的註解有助於分析)
- 這邊我先稍微拖拉一下捲軸看下反匯編視窗內是否可有跡可循
- 可以發現下方好像調用了很多USER32的東西 (API函數)
- 在反匯編窗口按下右鍵選擇
尋找
->目前模組中的名稱(標籤)
(快捷鍵Ctrl + N)注:在進行此操作時要在
OllyDBG
中保證是在目前被除錯程式的領空,我在第一篇中已經介紹了領空的概念,如我這裡除錯這個程式時OllyDBG
的標題欄顯示的就是「[CPU - 主執行緒, 模組 - CrackHea
- 打開了
名稱位於 CrackHea
的視窗 - 我們可以在點擊視窗標題
- 然後直接輸入關鍵字,他會自動對照開頭去高亮
- 例如輸入
getw
- 例如輸入
註:
GetWindowText
Windows API宏,在WinUser.h中根據是否已定義Unicode被分別定義為GetWindowTextW和GetWindowTextA。在函數後加入一個W為UNICODE 版,在函數後加入一個A為ASCII 版。
該函數將指定窗口的標題條文本(如果存在)拷貝到一個緩存區內。如果指定的窗口是一個控件,則拷貝控件的文本。但是,GetWindowText可能無法獲取外部應用程序中控件的文本,獲取自繪的控件或者是外部的密碼編輯框很有可能會失敗。
- 找到
GetWindowTextA
按下右鍵 - 選擇
尋找輸入函數參考
- 會開啟
參考位於 CrackHea:.test 到 USER32.GetWindwoTextA
視窗
- 在
00401323 call <jmp.&USER32.GetWindowTextA>
按下F2
設定斷點註:如果想要全部設定斷點,右鍵選擇
在每個指令上設定斷點(S)
,但是這邊僅需要對第一條設定斷點即可。
註:為什麼是下在這,其實這需要一點程式經驗,因為這個函數定義的名稱為
GetWindowTextA
,我大概解釋為取得視窗中text裡面的值。所以我判斷來取值的位置應該有判斷的邏輯可以去追。
- 斷點下好後,按下
F9
執行程式,會看到CrackHead.exe程式,被執行了 - 我們先點開
Try It
,然後點擊Check It
- 這次我們的程序會停在剛剛設定的斷點
反匯編視窗內容:
1 | 00401323 |. E8 4C010000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA |
分段分析
(以下在本人對組合語言不懂的情況下分析,所以以下為不負責任分析,如有錯誤請鞭小力一點)
- 稍微分析上面的Code,我假設
00401328 |. E8 A5000000 call 004013D2
這邊是關鍵 - 而
cmp eax,esi
是比較 - 而
0040132F |. 75 42 jnz short 00401373
是表示不等於 - 而且他是跳轉到
00401373 |> \EB 15 jmp short 0040138A
,已經跳過了Crudd's Crack Hea
,所以我假設這邊就是失敗跳轉參考:x86組合語言 - 第三章 | 基本指令集,要開始慢慢開始記這些語法了唷。
註:以上的假設是需要重複的去追程式執行過程,再慢慢進行假設。
繼續Debug
- 根據假設,我們按
F8
運行到00401328 |. E8 A5000000 call 004013D2
後按下F7
1 | 004013D2 /$ 56 push esi |
- 這時候因為我對於組合語言不熟,繼續
F8
,並且觀察資訊視窗
- 發現滿多的都還是看不懂的⋯所以參考文章
- 以下是參考教學文章中所註解的 (因為我還不熟組合語言)
1 | 004013D2 /$ 56 push esi ; ESI入棧 |
- 這邊看來就是將輸入的值做一些運算處理,然後將直往回丟
- 我們一路
F8
會回到0040132D |. 3BC6 cmp eax,esi
(這行表示比較這兩個值)- jnz 為不等於,剛剛假設這邊就是失敗跳轉
- 可以看到資訊視窗的內容 (可能與我的不一樣)
1 | esi=797A7553 |
- 對資訊視窗的
esi=797A7553
點選右鍵,選擇修改暫存器
- 會到如下圖。
- 對資訊視窗的
esi=797A7553
點選右鍵,選擇修改暫存器
- 會到如下圖。
此時可以發現很眼熟的
12345666
出現了所以表示他會將我輸入的
1234566
透過運算轉為16進位的00BC6142
然後去和797A7553
做比較答案呼之欲出,也就是我只要取得
797A7553
的有號或是無號的數值,去當註冊碼,這樣比對結果就會是一致複製
2038068563
貼到程式中,並點擊
Check It
- 成功了。
註:這個 crackme 是要求寫出註冊機的。我們先不要求寫註冊機,但註冊的算法我們要搞清楚。在前面說到的那個 ESI 暫存器值,看看我們上面的分析,其實對做註冊機來說是沒有多少說明的。要搞清註冊算法,必須知道上面那個 ESI 暫存器值是如何產生的,這弄清楚後才能真正清楚這個 crackme 算法。
總結
學習到這邊後,發現組合語言非常重要,在不懂組合語言的情況下,真的沒辦法分析太多;不過這邊的出發點本來就不是組合語言,在邊學邊看的過程中,慢慢學習,主要是先了解OllyDBG
的使用。
註:以上參考了
看雪論壇 的 OllyDBG 入门系列(三)-函数参考