今天做这个破解,也用了不少时间,大概四五个小时,一开始走了些弯路,写注册机需要数学推导。
相关资料下载链接:http://pan.baidu.com/s/1kVROQG3 密码:2h37
// 2016年8月13日 序列号-4nil-一只老虎的CRACKME // 1找断点 打开程序,输入注册名和注册码,点击注册无反应,估计是注册成功有反应 打开OD,查看所有参考字符串,什么也没找到,这里走了些弯路,后来用OD的插件 中文搜索引擎——智能搜索,在最后边找到了“恭喜你,注册成功” 双击,回到反编译窗口,上下翻翻看到,这里就一大段程序,在入口处下断点 2步骤分析 这个程序用到了很多画图的东西,第一遍过流程,就把基本的跳转和关键的Call标出来 经验:适当更改调转值,让程序顺序执行 经验:整体分析代码,看看返回值,看看寄存器变化,跟随数据看看 找到关键代码一点一点分析 3具体代码 字符串提示 ... 0048C82A /75 18 jnz short 壹只老虎.0048C844 ; 跳转就完蛋 0048C82C |. |6A 40 push 0x40 0048C82E |. |B9 ACC84800 mov ecx,壹只老虎.0048C8AC ; 恭喜你 0048C833 |. |BA B4C84800 mov edx,壹只老虎.0048C8B4 ; 注册成功!请联系我!QQ:609841314 0048C838 |. |A1 D0EB4800 mov eax,dword ptr ds:[0x48EBD0] 0048C83D |. |8B00 mov eax,dword ptr ds:[eax] 0048C83F |. |E8 F478FCFF call 壹只老虎.00454138 ; 显示提示窗口 0048C844 |> \33C0 xor eax,eax ... 0048C866 \. C3 retn 断点 0048C6D4 /. 55 push ebp 0048C6D5 |. 8BEC mov ebp,esp 0048C6D7 |. 83C4 84 add esp,-0x7C ... 0048C737 |. 8B45 FC mov eax,[local.1] 0048C73A |. E8 DD79F7FF call 壹只老虎.0040411C ;关键-获取用户名长度 0048C73F |. 83F8 0A cmp eax,0xA ;最小位数10 0048C742 0F8C FC000000 jl 壹只老虎.0048C844 ;跳转就完蛋 0048C748 |. 8B45 FC mov eax,[local.1] 0048C74B |. E8 CC79F7FF call 壹只老虎.0040411C ;关键-获取用户名长度 0048C750 |. 83F8 10 cmp eax,0x10 ;最大位数16 0048C753 0F8F EB000000 jg 壹只老虎.0048C844 ;跳转就完蛋 0048C759 |. 8B45 F8 mov eax,[local.2] 0048C75C |. E8 BB79F7FF call 壹只老虎.0040411C ;关键 0048C761 |. 83F8 11 cmp eax,0x11 ;注册码位数不能小于17位 0048C764 0F8C DA000000 jl 壹只老虎.0048C844 ;跳转就完蛋 0048C76A |. 8B45 F8 mov eax,[local.2] 0048C76D |. E8 AA79F7FF call 壹只老虎.0040411C ;关键 0048C772 |. 83F8 16 cmp eax,0x16 ;不能大于22位 0048C775 0F8F C9000000 jg 壹只老虎.0048C844 ;跳转就完蛋 0048C77B |. 8D45 FC lea eax,[local.1] 0048C77E |. 8B55 F4 mov edx,[local.3] 0048C781 |. E8 9E79F7FF call 壹只老虎.00404124 ;strcat,处理用户名在用户名后加i am Bin Laden 0048C786 |. BB 64000000 mov ebx,0x64 0048C78B |. 8D45 88 lea eax,[local.30] 0048C78E |> C600 2E /mov byte ptr ds:[eax],0x2E 0048C791 |. 40 |inc eax 0048C792 |. 4B |dec ebx 0048C793 |.^ 75 F9 \jnz short 壹只老虎.0048C78E ;初始化一块64H大小的空间 0048C795 |. 8B45 FC mov eax,[local.1] ;[local.1]是注册名,[local.2]是注册码 0048C798 |. E8 7F79F7FF call 壹只老虎.0040411C ;取长度 0048C79D |. 8BF8 mov edi,eax 0048C79F |. 85FF test edi,edi 0048C7A1 |. 7E 47 jle short 壹只老虎.0048C7EA -------------------------------------------------------------------------- 以下是核心算法 -------------------------------------------------------------------------- 0048C7A3 |. BB 01000000 mov ebx,0x1 0048C7A8 |> 8B45 F0 /mov eax,[local.4] ;检测i am yi zhi lao yu的长度,永远是12h 0048C7AB |. E8 6C79F7FF |call 壹只老虎.0040411C ;这里两个循环中,内循环的次数永远是12h(18) 0048C7B0 |. 8BF0 |mov esi,eax 0048C7B2 |. 85F6 |test esi,esi 0048C7B4 |. 7E 30 |jle short 壹只老虎.0048C7E6 0048C7B6 |. B9 01000000 |mov ecx,0x1 0048C7BB |> 8B45 FC |/mov eax,[local.1] 0048C7BE |. 0FB64418 FF ||movzx eax,byte ptr ds:[eax+ebx-0x1] ;取处理过的用户名第一个字符(外循环控制) 0048C7C3 |. 8B55 F8 ||mov edx,[local.2] 0048C7C6 |. 0FB6540A FF ||movzx edx,byte ptr ds:[edx+ecx-0x1] ;取密码的第一个字符(内循环控制) => 密码18位就够用,不够补0 0048C7CB |. F7EA ||imul edx 0048C7CD |. 51 ||push ecx 0048C7CE |. B9 1A000000 ||mov ecx,0x1A 0048C7D3 |. 33D2 ||xor edx,edx 0048C7D5 |. F7F1 ||div ecx 0048C7D7 |. 59 ||pop ecx 0048C7D8 |. 83C2 41 ||add edx,0x41 ;两者相乘的积对1Ah取余数,加41h 0048C7DB |. 8D0419 ||lea eax,dword ptr ds:[ecx+ebx] 0048C7DE |. 885405 87 ||mov byte ptr ss:[ebp+eax-0x79],dl ;把结果保存起来 0048C7E2 |. 41 ||inc ecx 0048C7E3 |. 4E ||dec esi 0048C7E4 |.^ 75 D5 |\jnz short 壹只老虎.0048C7BB ;内层循环的判断条件是18固定 0048C7E6 |> 43 |inc ebx 0048C7E7 |. 4F |dec edi 0048C7E8 |.^ 75 BE \jnz short 壹只老虎.0048C7A8 ;外层循环的判断条件是账号的长度+14 0048C7EA |> 8D45 EC lea eax,[local.5] 0048C7ED |. E8 6A76F7FF call 壹只老虎.00403E5C ;未知 0048C7F2 |. 8B45 F8 mov eax,[local.2] 0048C7F5 |. E8 2279F7FF call 壹只老虎.0040411C 0048C7FA |. 8BF8 mov edi,eax 0048C7FC |. 85FF test edi,edi 0048C7FE |. 7E 1F jle short 壹只老虎.0048C81F 0048C800 |. 8D5D 8E lea ebx,dword ptr ss:[ebp-0x72] ;从这开始 0048C803 |> 8D45 84 /lea eax,[local.31] 0048C806 |. 8A13 |mov dl,byte ptr ds:[ebx] 0048C808 |. E8 3778F7FF |call 壹只老虎.00404044 0048C80D |. 8B55 84 |mov edx,[local.31] 0048C810 |. 8D45 EC |lea eax,[local.5] 0048C813 |. 8B4D EC |mov ecx,[local.5] 0048C816 |. E8 4D79F7FF |call 壹只老虎.00404168 0048C81B |. 43 |inc ebx 0048C81C |. 4F |dec edi 0048C81D |.^ 75 E4 \jnz short 壹只老虎.0048C803 ;到这,两层循环得到的字符串的第六位开始查18位,倒叙得到明文 0048C81F |> 8B45 EC mov eax,[local.5] 0048C822 |. 8B55 F8 mov edx,[local.2] 0048C825 |. E8 3E7AF7FF call 壹只老虎.00404268 ;明文和注册码比较 0048C82A 75 18 jnz short 壹只老虎.0048C844 ;不想等,跳转就完蛋 0048C82C |. 6A 40 push 0x40 0048C82E |. B9 ACC84800 mov ecx,壹只老虎.0048C8AC ;恭喜你 0048C833 |. BA B4C84800 mov edx,壹只老虎.0048C8B4 ;注册成功!请联系我!QQ:609841314 ... 0048C866 \. C3 retn 4加密算法分析 处理用户名,在末尾添加i am Bin Laden,得新字符串记作NewName,并求其长度n 记输入的序列号为Code 则算法为: for(i=0; i 算法分析注册机
def main(): # input while True: name = raw_input('please enter your name - ') if len(name) < 10: print 'error, the min length of name is 10' elif len(name) > 16: print 'error, the max length of name is 16' else: break # prepare name = name + 'i am Bin Laden' len_name = len(name) name_list = list(name) code_list = [''] # find the last name_last = name_list[len_name-1] # enum the 1st character of serial for i in range(0, 128): if (ord(name_last)*i)%26 + 65 == i: code_first = i code_list[0] = chr(i) break # caculate the other for i in range(6, len_name): temp = chr(ord(name_list[i-1])*code_first%26 + 65) code_list.insert(1, temp) # format the serial code_final = ''.join(code_list) print 'the seiral is: ',code_final if raw_input('press any key to exit...'): pass if __name__ == '__main__': main()