OllyDBG 入門系列 字串參考

標 題: 【原創】OllyDBG 入門系列(二)-字串參考
作 者: CCDebuger
時 間: 2006-02-14,13:34:43
鏈 接: http://bbs.pediy.com/showthread.php?t=21308

引用:
感謝 chuxuezhe 朋友的反饋:

http://bbs.pediy.com/showthread.php?s=&threadid=24703

經檢查才發現原來是寫文章前曾用修改過的 Ultra String Reference 插件查找過字串,這個修改後的插件會把找到的字串自動添加到代碼後面作爲註釋,且所有字母都一律小寫,導致原來文章寫的時候註釋中的大小寫分不清楚,比較混亂。這次把文章一些地方修改了一下,全部用OD自帶功能進行操作,重新制作了幾個圖片。因爲我自己的失誤,在此對給大家造成了閱讀中的困惑表示抱歉!
OllyDBG 入門系列(二)-字串參考

作者:CCDebuger

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

http://bbs.pediy.com/upload/2006/4/image/1_crackme_gui.gif

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

http://bbs.pediy.com/upload/2006/4/image/1_error.gif 

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

http://bbs.pediy.com/upload/2006/4/image/1_explain.gif 

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

http://bbs.pediy.com/upload/2006/4/image/1_menu_string.gif

當然如果用上面那個 超級字串參考+ 插件會更方便。但我們的目標是熟悉 OllyDBG 的一些操作,我就儘量使用 OllyDBG 自帶的功能,少用插件。好了,現在出來另一個對話框,我們在這個對話框裏右擊,選擇“查找文本”菜單項,輸入“Wrong Serial, try again!”的開頭單詞“Wrong”(注意這裏查找內容要區分大小寫)來查找,找到一處:

http://bbs.pediy.com/upload/2006/4/image/5.gif 

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

http://bbs.pediy.com/upload/2006/4/image/6.gif

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

http://bbs.pediy.com/upload/2006/4/image/7.gif

分別雙擊上面標出的兩個地址,我們會來到對應的位置:

00440F79 |. BA 8C104400     MOV EDX,CrackMe3.0044108C             ; ASCII "Wrong Serial,try again!"
00440F7E |. A1 442C4400     MOV EAX,DWORD PTR DS:[442C44]
00440F83 |. 8B00            MOV EAX,DWORD PTR DS:[EAX]
00440F85 |. E8 DEC0FFFF     CALL CrackMe3.0043D068
00440F8A |. EB 18           JMP SHORT CrackMe3.00440FA4
00440F8C |> 6A 00           PUSH 0
00440F8E |. B9 80104400     MOV ECX,CrackMe3.00441080             ; ASCII "Beggar off!"
00440F93 |. BA 8C104400     MOV EDX,CrackMe3.0044108C             ; ASCII "Wrong Serial,try again!"
00440F98 |. A1 442C4400     MOV EAX,DWORD PTR DS:[442C44]
00440F9D |. 8B00            MOV EAX,DWORD PTR DS:[EAX]
00440F9F |. E8 C4C0FFFF     CALL CrackMe3.0043D068

我們在反彙編窗口中向上滾動一下再看看:

00440F2C |. 8B45 FC         MOV EAX,DWORD PTR SS:[EBP-4]
00440F2F |. BA 14104400     MOV EDX,CrackMe3.00441014             ; ASCII "Registered User"
00440F34 |. E8 F32BFCFF     CALL CrackMe3.00403B2C                ; 關鍵,要用F7跟進去
00440F39 |. 75 51           JNZ SHORT CrackMe3.00440F8C           ; 這裏跳走就完蛋
00440F3B |. 8D55 FC         LEA EDX,DWORD PTR SS:[EBP-4]
00440F3E |. 8B83 C8020000   MOV EAX,DWORD PTR DS:[EBX+2C8]
00440F44 |. E8 D7FEFDFF     CALL CrackMe3.00420E20
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           ; 這裏跳走就完蛋
00440F58 |. 6A 00 PUSH 0
00440F5A |. B9 3C104400     MOV ECX,CrackMe3.0044103C             ; ASCII "CrackMe cracked successfully"
00440F5F |. BA 5C104400     MOV EDX,CrackMe3.0044105C             ; ASCII "Congrats! You cracked this CrackMe!"
00440F64 |. A1 442C4400     MOV EAX,DWORD PTR DS:[442C44]
00440F69 |. 8B00            MOV EAX,DWORD PTR DS:[EAX]
00440F6B |. E8 F8C0FFFF     CALL CrackMe3.0043D068
00440F70 |. EB 32           JMP SHORT CrackMe3.00440FA4
00440F72 |> 6A 00           PUSH 0
00440F74 |. B9 80104400     MOV ECX,CrackMe3.00441080             ; ASCII "Beggar off!"
00440F79 |. BA 8C104400     MOV EDX,CrackMe3.0044108C             ; ASCII "Wrong Serial,try again!"
00440F7E |. A1 442C4400     MOV EAX,DWORD PTR DS:[442C44]
00440F83 |. 8B00            MOV EAX,DWORD PTR DS:[EAX]
00440F85 |. E8 DEC0FFFF     CALL CrackMe3.0043D068
00440F8A |. EB 18           JMP SHORT CrackMe3.00440FA4
00440F8C |> 6A 00           PUSH 0
00440F8E |. B9 80104400     MOV ECX,CrackMe3.00441080             ; ASCII "Beggar off!"
00440F93 |. BA 8C104400     MOV EDX,CrackMe3.0044108C             ; ASCII "Wrong Serial,try again!"
00440F98 |. A1 442C4400     MOV EAX,DWORD PTR DS:[442C44]
00440F9D |. 8B00            MOV EAX,DWORD PTR DS:[EAX]
00440F9F |. E8 C4C0FFFF     CALL CrackMe3.0043D068


大家注意看一下上面的註釋,我在上面標了兩個關鍵點。有人可能要問,你怎麼知道那兩個地方是關鍵點?其實很簡單,我是根據查看是哪條指令跳到“wrong serial,try again”這條字串對應的指令來決定的。如果你在 調試選項->CPU 標籤中把“顯示跳轉路徑”及其下面的兩個“如跳轉未實現則顯示灰色路徑”、“顯示跳轉到選定命令的路徑”都選上的話,就會看到是從什麼地方跳到出錯字串處的:

http://bbs.pediy.com/upload/2006/4/image/8.gif

我們在上圖中地址 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個字符。如下圖所示:

http://bbs.pediy.com/upload/2006/4/image/9.gif
 
現在我們來按 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,進去後光標停在這一句:

http://bbs.pediy.com/upload/2006/4/image/1_first_call.gif
 
我們所看到的那些 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”圖標打開斷點窗口):

http://bbs.pediy.com/upload/2006/4/image/1_breakpoint.gif

爲什麼要做這一步,而不是把這個斷點刪除呢?這裏主要是爲了保險一點,萬一分析錯誤,我們還要接着分析,要是把斷點刪除了就要做一些重複工作了。還是先禁用一下,如果經過實際驗證證明我們的分析是正確的,再刪不遲。現在我們把斷點禁用,在 OllyDBG 中按 F9 鍵讓程序運行。輸入我們經分析得出的內容:
用戶名:Registered User
註冊碼:GFX-754-IER-954
點擊“Register now !”按鈕,呵呵,終於成功了:

http://bbs.pediy.com/upload/2006/4/image/1_finish.gif

--------------------------------------------------------------------------------
【版權聲明】 本文純屬技術交流, 轉載請註明作者並保持文章的完整, 謝謝!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章