如何生成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<name.length;i++) {
        eax = [name characterAtIndex:i];
        eax *= esi;
        esi += 0x4;
        edx = eax<<0x6;
        eax = edx + eax *2 + 0x4e;
        eax += [email characterAtIndex:0];
        ecx += eax;
        eax = ecx;
        eax = ((ecx * 0x68db8bad) & 0x00000000ffffffff)>>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<name.length;i++) {
        eax = [name characterAtIndex:i];
        eax  *= esi;
        esi += 0x8;
        eax = eax + eax *4 + 0x4d;
        eax += [email characterAtIndex:4];
        ecx += eax;
        eax = ecx;
        eax = ((ecx * 0x68db8bad) & 0x00000000ffffffff)>>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 = @"o@p.com";
    NSString  *serial = [NSString stringWithFormat:@"%@-%@-%@",
                                     [self part1ByName:name email:email ],
                                     [self part2ByName:name email:email ],
                                     [self part3ByName:name email:email ]];
 return serial;
}


0x3 验证

设Name为qwer ,邮箱为o@p.com,根据Keygen程序得到序列号3796-6164-2223,输入程序,验证Success。:)!

Snip20171019_2.png
Snip20171019_1.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容