前言:
本文是破解系列教程的第五篇,带大家分析注册算法,建议大家边自己分析边看本教程,多尝试几次,最后做到不看本教程也能轻松跟踪出来……
下面是正文:
【破解过程】
打开OllyDbg v1.10b,载入crackme,随便输入姓名和注册码(这里建议用x和1234567,因为我的文章就是以这个注册码和姓名为例写的,
当然用其他也可以)单击check弹出错误消息" You Have Enter A Wrong Serial, Please Try Again ",在反汇编后的代码上右击
搜索->字符参考,找到You Have Enter A Wrong Serial, Please Try Again,双击来到这里(1)(这里用爆破的前几步方法是为了找到注
册算法的位置.因为,注册算法通常是在对比注册码正确不正确的前面)
0040133A |. 3BC6 cmp eax,esi
0040133C |. 75 15 jnz short Key-Crac.00401353
0040133E |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401340 |. 68 62344000 push Key-Crac.00403462 ; |Title = "Key/CrackMe #2 "
00401345 |. 68 B8344000 push Key-Crac.004034B8 ; |Text = " Good Job, I Wish You the Very Best"
0040134A |. 6A 00 push 0 ; |hOwner = NULL
0040134C |. E8 9D000000 call <jmp.&USER32.MessageBoxA> ; MessageBoxA
00401351 |. EB 13 jmp short Key-Crac.00401366
00401353 |> 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401355 |. 68 62344000 push Key-Crac.00403462 ; |Title = "Key/CrackMe #2 "
0040135A |. 68 86344000 push Key-Crac.00403486 (1) ; |Text = " You Have Enter A Wrong Serial, Please Try Again "
0040135F |. 6A 00 push 0 ; |hOwner = NULL
00401361 |. E8 88000000 call <jmp.&USER32.MessageBoxA> ; MessageBoxA
00401366 |> EB 15 jmp short Key-Crac.0040137D
------------------------------------------------------------------------------------------------------
向上找,来到这里(2)(关键部分1)
004012F6 |> 68 38304000 (2) push Key-Crac.00403038 ; /String = "xd"
004012FB |. E8 30010000 call <jmp.&KERNEL32.lstrlenA> ; lstrlenA<---获取字符长度
00401300 |. 33F6 xor esi,esi<---清零,esi是姓名运算后的存储寄存器
00401302 |. 8BC8 mov ecx,eax<---把字符长度的值eax放到ecx里
00401304 |. B8 01000000 mov eax,1<---eax=1??什么意思,高人指点.
00401309 |> 8B15 38304000 /mov edx,dword ptr ds:[403038]<---获取姓名第一个字符串x的16进制值
0040130F |. 8A90 37304000 |mov dl,byte ptr ds:[eax+403037]
00401315 |. 81E2 FF000000 |and edx,0FF<---edx=33006577<---这个什么意思不知道,对最后的注册码的运算好像没有影响
0040131B |. 8BDA |mov ebx,edx<---ebx=edx(x的16进制值)
0040131D |. 0FAFDA |imul ebx,edx<---ebx*edx(78*78)x的16进制值相乘
00401320 |. 03F3 |add esi,ebx<---esi+ebe,如果输入的是1个以上的字符,这个语句的作用是把前几个字符的注册码和第n个字符的注册码相加
00401322 |. 8BDA |mov ebx,edx<---3840=78(把ebx的值变成edx的值)
00401324 |. D1FB |sar ebx,1<---ebx除2(第一个字符的16进制值的一半)
00401326 |. 03F3 |add esi,ebx<---把姓名的第一个字符的16进制值的一半相加 也就是3c+3840=387c
00401328 |. 2BF2 |sub esi,edx<---再把相加后的值减去字符串16进制的值
0040132A |. 40 |inc eax<---eax+1
0040132B |. 49 |dec ecx<---ecx-1
0040132C |.^ 75 DB jnz short Key-Crac.00401309
0040132E |. 56 push esi
0040132F |. 68 38314000 push Key-Crac.00403138 ; ASCII "1234567"
00401334 |. E8 4A000000 call Key-Crac.00401383<---注册码运算-|
下面
-----------------------------------------------------------------------
注册码的运算(这个运算就比较简单了)(关键部分2)
00401383 /$ 55 push ebp
00401384 |. 8BEC mov ebp,esp
00401386 |. FF75 08 push dword ptr ss:[ebp+8] ; /String
00401389 |. E8 A2000000 call <jmp.&KERNEL32.lstrlenA> ; lstrlenA
0040138E |. 53 push ebx
0040138F |. 33DB xor ebx,ebx
00401391 |. 8BC8 mov ecx,eax
00401393 |. 8B75 08 mov esi,dword ptr ss:[ebp+8]
00401396 |> 51 /push ecx<-------这个大循环加小循环是求1234567的16进制值
00401397 |. 33C0 |xor eax,eax
00401399 |. AC |lods byte ptr ds:[esi]
0040139A |. 83E8 30 |sub eax,30
0040139D |. 49 |dec ecx
0040139E |. 74 05 |je short Key-Crac.004013A5
004013A0 |> 6BC0 0A |/imul eax,eax,0A
004013A3 |.^ E2 FB |loopd short Key-Crac.004013A0
004013A5 |> 03D8 |add ebx,eax
004013A7 |. 59 |pop ecx
004013A8 |.^ E2 EC loopd short Key-Crac.00401396
004013AA |. 8BC3 mov eax,ebx<---1234567的16进制值12D687
004013AC |. 5B pop ebx<----ebx存储的就是1234567的16进制值
004013AD |. C9 leave
004013AE . C2 0400 retn 4
-----------------------------------------------------------------------------
00401339 |. 5E pop esi
0040133A |. 3BC6 cmp eax,esi<---对比1234567的16进制值和字符串运算后的值
0040133C |. 75 15 jnz short Key-Crac.00401353<---爆破方法:把jnz改为jz即可
0040133E |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401340 |. 68 62344000 push Key-Crac.00403462 ; |Title = "Key/CrackMe #2 "
00401345 |. 68 B8344000 push Key-Crac.004034B8 ; |Text = " Good Job, I Wish You the Very Best"
0040134A |. 6A 00 push 0 ; |hOwner = NULL
0040134C |. E8 9D000000 call <jmp.&USER32.MessageBoxA> ; MessageBoxA
00401351 |. EB 13 jmp short Key-Crac.00401366
00401353 |> 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401355 |. 68 62344000 push Key-Crac.00403462 ; |Title = "Key/CrackMe #2 "
0040135A |. 68 86344000 push Key-Crac.00403486 ; |Text = " You Have Enter A Wrong Serial, Please Try Again "
0040135F |. 6A 00 push 0 ; |hOwner = NULL
00401361 |. E8 88000000 call <jmp.&USER32.MessageBoxA> ; MessageBoxA
00401366 |> EB 15 jmp short Key-Crac.0040137D
----------------------------------------------------------------------------------------------
【破解心得】
注册算法:
取每一个字符串的16进制值,然后相乘,再用字符串16进制值的一半相加,然后再用16进制值相减,存入esi里
本人编程很烂,只好用算术的方法写出来,希望高人能在后面把注册机贴出来。
用姓名x来举例把
x的16进制值78
78*78=3840
78/2=3c
3840+3c=387c
387c-78=3804
3804再传成10进制值为14340
脱式写法
{(字符串16进制值*字符串16进制值)+(字符串16进制值/2)-(字符串的16进制值)}转成10进制值=注册码
输入注册名x注册码14340,注册成功.
结束语:
其实大家完全可以根本这里的算法把注册机写出来,如果写不出来也没关系,以后会讲到如何写注册机。先让大家熟悉熟悉^_^
本文到此结束,希望对大家有帮助。