天天看點

OllyDBG 破解入門教程

一、OllyDBG 的安裝與配置

OllyDBG  版的釋出版本是個 ZIP 壓縮包,隻要解壓到一個目錄下,運作 OllyDBG.exe 就可以了。漢化版的釋出版本是個 RAR 壓縮包,同樣隻需解壓到一個目錄下運作 OllyDBG.exe

即可:

OllyDBG 中各個視窗的功能如上圖。簡單解釋一下各個視窗的功能,更詳細的内容可以參考 TT 小組翻譯的中文幫助:

反彙編視窗:顯示被調試程式的反彙編代碼,标題欄上的位址、HEX 資料、反彙編、注釋可以通過在視窗中右擊出現的菜單 界面選項->隐藏标題 或 顯示标題 來進行切換是否顯示。用滑鼠左鍵點選注釋标簽可以切換注釋顯示的方式。

寄存器視窗:顯示目前所選線程的 CPU 寄存器内容。同樣點選标簽 寄存器 (FPU) 可以切換顯示寄存器的方式。

資訊視窗:顯示反彙編視窗中選中的第一個指令的參數及一些跳轉目标位址、字串等。

資料視窗:顯示記憶體或檔案的内容。右鍵菜單可用于切換顯示方式。

堆棧視窗:顯示目前線程的堆棧。

要調整上面各個視窗的大小的話,隻需左鍵按住邊框拖動,等調整好了,重新啟動一下 OllyDBG 就可以生效了。

啟動後我們要把插件及 UDD 的目錄配置為絕對路徑,點選菜單上的 選項->界面,将會出來一個界面選項的對話框,我們點選其中的目錄标簽:

因為我這裡是把 OllyDBG 解壓在 F:\OllyDBG 目錄下,是以相應的 UDD 目錄及插件目錄按圖上配置。還有一個常用到的标簽就是上圖後面那個字型,在這裡你可以更改 OllyDBG 中顯示的字型。上圖中其它的選項可以保留為預設,若有需要也可以自己修改。修改完以後點選确定,彈出一個對話框,說我們更改了插件路徑,要重新啟動 OllyDBG。在這個對話框上點确定,重新啟動一下 OllyDBG,我們再到界面選項中看一下,會發現我們原先設定好的路徑都已儲存了。有人可能知道插件的作用,但對那個 UDD 目錄不清楚。我這簡單解釋一下:這個 UDD 目錄的作用是儲存你調試的工作。比如你調試一個軟體,設定了斷點,添加了注釋,一次沒做完,這時 OllyDBG 就會把你所做的工作儲存到這個 UDD 目錄,以便你下次調試時可以繼續以前的工作。

如果不設定這個 UDD 目錄,OllyDBG 預設是在其安裝目錄下儲存這些字尾名為 udd 的檔案,時間長了就會顯的很亂,是以還是建議專門設定一個目錄來儲存這些檔案。

另外一個重要的選項就是調試選項,可通過菜單 選項->調試設定 來配置:

新手一般不需更改這裡的選項,預設已配置好,可以直接使用。建議在對 OllyDBG 已比較熟的情況下再來進行配置。上面那個異常标簽中的選項經常會在脫殼中用到,建議在有一定調試基礎後學脫殼時再配置這裡。

除了直接啟動 OllyDBG 來調試外,我們還可以把 OllyDBG 添加到資料總管右鍵菜單,這樣我們就可以直接在 .exe 及 .dll 檔案上點右鍵選擇“用Ollydbg打開”菜單來進行調試。要把 OllyDBG 添加到資料總管右鍵菜單,隻需點菜單 選項->添加到浏覽器,将會出現一個對話框,先點選“添加 Ollydbg 到系統資料總管菜單”,再點選“完成”按鈕即可。要從右鍵菜單中删除也很簡單,還是這個對話框,點選“從系統資料總管菜單删除 Ollydbg”,再點選“完成”就行了。

OllyDBG 支援插件功能,插件的安裝也很簡單,隻要把下載下傳的插件(一般是個 DLL 檔案)複制到 OllyDBG 安裝目錄下的 PLUGIN 目錄中就可以了,OllyDBG 啟動時會自動識别。要注意的是 OllyDBG 1.10 對插件的個數有限制,最多不能超過 32 個,否則會出錯。建議插件不要添加的太多。

到這裡基本配置就完成了,OllyDBG 把所有配置都放在安裝目錄下的 ollydbg.ini 檔案中。 

二、基本調試方法

OllyDBG 有三種方式來載入程式進行調試,一種是點選菜單 檔案->打開 (快捷鍵是 F3)來打開一個可執行檔案進行調試,另一種是點選菜單 檔案->附加 來附加到一個已運作的程序上進行調試。注意這裡要附加的程式必須已運作。第三種就是用右鍵菜單來載入程式(不知這種算不算)。一般情況下我們選第一種方式。比如我們選擇一個 test.exe 來調試,通過菜單 檔案->打開 來載入這個程式,OllyDBG 中顯示的内容将會是這樣:

調試中我們經常要用到的快捷鍵有這些:

F2:設定斷點,隻要在光标定位的位置(上圖中灰色條)按F2鍵即可,再按一次F2鍵則會删除斷點。(相當于 SoftICE 中的 F9)

F8:單步步過。每按一次這個鍵執行一條反彙編視窗中的一條指令,遇到 CALL 等子程式不進入其代碼。(相當于 SoftICE 中的 F10)

F7:單步步入。功能同單步步過(F8)類似,差別是遇到 CALL 等子程式時會進入其中,進入後首先會停留在子程式的第一條指令上。(相當于 SoftICE 中的 F8)

F4:運作到標明位置。作用就是直接運作到光标所在位置處暫停。(相當于 SoftICE 中的 F7)

F9:運作。按下這個鍵如果沒有設定相應斷點的話,被調試的程式将直接開始運作。(相當于 SoftICE 中的 F5)

CTR+F9:執行到傳回。此指令在執行到一個 ret (傳回指令)指令時暫停,常用于從系統領空傳回到我們調試的程式領空。(相當于 SoftICE 中的 F12)

ALT+F9:執行到使用者代碼。可用于從系統領空快速傳回到我們調試的程式領空。(相當于 SoftICE 中的 F11)

上面提到的幾個快捷鍵對于一般的調試基本上已夠用了。要開始調試隻需設定好斷點,找到你感興趣的代碼段再按 F8 或 F7 鍵來一條條分析指令功能就可以了。就寫到這了,改天有空再接着灌。

OllyDBG 入門系列(二)-字串參考

作者:CCDebuger

上一篇是使用入門,現在我們開始正式進入破解。今天的目标程式是看雪兄《加密與解密》第一版附帶CD光牒中的 crackmes.cjb.net 鏡像打包中的 CFF Crackme #3,采用使用者名/序列号保護方式。原版加了個 UPX 的殼。剛開始學破解先不涉及殼的問題,我們主要是熟悉用 OllyDBG 來破解的一般方法。我這裡把殼脫掉來分析,附件是脫殼後的檔案,直接就可以拿來用。先說一下一般軟體破解的流程:拿到一個軟體先别接着馬上用 OllyDBG 調試,先運作一下,有幫助文檔的最好先看一下幫助,熟悉一下軟體的使用方法,再看看注冊的方式。如果是序列号方式可以先輸個假的來試一下,看看有什麼反應,也給我們破解留下一些有用的線索。如果沒有輸入注冊碼的地方,要考慮一下是不是讀取系統資料庫或 Key 檔案(一般稱 keyfile,就是程式讀取一個檔案中的内容來判斷是否注冊),這些可以用其它工具來輔助分析。如果這些都不是,原程式隻是一個功能不全的試用版,那要注冊為正式版本就要自己來寫代碼完善了。有點跑題了,呵呵。獲得程式的一些基本資訊後,還要用查殼的工具來查一下程式是否加了殼,若沒殼的話看看程式是什麼編譯器編的,如 VC、Delphi、VB 等。這樣的查殼工具有 PEiD 和 FI。有殼的話我們要盡量脫了殼後再來用 OllyDBG 調試,特殊情況下也可帶殼調試。下面進入正題:

我們先來運作一下這個 crackme(用 PEiD 檢測顯示是 Delphi 編的),界面如圖:

這個 crackme 已經把使用者名和注冊碼都輸好了,省得我們動手^_^。我們在那個“Register now !”按鈕上點選一下,将會跳出一個對話框:

好了,今天我們就從這個錯誤對話框中顯示的“Wrong Serial, try again!”來入手。啟動 OllyDBG,選擇菜單 檔案->打開 載入 CrackMe3.exe 檔案,我們會停在這裡:

我們在反彙編視窗中右擊,出來一個菜單,我們在 查找->所有參考文本字串 上左鍵點選:

當然如果用上面那個 超級字串參考+ 插件會更友善。但我們的目标是熟悉 OllyDBG 的一些操作,我就盡量使用 OllyDBG 自帶的功能,少用插件。

好了,現在出來另一個對話框,我們在這個對話框裡右擊,選擇“查找文本”菜單項,輸入“Wrong Serial, try again!”的開頭單詞“Wrong”(注意這裡查找内容要區分大小寫)來查找,找到一處:

在我們找到的字串上右擊,再在出來的菜單上點選“反彙編視窗中跟随”,我們來到這裡:

見上圖,為了看看是否還有其他的參考,可以通過選擇右鍵菜單查找參考->立即數,會出來一個對話框:

我們在上圖中位址 00440F2C 處按 F2 鍵設個斷點,現在我們按 F9 鍵,程式已運作起來了。我在上面那個編輯框中随便輸入一下,如 CCDebuger,下面那個編輯框我還保留為原來的“754-GFX-IER-954”,我們點一下那個“Register now !”按鈕,呵,OllyDBG 跳了出來,暫停在我們下的斷點處。我們看一下資訊視窗,你應該發現了你剛才輸入的内容了吧?我這裡顯示是這樣:

堆棧 SS:[0012F9AC]=00D44DB4, (ASCII "CCDebuger")

EAX=00000009

上面的記憶體位址 00D44DB4 中就是我們剛才輸入的内容,我這裡是 CCDebuger。你可以在 堆棧 SS:[0012F9AC]=00D44DB4, (ASCII "CCDebuger") 這條内容上左擊選擇一下,再點右鍵,在彈出菜單中選擇“資料視窗中跟随數值”,你就會在下面的資料視窗中看到你剛才輸入的内容。而 EAX=00000009 指的是你輸入内容的長度。如我輸入的 CCDebuger 是9個字元。如下圖所示:

現在我們來按 F8 鍵一步步分析一下:

00440F2C |. 8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]          ; 把我們輸入的内容送到EAX,我這裡是“CCDebuger”

00440F2F |. BA 14104400     MOV EDX,CrackMe3.00441014             ; ASCII "Registered User"

00440F34 |. E8 F32BFCFF     CALL CrackMe3.00403B2C                ; 關鍵,要用F7跟進去

00440F39 |. 75 51           JNZ SHORT CrackMe3.00440F8C           ; 這裡跳走就完蛋

當我們按 F8 鍵走到 00440F34 |. E8 F32BFCFF     CALL CrackMe3.00403B2C 這一句時,我們按一下 F7 鍵,進入這個 CALL,進去後光标停在這一句:

我們所看到的那些 PUSH EBX、 PUSH ESI 等都是調用子程式儲存堆棧時用的指令,不用管它,按 F8 鍵一步步過來,我們隻關心關鍵部分:

00403B2C /$ 53              PUSH EBX

00403B2D |. 56              PUSH ESI

00403B2E |. 57              PUSH EDI

00403B2F |. 89C6            MOV ESI,EAX                         ; 把EAX内我們輸入的使用者名送到 ESI

00403B31 |. 89D7            MOV EDI,EDX                         ; 把EDX内的資料“Registered User”送到EDI

00403B33 |. 39D0            CMP EAX,EDX                         ; 用“Registered User”和我們輸入的使用者名作比較

00403B35 |. 0F84 8F000000   JE CrackMe3.00403BCA                ; 相同則跳

00403B3B |. 85F6            TEST ESI,ESI                        ; 看看ESI中是否有資料,主要是看看我們有沒有輸入使用者名

00403B3D |. 74 68           JE SHORT CrackMe3.00403BA7          ; 使用者名為空則跳

00403B3F |. 85FF            TEST EDI,EDI

00403B41 |. 74 6B           JE SHORT CrackMe3.00403BAE

00403B43 |. 8B46 FC         MOV EAX,DWORD PTR DS:[ESI-4]        ; 使用者名長度送EAX

00403B46 |. 8B57 FC         MOV EDX,DWORD PTR DS:[EDI-4]        ; “Registered User”字串的長度送EDX

00403B49 |. 29D0            SUB EAX,EDX                         ; 把使用者名長度和“Registered User”字串長度相減

00403B4B |. 77 02           JA SHORT CrackMe3.00403B4F          ; 使用者名長度大于“Registered User”長度則跳

00403B4D |. 01C2            ADD EDX,EAX                         ; 把減後值與“Registered User”長度相加,即使用者名長度

00403B4F |> 52              PUSH EDX

00403B50 |. C1EA 02         SHR EDX,2                           ; 使用者名長度值右移2位,這裡相當于長度除以4

00403B53 |. 74 26           JE SHORT CrackMe3.00403B7B          ; 上面的指令及這條指令就是判斷使用者名長度最少不能低于4

00403B55 |> 8B0E            MOV ECX,DWORD PTR DS:[ESI]          ; 把我們輸入的使用者名送到ECX

00403B57 |. 8B1F            MOV EBX,DWORD PTR DS:[EDI]          ; 把“Registered User”送到EBX

00403B59 |. 39D9            CMP ECX,EBX                         ; 比較

00403B5B |. 75 58           JNZ SHORT CrackMe3.00403BB5         ; 不等則完蛋

根據上面的分析,我們知道使用者名必須是“Registered User”。我們按 F9 鍵讓程式運作,出現錯誤對話框,點确定,重新在第一個編輯框中輸入“Registered User”,再次點選那個“Register now !”按鈕,被 OllyDBG 攔下。因為位址 00440F34 處的那個 CALL 我們已經分析清楚了,這次就不用再按 F7 鍵跟進去了,直接按 F8 鍵通過。我們一路按 F8 鍵,來到第二個關鍵代碼處:

00440F49 |. 8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]         ; 取輸入的注冊碼

00440F4C |. BA 2C104400     MOV EDX,CrackMe3.0044102C            ; ASCII "GFX-754-IER-954"

00440F51 |. E8 D62BFCFF     CALL CrackMe3.00403B2C               ; 關鍵,要用F7跟進去

00440F56 |. 75 1A           JNZ SHORT CrackMe3.00440F72          ; 這裡跳走就完蛋

大家注意看一下,位址 00440F51 處的 CALL CrackMe3.00403B2C 和上面我們分析的位址 00440F34 處的 CALL CrackMe3.00403B2C 是不是彙編指令都一樣啊?這說明檢測使用者名和注冊碼是用的同一個子程式。而這個子程式 CALL 我們在上面已經分析過了。我們執行到現在可以很容易得出結論,這個 CALL 也就是把我們輸入的注冊碼與 00440F4C 位址處指令後的“GFX-754-IER-954”作比較,相等則 OK。

好了,我們已經得到足夠的資訊了。現在我們在菜單 檢視->斷點 上點選一下,打開斷點視窗(也可以通過組合鍵 ALT+B 或點選工具欄上那個“B”圖示打開斷點視窗):

為什麼要做這一步,而不是把這個斷點删除呢?這裡主要是為了保險一點,萬一分析錯誤,我們還要接着分析,要是把斷點删除了就要做一些重複工作了。還是先禁用一下,如果經過實際驗證證明我們的分析是正确的,再删不遲。現在我們把斷點禁用,在 OllyDBG 中按 F9 鍵讓程式運作。輸入我們經分析得出的内容:

使用者名:Registered User

注冊碼:GFX-754-IER-954

點選“Register now !”按鈕,呵呵,終于成功了:

OllyDBG 入門系列(三)-函數參考

現在進入第三篇,這一篇我們重點講解怎樣使用 OllyDBG 中的函數參考(即名稱參考)功能。仍然選擇 crackmes.cjb.net 鏡像打包中的一個名稱為 CrackHead 的crackme。老規矩,先運作一下這個程式看看:

呵,竟然沒找到輸入注冊碼的地方!别急,我們點一下程式上的那個菜單“Shit”(真是 Shit 啊,呵呵),在下拉菜單中選“Try It”,會來到如下界面:

我們點一下那個“Check It”按鈕試一下,哦,竟然沒反應!我再輸個“78787878”試試,還是沒反應。再試試輸入字母或其它字元,輸不進去。由此判斷注冊碼應該都是數字,隻有輸入正确的注冊碼才有動靜。用 PEiD 檢測一下,結果為 MASM32 / TASM32,怪不得程式比較小。資訊收集的差不多了,現在關掉這個程式,我們用 OllyDBG 載入,按 F9 鍵直接讓它運作起來,依次點選上面圖中所說的菜單,使被調試程式顯示如上面的第二個圖。先不要點那個“Check It”按鈕,保留上圖的狀态。現在我們沒有什麼字串好參考了,我們就在 API 函數上下斷點,來讓被調試程式中斷在我們希望的地方。我們在 OllyDBG 的反彙編視窗中右擊滑鼠,在彈出菜單中選擇 查找->目前子產品中的名稱 (标簽),或者我們通過按 CTR+N 組合鍵也可以達到同樣的效果(注意在進行此操作時要在 OllyDBG 中保證是在目前被調試程式的領空,我在第一篇中已經介紹了領空的概念,如我這裡調試這個程式時 OllyDBG 的标題欄顯示的就是“[CPU - 主線程, 子產品 - CrackHea]”,這表明我們目前在被調試程式的領空)。通過上面的操作後會彈出一個對話框,如圖:

對于這樣的編輯框中輸注冊碼的程式我們要設斷點首選的 API 函數就是 GetDlgItemText 及 GetWindowText。每個函數都有兩個版本,一個是 ASCII 版,在函數後添加一個 A 表示,如 GetDlgItemTextA,另一個是 UNICODE 版,在函數後添加一個 W 表示。如 GetDlgItemTextW。對于編譯為 UNCODE 版的程式可能在 Win98 下不能運作,因為 Win98 并非是完全支援 UNICODE 的系統。而 NT 系統則從底層支援 UNICODE,它可以在作業系統内對字串進行轉換,同時支援 ASCII 和 UNICODE 版本函數的調用。一般我們打開的程式看到的調用都是 ASCII 類型的函數,以“A”結尾。又跑題了,呵呵。現在回到我們調試的程式上來,我們現在就是要找一下我們調試的程式有沒有調用 GetDlgItemTextA 或 GetWindowTextA 函數。還好,找到一個 GetWindowTextA。在這個函數上右擊,在彈出菜單上選擇“在每個參考上設定斷點”,我們會在 OllyDBG 視窗最下面的那個狀态欄裡看到“已設定 2 個斷點”。另一種方法就是那個 GetWindowTextA 函數上右擊,在彈出菜單上選擇“查找輸入函數參考”(或者按Enter鍵),将會出現下面的對話框:

看上圖,我們可以把兩條都設上斷點。這個程式隻需在第一條指令設斷點就可以了。好,我們現在按前面提到的第一條方法,就是“在每個參考上設定斷點”,這樣上圖中的兩條指令都會設上斷點。斷點設好後我們轉到我們調試的程式上來,現在我們在被我們調試的程式上點選那個“Check It”按鈕,被 OllyDBG 斷下:

00401323 |. E8 4C010000         CALL            ; GetWindowTextA

00401328 |. E8 A5000000         CALL CrackHea.004013D2                      ; 關鍵,要按F7鍵跟進去

0040132D |. 3BC6                CMP EAX,ESI                                 ; 比較

0040132F |. 75 42               JNZ SHORT CrackHea.00401373                 ; 不等則完蛋

00401331 |. EB 2C               JMP SHORT CrackHea.0040135F

00401333 |. 4E 6F 77 20 7>      ASCII "Now write a keyg"

00401343 |. 65 6E 20 61 6>      ASCII "en and tut and y"

00401353 |. 6F 75 27 72 6>      ASCII "ou're done.",0

0040135F |> 6A 00               PUSH 0                                      ; Style = MB_OK|MB_APPLMODAL

00401361 |. 68 0F304000         PUSH CrackHea.0040300F                      ; Title = "Crudd's Crack Head"

00401366 |. 68 33134000         PUSH CrackHea.00401333                      ; Text = "Now write a keygen and tut and you're done."

0040136B |. FF75 08             PUSH DWORD PTR SS:[EBP+8]                   ; hOwner

0040136E |. E8 19010000         CALL               ; MessageBoxA

從上面的代碼,我們很容易看出 00401328 位址處的 CALL CrackHea.004013D2 是關鍵,必須仔細跟蹤。而注冊成功則會顯示一個對話框,标題是“Crudd's Crack Head”,對話框顯示的内容是“Now write a keygen and tut and you're done.”現在我按一下 F8,準備步進到 00401328 位址處的那條 CALL CrackHea.004013D2 指令後再按 F7 鍵跟進去。等等,怎麼回事?怎麼按一下 F8 鍵跑到這來了:

00401474 $- FF25 2C204000      JMP DWORD PTR DS:[    ; USER32.GetWindowTextA

0040147A $- FF25 30204000      JMP DWORD PTR DS:[]     ; USER32.LoadCursorA

00401480 $- FF25 1C204000      JMP DWORD PTR DS:[]       ; USER32.LoadIconA

00401486 $- FF25 20204000      JMP DWORD PTR DS:[]       ; USER32.LoadMenuA

0040148C $- FF25 24204000      JMP DWORD PTR DS:[]     ; USER32.MessageBoxA

原來是跳到另一個斷點了。這個斷點我們不需要,按一下 F2 鍵删掉它吧。删掉 00401474 位址處的斷點後,我再按 F8 鍵,呵,完了,跑到 User32.dll 的領空了。看一下 OllyDBG 的标題欄:“[CPU - 主線程, 子產品 - USER32],跑到系統領空了,OllyDBG 反彙編視窗中顯示代碼是這樣:

77D3213C 6A 0C                 PUSH 0C

77D3213E 68 A021D377           PUSH USER32.77D321A0

77D32143 E8 7864FEFF           CALL USER32.77D185C0

怎麼辦?别急,我們按一下 ALT+F9 組合鍵,呵,回來了:

00401328 |. E8 A5000000        CALL CrackHea.004013D2                     ; 關鍵,要按F7鍵跟進去

0040132D |. 3BC6               CMP EAX,ESI                                ; 比較

0040132F |. 75 42              JNZ SHORT CrackHea.00401373                ; 不等則完蛋

光标停在 00401328 位址處的那條指令上。現在我們按 F7 鍵跟進:

004013D2 /$ 56                PUSH ESI                                    ; ESI入棧

004013D3 |. 33C0              XOR EAX,EAX                                 ; EAX清零

004013D5 |. 8D35 C4334000     LEA ESI,DWORD PTR DS:[4033C4]               ; 把注冊碼框中的數值送到ESI

004013DB |. 33C9              XOR ECX,ECX                                 ; ECX清零

004013DD |. 33D2              XOR EDX,EDX                                 ; EDX清零

004013DF |. 8A06              MOV AL,BYTE PTR DS:[ESI]                    ; 把注冊碼中的每個字元送到AL

004013E1 |. 46                INC ESI                                     ; 指針加1,指向下一個字元

004013E2 |. 3C 2D             CMP AL,2D                                   ; 把取得的字元與16進制值為2D的字元(即“-”)比較,這裡主要用于判斷輸入的是不是負數

004013E4 |. 75 08             JNZ SHORT CrackHea.004013EE                 ; 不等則跳

004013E6 |. BA FFFFFFFF       MOV EDX,-1                                  ; 如果輸入的是負數,則把-1送到EDX,即16進制FFFFFFFF

004013EB |. 8A06              MOV AL,BYTE PTR DS:[ESI]                    ; 取“-”号後的第一個字元

004013ED |. 46                INC ESI                                     ; 指針加1,指向再下一個字元

004013EE |> EB 0B             JMP SHORT CrackHea.004013FB

004013F0 |> 2C 30             SUB AL,30                                   ; 每位字元減16進制的30,因為這裡都是數字,如1的ASCII碼是“31H”,減30H後為1,即我們平時看到的數值

004013F2 |. 8D0C89            LEA ECX,DWORD PTR DS:[ECX+ECX*4]            ; 把前面運算後儲存在ECX中的結果乘5再送到ECX

004013F5 |. 8D0C48            LEA ECX,DWORD PTR DS:[EAX+ECX*2]            ; 每位字元運算後的值與2倍上一位字元運算後值相加後送ECX

004013F8 |. 8A06              MOV AL,BYTE PTR DS:[ESI]                    ; 取下一個字元

004013FA |. 46                INC ESI                                     ; 指針加1,指向再下一個字元

004013FB |> 0AC0              or AL,AL

004013FD |.^ 75 F1            JNZ SHORT CrackHea.004013F0                 ; 上面一條和這一條指令主要是用來判斷是否已把使用者輸入的注冊碼計算完

004013FF |. 8D040A            LEA EAX,DWORD PTR DS:[EDX+ECX]              ; 把EDX中的值與經過上面運算後的ECX中值相加送到EAX

00401402 |. 33C2              XOR EAX,EDX                                 ; 把EAX與EDX異或。如果我們輸入的是負數,則此處功能就是把EAX中的值取反

00401404 |. 5E                POP ESI                                     ; ESI出棧。看到這條和下一條指令,我們要考慮一下這個ESI的值是哪裡運算得出的呢?

00401405 |. 81F6 53757A79     XOR ESI,797A7553                            ; 把ESI中的值與797A7553H異或

0040140B \. C3                RETN

這裡留下了一個問題:那個 ESI 寄存器中的值是從哪運算出來的?先不管這裡,我們接着按 F8 鍵往下走,來到 0040140B 位址處的那條 RETN 指令(這裡可以通過在調試選項的“指令”标簽中勾選“使用 RET 代替 RETN”來更改傳回指令的顯示方式),再按一下 F8,我們就走出 00401328 位址處的那個 CALL 了。現在我們回到了這裡:

0040132D |. 3BC6             CMP EAX,ESI                                  ; 比較

0040132F |. 75 42            JNZ SHORT CrackHea.00401373                  ; 不等則完蛋

光标停在了 0040132D 位址處的那條指令上。根據前面的分析,我們知道 EAX 中存放的是我們輸入的注冊碼經過計算後的值。我們來看一下資訊視窗:

ESI=E6B5F2F9

EAX=FF439EBE

左鍵選擇資訊視窗中的 ESI=E6B5F2F9,再按右鍵,在彈出菜單上選“修改寄存器”,我們會看到這樣一個視窗:

可能你的顯示跟我不一樣,因為這個 crackme 中已經說了每個機器的序列号不一樣。關掉上面的視窗,再對資訊視窗中的 EAX=FF439EBE 做同樣操作:

由上圖我們知道了原來前面分析的對我們輸入的注冊碼進行處理後的結果就是把字元格式轉為數字格式。我們原來輸入的是字串“12345666”,現在轉換為了數字 12345666。這下就很清楚了,随便在上面那個修改 ESI 圖中顯示的有符号或無符号編輯框中複制一個,粘貼到我們調試的程式中的編輯框中試一下:

呵呵,成功了。且慢高興,這個 crackme 是要求寫出注冊機的。我們先不要求寫注冊機,但注冊的算法我們要搞清楚。還記得我在前面說到的那個 ESI 寄存器值的問題嗎?現在看看我們上面的分析,其實對做注冊機來說是沒有多少幫助的。要搞清注冊算法,必須知道上面那個 ESI 寄存器值是如何産生的,這弄清楚後才能真正清楚這個 crackme 算法。今天就先說到這裡。

作  者:Angel_Kitty

出  處:https://www.cnblogs.com/ECJTUACM-873284962/

關于作者:阿裡雲ACE,目前主要研究方向是Web安全漏洞以及反序列化。如有問題或建議,請多多賜教!

版權聲明:本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結。

特此聲明:所有評論和私信都會在第一時間回複。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我

聲援部落客:如果您覺得文章對您有幫助,可以點選文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!

歡迎大家關注我的微信公衆号IT老實人(IThonest),如果您覺得文章對您有很大的幫助,您可以考慮賞部落客一杯咖啡以資鼓勵,您的肯定将是我最大的動力。thx.

OllyDBG 破解入門教程

我的公衆号是IT老實人(IThonest),一個有故事的公衆号,歡迎大家來這裡讨論,共同進步,不斷學習才能不斷進步。掃下面的二維碼或者收藏下面的二維碼關注吧(長按下面的二維碼圖檔、并選擇識别圖中的二維碼),個人QQ和微信的二維碼也已給出,掃描下面👇的二維碼一起來讨論吧!!!

OllyDBG 破解入門教程

歡迎大家關注我的Github,一些文章的備份和平常做的一些項目會存放在這裡。