如何生成CrackMe注册机之MSJ Challenge #2

本破解练习来自MSJ2009 Challenge#2,下载地址如下:https://reverse.put.as/wp-content/uploads/2010/05/MSJ20092.zip。
难度系数Level 2,所以破解起来比较麻烦,主要是计算Keygen的流程比较繁琐。
打开运行,如下。输入正确的名称、邮箱及Serial才能注册。

Snip20171019_4.png
Snip20171022_5.png

0x1 代码分析

Hopper中找到验证输入的关键函数[Level2 validateSerial:forName:forEmail:]。如下。

             -[Level2 validateSerial:forName:forEmail:]:
0000292c         push       ebp                                                 ; Objective C Implementation defined at 0x4120 (instance method)
0000292d         mov        ebp, esp
0000292f         push       edi
00002930         push       esi
00002931         push       ebx
00002932         sub        esp, 0x4c
00002935         mov        eax, dword [objc_msg_length]                        ; @selector(length)
0000293a         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000293e         mov        eax, dword [ebp+arg_8]
00002941         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002944         call       imp___jump_table__objc_msgSend
00002949         cmp        eax, 0xe
0000294c         jne        loc_2bf3

00002952         mov        eax, dword [objc_msg_length]                        ; @selector(length)
00002957         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000295b         mov        eax, dword [ebp+arg_10]
0000295e         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002961         call       imp___jump_table__objc_msgSend
00002966         cmp        eax, 0x3
00002969         jbe        loc_2bf3

0000296f         mov        eax, dword [objc_msg_lossyCString]                  ; @selector(lossyCString)
00002974         mov        esi, 0x4
00002979         xor        ebx, ebx
0000297b         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000297f         mov        eax, dword [ebp+arg_C]
00002982         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002985         call       imp___jump_table__objc_msgSend
0000298a         mov        dword [esp+0x58+var_50], 0x0
00002992         mov        edi, eax
00002994         mov        eax, dword [objc_msg_characterAtIndex_]             ; @selector(characterAtIndex:)
00002999         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
0000299d         mov        eax, dword [ebp+arg_10]
000029a0         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
000029a3         call       imp___jump_table__objc_msgSend
000029a8         mov        dword [esp+0x58+var_50], 0x4
000029b0         movzx      eax, ax
000029b3         mov        dword [ebp+var_30], eax
000029b6         mov        eax, dword [objc_msg_characterAtIndex_]             ; @selector(characterAtIndex:)
000029bb         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
000029bf         mov        eax, dword [ebp+arg_10]
000029c2         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
000029c5         call       imp___jump_table__objc_msgSend
000029ca         mov        dword [esp+0x58+var_58], edi                        ; argument #1 for method imp___jump_table__strlen
000029cd         movzx      eax, ax
000029d0         mov        dword [ebp+var_2C], eax
000029d3         call       imp___jump_table__strlen
000029d8         xor        ecx, ecx
000029da         mov        dword [ebp+var_40], eax
000029dd         jmp        loc_2a16

             loc_29df:
000029df         movsx      eax, byte [edi+ebx]                                 ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+237
000029e3         inc        ebx
000029e4         imul       eax, esi
000029e7         add        esi, 0x4
000029ea         mov        edx, eax
000029ec         shl        edx, 0x6
000029ef         lea        eax, dword [edx+eax*2+0x4e]
000029f3         add        eax, dword [ebp+var_30]
000029f6         add        ecx, eax
000029f8         mov        eax, 0x68db8bad
000029fd         imul       ecx
000029ff         mov        eax, ecx
00002a01         sar        eax, 0x1f
00002a04         sar        edx, 0xc
00002a07         sub        edx, eax
00002a09         mov        eax, ecx
00002a0b         imul       edx, edx, 0x2710
00002a11         sub        eax, edx
00002a13         mov        dword [ebp+var_28], eax

             loc_2a16:
00002a16         cmp        dword [ebp+var_40], ebx                             ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+177
00002a19         ja         loc_29df

00002a1b         mov        eax, dword [ebp+var_28]
00002a1e         mov        esi, 0x4
00002a23         xor        ebx, ebx
00002a25         mov        dword [esp+0x58+var_50], 0x3088                     ; @"%i"
00002a2d         mov        dword [esp+0x58+var_4C], eax
00002a31         mov        eax, dword [objc_msg_stringWithFormat_]             ; @selector(stringWithFormat:)
00002a36         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002a3a         mov        eax, dword [cls_NSString]                           ; cls_NSString
00002a3f         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002a42         call       imp___jump_table__objc_msgSend
00002a47         mov        dword [esp+0x58+var_58], edi                        ; argument #1 for method imp___jump_table__strlen
00002a4a         mov        dword [ebp+var_24], eax
00002a4d         call       imp___jump_table__strlen
00002a52         xor        ecx, ecx
00002a54         mov        dword [ebp+var_3C], eax
00002a57         jmp        loc_2a8b

             loc_2a59:
00002a59         movsx      eax, byte [edi+ebx]                                 ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+354
00002a5d         inc        ebx
00002a5e         imul       eax, esi
00002a61         add        esi, 0x8
00002a64         lea        eax, dword [eax+eax*4+0x4d]
00002a68         add        eax, dword [ebp+var_2C]
00002a6b         add        ecx, eax
00002a6d         mov        eax, 0x68db8bad
00002a72         imul       ecx
00002a74         mov        eax, ecx
00002a76         sar        eax, 0x1f
00002a79         sar        edx, 0xc
00002a7c         sub        edx, eax
00002a7e         mov        eax, ecx
00002a80         imul       edx, edx, 0x2710
00002a86         sub        eax, edx
00002a88         mov        dword [ebp+var_20], eax

             loc_2a8b:
00002a8b         cmp        ebx, dword [ebp+var_3C]                             ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+299
00002a8e         jb         loc_2a59

00002a90         mov        eax, dword [ebp+var_20]
00002a93         xor        ebx, ebx
00002a95         mov        esi, 0x4
00002a9a         mov        dword [esp+0x58+var_50], 0x3088                     ; @"%i"
00002aa2         mov        edi, 0x4
00002aa7         mov        dword [esp+0x58+var_4C], eax
00002aab         mov        eax, dword [objc_msg_stringWithFormat_]             ; @selector(stringWithFormat:)
00002ab0         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002ab4         mov        eax, dword [cls_NSString]                           ; cls_NSString
00002ab9         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002abc         call       imp___jump_table__objc_msgSend
00002ac1         mov        edx, 0x68db8bad
00002ac6         mov        dword [esp+0x58+var_50], 0x3088                     ; @"%i"
00002ace         mov        dword [ebp+var_38], eax
00002ad1         mov        eax, dword [ebp+var_30]
00002ad4         imul       eax, dword [ebp+var_2C]
00002ad8         mov        ecx, eax
00002ada         add        ecx, 0x4d2
00002ae0         mov        eax, ecx
00002ae2         imul       edx
00002ae4         mov        eax, ecx
00002ae6         sar        eax, 0x1f
00002ae9         sar        edx, 0xc
00002aec         sub        edx, eax
00002aee         mov        eax, dword [objc_msg_stringWithFormat_]             ; @selector(stringWithFormat:)
00002af3         imul       edx, edx, 0x2710
00002af9         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002afd         mov        eax, dword [cls_NSString]                           ; cls_NSString
00002b02         sub        ecx, edx
00002b04         mov        dword [esp+0x58+var_4C], ecx
00002b08         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002b0b         call       imp___jump_table__objc_msgSend
00002b10         mov        dword [esp+0x58+var_50], ebx
00002b14         mov        dword [esp+0x58+var_4C], esi
00002b18         mov        si, 0x5
00002b1c         mov        dword [ebp+var_34], eax
00002b1f         mov        eax, dword [objc_msg_substringWithRange_]           ; @selector(substringWithRange:)
00002b24         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002b28         mov        eax, dword [ebp+arg_8]
00002b2b         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002b2e         call       imp___jump_table__objc_msgSend
00002b33         mov        dword [esp+0x58+var_50], esi
00002b37         mov        si, 0xa
00002b3b         mov        dword [esp+0x58+var_4C], edi
00002b3f         mov        ebx, eax
00002b41         mov        eax, dword [objc_msg_substringWithRange_]           ; @selector(substringWithRange:)
00002b46         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002b4a         mov        eax, dword [ebp+arg_8]
00002b4d         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002b50         call       imp___jump_table__objc_msgSend
00002b55         mov        dword [esp+0x58+var_50], esi
00002b59         mov        dword [esp+0x58+var_4C], edi
00002b5d         mov        dword [ebp+var_1C], eax
00002b60         mov        eax, dword [objc_msg_substringWithRange_]           ; @selector(substringWithRange:)
00002b65         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002b69         mov        eax, dword [ebp+arg_8]
00002b6c         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002b6f         call       imp___jump_table__objc_msgSend
00002b74         mov        dword [esp+0x58+var_58], 0x3098                     ; @"Serial Number: %@-%@-%@", argument #1 for method imp___jump_table__NSLog
00002b7b         mov        esi, eax
00002b7d         mov        eax, dword [ebp+var_34]
00002b80         mov        dword [esp+0x58+var_4C], eax
00002b84         mov        eax, dword [ebp+var_38]
00002b87         mov        dword [esp+0x58+var_50], eax
00002b8b         mov        eax, dword [ebp+var_24]
00002b8e         mov        dword [esp+0x58+var_54], eax
00002b92         call       imp___jump_table__NSLog
00002b97         mov        eax, dword [ebp+var_24]
00002b9a         mov        dword [esp+0x58+var_58], ebx                        ; argument #1 for method imp___jump_table__objc_msgSend
00002b9d         mov        dword [esp+0x58+var_50], eax
00002ba1         mov        eax, dword [objc_msg_isEqual_]                      ; @selector(isEqual:)
00002ba6         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002baa         call       imp___jump_table__objc_msgSend
00002baf         test       al, al
00002bb1         je         loc_2bf3

00002bb3         mov        eax, dword [ebp+var_38]
00002bb6         mov        dword [esp+0x58+var_50], eax
00002bba         mov        eax, dword [objc_msg_isEqual_]                      ; @selector(isEqual:)
00002bbf         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002bc3         mov        eax, dword [ebp+var_1C]
00002bc6         mov        dword [esp+0x58+var_58], eax                        ; argument #1 for method imp___jump_table__objc_msgSend
00002bc9         call       imp___jump_table__objc_msgSend
00002bce         test       al, al
00002bd0         je         loc_2bf3

00002bd2         mov        eax, dword [ebp+var_34]
00002bd5         mov        dword [esp+0x58+var_58], esi                        ; argument #1 for method imp___jump_table__objc_msgSend
00002bd8         mov        dword [esp+0x58+var_50], eax
00002bdc         mov        eax, dword [objc_msg_isEqual_]                      ; @selector(isEqual:)
00002be1         mov        dword [esp+0x58+var_54], eax                        ; argument #2 for method imp___jump_table__objc_msgSend
00002be5         call       imp___jump_table__objc_msgSend
00002bea         mov        edx, 0x1
00002bef         test       al, al
00002bf1         jne        loc_2bf5

             loc_2bf3:
00002bf3         xor        edx, edx                                            ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+32, -[Level2 validateSerial:forName:forEmail:]+61, -[Level2 validateSerial:forName:forEmail:]+645, -[Level2 validateSerial:forName:forEmail:]+676

             loc_2bf5:
00002bf5         add        esp, 0x4c                                           ; CODE XREF=-[Level2 validateSerial:forName:forEmail:]+709
00002bf8         mov        eax, edx
00002bfa         pop        ebx
00002bfb         pop        esi
00002bfc         pop        edi
00002bfd         leave
00002bfe         ret
                        ; endp

这个函数包含两个循环,第一个循环生成第一部分的Serial,part1,第二个循环生成第二部分的Serial,part2 ,最后计算第三部分的Serial,part3。然后通过“-”连接起来。所以,Serial的格式为 part1-part2-part3。
其中,具体分析可得到:
part1:见代码段【 loc_29df】循环取输入的Name和Email的第一位字符ASCII码值进行一系列的计算,取最后的结果。
part2:见代码段【 loc_2a59】循环取输入的Name和Email的第五位字符ASCII码值进行一系列的计算,取最后的结果。
part3:见代码段【 00002ad1-00002b0b 】取Email的第一和五位字符ASCII码值进行一系列的计算,取最后的结果。

最后截取输入的Serial,是否和计算得到的Serial每一部分都相等。

0x2 Keygen算法

如何写keygen呢?这里直接复制了汇编的计算过程,没有深究算法的原理,用Objective C重新写了一遍汇编。关键代码如下。

- (NSString*)part1ByName:(NSString *)name email:(NSString *) email {
    signed long esi = 0x4;
    signed long ecx = 0;
    signed long edx = 0;
    signed long eax = 0;
    for (int i = 0; i>32>>0x1f;
        edx =((ecx * 0x68db8bad) & 0xffffffff00000000)>>32>>(0xc);
        edx = edx - eax;
        eax = ecx;
        edx *= 0x2710;
        eax = eax-edx;
    }
    return [NSString stringWithFormat:@"%d",eax];
}
- (NSString*)part2ByName:(NSString *)name email:(NSString *) email {
    signed long esi = 0x4;
    signed long ecx = 0;
    signed long edx = 0;
    signed long eax = 0;
    for (int i = 0; i>32>>0x1f;
        edx =((ecx * 0x68db8bad) & 0xffffffff00000000)>>32>>(0xc);
        edx = edx - eax;
        eax = ecx;
        edx *= 0x2710;
        eax = eax - edx;
        
    }
    return [NSString stringWithFormat:@"%d",eax];
}
- (NSString*)part3ByName:(NSString *)name email:(NSString *) email {
    signed long ecx = 0;
    signed long eax = [email characterAtIndex:0];
    eax *= [email characterAtIndex:4];
    ecx = eax;
    ecx+=0x4d2;
    eax = ecx;
    long edx =  0x68db8bad;
    signed long tem = edx * eax ;
    eax = (tem & 0x00000000ffffffff)>>32>>0x1f;
    edx =(tem & 0xffffffff00000000)>>32>>(0xc);
    edx *= 0x2710;
    ecx -= edx;
    return [NSString stringWithFormat:@"%d",ecx];
}

- (NSString*)keyGen {
    NSString  *name = @"qwer";
    NSString  *email = @"[email protected]";
    NSString  *serial = [NSString stringWithFormat:@"%@-%@-%@",
                                     [self part1ByName:name email:email ],
                                     [self part2ByName:name email:email ],
                                     [self part3ByName:name email:email ]];
 return serial;
}


0x3 验证

设Name为qwer ,邮箱为[email protected],根据Keygen程序得到序列号3796-6164-2223,输入程序,验证Success。:)!

Snip20171019_2.png
Snip20171019_1.png

你可能感兴趣的:(如何生成CrackMe注册机之MSJ Challenge #2)