【破文作者】 小弟[爆破王]
【文章题目】 菜鸟必看的破解文章(3)-算法分析
【软件名称】 crackme
【加密方式】 姓名+注册码
【破解工具】 OllyDbg v1.10b(这个不用说了吧^_^),字符串计算器(计算字符的16进制值),windows自带的计算器(用于各个进制之间的换算)
【破解平台】 XP SP2
----------------------------------------------------------------------------------------------
【文章简介】
呵呵,上次列了一个单子,里面没有列出算法分析的文章,因为写那个列表的时候对汇编还不是很熟悉,寒假每天晚上熬夜把
有关汇编的书全部溜了一遍,呵呵,今天早上找了一个crakme试试寒假看书有什么效果没有,没想到一下就把这个crackme的
算法给整理出来了呵呵。高兴呀~~~,破完马上就写了这篇文章来和广大菜鸟分享一下.
这个算法很简单,但是有的菜鸟一定看不懂,因为我是菜鸟的时候就什么算法的文章也看不懂(众菜鸟怒:你以为我们和你一样
啊?*^_^*),所以这次我写的详细一点,希望广大菜鸟能看得懂,如果还有什么不懂,可以在下面贴出,我会解答.
建议:建议大家边跟踪边看本帖,对不懂的汇编指令你可以查查,这样效果比较好.
----------------------------------------------------------------------------------------------
【破解过程】
打开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,注册成功.
这里说明下,因为注册名是几个字符,字符运算部分就循环多少次,为了方便菜鸟分析算法,所以用1个字符的姓名来举例
建议广大菜鸟学学汇编,并掌握一门高级语言(如c++等),然后还要有一定的联想能力,比如看见x和78,就能想到78是x的16进制值,
只有这样才能对算法进行分析,要不然会一头雾水,什么也不明白最好能把软件破解工具新年大礼包里的crackme的难度为0和1的
crackme的注册算法都分析一下,对以后的破解有好处.如果你很菜,你可以把新年大礼包的crackme的全部爆破,因为爆破有时难度
为9的软件有时也很好爆破,这样你就和我一样成为爆破王了^_^然后在进行算法分析的学习.
----------------------------------------------------------------------------------------------
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
----------------------------------------------------------------------------------------------
文章写于2005-2-25 99:99:99<<看没看见这里的恶搞^_^
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课