首页
社区
课程
招聘
[原创]VMP分析插件v1.4(2013/01/30更新)
2012-8-13 12:43 216788

[原创]VMP分析插件v1.4(2013/01/30更新)

2012-8-13 12:43
216788
收藏
点赞7
打赏
分享
最新回复 (235)
雪    币: 99
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
overseait 2012-8-19 22:54
51
0
好久没有来看雪了。 支持
雪    币: 64
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
逆帅 2012-8-23 00:14
52
0
mark。。。
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bkxiang 2012-8-24 11:00
53
0
请教LZ一个问题:一段代码经VMP处理后,把原本易读懂的代码变得很难懂了。
比如简单点就说成一个函数,funcA经vmp处理后变成了vmp_funcA,这样原本能看懂funcA算法,变成vmp_funcA后就读不懂了。但是通常函数都是有输入输出的(而非只是运算没有参数也没有结果),如果可以不关心funcA是怎么做的,而只关心做的结果(黑盒的输入输出,知道函数处理的结果在哪后,就可以获取或修改)。
想请教下进虚拟机前,和出虚拟机后,funcA的输入输出在哪里,VMP的输入输出是怎样的原理传递的?(进去前,出来后,即在VMP的外面,这样的输入输出那就应该是没加密能看到或读懂的吧)

刚开始学习VMP,表述不一定合适,希望能看懂说的意思。大概和您提到的思想差不多,关心数据不关心算法。麻烦LZ提示下,谢谢!
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bkxiang 2012-8-24 11:37
54
0
恭喜总顶了,总顶前后的两贴被我占了,haha, 对LZ贡献的肯定啊
雪    币: 185
活跃值: (405)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fireworld 2012-8-24 13:02
55
0
牛x 马上有更新了啊 收藏之
雪    币: 2175
活跃值: (966)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Crakme 2012-8-24 13:55
56
0
这个真的只能膜拜了
雪    币: 130
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
welcomeg 2012-8-24 14:08
57
0
牛人+支持+膜拜~~~~
雪    币: 1644
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yodamaster 2012-8-24 14:53
58
0
厉害!感谢分享。
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
coverme 2012-8-24 18:09
59
0
很好,很强大,顶一个
雪    币: 363
活跃值: (338)
能力值: ( LV15,RANK:310 )
在线值:
发帖
回帖
粉丝
dragonltx 6 2012-8-24 20:42
60
0
v587~~~~~~~~~~~
雪    币: 12181
活跃值: (3342)
能力值: ( LV15,RANK:1565 )
在线值:
发帖
回帖
粉丝
AloneWolf 3 2012-8-25 07:22
61
0
3Q...收藏一个先
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
zdhysd 3 2012-8-25 09:08
62
0
VMP其实没有什么输入输出,只是运行环境的切换,进入虚拟机前会把除ESP外的寄存器和标志等内容压入虚拟堆栈,进入虚拟机后再弹出到虚拟寄存器开始执行。在虚拟机中执行时也可以写入内存或真实堆栈等保存计算结果,这些和没加虚拟机时是一样的。退出虚拟机时会把对应真实寄存器的数据弹出到寄存器中,清除掉虚拟堆栈中的数据,只保留真实堆栈。如果是整个函数加密的话和普通函数没有区别,部分加密也差不多,看看寄存器和堆栈就行了。
雪    币: 523
活跃值: (827)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
笑熬浆糊 2 2012-8-25 10:04
63
0
太没天理....这么牛B的工具没人看?
雪    币: 89
活跃值: (53)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
swlilike 2012-8-25 10:35
64
0
不来膜拜一下  心里不舒服
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bkxiang 2012-8-25 13:02
65
0
谢谢答复!麻烦看看是不是这样理解
一段加VMP的算法代码执行了些功能,那肯定这段VMP代码会有结果产生,后续处理将依据这段代码产生的结果来执行不同的分支(比方:收到一段加密封包,解密的结果就两种pass或fail, 解密代码加VMP,逆向VMP的解密算法很难,如果只需要修改解密的结果)
类似这样的执行中间结果记录在真实的内存中,vmp代码读写这些真实内存,这些内存在哪里?怎样找到这些内存指针?
我理解的是不是这些内存都是写入在bytecode里的,很难直接从bytecode里识别出这些地址来?
雪    币: 1270
活跃值: (230)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
zdhysd 3 2012-8-25 15:09
66
0
VMP其实就是把汇编指令翻译成虚拟机指令,在虚拟机中执行,和原来的程序是相同的。对于被加密程序结束后依然有效的数据保存位置和原来完全一样,结束后无效的数据一般保存在虚拟堆栈和虚拟寄存器中。结束后有效的数据是指这段代码执行完后还可以访问的内容,比如内存、真实堆栈未弹出的内容、真实寄存器等。真实寄存器在虚拟机中被随机分配到虚拟寄存器,退出虚拟机时恢复,其他的基本保存在原位,你说的输出应该就是这些东西了。

我加了一个测试程序,你可以看看

C语言代码,测试3种输出数据,绝对内存、相对内存、寄存器

int aaa;
int ceshi(int a, int b, int *c)
{
	aaa = a + b;//写内存,绝对地址
	c[10] = a - b;//写内存,相对地址
	return a ^ b;//返回,返回值在寄存器EAX中
}


对应的汇编代码

00401112 ceshi  /$  55            PUSH EBP
00401113        |.  8BEC          MOV EBP,ESP
00401115        |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
00401118        |.  0345 0C       ADD EAX,DWORD PTR SS:[EBP+C]
0040111B        |.  A3 D8984000   MOV DWORD PTR DS:[4098D8],EAX
00401120        |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]
00401123        |.  2B4D 0C       SUB ECX,DWORD PTR SS:[EBP+C]
00401126        |.  8B55 10       MOV EDX,DWORD PTR SS:[EBP+10]
00401129        |.  894A 28       MOV DWORD PTR DS:[EDX+28],ECX
0040112C        |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
0040112F        |.  3345 0C       XOR EAX,DWORD PTR SS:[EBP+C]
00401132        |.  5D            POP EBP
00401133        \.  C3            RETN


用VMP2.03普通保护加密,反汇编并分析后的VMP虚拟机代码,注释栏显示引用数据

下面把虚拟堆栈中的初始化内容弹出到寄存器中
//
0040E716 VMP_ceshi  /$  25           vPopReg4 vR9        堆栈0:(常量)0
0040E717            |.  04 301DAB10  vPushImm4 10AB1D30  (常量)10AB1D30
0040E71C            |.  56           vAdd4               堆栈0:(常量)10AB1D30,堆栈4:(常量)0
0040E71D            |.  29           vPopReg4 vR10       堆栈0:(标志)
0040E71E            |.  29           vPopReg4 vR10       堆栈4:(常量)10AB1D30
0040E71F            |.  19           vPopReg4 vR6        堆栈8:(寄存器)EAX
0040E720            |.  35           vPopReg4 vR13       堆栈0C:(寄存器)ECX
0040E721            |.  0D           vPopReg4 vR3        堆栈10:(标志)
0040E722            |.  1D           vPopReg4 vR7        堆栈14:(寄存器)EBP
0040E723            |.  01           vPopReg4 vR0        堆栈18:(寄存器)EBP
0040E724            |.  31           vPopReg4 vR12       堆栈1C:(寄存器)EBX
0040E725            |.  09           vPopReg4 vR2        堆栈20:(寄存器)EDI
0040E726            |.  11           vPopReg4 vR4        堆栈24:(寄存器)EDX
0040E727            |.  3D           vPopReg4 vR15       堆栈28:(寄存器)ESI
0040E728            |.  05           vPopReg4 vR1        堆栈2C:(常量)144D97D2
0040E729            |.  15           vPopReg4 vR5        堆栈30:(常量)738B00A

PUSH EBP
这里没有识别为真实堆栈操作,因为在同一个指令块中PUSH再POP,中间没有vPopVEsp,当作虚拟堆栈中的临时变量
//
0040E72A            |.  1B           vPushReg4 vR7       vR7:(寄存器)EBP			

MOV EBP,ESP
vR8对应EBP
//
0040E72B            |.  1E           vPushVEsp           (vESP)30
0040E72C            |.  21           vPopReg4 vR8        堆栈2C:(vESP)30

0040E72D            |.  5E 0C        vPushImmSx1 0C      (常量)0C

MOV EAX,DWORD PTR SS:[EBP+8]
因为上面的PUSH EBP没有被识别为真实堆栈操作,这里的真实ESP还是压入EBP之前的,所以显示真实堆栈4
//
0040E72F            |.  5E 08        vPushImmSx1 8       (常量)8
0040E731            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E732            |.  3E           vAdd4               堆栈24:(vESP)30,堆栈28:(常量)8
0040E733            |.  1D           vPopReg4 vR7        堆栈24:(标志)
0040E734            |.  68           vReadMemSs4         真实堆栈4:(变量),堆栈28:(vESP)38
0040E735            |.  1D           vPopReg4 vR7        堆栈28:(变量)

ADD EAX,DWORD PTR SS:[EBP+C]
这里显示真实堆栈8,原因同上
EAX值保存在vR1中
//
0040E736            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E737            |.  80           vAdd4               堆栈28:(vESP)30,堆栈2C:(常量)0C
0040E738            |.  39           vPopReg4 vR14       堆栈28:(标志)
0040E739            |.  66           vReadMemSs4         真实堆栈8:(变量),堆栈2C:(vESP)3C
0040E73A            |.  1B           vPushReg4 vR7       vR7:(变量)
0040E73B            |.  56           vAdd4               堆栈28:(变量),堆栈2C:(变量)
0040E73C            |.  05           vPopReg4 vR1        堆栈28:(标志)
0040E73D            |.  05           vPopReg4 vR1        堆栈2C:(变量)

这里先压入下面要用的堆栈偏移,VMP是堆栈机,有很多这样的代码,顺序不一定和原来一样
其实纯堆栈机基本相当于后缀表达式,但是VMP还有寄存器,这就复杂一点了。如果不知道数据从哪里来或在那里使用,可以把信息窗口切换到显示数据
//
0040E73E            |.  CF 0C        vPushImmSx1 0C      (常量)0C
0040E740            |.  6F 08        vPushImmSx1 8       (常量)8

MOV DWORD PTR DS:[4098D8],EAX
写内存,很明显了,地址就是4098D8
//
0040E742            |.  03           vPushReg4 vR1       vR1:(变量)
0040E743            |.  04 D8984000  vPushImm4 4098D8    (常量)4098D8
0040E748            |.  F4           vWriteMemDs4        堆栈20:(常量)4098D8,堆栈24:(变量)

MOV ECX,DWORD PTR SS:[EBP+8]
//
0040E749            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E74A            |.  3E           vAdd4               堆栈24:(vESP)30,堆栈28:(常量)8
0040E74B            |.  19           vPopReg4 vR6        堆栈24:(标志)
0040E74C            |.  68           vReadMemSs4         真实堆栈4:(变量),堆栈28:(vESP)38

MOV EDX,DWORD PTR SS:[EBP+10]
这里没有按照原来的顺序执行
EDX值保存在vR7中
//
0040E74D            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E74E            |.  6F 10        vPushImmSx1 10      (常量)10
0040E750            |.  56           vAdd4               堆栈20:(常量)10,堆栈24:(vESP)30
0040E751            |.  1D           vPopReg4 vR7        堆栈20:(标志)
0040E752            |.  68           vReadMemSs4         真实堆栈0C:(变量),堆栈24:(vESP)40
0040E753            |.  1D           vPopReg4 vR7        堆栈24:(变量)

SUB ECX,DWORD PTR SS:[EBP+C]
ECX值保存在vR14中
减法在VMP中变成了
(([EBP+8] nand [EBP+8]) + [EBP+C]) nand (([EBP+8] nand [EBP+8]) + [EBP+C])
= not(not[EBP+8] + [EBP+C])
= [EBP+8] - [EBP+C]
//
0040E754            |.  2D           vPopReg4 vR11       堆栈28:(变量)
0040E755            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E756            |.  3E           vAdd4               堆栈28:(vESP)30,堆栈2C:(常量)0C
0040E757            |.  15           vPopReg4 vR5        堆栈28:(标志)
0040E758            |.  66           vReadMemSs4         真实堆栈8:(变量),堆栈2C:(vESP)3C
0040E759            |.  2B           vPushReg4 vR11      vR11:(变量)
0040E75A            |.  2B           vPushReg4 vR11      vR11:(变量)
0040E75B            |.  44           vNand4              堆栈24:(变量),堆栈28:(变量)
0040E75C            |.  35           vPopReg4 vR13       堆栈24:(标志)
0040E75D            |.  56           vAdd4               堆栈28:(变量),堆栈2C:(变量)
0040E75E            |.  35           vPopReg4 vR13       堆栈28:(标志)
0040E75F            |.  1E           vPushVEsp           (vESP)2C
0040E760            |.  66           vReadMemSs4         堆栈2C:(变量),堆栈28:(vESP)2C
0040E761            |.  44           vNand4              堆栈28:(变量),堆栈2C:(变量)
0040E762            |.  11           vPopReg4 vR4        堆栈28:(标志)
0040E763            |.  39           vPopReg4 vR14       堆栈2C:(变量)

MOV DWORD PTR DS:[EDX+28],ECX
//
0040E764            |.  37           vPushReg4 vR14      vR14:(变量)
0040E765            |.  CF 28        vPushImmSx1 28      (常量)28
0040E767            |.  1B           vPushReg4 vR7       vR7:(变量)
0040E768            |.  5D           vAdd4               堆栈24:(变量),堆栈28:(常量)28
0040E769            |.  19           vPopReg4 vR6        堆栈24:(标志)
0040E76A            |.  F4           vWriteMemDs4        堆栈28:(变量),堆栈2C:(变量)


MOV EAX,DWORD PTR SS:[EBP+8]
XOR EAX,DWORD PTR SS:[EBP+C]
EAX值保存在vR3中
这里和原来不是完全对应,直接计算了,异或在VMP中转成了下面的计算
([EBP+C] nand [EBP+8]) nand (([EBP+8] nand [EBP+8]) nand ([EBP+C] nand [EBP+C]))
//
0040E76B            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E76C            |.  6F 0C        vPushImmSx1 0C      (常量)0C
0040E76E            |.  56           vAdd4               堆栈28:(常量)0C,堆栈2C:(vESP)30
0040E76F            |.  2D           vPopReg4 vR11       堆栈28:(标志)
0040E770            |.  68           vReadMemSs4         真实堆栈8:(变量),堆栈2C:(vESP)3C
0040E771            |.  6F 08        vPushImmSx1 8       (常量)8
0040E773            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E774            |.  56           vAdd4               堆栈24:(vESP)30,堆栈28:(常量)8
0040E775            |.  2D           vPopReg4 vR11       堆栈24:(标志)
0040E776            |.  9A           vReadMemSs4         真实堆栈4:(变量),堆栈28:(vESP)38
0040E777            |.  19           vPopReg4 vR6        堆栈28:(变量)
0040E778            |.  E2           vPushVEsp           (vESP)2C
0040E779            |.  9A           vReadMemSs4         堆栈2C:(变量),堆栈28:(vESP)2C
0040E77A            |.  46           vNand4              堆栈28:(变量),堆栈2C:(变量)
0040E77B            |.  05           vPopReg4 vR1        堆栈28:(标志)
0040E77C            |.  17           vPushReg4 vR6       vR6:(变量)
0040E77D            |.  6C           vPushVEsp           (vESP)28
0040E77E            |.  68           vReadMemSs4         堆栈28:(变量),堆栈24:(vESP)28
0040E77F            |.  44           vNand4              堆栈24:(变量),堆栈28:(变量)
0040E780            |.  35           vPopReg4 vR13       堆栈24:(标志)
0040E781            |.  46           vNand4              堆栈28:(变量),堆栈2C:(变量)
0040E782            |.  11           vPopReg4 vR4        堆栈28:(标志)
0040E783            |.  1F           vPushReg4 vR8       vR8:(vESP)30
0040E784            |.  B6 0C        vPushImmSx1 0C      (常量)0C
0040E786            |.  56           vAdd4               堆栈24:(常量)0C,堆栈28:(vESP)30
0040E787            |.  2D           vPopReg4 vR11       堆栈24:(标志)
0040E788            |.  9A           vReadMemSs4         真实堆栈8:(变量),堆栈28:(vESP)3C
0040E789            |.  17           vPushReg4 vR6       vR6:(变量)
0040E78A            |.  46           vNand4              堆栈24:(变量),堆栈28:(变量)
0040E78B            |.  35           vPopReg4 vR13       堆栈24:(标志)
0040E78C            |.  46           vNand4              堆栈28:(变量),堆栈2C:(变量)
0040E78D            |.  35           vPopReg4 vR13       堆栈28:(标志)
0040E78E            |.  0D           vPopReg4 vR3        堆栈2C:(变量)

把真实寄存器对应的数据压入堆栈,执行vRet时会弹出到对应的真实寄存器中
//
0040E78F            |.  05           vPopReg4 vR1        堆栈30:(寄存器)EBP
0040E790            |.  3B           vPushReg4 vR15      vR15:(寄存器)ESI
0040E791            |.  1B           vPushReg4 vR7       vR7:(变量)
0040E792            |.  07           vPushReg4 vR2       vR2:(寄存器)EDI
0040E793            |.  2F           vPushReg4 vR12      vR12:(寄存器)EBX
0040E794            |.  FF           vPushReg4 vR0       vR0:(寄存器)EBP
0040E795            |.  03           vPushReg4 vR1       vR1:(寄存器)EBP
0040E796            |.  33           vPushReg4 vR13      vR13:(标志)
0040E797            |.  37           vPushReg4 vR14      vR14:(变量)
0040E798            |.  0B           vPushReg4 vR3       vR3:(变量)
0040E799            |.  07           vPushReg4 vR2       vR2:(寄存器)EDI
0040E79A            |.  2B           vPushReg4 vR11      vR11:(标志)
0040E79B            \.  EF           vRet                真实堆栈0:(变量),堆栈18:(标志),堆栈10:(变量),堆栈14:(变量),堆栈2C:(变量),堆栈24:(寄存器)EBX,堆栈1C:(寄存器)EBP,堆栈30:(寄存器)ESI,堆栈28:(寄存器)EDI
雪    币: 216
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
darkradx 2012-8-25 19:49
67
0
牛插啊,谢谢LZ
雪    币: 89
活跃值: (159)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xxhaishixx 2012-8-25 21:32
68
0
这个插件很强大的说
雪    币: 15
活跃值: (512)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jfztaq 2012-8-26 12:42
69
0
mark一下,以后需要的时候再用
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liyizhu 2012-8-26 14:54
70
0
  强大 vmp 分析插件 支持+顶
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bkxiang 2012-8-26 17:44
71
0
非常感谢,仔细消化一下!
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 4 2012-8-26 18:26
72
0
收藏更新了,谢谢分享。
VMP
雪    币: 79
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rootkie 2012-8-28 14:19
73
0
单凭楼主这么有耐心打这么多字都必须得顶。
雪    币: 215
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bqrmfjhh 2012-8-28 21:42
74
0
这真是不得了得好东西。
雪    币: 1579
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
柔情似水 2012-8-29 16:28
75
0
让我撞死吧,太牛了
游客
登录 | 注册 方可回帖
返回