首页
社区
课程
招聘
[原创]对一个具有VM的CrackMe的详细分析
发表于: 2011-3-17 21:57 9680

[原创]对一个具有VM的CrackMe的详细分析

2011-3-17 21:57
9680

标 题: 对一个具有VM的CrackMe的详细分析
作 者: 曹无咎
时 间: 2011.3.17  18:25

详细信息:

这个CM是我刚学crack的时候就下载了,当时看的时候,看到代码JMP来JMP去的,很是纠结,于是就保

存在了硬盘上,差不多有一年了,今天拿出来玩玩(宿舍路由器被万恶的网通公司给封了,不能上网了

),看看水平有没有提高。
好吧,现在开始分析了:
首先直接OD载入这个CM,没有搜索到什么有用的字符串,直接输入用户名(pediy)和注册码(123456

),点击确定,出现错误的提示,回溯法找到了关键点,如下所示:
004017AF   .  68 BF204000   push    004020BF
004017B4   .  68 A9204000   push    004020A9
004017B9   .  6A 00         push    0
004017BB   .  8D45 EF       lea     eax, dword ptr [ebp-11]
004017BE   .  50            push    eax
004017BF   .  E8 9CF8FFFF   call    00401060                         ;  用户名
004017C4   .  B8 BF204000   mov     eax, 004020BF
004017C9   .  83C0 04       add     eax, 4
004017CC   .  C700 00000000 mov     dword ptr [eax], 0
004017D2   .  C740 04 01000>mov     dword ptr [eax+4], 1
004017D9   .  68 BF204000   push    004020BF
004017DE   .  68 CF204000   push    004020CF
004017E3   .  6A 00         push    0
004017E5   .  8D45 DE       lea     eax, dword ptr [ebp-22]
004017E8   .  50            push    eax
004017E9   .  E8 72F8FFFF   call    00401060                         ;  注册码
004017EE   .  68 BF204000   push    004020BF
004017F3   .  68 F7204000   push    004020F7
004017F8   .  68 F4144000   push    004014F4                         ;  ASCII "Wrong!"
004017FD   .  6A 00         push    0
004017FF   .  E8 5CF8FFFF   call    00401060
00401804   .  A1 CB204000   mov     eax, dword ptr [4020CB]
00401809   .  50            push    eax                              ; /Style =>

MB_OK|MB_ICONHAND|MB_APPLMODAL
0040180A   .  68 F4144000   push    004014F4                         ; |Title = "Wrong!"
0040180F   .  68 F4144000   push    004014F4                         ; |Text = "Wrong!"
00401814   .  FF35 54204000 push    dword ptr [402054]               ; |hOwner = 000101C2

(class='#32770')
0040181A   .  E8 4D000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA

很明显了,00401060这里就是call进虚拟机了,004017BF此处出现了用户名字,即在虚拟机里面处理用

户名字了,同理,004017E9和004017FF分别是对注册码处理和对用户名和注册码处理结果的比较(以及

处理字符串的问题)。
现在我们进虚拟机里面看看,首先是开辟一个大小为130h的栈(我对虚拟机的理解,就是模仿CUP各个

寄存器的工作方式,不知对不对,还请大家指点):

00401060   $  55            push    ebp
00401061   .  8BEC          mov     ebp, esp
00401063   .  81C4 D0FEFFFF add     esp, -130

到了00401060后,注意看数据窗口,转换成地址模式,可以看到从00402000——0040204C共有20个地址

,这些就是虚拟机模拟的一些指令了(这些指令把一些指令搞复杂了)
00402000  004010D7  crackme.004010D7
00402004  004010D9  crackme.004010D9
00402008  004010FF  crackme.004010FF
0040200C  00401133  crackme.00401133
00402010  00401169  crackme.00401169
00402014  00401196  crackme.00401196
00402018  004013FC  crackme.004013FC
0040201C  004012B8  crackme.004012B8
00402020  004011C6  crackme.004011C6
00402024  00401203  crackme.00401203
00402028  00401240  crackme.00401240
0040202C  00401268  crackme.00401268
00402030  00401290  crackme.00401290
00402034  004012CF  crackme.004012CF
00402038  004012E6  crackme.004012E6
0040203C  00401309  crackme.00401309
00402040  0040132E  crackme.0040132E
00402044  0040135D  crackme.0040135D
00402048  00401392  crackme.00401392
0040204C  004013C7  crackme.004013C7

向下看就会发现,这些地址跑跑之后都会有个JMP

继续看:

00401069   .  C745 E4 00000>mov     dword ptr [ebp-1C], 0
00401070   .  C745 E8 00000>mov     dword ptr [ebp-18], 0
00401077   .  C745 F1 00000>mov     dword ptr [ebp-F], 0
0040107E   .  C645 FD 00    mov     byte ptr [ebp-3], 0
00401082   .  C645 FE 00    mov     byte ptr [ebp-2], 0
00401086   .  C745 F5 00000>mov     dword ptr [ebp-B], 0
0040108D   .  8D85 D0FEFFFF lea     eax, dword ptr [ebp-130]
00401093   .  8945 F1       mov     dword ptr [ebp-F], eax
00401096   .  8B45 14       mov     eax, dword ptr [ebp+14]
00401099   .  8945 E0       mov     dword ptr [ebp-20], eax
0040109C   .  8B45 08       mov     eax, dword ptr [ebp+8]           ;  用户名
0040109F   .  8945 D0       mov     dword ptr [ebp-30], eax
004010A2   .  8B45 0C       mov     eax, dword ptr [ebp+C]
004010A5   .  8945 D8       mov     dword ptr [ebp-28], eax
004010A8   .  C745 DC 00000>mov     dword ptr [ebp-24], 0
004010AF   .  C745 D4 00000>mov     dword ptr [ebp-2C], 0
004010B6   .  8B45 10       mov     eax, dword ptr [ebp+10]
004010B9   .  8945 EC       mov     dword ptr [ebp-14], eax

这些是对刚刚开辟的栈进行初始化的,比如说esp,eip,ebp等

仔细分析的话,就会发现,JMP经常会JMP到这里(004010BC),我认为这里应该是在分析到底应该执行

哪条指令,现在就有些头绪了,JMP来JMP去就是在处理数据了
004010BC   > /FF45 EC       inc     dword ptr [ebp-14]               ;  crackme.004020A9
004010BF   . |8B45 EC       mov     eax, dword ptr [ebp-14]
004010C2   . |8A00          mov     al, byte ptr [eax]
004010C4   . |8845 F0       mov     byte ptr [ebp-10], al
004010C7   . |B8 00204000   mov     eax, 00402000
004010CC   . |0FB65D F0     movzx   ebx, byte ptr [ebp-10]
004010D0   . |C1E3 02       shl     ebx, 2
004010D3   . |03C3          add     eax, ebx
004010D5   . |FF20          jmp     dword ptr [eax]

虚拟机的难点应该就是分析这些虚拟过的指令了,现在分析一下这些指令的实际功能是什么。

004010D7  :这个没有进行什么实际的运算

004010D9  :将一个byte转换成dword,并压入eax,可以看作是压栈操作(push)

004010FF  :pop指令
             004010FF   .  FF45 EC       inc     dword ptr [ebp-14]
             00401102   .  8B45 EC       mov     eax, dword ptr [ebp-14]
             00401105   .  0FB600        movzx   eax, byte ptr [eax]
             00401108   .  8845 F0       mov     byte ptr [ebp-10], al
             0040110B   .  8B45 E0       mov     eax, dword ptr [ebp-20]
             0040110E   .  0FB65D F0     movzx   ebx, byte ptr [ebp-10]
             00401112   .  C1E3 02       shl     ebx, 2
             00401115   .  03C3          add     eax, ebx
             00401117   .  8945 E4       mov     dword ptr [ebp-1C], eax
             0040111A   .  8B18          mov     ebx, dword ptr [eax]
             0040111C   .  895D E8       mov     dword ptr [ebp-18], ebx
             0040111F   .  8345 F1 04    add     dword ptr [ebp-F], 4
             00401123   .  8B45 F1       mov     eax, dword ptr [ebp-F]
             00401126   .  8945 E4       mov     dword ptr [ebp-1C], eax
             00401129   .  8B5D E8       mov     ebx, dword ptr [ebp-18]
             0040112C   .  8918          mov     dword ptr [eax], ebx
             0040112E   .  895D F5       mov     dword ptr [ebp-B], ebx
             00401131   .^ EB 89         jmp     short 004010BC

00401133   :pop指令,从栈中弹出值
             00401133   .  FF45 EC       inc     dword ptr [ebp-14]
             00401136   .  8B45 EC       mov     eax, dword ptr [ebp-14]
             00401139   .  8A00          mov     al, byte ptr [eax]
             0040113B   .  8845 F0       mov     byte ptr [ebp-10], al
             0040113E   .  8B45 E0       mov     eax, dword ptr [ebp-20]
             00401141   .  0FB65D F0     movzx   ebx, byte ptr [ebp-10]
             00401145   .  C1E3 02       shl     ebx, 2
             00401148   .  03C3          add     eax, ebx
             0040114A   .  8B5D F5       mov     ebx, dword ptr [ebp-B]
             0040114D   .  8945 E4       mov     dword ptr [ebp-1C], eax
             00401150   .  8918          mov     dword ptr [eax], ebx
             00401152   .  836D F1 04    sub     dword ptr [ebp-F], 4
             00401156   .  8B45 F1       mov     eax, dword ptr [ebp-F]
             00401159   .  8945 E4       mov     dword ptr [ebp-1C], eax
             0040115C   .  8B00          mov     eax, dword ptr [eax]
             0040115E   .  8945 F5       mov     dword ptr [ebp-B], eax
             00401161   .  8945 E8       mov     dword ptr [ebp-18], eax
             00401164   .^ E9 53FFFFFF   jmp     004010BC

00401169   :加法运算
            00401169   .  8B45 F5       mov     eax, dword ptr [ebp-B]
            0040116C   .  836D F1 04    sub     dword ptr [ebp-F], 4
            00401170   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
            00401173   .  895D E4       mov     dword ptr [ebp-1C], ebx
            00401176   .  8B13          mov     edx, dword ptr [ebx]
            00401178   .  8955 E8       mov     dword ptr [ebp-18], edx
            0040117B   .  0145 E8       add     dword ptr [ebp-18], eax  add指令,加运算(

不知道这样认为对不对,如何判断指令的实际意义,还望大侠指点,谢谢)
            0040117E   .  0F9445 FE     sete    byte ptr [ebp-2]
            00401182   .  0F9845 FD     sets    byte ptr [ebp-3]
            00401186   .  FF75 E8       push    dword ptr [ebp-18]
            00401189   .  8F45 F5       pop     dword ptr [ebp-B]
            0040118C   .  8B45 E8       mov     eax, dword ptr [ebp-18]
            0040118F   .  8903          mov     dword ptr [ebx], eax
            00401191   .^ E9 26FFFFFF   jmp     004010BC

00401196   :减法运算
            00401196   .  8B45 F5       mov     eax, dword ptr [ebp-B]
            00401199   .  836D F1 04    sub     dword ptr [ebp-F], 4
            0040119D   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
            004011A0   .  895D E4       mov     dword ptr [ebp-1C], ebx
            004011A3   .  8B13          mov     edx, dword ptr [ebx]
            004011A5   .  8955 E8       mov     dword ptr [ebp-18], edx
            004011A8   .  8745 E8       xchg    dword ptr [ebp-18], eax
            004011AB   .  2945 E8       sub     dword ptr [ebp-18], eax   这里有个sub指令

,应该是减运算
            004011AE   .  0F9445 FE     sete    byte ptr [ebp-2]
            004011B2   .  0F9845 FD     sets    byte ptr [ebp-3]
            004011B6   .  FF75 E8       push    dword ptr [ebp-18]
            004011B9   .  8F45 F5       pop     dword ptr [ebp-B]
            004011BC   .  8B45 E8       mov     eax, dword ptr [ebp-18]
            004011BF   .  8903          mov     dword ptr [ebx], eax
            004011C1   .^ E9 F6FEFFFF   jmp     004010BC

004011C6  :这段代码中我看见有个MUL操作,猜测是为乘法运算(关于虚拟指令我也是猜测其中的功

能,如有错误还望大侠指教,谢谢了)

00401203  :除运算
            00401203   .  8B45 F5       mov     eax, dword ptr [ebp-B]
            00401206   .  836D F1 04    sub     dword ptr [ebp-F], 4
            0040120A   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
            0040120D   .  895D E4       mov     dword ptr [ebp-1C], ebx
            00401210   .  8B1B          mov     ebx, dword ptr [ebx]
            00401212   .  895D E8       mov     dword ptr [ebp-18], ebx
            00401215   .  33D2          xor     edx, edx
            00401217   .  66:C705 20124>mov     word ptr [401220], 0F3F7
            00401220   .  33C0          xor     eax, eax   异或运算,分析下后发现是除法
            00401222   .  8945 E8       mov     dword ptr [ebp-18], eax
            00401225   .  0F9445 FE     sete    byte ptr [ebp-2]
            00401229   .  0F9845 FD     sets    byte ptr [ebp-3]
            0040122D   .  FF75 E8       push    dword ptr [ebp-18]
            00401230   .  8F45 F5       pop     dword ptr [ebp-B]
            00401233   .  8B45 E8       mov     eax, dword ptr [ebp-18]
            00401236   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
            00401239   .  8903          mov     dword ptr [ebx], eax
            0040123B   .^ E9 7CFEFFFF   jmp     004010BC

00401240  :与运算
            00401240   .  8B45 F5       mov     eax, dword ptr [ebp-B]
            00401243   .  836D F1 04    sub     dword ptr [ebp-F], 4
            00401247   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
            0040124A   .  895D E4       mov     dword ptr [ebp-1C], ebx
            0040124D   .  8B13          mov     edx, dword ptr [ebx]
            0040124F   .  8955 E8       mov     dword ptr [ebp-18], edx
            00401252   .  8745 E8       xchg    dword ptr [ebp-18], eax
            00401255   .  2145 E8       and     dword ptr [ebp-18], eax 与运算
            00401258   .  FF75 E8       push    dword ptr [ebp-18]
            0040125B   .  8F45 F5       pop     dword ptr [ebp-B]
            0040125E   .  8B45 E8       mov     eax, dword ptr [ebp-18]
            00401261   .  8903          mov     dword ptr [ebx], eax
            00401263   .^ E9 54FEFFFF   jmp     004010BC

00401268  :或运算
  
00401290  :异或运算

004012CF   :保存用户名的字节
            004012CF   .  836D F1 04    sub     dword ptr [ebp-F], 4
            004012D3   .  8B45 F1       mov     eax, dword ptr [ebp-F]
            004012D6   .  8945 E4       mov     dword ptr [ebp-1C], eax
            004012D9   .  8B18          mov     ebx, dword ptr [eax]
            004012DB   .  895D E8       mov     dword ptr [ebp-18], ebx
            004012DE   .  895D F5       mov     dword ptr [ebp-B], ebx
            004012E1   .^ E9 D6FDFFFF   jmp     004010BC

004012E6  : 这条指令是取用户名的第一个字节(当然是循环取啦,p=70H)
             004012E6   .  8B45 D0       mov     eax, dword ptr [ebp-30]
             004012E9   .  0345 D4       add     eax, dword ptr [ebp-2C]
             004012EC   .  FF45 D4       inc     dword ptr [ebp-2C]
             004012EF   .  0FB600        movzx   eax, byte ptr [eax]
             004012F2   .  8945 F5       mov     dword ptr [ebp-B], eax
             004012F5   .  8345 F1 04    add     dword ptr [ebp-F], 4
             004012F9   .  8B5D F1       mov     ebx, dword ptr [ebp-F]
             004012FC   .  895D E4       mov     dword ptr [ebp-1C], ebx
             004012FF   .  8945 E8       mov     dword ptr [ebp-18], eax
             00401302   .  8903          mov     dword ptr [ebx], eax
             00401304   .^ E9 B3FDFFFF   jmp     004010BC

004012B8   :将用户名第一个字节压入栈中
             004012B8   .  8345 F1 04    add     dword ptr [ebp-F], 4
             004012BC   .  8B5D F5       mov     ebx, dword ptr [ebp-B]
             004012BF   .  895D E8       mov     dword ptr [ebp-18], ebx
             004012C2   .  8B45 F1       mov     eax, dword ptr [ebp-F]
             004012C5   .  8945 E4       mov     dword ptr [ebp-1C], eax
             004012C8   .  8918          mov     dword ptr [eax], ebx

00401309   :
            
0040132E   :

0040135D   :

00401392   :

004013C7  :条件跳转指令,这个是算法的循环处,几jl之类的指令,现在返回到循环开始处,进行下

一轮的循环运算

004013FC  :retn,退出虚拟机

这些基本的操作都明了了(这些我也有些不知道正确与否,但是算出来的注册码貌似是对的,运气运气

啊)

重新载入CM,输入username:pediy   serial:123456

有了这些指令,分析就简单多了(分析过程太繁琐了,这里就不浪费空间贴出来了):

首先取了2保存,然后逐字节去用户名相乘,
既 2*70*65*64*69*79= B1437580+7F=B14375FF(16进制)=2973988351

处理注册码:1(31h) 2(32h) 3(33h) 4(34h) 5(35h) 6(36)

首先将数字转换为十进制数,然后做指数运算  1*10^0+2*10^1+3*10^2+4*10^3+5*10^4+6*10^5=654321
                                           1       20    300    4000   50000   600000
9FBF1(十六进制)-EB-5(减5这个操作是在这个call004017F3实现的)

然后比较 B14375FF和(9FBF1(十六进制)-EB-5)是否相等,如果相等的话,注册成功!

这样可以给出pediy的正确注册码:1958893792

终于分析完了,小菜鸟第一次分析,如有失误之处,还望同学们指出,多谢指教了

知道了运算过程,注册机也就好写了,但我编程一窍不通,还要好好学习!

感谢各种大牛,纠结不能上网,现在也不能发出去。。。。

注册机代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main()
{
        char Name[32] = "0";
        char Key[32] = "0";
        printf("please input your name:\n");
        scanf("%s",Name);
        int count = 2;
        for(int i = 0; i<strlen(Name); i++)
        {
                count *= *(Name + i);
        }
        count += 0x7F;
        count += (5 + 0x0EB);
        itoa(count, Key, 10);
        i = strlen(Key)-1;
        printf(" the key:\n");
        for(int j = i ;j>=0 ;j--)
        {
                printf("%c",*(Key+j));
        }
        printf("\n");
}

注册机只能用户名是数字的时候可以用(编程菜鸟,不懂)


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
无法学习,只能XX
2011-3-17 22:11
0
雪    币: 630
活跃值: (665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
LZ牛人 膜拜!~
2011-3-18 15:17
0
雪    币: 135
活跃值: (1735)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
这个CM是从您那里得到的
2011-3-18 15:25
0
雪    币: 630
活跃值: (665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
LZ有教程吗 看的好累啊
好迷糊
2011-3-18 15:51
0
雪    币: 630
活跃值: (665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
跪求交往哦 我的邮箱 +qq xudaoliang0910@sina.com
2011-3-25 22:12
0
雪    币: 282
活跃值: (236)
能力值: ( LV3,RANK:37 )
在线值:
发帖
回帖
粉丝
7
曹大就是曹大。太牛B了。
2013-1-28 09:30
0
雪    币: 2
活跃值: (256)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看的好累啊,继续看
2013-3-15 14:52
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
9
据我所知 vmp 是没有vnop 的 dispatcher 也不一样 不知道是版本的问题 还是 不是一种虚拟机

不过虚拟机 都差不多吧, 不知道有没有相应的分析插件

手工分析 根本就是 自虐啊
2013-3-15 16:25
0
游客
登录 | 注册 方可回帖
返回