How to Crack App by Self-Keygen

本次練習(xí)破解注冊(cè)碼使用的是一款商業(yè)軟件,所以沒有提供下載地址。這里簡(jiǎn)記為xxx.app。運(yùn)行后,有注冊(cè)License的界面。輸入郵箱和Serial即可。注冊(cè)后的效果如圖。

Snip20171026_2.png

這個(gè)序列號(hào)是怎么算出來的呢?這里使用了一個(gè)通用的技巧——self-keygen,或者叫auto-keygen。即通過動(dòng)態(tài)運(yùn)行程序,讓程序自己告訴我們Serial。能這樣做的原因在于,通常,程序會(huì)根據(jù)輸入的條件如郵箱,計(jì)算出正確的Serial,保存在內(nèi)存某處,然后和輸入的Serial比較。如果相等,就通過驗(yàn)證。所以,只要在內(nèi)存中偷出這Serial,便可以得出注冊(cè)碼,不用研究如何去復(fù)制Serial的生成算法。

0x1 代碼靜態(tài)分析

在Hopper中打開目標(biāo)程序。很容易找到判斷是否為注冊(cè)的地方。
在程序的入口有如下代碼。即initializeWithLicenseSecret方法中判斷。

0000000100001e64         mov        rsi, r15                                    ; argument "selector" for method _objc_msgSend
0000000100001e67         call       r14                                         ; _objc_msgSend
0000000100001e6a         mov        rdi, rax                                    ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000100001e6d         call       imp___stubs__objc_retainAutoreleasedReturnValue
0000000100001e72         mov        rbx, rax
0000000100001e75         mov        rsi, qword [0x1000ad508]                    ; @selector(initializeWithLicenseSecret:storeURL:daysForTrial:), argument "selector" for method _objc_msgSend
0000000100001e7c         lea        rdx, qword [cfstring_secretPa__wordForXXX] ; @"secretd*****"
0000000100001e83         lea        rcx, qword [cfstring_http_xxx_php] ; @"xxx.php"
0000000100001e8a         mov        r8d, 0x7
0000000100001e90         mov        rdi, rbx                                    ; argument "instance" for method _objc_msgSend
0000000100001e93         call       r14                                         ; _objc_msgSend
0000000100001e96         mov        rdi, rbx                                    ; argument "instance" for method _objc_release
0000000100001e99         call       qword [_objc_release_1000881e8]             ; _objc_release
0000000100001e9f         mov        rdi, qword [rbp+var_30]                     ; argument "instance" for method _objc_release
0000000100001ea3         mov        rax, qword [_objc_release_1000881e8]
0000000100001eaa         add        rsp, 0x8
0000000100001eae         pop        rbx
0000000100001eaf         pop        r12
0000000100001eb1         pop        r13
0000000100001eb3         pop        r14
0000000100001eb5         pop        r15
0000000100001eb7         pop        rbp
0000000100001eb8         jmp        rax                                         ; _objc_release
                        ; endp

但是在程序其他部分,卻找不到initializeWithLicenseSecret實(shí)現(xiàn)。后來發(fā)現(xiàn)原來是Framework中的方法。即程序?qū)Ⅱ?yàn)證邏輯放入了專門的Framework中。見下圖Framework文件夾。

Snip20171027_1.png

在Hopper中打開Framework,發(fā)現(xiàn)isLicensed方法有如下代碼。loc_61e78 中l(wèi)icenseForEmailAddress為計(jì)算Serial的方法,然后調(diào)用isEqualToString方法比較是否與輸入相等。接著看此licenseForEmailAddress方法,發(fā)現(xiàn)最終調(diào)用licenseForEmailAddress:withSecret:計(jì)算注冊(cè)碼。所以在動(dòng)態(tài)運(yùn)行時(shí),只要獲取此函數(shù)的輸出即可。

0000000000061e55         mov        rbx, rdi
0000000000061e58         call       qword [_objc_msgSend_25b2e8]                ; _objc_msgSend
0000000000061e5e         cmp        rax, 0x3
0000000000061e62         jae        loc_61e78

0000000000061e64         xor        r12d, r12d
0000000000061e67         jmp        loc_61db3

                    loc_61e6c:
0000000000061e6c         xor        r12d, r12d                                  ; CODE XREF=-[License isLicensed]+574
0000000000061e6f         mov        rdi, qword [rbp+var_30]
0000000000061e73         jmp        loc_61db6

                    loc_61e78:
0000000000061e78         mov        rsi, qword [0x2c3c48]                       ; @selector(licenseForEmailAddress:), argument "selector" for method _objc_msgSend, CODE XREF=-[HSLicense isLicensed]+640
0000000000061e7f         mov        rdi, r14                                    ; argument "instance" for method _objc_msgSend
0000000000061e82         mov        rdx, r13
0000000000061e85         call       r15                                         ; _objc_msgSend
0000000000061e88         mov        rdi, rax                                    ; argument "instance" for method imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061e8b         call       imp___stubs__objc_retainAutoreleasedReturnValue
0000000000061e90         mov        r14, rax
0000000000061e93         mov        rsi, qword [0x2c0b28]                       ; @selector(isEqualToString:), argument "selector" for method _objc_msgSend
0000000000061e9a         mov        rdi, r14                                    ; argument "instance" for method _objc_msgSend
0000000000061e9d         mov        rdx, rbx
0000000000061ea0         call       r15                                         ; _objc_msgSend
0000000000061ea3         mov        r12b, al
0000000000061ea6         mov        rdi, r14                                    ; argument "instance" for method _objc_release
0000000000061ea9         call       qword [_objc_release_25b2f8]                ; _objc_release
0000000000061eaf         jmp        loc_61db3

0x2 動(dòng)態(tài)分析

由于需要調(diào)試的代碼位于Framework中,不方便動(dòng)態(tài)運(yùn)行調(diào)試,所以選擇了Mac OS X自帶的lldb debug工具。唯一的區(qū)別是沒有操作界面,純Command Line。
首先運(yùn)行l(wèi)ldb,啟動(dòng)程序,并輸入郵箱。使用下面命令設(shè)置好BreakPoint。

br s -n licenseForEmailAddress:withSecret:
Snip20171027_4.png

接著使用di命令,反匯編當(dāng)前函數(shù)。

Snip20171027_6.png

可以看到 0x100467a01 uppercaseString方法為計(jì)算Serial的最后一步。所以在此處設(shè)置斷點(diǎn)。

 br s -a 0x100467a01

單步運(yùn)行,根據(jù)Hopper靜態(tài)代碼分析,知r15保存最終結(jié)果。
使用lldb memory read命令打印內(nèi)存,在輸出中即可得到注冊(cè)碼。如下圖中B9D3C9-816381-FC5AA0-75B626-C7564D。

0x1098a4b90: 22 42 39 44 33 43 39 2d 38 31 36 33 38 31 2d 46  "B9D3C9-816381-F
0x1098a4ba0: 43 35 41 41 30 2d 37 35 42 36 32 36 2d 43 37 35  C5AA0-75B626-C75
0x1098a4bb0: 36 34 44 00 00 00 00 00 00 00 00 00 00 00 00 00  64D.............
8.png

代入程序驗(yàn)證Success。:)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在上一篇《How to Crack App by Self-Keygen》中,通過打印內(nèi)存獲取到了Serial,但...
    Mr_Xiao閱讀 420評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,678評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,276評(píng)論 25 708
  • LLDB的Xcode默認(rèn)的調(diào)試器,它與LLVM編譯器一起,帶給我們更豐富的流程控制和數(shù)據(jù)檢測(cè)的調(diào)試功能。平時(shí)用Xc...
    CoderSC閱讀 1,511評(píng)論 0 2
  • 據(jù)說高溫已經(jīng)達(dá)到四十度之巨,倒是一直后知后覺來著,因?yàn)檫@個(gè)假期已經(jīng)宅成了精,如非必須幾乎都沒有出門的時(shí)候。...
    此時(shí)木棉閱讀 197評(píng)論 1 0

友情鏈接更多精彩內(nèi)容