用OllyDbg做破解


朋友所托,要幫忙破解一個MFC的小程序,他急等着用 (背景:幾個人合伙創業,其中一個負責寫這個有點小核心的項目,為了鞏固自己的”地位“搞的小把戲,給加了密,要用必須通過他 - 我艹~~~)。

雖說自己搞C++比較多,相對來講native一點,但是對於匯編與破解,了解相當有限,去年這朋友也找過我,因為當時剛換公司比較忙,是求助另外一好友才搞定的。這次還是自己花點時間研究研究吧。工具嗎,用windbg貌似只能看,softice與ollydbg之間,選擇了ollydbg。

一、基礎知識

ollydbg是一個動態反匯編分析調試工具,其功能強大的令人發指,而且居然還是免費的,其官方地址為:http://www.ollydbg.de/,下載與介紹都在上面。

要用ollydbg做破解,最好先過一遍下面的知識點:

  1. 了解匯編語言的基本結構,特別是函數的調用與返回,參數傳遞等,可以參考這篇文章:反匯編深入分析函數調用, 簡短卻又清晰,切中要點,我配合visualstudio的反匯編窗口執行了幾遍,基本掌握了其結構。(我自己也維護了一個分析:https://gist.github.com/2904354)
    另外,Intel這三大卷:Intel® 64 and IA-32 Architectures Software Developer Manuals也是非常經典的參考資料,沒必要讀,但不理解時可以查查,尤其是第一卷中的基本結構介紹和第二卷的指令集介紹。
  2. OllyDbg入門完全教程(完美排版), 非常詳盡的介紹了ollydbg的各個組成部分及功能,40來頁的內容,花一個小時過一遍就可以了。
  3. OD入門系列圖文詳細教程-破解做輔助起步,通過一個例子詳細解釋了破解的全過程,非常有用。其中文中用到的看雪《加密與解密》書中的程序crackme可以在這里下載到:http://download.csdn.net/detail/tokey003/3672236

二、實例操作

先是一個非常簡單的helloworld程序,源碼如下:

 1 #include <cstdio>
 2 #include <windows.h>
 3 
 4 #pragma comment(lib, "user32.lib")
 5 
 6 void printHelloWorld(int a)
 7 {
 8         MessageBox(NULL, "Hello, World", "Greetings", MB_ICONWARNING);
 9 }
10 
11 int main()
12 {
13         bool bMsgBox = false;
14         if(bMsgBox)
15         {
16             printHelloWorld(10);
17         }
18         else
19         {
20             printf("Hello, World");
21         }
22 }

該程序總是在console輸出"Hello, World",現在要修改其binary,使其總是彈出一個MessageBox。

編譯並使用ollydbg打開,因為我知道要傳一個參數10到printHelloWorld函數中去,可以肯定會有一個指令:PUSH 0A,關鍵代碼在其附近,在反匯編窗口搜索定位:

可以看到,在PUSH 0A前面是一個條件判斷,對應源代碼中的那個判斷,於是不難推出,Mov BYTE PTR SS:[LOCAL.1+3],0就是給bool型變量bMsgBox賦值的指令,0就是false。

於是,在這里雙擊該指令,把0改成1,運行便看到程序彈出了messagebox。

注意,為了保存修改過的可執行文件,你需要:

  • 右鍵-Edit-Copy to executable, 彈出該二進制文件的內容窗口
  • 右鍵 - Save file

三、破解

需要破解的程序,其行為是:在任何一台機器上使用該程序,你需要輸入一個授權碼,該授權碼由特定程序通過系統信息產生,其工作流程為:

  1. 在客戶電腦上運行該程序,獲取系統信息(一個字符串)
  2. 將該字符串發給授權人,他有一個工具會產生授權碼,並發給使用者
  3. 使用者輸入該授權碼,程序驗證,如通過則可使用。

單從行為上分析,突破口在於授權驗證這一步,該程序要驗證輸入的授權碼是否正確,也就是說它肯定知道正確的驗證碼,也就是說由系統信息產生授權碼的算法也是內置在客戶程序這邊的,我們只不過需要一個辦法把它讀出來。

該驗證步驟是:獲取系統信息,並個根據該信息產生正確的授權碼,然后從某文本文件讀入用戶輸入的驗證碼,對兩者進行對比,如果成功,則彈出一個messagebox:output(true), 否則就是output(false)。根據以上信息,設置以下斷點:

  • 菜單View-executable modules - show names,找到ReadFile和MessageBoxA,打上斷點
  • 在反匯編窗口右鍵,Search for - all referenced strings, 找到output字符串,並設斷點

有了這幾個斷點,你就可以在運行中觀察寄存器/棧/內存等內容,以及匯編指令來了解整個程序的運作機理。多走幾遍,多觀察思考,適當添加斷點與注釋。特別注意哪些條件測試指令與call指令,確定其行為后繼續跟進去。

這樣,就找到了其內部獲取系統信息的函數調用,與根據系統信息算出授權碼的函數調用,從而得到了正確的授權碼,結束。

當然,要做的好一點的話,還可以:

  • 分析其授權碼產生函數的算法,自己寫一個產生器
  • 或者,動態修改其可執行文件,將其產生的授權碼用一個MessageBox輸出。

但對於第一項,這需要閱讀很多匯編代碼,我沒時間;對於第二項,需要插入對windows API函數的調用,這比簡單的修改一個指令要復雜,暫時還不會,也不打算仔細研究。畢竟,是朋友所托,完成任務即可,不打算仔細研究 - 我還有很多其他重要的事情要做。

四、技巧總結

  • 你可以通過猜測可能調到的Windows API函數,設置斷點作為突破口
  • 你也可以通過可能reference到的字符串設置斷點
  • 查到指令也是一個方法,但估計不是很有用 - 在沒有源代碼的情況下你很難預測一個特殊的指令被調用到了
  • 選中指令后,你可以右鍵-help on command來查到匯編指令幫助
  • 你可以雙擊匯編指令進行修改
  • 你可以添加注釋 - 在一個漫長的破解過程中,記下你發現的是蠻重要的
  • 選中指令后,你可以看到其跳轉關系
  • 我還很初級,這個強大的工具有更多技巧去發現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM