给最最菜鸟的同学写的算法分析
【破文标题】给最最菜鸟的同学写的算法分析【破文作者】blitz
【作者邮箱】[email protected]
【作者主页】
【破解工具】Peid,OD,计算工具
【破解平台】WinXP SP2
【软件名称】KeyGenMe_04.exe
【软件大小】376K
【原版下载】
【保护方式】无壳
【软件简介】从看雪上找到的一个入门CM,是个大大给我们写来练习算法的.一共5个,其他4个我也不会..
【破解声明】发表点心得,欢迎交流指导!
------------------------------------------------------------------------
【破解过程】Peid查壳,无壳,Borland Delphi 6.0所写.
OD载入
插件-超级字符串参考
往下拉,在初始CPU选择附近可以看到'Congratulations'字符,双击其来到相关代码处.
00450141|.03C2 ADD EAX,EDX
00450143|.83F8 70 CMP EAX,70
00450146|.75 2A JNZ SHORT KeyGenMe.00450172
00450148|.8B45 F4 MOV EAX,DWORD PTR SS:
0045014B|.0FB640 04 MOVZX EAX,BYTE PTR DS:
0045014F|.8B55 F4 MOV EDX,DWORD PTR SS:
00450152|.0FB652 09 MOVZX EDX,BYTE PTR DS:
00450156|.F7EA IMUL EDX
00450158|.3D 8C0A0000 CMP EAX,0A8C
0045015D|.75 13 JNZ SHORT KeyGenMe.00450172
0045015F|.6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00450161|.68 98014500 PUSH KeyGenMe.00450198 ; |congratulations //字符串
00450166|.68 A8014500 PUSH KeyGenMe.004501A8 ; |good job,man!
0045016B|.6A 00 PUSH 0 ; |hOwner = NULL
0045016D|.E8 2E63FBFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
00450172|>33C0 XOR EAX,EAX //走到这里就注册失败
00450174|.5A POP EDX
00450175|.59 POP ECX
00450176|.59 POP ECX
00450177|.64:8910 MOV DWORD PTR FS:,EDX
0045017A|.68 94014500 PUSH KeyGenMe.00450194
0045017F|>8D45 F4 LEA EAX,DWORD PTR SS:
00450182|.BA 02000000 MOV EDX,2
00450187|.E8 A83CFBFF CALL KeyGenMe.00403E34
0045018C\.C3 RETN
在字符串向上分析,发现在00450158出有一个比较,其下一行代码是00450158处的比较不相等就跳走
但是要跳到哪里呢?选定跳走的那一行,然后按回车键看看如果要跳,跳到哪里
回车就来到00450172这一行,下方的数据框里显示都是那些地方跳到这里
跳转来自 0045008E, 004500B4, 004500D6, 004500E7, 00450107, 0045011C, 00450131, 00450146, 0045015D
哇,好多地方都要来这里.
分析一下,有congratulations字符串的那行肯定是注册码正确后的提示框,而前边的比较命令和后边的JNZ命令意思是和0A8C比较,不相等就跳,但是一跳就没有正确认证的提示框了,就是失败了.一般的软件这里就是关键跳了,但是这个不是,因为它只是关键跳中间的一个.原因很简单,我们跑到了它要跳往的地方,发现好多跳转,它们的作用都一样,就是在某些条件以后,发现不合规矩,就跳向失败,不给你注册成功的的机会.
对付这种验证最好的办法就是跑到最早跳到失败的地方开始分析,看看它都设了什么条件.
好的,我们去0045008E看看.选定'跳转来自..'一行,右键选择'转到JL来自0045008E
00450074|.8B80 00030000 MOV EAX,DWORD PTR DS:
0045007A|.E8 D9F2FDFF CALL KeyGenMe.0042F358
0045007F|.8B45 F8 MOV EAX,DWORD PTR SS:
00450082|.E8 4940FBFF CALL KeyGenMe.004040D0
00450087|.8945 F0 MOV DWORD PTR SS:,EAX
0045008A|.837D F0 02 CMP DWORD PTR SS:,2
0045008E|.0F8C DE000000 JL KeyGenMe.00450172
00450094|.8D55 F4 LEA EDX,DWORD PTR SS:
00450097|.8B45 FC MOV EAX,DWORD PTR SS:
0045009A|.8B80 08030000 MOV EAX,DWORD PTR DS:
004500A0|.E8 B3F2FDFF CALL KeyGenMe.0042F358
004500A5|.8B45 F4 MOV EAX,DWORD PTR SS:
004500A8|.E8 2340FBFF CALL KeyGenMe.004040D0
004500AD|.8945 EC MOV DWORD PTR SS:,EAX
004500B0|.837D EC 0A CMP DWORD PTR SS:,0A
004500B4|.0F85 B8000000 JNZ KeyGenMe.00450172
004500BA|.8B45 EC MOV EAX,DWORD PTR SS:
004500BD|.85C0 TEST EAX,EAX
004500BF|.7E 34 JLE SHORT KeyGenMe.004500F5
004500C1|.8945 E4 MOV DWORD PTR SS:,EAX
004500C4|.C745 E8 01000>MOV DWORD PTR SS:,1
004500CB|>8B45 F4 /MOV EAX,DWORD PTR SS:
004500CE|.8B55 E8 |MOV EDX,DWORD PTR SS:
004500D1|.807C10 FF 30|CMP BYTE PTR DS:,30
004500D6|.0F82 96000000 |JB KeyGenMe.00450172
004500DC|.8B45 F4 |MOV EAX,DWORD PTR SS:
004500DF|.8B55 E8 |MOV EDX,DWORD PTR SS:
004500E2|.807C10 FF 39|CMP BYTE PTR DS:,39
004500E7|.0F87 85000000 |JA KeyGenMe.00450172
004500ED|.FF45 E8 |INC DWORD PTR SS:
004500F0|.FF4D E4 |DEC DWORD PTR SS:
004500F3|.^ 75 D6 \JNZ SHORT KeyGenMe.004500CB
004500F5|>8B45 F4 MOV EAX,DWORD PTR SS:
004500F8|.0FB600 MOVZX EAX,BYTE PTR DS:
004500FB|.8B55 F4 MOV EDX,DWORD PTR SS:
004500FE|.0FB652 05 MOVZX EDX,BYTE PTR DS:
00450102|.03C2 ADD EAX,EDX
00450104|.83F8 6D CMP EAX,6D
00450107|.75 69 JNZ SHORT KeyGenMe.00450172
00450109|.8B45 F4 MOV EAX,DWORD PTR SS:
0045010C|.0FB640 01 MOVZX EAX,BYTE PTR DS:
00450110|.8B55 F4 MOV EDX,DWORD PTR SS:
00450113|.0FB652 06 MOVZX EDX,BYTE PTR DS:
00450117|.03C2 ADD EAX,EDX
00450119|.83F8 67 CMP EAX,67
0045011C|.75 54 JNZ SHORT KeyGenMe.00450172
0045011E|.8B45 F4 MOV EAX,DWORD PTR SS:
00450121|.0FB640 02 MOVZX EAX,BYTE PTR DS:
00450125|.8B55 F4 MOV EDX,DWORD PTR SS:
00450128|.0FB652 07 MOVZX EDX,BYTE PTR DS:
0045012C|.03C2 ADD EAX,EDX
0045012E|.83F8 69 CMP EAX,69
00450131|.75 3F JNZ SHORT KeyGenMe.00450172
00450133|.8B45 F4 MOV EAX,DWORD PTR SS:
00450136|.0FB640 03 MOVZX EAX,BYTE PTR DS:
0045013A|.8B55 F4 MOV EDX,DWORD PTR SS:
0045013D|.0FB652 08 MOVZX EDX,BYTE PTR DS:
00450141|.03C2 ADD EAX,EDX
00450143|.83F8 70 CMP EAX,70
00450146|.75 2A JNZ SHORT KeyGenMe.00450172
00450148|.8B45 F4 MOV EAX,DWORD PTR SS:
0045014B|.0FB640 04 MOVZX EAX,BYTE PTR DS:
0045014F|.8B55 F4 MOV EDX,DWORD PTR SS:
00450152|.0FB652 09 MOVZX EDX,BYTE PTR DS:
00450156|.F7EA IMUL EDX
00450158|.3D 8C0A0000 CMP EAX,0A8C
0045015D|.75 13 JNZ SHORT KeyGenMe.00450172
0045015F|.6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00450161|.68 98014500 PUSH KeyGenMe.00450198 ; |congratulations
00450166|.68 A8014500 PUSH KeyGenMe.004501A8 ; |good job,man!
0045016B|.6A 00 PUSH 0 ; |hOwner = NULL
0045016D|.E8 2E63FBFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
00450172|>33C0 XOR EAX,EAX
00450174|.5A POP EDX
00450175|.59 POP ECX
00450176|.59 POP ECX
00450177|.64:8910 MOV DWORD PTR FS:,EDX
0045017A|.68 94014500 PUSH KeyGenMe.00450194
0045017F|>8D45 F4 LEA EAX,DWORD PTR SS:
00450182|.BA 02000000 MOV EDX,2
00450187|.E8 A83CFBFF CALL KeyGenMe.00403E34
0045018C\.C3 RETN
0045018D .^ E9 8236FBFF JMP KeyGenMe.00403814
00450192 .^ EB EB JMP SHORT KeyGenMe.0045017F
00450194 .8BE5 MOV ESP,EBP
00450196 .5D POP EBP
00450197 .C3 RETN
00450198 .43 6F 6E 67 7>ASCII "Congratulations",0
004501A8 .47 6F 6F 64 2>ASCII "Good job,man!",0
004501B6 00 DB 00
004501B7 00 DB 00
004501B8 .55 PUSH EBP
004501B9 .8BEC MOV EBP,ESP
004501BB .33C0 XOR EAX,EAX
004501BD .55 PUSH EBP
004501BE .68 DD014500 PUSH KeyGenMe.004501DD
004501C3 .64:FF30 PUSH DWORD PTR FS:
004501C6 .64:8920 MOV DWORD PTR FS:,ESP
004501C9 .FF05 D43B4500 INC DWORD PTR DS:
004501CF .33C0 XOR EAX,EAX
004501D1 .5A POP EDX
004501D2 .59 POP ECX
004501D3 .59 POP ECX
004501D4 .64:8910 MOV DWORD PTR FS:,EDX
004501D7 .68 E4014500 PUSH KeyGenMe.004501E4
004501DC >C3 RETN ;RET 用作跳转到 004501E4
这是整个验证过程了.
在0045008E上边,什么东西在赋值(MOV)比较(CMP)之后就给跳(JL)走了,还是走到失败,肯定是什么验证过了,然后不过关才走的.我们在赋值的那一行下F2断点
好了,F9一下运行程序.
在原程序里随便输入几个注册信息,像我就输入注册名blitz,注册码123456,然后点check.
这里注册码输入数字,一会解释.
好神奇,那个程序像卡死了一样,OD弹了出来,显示运行到了我们下断点的位置.好了,我们下断成功.
我们发现中断的这一行经过上边的CALL以后,把EAX中的值赋给了SS堆栈,这个我们不管它
我的EAX里储存的是00000005,和我的注册信息也有什么关系呢?..
先想想你的注册信息位数吧?..我的blitz正好5位,123456是6位,所以它应该是验证注册名的.
你可以CTRL+F2重新载入,输入你的名字,实践证明,它确实存的是位数.
这些东西你先记住,接触的多了自然就有敏感性了.我也才注意到的.
好了.我们F8继续追.拿5和2比较以后,它没让我跳向失败.JL是小于/等于时跳,也就是说注册码在3位和3位以上.
我们F8继续.注意004500A5,因为这歩的数据窗口中出现了我们输入的注册码.我们来分析其内容.
004500A5|.8B45 F4 MOV EAX,DWORD PTR SS:
它把堆栈SS:的值赋给了EAX,然后EAX的值就成了我们的注册码,可见堆栈SS:里就存的是我们输入的注册码
F8运行到004500AD的时候,我们发现EAX成了6,就是我输入的注册码的位数,还把它赋给了SS:
F8继续,用我们的注册码位数去和0A比较,我的是6,当然不等啦.人家下边说不等就失败
0A是16进制数,,改成0A的十进制,即10,用计算工具可以换算.
你可以重新载入,然后输入10位注册码再来一遍,但我推荐在右边的寄存器里把EAX改下再比,还可以汇编JNE
这些小技巧累计多了很有用的.
=============================分支,扩展内容==============================
顺便提下004500BD TEST EAX,EAX 是配合下边JLE用的,意思是没填注册码的话就不用过注册码验证,而不是跳向注册失败.这里的注册码验证也算整个软件注册认证的一个分支,就是校验注册码输入是否规范.我们来分析这个程序注册码验证的过程.这些是JLE以后的内容.
004500C1|.8945 E4 MOV DWORD PTR SS:,EAX //把注册码位数存入SS:
004500C4|.C745 E8 01000>MOV DWORD PTR SS:,1 //把1存入SS:
004500CB|>8B45 F4 /MOV EAX,DWORD PTR SS: //取注册码入EAX
004500CE|.8B55 E8 |MOV EDX,DWORD PTR SS: //取刚刚赋值的1入EDX
004500D1|.807C10 FF 30|CMP BYTE PTR DS:,30 //拿注册码第一位与30比较*注
004500D6|.0F82 96000000 |JB KeyGenMe.00450172 //小于就跳注册失败
004500DC|.8B45 F4 |MOV EAX,DWORD PTR SS: //取注册码入EAX
004500DF|.8B55 E8 |MOV EDX,DWORD PTR SS: //取刚刚赋值的1入EDX
004500E2|.807C10 FF 39|CMP BYTE PTR DS:,39 //拿注册码第一位与39比较*注
004500E7|.0F87 85000000 |JA KeyGenMe.00450172 //大于就跳注册失败
004500ED|.FF45 E8 |INC DWORD PTR SS: //加1,即本轮的1+1
004500F0|.FF4D E4 |DEC DWORD PTR SS: //注册码位数减1
004500F3|.^ 75 D6 \JNZ SHORT KeyGenMe.004500CB //这个不是不想等就跳,是不为0就跳
这段的头两行起引导的作用,后边几行是个循环,作用是逐个验证注册码输入是否规范,30和39是在16进制ASCII码里代表0到9,整段是验证注册码输入是否为数字,不为数字就跳.整个验证过程自己多跟几遍就明白了.
想明白的就可以跑出循环了,选定循环底部下边一行,点F4或右键选择断点-运行到选定位置
==========================================================================================
校验完注册码,我们继续跟程序.
F4到004500F5
004500F5|> \8B45 F4 MOV EAX,DWORD PTR SS: //把注册码入EAX
004500F8|.0FB600 MOVZX EAX,BYTE PTR DS: //取单个注册码,当前取第1位,入EAX
004500FB|.8B55 F4 MOV EDX,DWORD PTR SS: //取注册码到EDX
004500FE|.0FB652 05 MOVZX EDX,BYTE PTR DS://取单个注册码,当前取第6位,入EDX
00450102|.03C2 ADD EAX,EDX //把EDX值加到EAX里
00450104|.83F8 6D CMP EAX,6D //与固定值6D比较
00450107|.75 69 JNZ SHORT KeyGenMe.00450172 //不等跳失败
下边与上边基本相同,不加注释了.
00450109|.8B45 F4 MOV EAX,DWORD PTR SS:
0045010C|.0FB640 01 MOVZX EAX,BYTE PTR DS:
00450110|.8B55 F4 MOV EDX,DWORD PTR SS:
00450113|.0FB652 06 MOVZX EDX,BYTE PTR DS:
00450117|.03C2 ADD EAX,EDX
00450119|.83F8 67 CMP EAX,67
0045011C|.75 54 JNZ SHORT KeyGenMe.00450172
0045011E|.8B45 F4 MOV EAX,DWORD PTR SS:
00450121|.0FB640 02 MOVZX EAX,BYTE PTR DS:
00450125|.8B55 F4 MOV EDX,DWORD PTR SS:
00450128|.0FB652 07 MOVZX EDX,BYTE PTR DS:
0045012C|.03C2 ADD EAX,EDX
0045012E|.83F8 69 CMP EAX,69
00450131|.75 3F JNZ SHORT KeyGenMe.00450172
00450133|.8B45 F4 MOV EAX,DWORD PTR SS:
00450136|.0FB640 03 MOVZX EAX,BYTE PTR DS:
0045013A|.8B55 F4 MOV EDX,DWORD PTR SS:
0045013D|.0FB652 08 MOVZX EDX,BYTE PTR DS:
00450141|.03C2 ADD EAX,EDX
00450143|.83F8 70 CMP EAX,70
00450146|.75 2A JNZ SHORT KeyGenMe.00450172
00450148|.8B45 F4 MOV EAX,DWORD PTR SS:
0045014B|.0FB640 04 MOVZX EAX,BYTE PTR DS:
0045014F|.8B55 F4 MOV EDX,DWORD PTR SS:
00450152|.0FB652 09 MOVZX EDX,BYTE PTR DS:
00450156|.F7EA IMUL EDX //IMUL??,相乘!
00450158|.3D 8C0A0000 CMP EAX,0A8C
0045015D|.75 13 JNZ SHORT KeyGenMe.00450172
好了,整个算法分析完了..
算法总结下.
软件采取注册码的不同位数相加与固定码比较,不相等则失败.算法与注册名无关,但要求注册名大于等于3位
算法过程:
注册名位数大于等于3
注册码位数等于10
注册码第1,6位16位ASCII码相加,与6D相比
注册码第2,7位16位ASCII码相加,与67相比
注册码第3,8位16位ASCII码相加,与69相比
注册码第4,9位16位ASCII码相加,与70相比
注册码第5,10位16位ASCII码相加,与0a8c相比
我也是菜鸟,对进制也不很了解.反正我把6D换成73算得,即把D换成13,再加60
我知道这是绝对错误的,但没办法,基础不好么..就先这么用着,以后提高了再改回来.希望高手能提供些帮助.
自己在那里算一会,除了最后一组乘的,其他都可以算出来.
最后一组我换10进制算出来的.过程如下.0a8c十进制2700,除以ASCII码的十进制,一个个试出来.
提供一组可用的注册码:5128286786
非明码比较,不能做内存注册机!
------------------------------------------------------------------------
【破解总结】我就这么马马虎虎算出来了,更贴近'蒙'一点.希望高手指教.
一点心得,希望可以帮助与我一样的菜鸟理解.
CM及运算工具附件提供.
另外,祝愿12月新来的朋友能一路好走!.
------------------------------------------------------------------------
【版权声明】版权所有 www.chinapyg.com blitz
[ 本帖最后由 blitz 于 2007-12-1 12:20 编辑 ] 还有,要爆破的话把0045008E 改成JMP 0045015F 就好... 学习一下。/:014 谢谢楼主,仔细看看我还是能懂不少,有些信心了。 写的挺详细,进制整体转换为10进制会方便点. 學習了
不曉得哪時候能達到樓主的境界 原帖由 topcity2001 于 1/12/2007 12:11 发表 https://www.chinapyg.com/images/common/back.gif
學習了
不曉得哪時候能達到樓主的境界
如果你是真挚地说出来的话,我可以告诉你,也许就在明天! /:014 真正的菜鸟来学习了 看不懂啊,看来还得学习呀 原帖由 blitz 于 2007-12-1 12:16 发表 https://www.chinapyg.com/images/common/back.gif
如果你是真挚地说出来的话,我可以告诉你,也许就在明天!
看动漫,也能让人深刻感悟。
《海贼王》里面,当索隆说,我迟早会成为天下第一的剑客。
鹰眼男人反问他,“迟早”是多久?
……