美文网首页
如何完美破解AquaticPrime License

如何完美破解AquaticPrime License

作者: Mr_Xiao | 来源:发表于2017-11-01 01:12 被阅读0次

    本练习对象为Exces,一款小工具软件。下载地址:http://excesapp.com。作者本人其实已经描述了如何破解Exces,只是文中方法是暴力破解。笔者认为稍显简单粗暴——技不止于此!因此,尝试从真正注册license入手,实现完美破解!
    Exces是如何注册的呢?运行Exces,见下图,可以看到注册license方法。在Preferences弹出框中,拖入一个有效的license文件。

    Snip20171031_6.png
    Snip20171031_4.png

    那这个license文件是怎么样的呢?我们在Hopper中分析。

    0x1 代码分析

    在Hopper中打开Exces,找到verifyLicenseFile:方法。

    
    
            ; ================ B E G I N N I N G   O F   P R O C E D U R E ================
    
            ; Variables:
            ;    arg_8: 16
            ;    _cmd: 12
            ;    self: 8
            ;    var_1C: -28
            ;    var_34: -52
            ;    var_38: -56
            ;    var_3C: -60
            ;    var_40: -64
            ;    var_44: -68
            ;    var_48: -72
    
    
                 -[SSExcesAppController verifyLicenseFile:]:
    000051fc         push       ebp                                                 ; Objective C Implementation defined at 0x14ef8 (instance method)
    000051fd         mov        ebp, esp
    000051ff         push       edi
    00005200         push       esi
    00005201         push       ebx
    00005202         sub        esp, 0x3c
    00005205         mov        eax, dword [ebp+arg_8]
    00005208         mov        edi, dword [ebp+self]
    0000520b         mov        dword [ebp+var_1C], eax
    0000520e         mov        dword [esp+0x48+var_40], eax
    00005212         mov        eax, dword [objc_msg_verifyPath_]                   ; @selector(verifyPath:)
    00005217         mov        dword [esp+0x48+var_48], edi                        ; argument #1 for method imp___jump_table__objc_msgSend
    0000521a         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000521e         call       imp___jump_table__objc_msgSend
    00005223         test       eax, eax
    00005225         je         loc_530d
    
    0000522b         mov        eax, dword [objc_msg_alloc]                         ; @selector(alloc)
    00005230         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005234         mov        eax, dword [cls_NSTask]                             ; cls_NSTask
    00005239         mov        dword [esp+0x48+var_48], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
    0000523c         call       imp___jump_table__objc_msgSend
    00005241         mov        edx, dword [objc_msg_init]                          ; @selector(init)
    00005247         mov        dword [esp+0x48+var_44], edx                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000524b         mov        dword [esp+0x48+var_48], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
    0000524e         call       imp___jump_table__objc_msgSend
    00005253         mov        dword [esp+0x48+var_40], 0x12418                    ; @"/bin/cp"
    0000525b         mov        ebx, eax
    0000525d         mov        eax, dword [objc_msg_setLaunchPath_]                ; @selector(setLaunchPath:)
    00005262         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005265         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005269         call       imp___jump_table__objc_msgSend
    0000526e         mov        eax, dword [objc_msg_stringByExpandingTildeInPath]  ; @selector(stringByExpandingTildeInPath)
    00005273         mov        esi, dword [cls_NSArray]                            ; cls_NSArray
    00005279         mov        dword [esp+0x48+var_48], 0x123b8                    ; @"~/Library/Preferences/com.seosoft.exces.licence.excli", argument #1 for method imp___jump_table__objc_msgSend
    00005280         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005284         call       imp___jump_table__objc_msgSend
    00005289         mov        dword [esp+0x48+var_34], 0x0
    00005291         mov        dword [esp+0x48+var_38], eax
    00005295         mov        eax, dword [ebp+var_1C]
    00005298         mov        dword [esp+0x48+var_40], 0x12428                    ; @"-r"
    000052a0         mov        dword [esp+0x48+var_3C], eax
    000052a4         mov        eax, dword [objc_msg_arrayWithObjects_]             ; @selector(arrayWithObjects:)
    000052a9         mov        dword [esp+0x48+var_48], esi                        ; argument #1 for method imp___jump_table__objc_msgSend
    000052ac         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000052b0         call       imp___jump_table__objc_msgSend
    000052b5         mov        dword [esp+0x48+var_40], eax
    000052b9         mov        eax, dword [objc_msg_setArguments_]                 ; @selector(setArguments:)
    000052be         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000052c1         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000052c5         call       imp___jump_table__objc_msgSend
    000052ca         mov        eax, dword [objc_msg_launch]                        ; @selector(launch)
    000052cf         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000052d2         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000052d6         call       imp___jump_table__objc_msgSend
    000052db         mov        ebx, dword [edi+0xc]
    000052de         mov        byte [edi+0x2c], 0x1
    000052e2         mov        eax, dword [objc_msg_selectedToolbarItem]           ; @selector(selectedToolbarItem)
    000052e7         mov        dword [esp+0x48+var_48], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000052ea         mov        dword [esp+0x48+var_44], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000052ee         call       imp___jump_table__objc_msgSend
    000052f3         mov        dword [ebp+arg_8], eax
    000052f6         mov        eax, dword [objc_msg_toolbarHit_]                   ; @selector(toolbarHit:)
    000052fb         mov        dword [ebp+self], ebx
    000052fe         mov        dword [ebp+_cmd], eax
    00005301         add        esp, 0x3c
    00005304         pop        ebx
    00005305         pop        esi
    00005306         pop        edi
    00005307         leave
    00005308         jmp        imp___jump_table__objc_msgSend
                            ; endp
    
                 loc_530d:
    0000530d         add        esp, 0x3c                                           ; CODE XREF=-[SSExcesAppController verifyLicenseFile:]+41
    00005310         pop        ebx
    00005311         pop        esi
    00005312         pop        edi
    00005313         leave
    00005314         ret
                            ; endp
    
    

    其中,关键点为调用的verifyPath:方法;如果verifyPath方法通过,便将License文件cp(拷贝) 到~/Library/Preferences/com.seosoft.exces.licence.excli。由此得到 一点提示,即licence 文件为excli后缀。

    接下来看verifyPath:方法。

    00005315         push       ebp                                                 ; Objective C Implementation defined at 0x14eec (instance method)
    00005316         mov        ebp, esp
    00005318         push       edi
    00005319         push       esi
    0000531a         push       ebx
    0000531b         sub        esp, 0x1c
    0000531e         mov        eax, dword [objc_msg_string]                        ; @selector(string)
    00005323         mov        edi, dword [ebp+self]
    00005326         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000532a         mov        eax, dword [cls_NSMutableString]                    ; cls_NSMutableString
    0000532f         mov        dword [esp+0x28+var_28], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005332         call       imp___jump_table__objc_msgSend
    00005337         mov        dword [esp+0x28+var_20], 0x12438                    ; @"0xE6242CBE8E7686CB4AFB143FAF6D"
    0000533f         mov        ebx, eax
    00005341         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005346         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005349         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000534d         call       imp___jump_table__objc_msgSend
    00005352         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005357         mov        dword [esp+0x28+var_20], 0x12448                    ; @"6B7805475B6D856812"
    0000535f         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005362         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005366         call       imp___jump_table__objc_msgSend
    0000536b         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005370         mov        dword [esp+0x28+var_20], 0x12458                    ; @"9"
    00005378         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    0000537b         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000537f         call       imp___jump_table__objc_msgSend
    00005384         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005389         mov        dword [esp+0x28+var_20], 0x12458                    ; @"9"
    00005391         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005394         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005398         call       imp___jump_table__objc_msgSend
    0000539d         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    000053a2         mov        dword [esp+0x28+var_20], 0x12468                    ; @"1D6547D406"
    000053aa         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000053ad         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000053b1         call       imp___jump_table__objc_msgSend
    000053b6         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    000053bb         mov        dword [esp+0x28+var_20], 0x12478                    ; @"A2C26"
    000053c3         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000053c6         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000053ca         call       imp___jump_table__objc_msgSend
    000053cf         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    000053d4         mov        dword [esp+0x28+var_20], 0x12488                    ; @"3"
    000053dc         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000053df         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000053e3         call       imp___jump_table__objc_msgSend
    000053e8         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    000053ed         mov        dword [esp+0x28+var_20], 0x12488                    ; @"3"
    000053f5         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    000053f8         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    000053fc         call       imp___jump_table__objc_msgSend
    00005401         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005406         mov        dword [esp+0x28+var_20], 0x12498                    ; @"BE7F9494B188D12EE391D7A"
    0000540e         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005411         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005415         call       imp___jump_table__objc_msgSend
    0000541a         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    0000541f         mov        dword [esp+0x28+var_20], 0x124a8                    ; @"9C9E84B05"
    00005427         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    0000542a         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    0000542e         call       imp___jump_table__objc_msgSend
    00005433         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005438         mov        dword [esp+0x28+var_20], 0x124b8                    ; @"8"
    00005440         mov        dword [esp+0x28+var_28], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
    00005443         mov        dword [esp+0x28+var_24], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
    00005447         call       imp___jump_table__objc_msgSend
    0000544c         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)  
    .....
    .....
    

    代码太长,看伪代码就比较清晰了。

    void * -[SSExcesAppController verifyPath:](void * self, void * _cmd, void * arg_8) {
        edi = self;
        ebx = [NSMutableString string];
        [ebx appendString:@"0xE6242CBE8E7686CB4AFB143FAF6D"];
        [ebx appendString:@"6B7805475B6D856812"];
        [ebx appendString:@"9"];
        [ebx appendString:@"9"];
        [ebx appendString:@"1D6547D406"];
        [ebx appendString:@"A2C26"];
        [ebx appendString:@"3"];
        [ebx appendString:@"3"];
        [ebx appendString:@"BE7F9494B188D12EE391D7A"];
        [ebx appendString:@"9C9E84B05"];
        [ebx appendString:@"8"];
        [ebx appendString:@"8"];
        [ebx appendString:@"742EAE04CFE6831F338"];
        [ebx appendString:@"B2D"];
        [ebx appendString:@"9"];
        [ebx appendString:@"9"];
        [ebx appendString:@"E4AC7202CE86FEDDF170EF6AE"];
        [ebx appendString:@"1"];
        [ebx appendString:@"D"];
        [ebx appendString:@"D"];
        [ebx appendString:@"50DC8A8EDE47CA3EC1B11B86BED"];
        [ebx appendString:@"945AB07989D"];
        [ebx appendString:@"B"];
        [ebx appendString:@"B"];
        [ebx appendString:@"A634511AE20B8ADFC"];
        [ebx appendString:@"501D130BE"];
        [ebx appendString:@"4"];
        [ebx appendString:@"4"];
        [ebx appendString:@"EDF1DC6129A929A12A8"];
        [ebx appendString:@"506739EE47871476D5"];
        esi = [[AquaticPrime aquaticPrimeWithKey:ebx] dictionaryForLicenseFile:arg_8];
        if (([[esi objectForKey:@"Expires"] isEqualToString:@"never"] == 0x0) && ([[NSCalendarDate calendarDate] isGreaterThan:[NSCalendarDate dateWithString:[esi objectForKey:@"Expires"] calendarFormat:@"%d/%m/%Y"]] != 0x0)) {
                esi = 0x0;
        }
        else {
                if (*(edi + 0xc) == 0x0) {
                        *(edi + 0xc) = [SSExcesPrefController new];
                }
                [*(edi + 0xc) setLicenseDictionary:esi];
        }
        eax = esi;
        return eax;
    }
    

    从代码可以看出,先拼接出Key,因此这个Key是写死在APP里面的。然后调用[AquaticPrime aquaticPrimeWithKey],通过dictionaryForLicenseFile方法从license文件中读出Expires字段。如果Expires为never或者Expires定义的日期在当前日期后面,则校验通过。所以,看来验证的逻辑比较简单。但如何伪装一份license让APP接受,那就要看AquaticPrime调用的aquaticPrimeWithKey方法。

    0x2 AquaticPrime Framework

    AquaticPrime是什么?Google一下,就知道AquaticPrime为Mac OS X上流行的利用RSA加密算法进行license验证的Framework。大概原理是生成RSA公钥、私钥对,用私钥加密生成license文件。公钥则放APP里,用来解密和检验license。由于RSA具有非对称性,使用私钥加密的字符,配对的公钥(即上述拼接的Key)才能解密,并且从公钥无法得到私钥,所以具备很好的保密性。由于APP无法知道私钥,无从知道license怎么来的,也无法解密任意的license。看到这里,似乎非暴力破解此APP是无望了。开始笔者也是这么认为的。还好,AquaticPrime为开源软件,在github找到AquaticPrimeFramework源代码,看到了希望的曙光。

    0x3 破解AquaticPrime

    AquaticPrimeFramework源码提供了生成license文件的APP,可以生成出一对RSA钥匙和对应的license文件。所以,破解的思路就是自制一份license文件和RSA公、私钥,然后将APP中的公钥替换为自制公钥 。

    (1)生成license和RSA公、私钥

    如下图。根据代码分析,license中的Expires字段设为never,后缀名为excli。


    Snip20171101_9.png Snip20171101_8.png

    (2)使用自制的公钥替换APP公钥

    这里使用了Hex Fiend二进制编辑工具。用Hex Fiend打开APP,找到公钥字符串,全部替换为自制的公钥。如下二图。

    替换前:


    Snip20171101_11.png

    替换后:

    Snip20171101_12.png

    (3)修改verifyPath方法,导入自制的公钥

    在Hopper中编辑verifyPath方法,只保留第一个objc_msg_appendString_ 0x12438方法,然后在0x12438定义的字符串中将length设为0x102。即一次性将公钥导入,省去混淆公钥的过程(代码太长,省略部分)。

    ...
    ...
    0000531e         mov        eax, dword [objc_msg_string]                        ; @selector(string)
    00005323         mov        edi, dword [ebp+8]
    00005326         mov        dword [esp+4], eax                                  ; argument #2 for method imp___jump_table__objc_msgSend
    0000532a         mov        eax, dword [cls_NSMutableString]                    ; cls_NSMutableString
    0000532f         mov        dword [esp], eax                                    ; argument #1 for method imp___jump_table__objc_msgSend
    00005332         call       imp___jump_table__objc_msgSend
    00005337         mov        dword [esp+8], 0x12438                              ; @"0xDC24E2A5B7C87320A6663704670BC09E4B6AE5301D40CDCCE5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE…"
    0000533f         mov        ebx, eax
    00005341         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005346         mov        dword [esp], ebx                                    ; argument #1
    00005349         mov        dword [esp+4], eax                                  ; argument #2
    0000534d         call       imp___jump_table__objc_msgSend
    00005352         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005357         mov        dword [esp+8], 0x12448                              ; @"09E4B6AE5301D40CDCCE5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
    0000535f         mov        dword [esp], ebx                                    ; argument #1
    00005362         mov        dword [esp+4], eax                                  ; argument #2
    00005366         nop        dword [eax+eax]
    0000536b         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005370         mov        dword [esp+8], 0x12458                              ; @"E5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
    00005378         mov        dword [esp], ebx                                    ; argument #1
    0000537b         mov        dword [esp+4], eax                                  ; argument #2
    0000537f         nop        dword [eax+eax]
    00005384         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    00005389         mov        dword [esp+8], 0x12458                              ; @"E5F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
    00005391         mov        dword [esp], ebx                                    ; argument #1
    00005394         mov        dword [esp+4], eax                                  ; argument #2
    00005398         nop        dword [eax+eax]
    0000539d         mov        eax, dword [objc_msg_appendString_]                 ; @selector(appendString:)
    000053a2         mov        dword [esp+8], 0x12468                              ; @"F79259AAD0765A4BB5ED02ABBECCC6323852E44ACB97BA6D9AEEFE7AE420AD2991803853D76741F5118C36878E0A5C1067A2705788D1A5145430D3BA4B37469BF2F48A5EE210529A238ED86296B4563EBA56D23BC15D7980586079F58A83C24E0B73BE4336DE959EE47871476D5"
    000053aa         mov        dword [esp], ebx                                    ; argument #1
    000053ad         mov        dword [esp+4], eax                                  ; argument #2
    ...
    ...
    

    0x4 程序验证

    将自制的license文件拖入Exces,验证成功!:)!

    Snip20171031_3.png

    相关文章

      网友评论

          本文标题:如何完美破解AquaticPrime License

          本文链接:https://www.haomeiwen.com/subject/fqgipxtx.html