首页
社区
课程
招聘
[原创]说说 vmp 的那点事儿
发表于: 2013-6-3 21:09 24697

[原创]说说 vmp 的那点事儿

2013-6-3 21:09
24697

本帖由 透明色 发布于 看雪论坛, 谢绝任何形式的转载 .

首先特别感谢 zdhysd大 , 写出了那么好的vmp插件, 春节后去了几封邮件,得zdhysd大耐心解惑,表示很感谢.

本篇 以一个简单的cm为例,讲解一下vmp 从分析到破解的全过程. 但是基础的东西在这里就不再啰嗦了,
假设读者了解虚拟机的基本概念.如果不了解,请先移步去阅读一下 vmp基础的帖子.

这个cm是自己写的,使用的是mfc ,release编译,写得比较简单。没有加anti,拿来演示一下 vmp 的分析与破解方法。

register()函数的反汇编如下:对虚拟码的分析的时候,参考下原始的汇编。
--------------
  00401450    sub     esp, 0x3C
  00401453    lea     eax, dword ptr [esp+0x14]
  00401457    push    esi
  00401458    push    edi
  00401459    push    0x14
  0040145B    push    eax
  0040145C    mov     esi, ecx
  0040145E    push    0x3E8
  00401463    call    <jmp.&MFC42.#?GetDlgItemTextA@CW>
  00401468    lea     ecx, dword ptr [esp+0x30]
  0040146C    push    0x14
  0040146E    push    ecx
  0040146F    push    0x3E9
  00401474    mov     ecx, esi
  00401476    call    <jmp.&MFC42.#?GetDlgItemTextA@CW>
  0040147B    lea     edi, dword ptr [esp+0x1C]
  0040147F    or      ecx, 0xFFFFFFFF
  00401482    xor     eax, eax
  00401484    lea     edx, dword ptr [esp+0x1C]
  00401488    repne   scas byte ptr es:[edi]
  0040148A    not     ecx
  0040148C    dec     ecx
  0040148D    push    ecx
  0040148E    push    edx
  0040148F    call    00401150
  00401494    add     esp, 0x8
  00401497    push    eax                              ; /<%X>
  00401498    lea     eax, dword ptr [esp+0xC]         ; |
  0040149C    push    00403080                         ; |%x
  004014A1    push    eax                              ; |s
  004014A2    call    dword ptr [<&USER32.wsprintfA>]  ; \wsprintfA
  004014A8    lea     edi, dword ptr [esp+0x14]
  004014AC    or      ecx, 0xFFFFFFFF
  004014AF    xor     eax, eax
  004014B1    add     esp, 0xC
  004014B4    xor     edx, edx
  004014B6    repne   scas byte ptr es:[edi]
  004014B8    not     ecx
  004014BA    dec     ecx
  004014BB    je      short 004014E1
  004014BD    movsx   ecx, byte ptr [esp+edx+0x8]
  004014C2    movsx   eax, byte ptr [esp+edx+0x30]
  004014C7    sub     ecx, eax
  004014C9    cmp     ecx, 0x1
  004014CC    jnz     short 00401509
  004014CE    lea     edi, dword ptr [esp+0x8]
  004014D2    or      ecx, 0xFFFFFFFF
  004014D5    xor     eax, eax
  004014D7    inc     edx
  004014D8    repne   scas byte ptr es:[edi]
  004014DA    not     ecx
  004014DC    dec     ecx
  004014DD    cmp     edx, ecx
  004014DF    jb      short 004014BD
  004014E1    lea     eax, dword ptr [esp+0x8]
  004014E5    push    eax
  004014E6    push    00403064                         ;  d7 a2 b2 e1 b3 c9 b9 a6 00
  004014EB    call    004011D0
  004014F0    add     esp, 0x8
  004014F3    lea     ecx, dword ptr [esp+0x8]
  004014F7    push    0x0
  004014F9    push    0x0
  004014FB    push    ecx
  004014FC    mov     ecx, esi
  004014FE    call    <jmp.&MFC42.#?MessageBoxA@CWnd@@>
  00401503    pop     edi
  00401504    pop     esi
  00401505    add     esp, 0x3C
  00401508    retn
  00401509    lea     ecx, dword ptr [esp+0x8]
  0040150D    push    ecx
  0040150E    push    00403040                         ;  d7 a2 b2 e1 c2 eb ca a7 b0 dc 00
  00401513    call    004011D0
  00401518    add     esp, 0x8
  0040151B    lea     edx, dword ptr [esp+0x8]
  0040151F    mov     ecx, esi
  00401521    push    0x0
  00401523    push    0x0
  00401525    push    edx
  00401526    call    <jmp.&MFC42.#?MessageBoxA@CWnd@@>
  0040152B    pop     edi
  0040152C    pop     esi
  0040152D    add     esp, 0x3C
  00401530    retn

--------------

vmp版本为2.09 ,保护强度共有三种(变异,虚拟,超级),将上面的代码使用 第二种编译。

od打开,(步骤一)下断在 GetDlgItem,随便输入吧,断下 两次,再返回到用户代码。

首先分析一下, vm代码的流程 。用脚本跟踪一下。得到类似于下面的流程

---------------
        471422--4716E0
        4716E1--4719AD
        4716E1--4719AD
        4716E1--4719AD
        4716E1--4719AD
        4716E1--4719AD
        4716E1--4719AD
        4592C8--459AB6; 退出vm代码⑴
        425049--42519A
        43D1F7--43D65B; 退出vm代码⑵
        4652D3--465599
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        46559A--46583F
        482A1C--482C8E
        4325C0--4329E3
        4817E0--481EC4; 退出vm代码⑶
        439FDA--43A174
        42C5A6--42C9A1; 退出vm代码⑷,调用messgeboxA 弹出注册失败。

---------------

讲一下几个关键的虚拟指令

        Vjmp vmp的虚拟码都是一小块独立的段,每一段都是独立的,
        它们之间的调用是通过 vjmp实现的,即在一个段的最后是一个 vjmp指令。

        vret 和 vcall 是调用外部代码的 两个指令
        它们的区别是 前者是退出虚拟机的 ,而后者不会退出虚拟机。(即虚拟机的栈内环境及寄存器不会破坏)
        与vjmp 一样vret 也存在于段尾, 而vcall 在于于段的中间

        而上面帖出的流程,是用脚本通过 跟踪vjmp 和 vret 来实现的。

        好了,扫盲的知识就到这里。接着分析这个流程。

我们发现虚拟代码有两段循环,程序检验的代码实际上是一个 for{if()goto;}形式的循环判断。怎么会有两段呢,
其实这两段都不是 我们要找的关键代码,而是对虚拟机对 repne 的模拟。这些个位置其实是strlen(),应该是使用release之后,
编译器将strlen()给内联掉了。而repne是用来实现strlen的。虚拟机中是没有 repne 对应的虚拟指令的,
所以要有一组代码来模拟它。

至于⑴ ⑵ ⑶ 的作用,请大家根据原始汇编来分析。

关键的代码是这里:
---------------
        482A1C--482C8E
        4325C0--4329E3
---------------

再插一点内容,讲一下vmp 怎样模拟jcc ,附件里的 cm01G.exe 关键跳转改成了 vmp的样式,分析虚拟码之前,请先研究一下这个例子.

---------------
        004014B3    repne   scas byte ptr es:[edi]
        004014B5    not     ecx
        004014B7    dec     ecx
        004014B8    je      short 004014F2
        004014BA    movsx   ecx, byte ptr [ebp+edx-0x14]
        004014BF    movsx   eax, byte ptr [ebp+edx-0x3C]
        004014C4    sub     ecx, eax
        004014C6    dec     ecx
        004014C7    push    004014E0                                ;判断跳转的一个目标
        004014CC    push    00401518                                ;判断跳转的另一个目标
        004014D1    pushfd
        004014D2    pop     eax                                                ;eax 等于标志寄存器的值
        004014D3    and     eax, 0x40                                ;判断zf位
        004014D6    shr     eax, 0x4                                ;这里只能得到 4 或者 0
        004014D9    mov     eax, dword ptr [esp+eax];根据结果取到偏移
        004014DC    push    eax
        004014DD    retn    0x8                                                ;实现跳转
        004014E0    lea     edi, dword ptr [ebp-0x14]
        004014E3    or      ecx, 0xFFFFFFFF
        004014E6    xor     eax, eax                         ;  d7 a2 b2 e1 b3 c9 b9 a6 00
        004014E8    inc     edx
---------------

附件中的 fail 和 sucess ,就是对4325C0--4329E3这段虚拟代码的记录,但是里面垃圾代码太多了,为了节约版面就不再帖出来了,已经加了注释,
请参考我们模拟的代码来理解.



接下来讲一下破解,附图演示了虚拟码 实现的跳转的过程,我们只需要修改代码中的常量,让它生成一样的假码,无论何种跳转都指向一个地址,
有些类似于爆破.我们这里把 432883 的 VpushImmx4 把这里的值改为 42D07AF1 ,重复步骤一,然后右键分析虚拟机程序,找到位置修改虚拟码, 剩下来就是写个Loader 了.

直接上代码:
---------------

#include "stdafx.h"
#include "loader.h"

int main(int argc, char* argv[])
{

        const char* code =
"D8 A6 9E E6 BD 82 B1 D0 E1 1F BA 0C BB E8 E7 DC 4E 22 7F 46 8B BA 28 DF 28 C1 DE B2 21 C6 C2 8C "
"A0 8D C8 8D BC F5 65 A3 3A 55 77 ED E3 9D E6 9F 6A 54 B1 5D 96 73 75 F2 93 E2 06 ED AF 20 C1 1C "
"4E 5E 35 CA C7 D8 4F F3 52 AC 89 CF 5D 33 9E 4F 0F ED 35 FA 14 84 39 85 04 C0 CF 7C 6E 9D 6A 6C "
"23 6E 8E E2 D4 03 CB FD 6C 3F 6A 3E EB 74 A5 FD 07 F7 5C 39 86 4F CC DE 0D 7A 0E 03 89 37 54 F8 "
"0F 08 32 20 3A D1 79 2B 9A 12 C7 C8 59 86 CD E8 56 9B 2A 93 10 F1 04 ED 3E 08 CB E6 CD 7F CA 9F "
"6A 30 E4 53 41 0C 07 49 3C 33 23 8E 39 0D 24 B6 FF BA CD 17 9B 51 BE 93 4A 75 6A 5C D9 48 3E 67 "
"44 E2 1F DF 18 88 14 45 55 65 14 25 95 4A C3 8B C9 11 A0 CB 1A 59 82 67 A4 65 12 B9 D4 42 47 E0 "
"60 AF A3 4A 44 E2 29 D6 40 51 9C F7 75 7F F5 A1 E5 27 D0 03 7E 37 DD 52 C6 05 13 52 AF AB 0A AD "
"36 D8 77 F9 AB 73 AE 1B 88 FC 86 F6 94 02 31 FC B7 E2 31 94 2C F1 0B 38 D7 20 0B BD 65 56 2A 7D "
"B3 AD BA CB 08 01 B0 AE 44 7B 34 79 A3 91 43 24 01 88 2D 9C 95 DC 2F C5 42 5D 86 71 3D DD A8 30 "
"37 B1 C6 BD 97 24 6F 6D 03 02 8C A9 06 92 7E 0A D9 67 22 81 6C CF AE F5 93 B3 51 59 86 3C E9 4A ";

        Loader l = Loader("cm01.vmp.exe");
        l.run();
        Sleep(3000);
        l.patch(0x432884,code);
        return 0;
}

---------------

运行生成的 cmcc ,等待 loader退出之后,随便输入几个 , 注册成功.

附件中包括 : 原始的cm  , 加壳后的cm , 用来演示 vm变形的 cm01G.exe 以及记录的两个流程

ps:
一些不重要的东西 就在后面说一下吧.

1: 为什么不说一下vmp的脱壳?

        请先给我一个需要脱壳的理由先 !! 哥懒得解释

2: 虚拟代码应该如何分析?

        读懂几个汇编指令 ,不代表你能够读懂一段汇编 .同理,弄懂了一个个handler ,不代表你能理解一段虚拟码 .它本身就是一个拆分 ,混淆的 东西 . 就是为了对抗 静态分析 .所以vmp真心不适合 静态分析 ,个人感觉动态分析比较好一点.

3: 没有3了

好了,就说这些 .如果有需要讨论的童鞋,可以QQ我, 不过我是入门刚半年的初学者. 一些东西我也说不好. 希望可以共同进步吧.


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (26)
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
2
写代码的时候 减法弄错顺序了 , 所以 可能注册码 会有非 字母和数字的 情况 .  就不改了  ,大家将就着看吧
2013-6-3 21:11
0
雪    币: 3380
活跃值: (1373)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
分析的很精彩--顶--通俗易懂
2013-6-3 21:15
0
雪    币: 47147
活跃值: (20485)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
参照这帖的方法:http://bbs.pediy.com/showpost.php?postid=292659
2013-6-3 21:23
0
雪    币: 1839
活跃值: (295)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
5
楼主,怎么长的女生的头发,男生的脸
2013-6-3 22:25
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
6
切 ,你眼神有问题
2013-6-3 22:26
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
还不错,支持加精
2013-6-3 22:30
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
只是LOAD的话,讲不清楚
2013-6-3 23:53
0
雪    币: 154
活跃值: (40)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
9
很好理解,谢谢分享!
2013-6-4 00:52
0
雪    币: 291
活跃值: (48)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
学习学习
2013-6-4 01:18
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不错,支持一下了
2013-6-4 01:41
0
雪    币: 1626
活跃值: (148)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
12
Fuck vmp
2013-6-4 06:16
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
cwz
13
支持一下
2013-6-4 08:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
不错,表示正在学习中!!!
2013-6-4 08:05
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
学习一下,谢谢楼主分享
2013-6-4 08:35
0
雪    币: 137
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
貌似是女的额
2013-6-4 10:49
0
雪    币: 576
活跃值: (1163)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
应该是女的。。
2013-6-4 11:00
0
雪    币: 102
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
居然是女的。。
2013-6-4 12:38
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
19
切 , 放张马子的照片不可以啊
2013-6-4 13:37
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
20
.........
2013-6-4 13:40
0
雪    币: 60
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
留名  待查看
2013-6-4 16:58
0
雪    币: 196
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习学习,谢谢楼主的分享
2013-6-4 18:38
0
雪    币: 61
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
不错的东东,正在学习中~~~~
2013-6-4 18:49
0
雪    币: 177
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
貌似对于新手来说很强大的样子
2013-6-5 12:44
0
游客
登录 | 注册 方可回帖
返回
//