[KeyGenMe] 新人写的CM 求打脸之算法分析+KEYGEN
本帖最后由 易木马 于 2015-8-1 14:23 编辑CM标题:新人写的CM 求打脸
CM地址:https://www.52hb.com/thread-12180-1-1.html
作者:易木马(DevilMayCry)
难度等级:超级简单(但是很烦人)
推荐理由:很有意思,我们会用到SPy++,很有亮点哦!~
内容提纲:1、找按钮事件
2、分析关键位置
3、算法分析
4、制作KeyGen
题外话:这个KeyGenMe算法分析,是源于前几天原作者发了帖子一直没有人解出注册码来,爆破也少,不知道是为什么,我想了想,大概就两种情况:一是大牛不屑一顾,二是小菜分析着也烦,当然这些CrackMe、KeyGenMe也好,本身并没有太大的意义,仅供大家娱乐娱乐,所以上手的人少了。或说熟练一下汇编或说初步熟习一下逆向分析思路。
一、找按钮事件。
这个方法有很多种,我各人喜欢直接拉到代码启始位置,往下翻,但这里不用直接ASCII查找。
双击到代码处。向上找看是谁跳转过了,“恭喜成功”。
二、找关键位置
0040126C|. /0F84 3F000000 je cm.004012B1 ;认定为关键跳JE,当然爆破可以开始啦,这里我们不讲这个。
接下来,我们要找是谁让这个跳转实现。找到这里
<p>0040122E|.50 push eax ;user32.76DB4411
0040122F|.FF75 EC push
00401232|.E8 94FEFFFF call cm.004010CB ;在这个CALL里面返回值EAX,这里才起决定性作用, 我们叫它关键CALL(算法CALL)
00401237|.83C4 08 add esp,0x8
0040123A|.83F8 00 cmp eax,0x0 ;*************
0040123D|.B8 00000000 mov eax,0x0
00401242|.0F94C0 sete al ;*************这里修改了EAX的值,但不起决定性的作用!!!
00401245|.8945 E8 mov ,eax ;而变量6的值又来自EAX。
00401248|.8B5D EC mov ebx,
************************************************</p><p>这期间并没有修改变量6 的值。继续向上分析!</p><p>************************************************
00401268|>837D E8 00 cmp ,0x0 ;决定跳转的变量6与0之间的关系。
0040126C|.0F84 3F000000 je cm.004012B1 ;认定为关键跳转,JE</p>按钮事件里面的关键CALL,关键跳转就这样找到了,如果只是简单的爆破,到这里就可以收场了,但是这是一个KEYGENME,我们得看看算法。。。
三、算法分析
通过第二步我们找到了关键CALL,和关键跳我们来理一下思路。
1、00040126C的JE不实现跳转,
2、得不为0,来自EAX,
3、eax的值得不为0,因为用了,SETE AL则要求 CMP EAX,0的结果要相等。
4、eax的返回值必须为0,00401232|.E8 94FEFFFF call cm.004010CB ,说明这里返回为0一切OK,
至此一主事件分析结束,结论:00401232返回为0变OK!!!!
那么进入CALL 004010CB分析:
004010F1|> \F7C2 03000000 test edx,0x3 ;这里开始了
004010F7|.75 37 jnz short cm.00401130
004010F9|>8B02 /mov eax,dword ptr ds: ;取假码
004010FB|.3A01 |cmp al,byte ptr ds: ;与真码第一位比较
004010FD|.75 2B |jnz short cm.0040112A ;不相等结束
004010FF|.0AC0 |or al,al
00401101|.74 24 |je short cm.00401127 ;是否比较结束了
00401103|.3A61 01 |cmp ah,byte ptr ds: ;第二位
00401106|.75 22 |jnz short cm.0040112A
00401108|.0AE4 |or ah,ah
0040110A|.74 1B |je short cm.00401127 ;是否比较结束了
0040110C|.C1E8 10 |shr eax,0x10
0040110F|.3A41 02 |cmp al,byte ptr ds: ;第三位
00401112|.75 16 |jnz short cm.0040112A
00401114|.0AC0 |or al,al
00401116|.74 0F |je short cm.00401127 ;是否比较结束了
00401118|.3A61 03 |cmp ah,byte ptr ds: ;第四位
0040111B|.75 0D |jnz short cm.0040112A
0040111D|.83C1 04 |add ecx,0x4 ;修改循环变量
00401120|.83C2 04 |add edx,0x4 ;每次加4,修改循环变量
00401123|.0AE4 |or ah,ah ;没有为进入下一次循环
00401125|.^ 75 D2 \jnz short cm.004010F9
00401127|>33C0 xor eax,eax ;EAX=0返回
00401129|.C3 retn ;这里是我们想要的
0040112A|>1BC0 sbb eax,eax ;这里不是我们想要的
0040112C|.D1E0 shl eax,1
0040112E|.40 inc eax
0040112F|.C3 retn ;这里返回-1大概的意思我们是明白了,这个关键的CALL就是进行字符串的比较,返回比较的结果,相等返回为0.
004010CB/$8B5424 04 mov edx,dword ptr ss: ;我们输入的注册码
004010CF|.8B4C24 08 mov ecx,dword ptr ss: ;通过上面计算地注册码
我们在数据窗口里面查看这个字符串,我们可以得到这样一个公式:机器码+“特殊值”。
这里我们启用SPY++(为什么用我们后面讲)。
用SPY++查找我们的窗体,我们发现有一个窗口的标题与这个注册码内容相同。
正好,一模一样。与这个按钮事件里面的三次调用
00401171|.6A FF push -0x1
00401173|.6A 08 push 0x8
00401175|.68 04000116 push 0x16010004
0040117A|.68 01000152 push 0x52010001
0040117F|.E8 0F170000 call cm.00402893 ;第一次调用,取编辑框1机器码!!
0040118A|.6A FF push -0x1
0040118C|.6A 08 push 0x8
0040118E|.68 1C000116 push 0x1601001C
00401193|.68 01000152 push 0x52010001
00401198|.E8 F6160000 call cm.00402893 ;第二次调用,取编辑框2上图控件标题
00401212|> \6A FF push -0x1
00401214|.6A 08 push 0x8
00401216|.68 05000116 push 0x16010005
0040121B|.68 01000152 push 0x52010001
00401220|.E8 6E160000 call cm.00402893 ;第三次调用,取编辑框 假注册
好了,程序的流程我们也知道了,算法处理的方式我们也知道了。接下来我们做注册机
四、KEYGEN编写 (VC)
由于分析出来这个比较简单,我就不多说了。机器码24位+编辑框标题,标题内容比较长,但后面是重复的1428个“6359832”,固定的3.1832。大概如下:
CString szStr;
if(m_OsVersion.GetLength()!=24)
{
MessageBox("请输入24位机器码!!","提示",MB_OK);
m_OsVersion="";
UpdateData(false);
return;
}
szStr=m_OsVersion+"3.1832";
for(int i=0;i<1428;i++)
{
szStr+="6359832";
}
m_Key=szStr;
UpdateData(false);
测试KeyGenMe_xiaodiaomao:
{:5_188:}沙发来了 求奖励 {:6_221:}沙发没了,板凳是我的了。 谢谢,很新鲜的东西,学习下SPy++的用法...
页:
[1]