今天做这个破解,也用了不少时间,大概四五个小时,一开始走了些弯路,写注册机需要数学推导。
相关资料下载链接: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()