易木马 发表于 2015-8-1 14:09

[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:

冷瞳 发表于 2015-8-1 14:11

{:5_188:}沙发来了 求奖励

小峰 发表于 2015-8-1 15:11

{:6_221:}沙发没了,板凳是我的了。

ningzhonghui 发表于 2015-8-1 22:07

谢谢,很新鲜的东西,学习下SPy++的用法...
页: [1]
查看完整版本: [KeyGenMe] 新人写的CM 求打脸之算法分析+KEYGEN