https://www.52pojie.cn/thread-709699-1-1.html
將上面鏈接中的160個CrackMe的打包文件
下載下來之後, 打開該chm
, 選擇第一個Acid burn
, 下載保存到本地, 然後解壓, 運行其中的 exe 程序
0x00 查殼
殼是啥? 爲啥要查殼脫殼? 不懂, 先跳過!
程序是使用delphi
編寫的無殼
0x01 分析程序
首先了解下這個軟件運行時的情況,記錄下有哪幾個需要破解的位置。
程序運行時會彈出一個NAG窗口
, 標題是hello you have to kill me
,這個窗口是要去除的
NAG窗口
: 軟件未註冊或軟件的試用版經常會彈出一些提示窗口要求註冊,這些窗口被稱爲nag窗口
然後點擊確定
後進入程序的主窗口
進去後發現有兩個按鈕, 根據按鈕上的字符串判斷應該是需要輸入序列號和名稱的位置。
首先看下左邊那個按鈕,點擊進去看下情況,發現有兩個輸入框,分別是輸入用戶名和序列號,然後點擊Check it Baby
,程序會進行校驗,校驗失敗會彈出下面窗口,提醒你Try Again!!
可以發現上面這個位置是一個需要破解的點。
然後點擊I give up
按鈕返回到程序的主界面,看下右邊那個按鈕的情況。
點擊進去後發現有一個輸入框,提醒你輸入序列號,然後點擊Check it Baby
,程序會進行校驗,校驗失敗會彈出下面窗口,提示你Failed!
記錄下這個位置也是一個需要破解的點。
綜上所述,我們可以看到這個程序有三個點需要破解:
- 程序主界面之前的一個NAG窗口
- Serial/Name校驗頁面
- Serial校驗頁面
0x02 NAG窗口去除
首先我們先要破解第一個NAG窗口, 啓動OllyDbg軟件, 選擇菜單的文件
-> 打開
-> 選擇Acid burn.exe
此時文件會停留在如下位置, 雙擊註釋位置能添加自定義註釋
用OD打開後可以按F8
單步步過, 調試一遍看下程序的調用情況. 可以發現單步調試到 call Acid_bur.00429F8C
時, 第一個NAG窗口出現了
每按一次
F8
, 將執行反彙編窗口中的一條指令, 遇到CALL
等子程序不進入其代碼
很明顯第一個NAG窗口的主函數在這個調用函數裏面, 所以在這個點按F2
下一個斷點, 斷點下成功會變紅
按
F2
之後, 程序運行到此處會暫停, 再按一次F2
鍵會刪除斷點
然後按Ctrl+F2
重新加載程序, 按F9
運行到斷點call Acid_bur.00429F8C
處, 按F7
單步步入 進入該函數, 然後再繼續按F8
單步步過調試,在call dword ptr ds:[esi+0x24]
這個位置NAG窗口又出來了
Ctrl+F2
: 重新運行程序.
F9
: 如果沒有設置斷點, 被調試的程序會直接開始運行; 如果設置了斷點, 程序會停在斷點處.
F7
: 單步步入, 功能和單步步過F8
類似, 區別是遇到CALL
等子程序時會進入其中
老方法, 按F2
下斷點、Ctrl+F2
重新加載程序,按F9
運行到第一個斷點call Acid_bur.00429F8C
處, F7
進入函數, 按F9
運行到第二個斷點call dword ptr ds:[esi+0x24]
, 按F7
進入該函數, 繼續F8
單步調試,在call dword ptr ds:[ebx+0x1CC]
位置NAG窗口
繼續彈出
老規矩, F2
下斷點, Ctrl+F2
重新運行, 不斷使用F9
和F7
使得程序運行到call dword ptr ds:[ebx+0x1CC]
然後我們直接按F7
單步步入進去, F7
進入call Acid_bur.0042A170
此時我們可以看到熟悉的字眼MessageBoxA
, 顯然這個第四次進入的函數call dword ptr ds:[ebx+0x1CC]
, 就是調用彈出對話框的函數. 所以, 不應該繼續往下分析了, 應該往回看.
按Esc
, 回到第四次進入, 調用彈框的地方, 沒啥好分析的, 就是一些賦值, 應該是對話框的標題, 內容之類的
再按幾次Esc
, 回到第三次進入的地方
在這個位置我們需要注意一下, 此處存在比較語句cmp
和跳轉語句je
cmp
: 用第一個操作減去第二個操作數, 若執行指令後,ZF=1
, 則說明兩個數相等, 因爲zero爲1說明結果爲0.
zf
代表Zero Flag
, 表示零標誌位
je
代表jmp equal
, 表示等於就跳轉, 是否等於可以看zf
的值,zf=1
, 則跳轉;zf=0
則不跳轉
我們將代碼重新執行一次, F8
運行到這個je
語句這裏, 留意到右邊寄存器窗口, 此時的zf=0
, 說明不會跳轉, 因爲不跳轉, 所以執行了彈框函數call dword ptr ds:[ebx+0x1CC]
注意左邊的線, 白色說明不跳, 紅色則會跳
因此這裏我們可以使用暴力破解的方式直接jmp
過來, 跳過彈窗函數
雙擊je short Acid_bur.00425643
, 將彈框內的je short 00425643
改成jmp 00425643
, 點擊彙編
這樣修改是爲了程序運行到0042562F
處直接跳到00425643
處, 越過彈窗函數
修改完畢後我們右鍵
->複製到可執行文件
->所有修改
->全部複製
然後自動跳到D窗口
,右鍵
->保存文件
, 將程序重命名爲Acid_burn1.exe
然後按F3
加載Acid burn1.exe
程序,按F9
直接運行可以發現沒有了NAG窗口, 至此, 第一個NAG窗口去除成功
0x03 分析Serial
隨便輸入一組錯誤的序列號, 程序彈出一個失敗的提示框
可以從這個字符串入手, 啓動OllyDbg軟件,選擇菜單的文件
-> 打開
-> 選擇Acid burn.exe
此時文件會停留在如下位置, 雙擊註釋位置能添加自定義註釋
在反彙編窗口右鍵鼠標,選擇查找
->所有參考文本字串
彈出如下圖所示的對話框
右鍵選擇查找文本
-> 輸入Try
定位Try Again!!
位置
接着右鍵鼠標,點擊反彙編窗口中跟隨
接着定位到如下圖所示位置
可以看到, 除了Try Agained!!
, Failed
之外, 上面還有Congratz!
和God Job dude!!
我們先看看Try Again!!
在哪先, 選中該語句右鍵查找參考
->選定地址
(快捷鍵Ctrl+R
)
彈出如下圖所示的參考頁面
雙擊上面的地址(0042F4F8
), 去到對應的位置
然後我們按Esc
返回, 再查看其他的位置, 在反彙編窗口加上註釋如下:
注意查看此時的反彙編窗口的彙編代碼
JNZ
=jump if not zero
運算結果不爲零則跳轉, 即ZF
不爲1時跳轉
簡單講一下這裏的邏輯: 先調用一個函數call Acid_bur.004039FC
, 如果返回結果不爲0, 則jnz short Acid_bur.0042F4F1
, 即跳轉到下面的失敗彈框; 如果返回結果爲0, 則不跳轉, 執行成功的彈框.
成功彈框執行完成之後, 會有一個jmp short Acid_bur.0042F509
, 跳過失敗彈框的邏輯, 因爲前面已經執行完成功彈框的邏輯了, 當然要跳過失敗彈框的邏輯啦!
走到這一步就很好解決了, 得出方法一: 修改上面的JNZ
改爲NOP
, 讓他直接往下執行就行了唄
NOP是英語No Operation的縮寫。
NOP
無操作數,所以稱爲空操作。
方法一
雙擊jnz short Acid_bur.0042F4F1
, 改成nop
修改完畢後我們右鍵
->複製到可執行文件
->所有修改
->全部複製
然後自動跳到D窗口
,右鍵
->保存文件
, 將程序重命名爲Acid_burn2.exe
然後按F3
加載Acid burn2.exe
程序, 按F9
直接運行, 此時隨便輸入一個序列號, 如下圖:
方法二
方法一的思路是, 不管前面的函數返回啥, 我將jnz short Acid_bur.0042F4F1
, 改成nop
, 直接不跳轉, 讓程序繼續往下執行.
這裏我們不妨在這個jnz
前面的函數call Acid_bur.004039FC
上按F2
插入一個斷點, 看看發生了這個函數發生了啥
插入斷點後, Ctrl+F2
重新運行, F9
運行, 然後打開Serial窗口
, 隨便輸入一個序列號, 比如我輸入了sdfsdf
, 然後點擊Check it Baby!
切換OD, 程序自動停到當前斷點處, 此時注意右邊寄存器窗口中出現了兩個值, EAX
的值是我們輸入的sdfsdf
, 而EDX
的值是Hello Dude!
, 很可能這個值就是真正的序列號
驗證的方法很簡單, Ctrl+F2
重新運行 ->F9
運行, 輸入該字符串Hello Dude!
->F9
繼續運行, 彈框如下:
發現Hello Dude!
就是正確的序列號
秉着嚴謹的態度, 我們按F7
進去該函數看一下, 看到了熟悉的cmp
, 以及下面的je
這裏的je
跳轉沒有實現, 所以, 我們可以參考上面的NAG窗口去除
, 直接修改成jmp
, 直接跳到00403A9A
, 以達到隨便輸入都彈出正確的框框, 具體操作此處不再重複.
0x04 分析Serial/Name
F3
加載解決Serial
之後保存的的Acid burn2.exe
, F9
直接運行, 然後隨便輸入, 點擊Check it Baby!
, 此時的錯誤彈框先不要關
回到OD, 按F12
暫停, 點擊堆棧K小圖標(Ctrl+K)
, 如下圖:
這裏有兩個MessageBox的地址,第一個地址爲77D5082F
這個地址明顯太大, 不在模塊的領空, 不是的。第二個地址爲0042A1AE
, 和00400100
地址非常接近,十有八九就是它了。
關於
程序領空
和系統領空
, 具體請查看 https://www.52pojie.cn/thread-75582-1-1.html , 我們只需要明白00400000
這個基址開始的地址,一直到00488000
結束的基址都是程序領空
右鍵
-> 顯示調用
注意觀察彈框開始的 push ebp
左邊, 那裏有一根線, 可以幫助我們定界
在頭部push ebp
下按F2
下斷點, Ctrl+F2
重新運行, F9
運行, 重新隨便輸入序列號和名字, 點擊Check it baby!!
按鈕, 程序停在斷電處, 此時在右下角堆棧處找到最近一條Return語句
0012F974 0042FB37 返回到 Acid_bur.0042FB37 來自 Acid_bur.0042A170
右鍵
->反彙編窗口中跟隨
0042FAD5 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; UNICODE "-"
0042FADA |. FF75 F8 push [local.2] ; Acid_bur.0042FBB8
0042FADD |. 8D45 F4 lea eax,[local.3]
0042FAE0 |. BA 05000000 mov edx,0x5
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC
0042FAEA |. 8D55 F0 lea edx,[local.4]
0042FAED |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3 |. E8 60AFFEFF call Acid_bur.0041AA58
0042FAF8 |. 8B55 F0 mov edx,[local.4]
0042FAFB |. 8B45 F4 mov eax,[local.3]
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC
0042FB03 |. 75 1A jnz short Acid_bur.0042FB1F ; 這是個關鍵的判斷
0042FB05 |. 6A 00 push 0x0
0042FB07 |. B9 CCFB4200 mov ecx,Acid_bur.0042FBCC
0042FB0C |. BA D8FB4200 mov edx,Acid_bur.0042FBD8
0042FB11 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB16 |. 8B00 mov eax,dword ptr ds:[eax] ; Acid_bur.00424090
0042FB18 |. E8 53A6FFFF call Acid_bur.0042A170
0042FB1D |. EB 18 jmp short Acid_bur.0042FB37 ; 這個跳轉跳過了錯誤彈框
0042FB1F |> 6A 00 push 0x0
0042FB21 |. B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; ASCII 54,"ry Again!"
0042FB26 |. BA 80FB4200 mov edx,Acid_bur.0042FB80 ; ASCII 53,"orry , The serial is incorect !"
0042FB2B |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB30 |. 8B00 mov eax,dword ptr ds:[eax] ; Acid_bur.00424090
0042FB32 |. E8 39A6FFFF call Acid_bur.0042A170 ; 錯誤彈框
0042FB37 |> 33C0 xor eax,eax ; 返回到了這裏
簡單分析一下上面的代碼: jnz short Acid_bur.0042FB1F
會通過它上面的call Acid_bur.004039FC
判斷我們的輸入是否正確,判斷的結果存在EAX中,如果EAX不等於就跳轉到錯誤提示信息框那裏
我們的目的是無論輸入是否正確都通過驗證, 所以最簡單的辦法就是將jnz short Acid_bur.0042FB1F
這句使用NOP
填充
我們嘗試一下:選擇JNZ這句,右鍵
->二進制
->用NOP填充
. 按F9
繼續運行程序
回到原始程序,再次點擊Check it baby!
, 發現它卡住了, 莫慌, 是因爲我們之前在push ebp
下了一個斷點, 切換回OD, 再按F9
運行, 如下圖:
此時我們重新打開未修改過的Acid burn2.exe
, 再讓它彈出錯誤窗口, 切換OD, 再按F12
暫停一下, 按堆棧k
小圖標(Ctrl+K)窗口, 看一下最後一個調用, 是不是發現什麼特殊的地方?
對啦!那個CALL就是調用MessageBox的地方,所以,下次我們就不用在MessageBox處下斷跟蹤了,直接最後一個地址
->右鍵
->顯示調用
得知這個小技巧之後, 我們還需要處理最後一個小問題, 如果輸入的Serial
的長度小於4, 就會彈出錯誤的窗口.
我們保持當前錯誤窗口別關掉, 回到OD, 按F12
暫停->點堆棧k小圖標
->最後一個地址
->顯示調用
顯然, 我們的目的就是讓它無論如何都要跳, 所以直接將jge short Acid_bur.0042FA79
改成jmp 0042FA79
即可
F9
運行->切換程序->再點一下Check it Baby!
, 如下:
最後, 按照上面講過的流程, 保存下來即可
0x05 總結
至此, 這個程序的破解工作已經全部完成!
我們大概學瞭如下內容:
- OD的一些快捷鍵, 如F7, F8, F9, F12等等
- 字符串搜索定位
- F12暫停法分析程序
- 修改完後怎麼保存
- 取消類似
jnz
的跳轉, 即改成NOP; 強制跳轉, 即改成jmp
- 還有複習了一些彙編語法
歡迎大家訪問我的博客: https://fengwenhua.top , 雖然博客上面沒啥東西!