能力值:
( LV2,RANK:10 )
|
-
-
51 楼
好久没有来看雪了。 支持
|
能力值:
( LV2,RANK:10 )
|
-
-
52 楼
mark。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
53 楼
请教LZ一个问题:一段代码经VMP处理后,把原本易读懂的代码变得很难懂了。
比如简单点就说成一个函数,funcA经vmp处理后变成了vmp_funcA,这样原本能看懂funcA算法,变成vmp_funcA后就读不懂了。但是通常函数都是有输入输出的(而非只是运算没有参数也没有结果),如果可以不关心funcA是怎么做的,而只关心做的结果(黑盒的输入输出,知道函数处理的结果在哪后,就可以获取或修改)。
想请教下进虚拟机前,和出虚拟机后,funcA的输入输出在哪里,VMP的输入输出是怎样的原理传递的?(进去前,出来后,即在VMP的外面,这样的输入输出那就应该是没加密能看到或读懂的吧)
刚开始学习VMP,表述不一定合适,希望能看懂说的意思。大概和您提到的思想差不多,关心数据不关心算法。麻烦LZ提示下,谢谢!
|
能力值:
( LV2,RANK:10 )
|
-
-
54 楼
恭喜总顶了,总顶前后的两贴被我占了,haha, 对LZ贡献的肯定啊
|
能力值:
( LV2,RANK:10 )
|
-
-
55 楼
牛x 马上有更新了啊 收藏之
|
能力值:
( LV2,RANK:10 )
|
-
-
56 楼
这个真的只能膜拜了
|
能力值:
( LV3,RANK:20 )
|
-
-
57 楼
牛人+支持+膜拜~~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
58 楼
厉害!感谢分享。
|
能力值:
( LV2,RANK:10 )
|
-
-
59 楼
很好,很强大,顶一个
|
能力值:
( LV15,RANK:310 )
|
-
-
60 楼
v587~~~~~~~~~~~
|
能力值:
( LV15,RANK:1565 )
|
-
-
61 楼
3Q...收藏一个先
|
能力值:
( LV8,RANK:130 )
|
-
-
62 楼
VMP其实没有什么输入输出,只是运行环境的切换,进入虚拟机前会把除ESP外的寄存器和标志等内容压入虚拟堆栈,进入虚拟机后再弹出到虚拟寄存器开始执行。在虚拟机中执行时也可以写入内存或真实堆栈等保存计算结果,这些和没加虚拟机时是一样的。退出虚拟机时会把对应真实寄存器的数据弹出到寄存器中,清除掉虚拟堆栈中的数据,只保留真实堆栈。如果是整个函数加密的话和普通函数没有区别,部分加密也差不多,看看寄存器和堆栈就行了。
|
能力值:
( LV6,RANK:90 )
|
-
-
63 楼
太没天理....这么牛B的工具没人看?
|
能力值:
( LV2,RANK:10 )
|
-
-
64 楼
不来膜拜一下 心里不舒服
|
能力值:
( LV2,RANK:10 )
|
-
-
65 楼
谢谢答复!麻烦看看是不是这样理解
一段加VMP的算法代码执行了些功能,那肯定这段VMP代码会有结果产生,后续处理将依据这段代码产生的结果来执行不同的分支(比方:收到一段加密封包,解密的结果就两种pass或fail, 解密代码加VMP,逆向VMP的解密算法很难,如果只需要修改解密的结果)
类似这样的执行中间结果记录在真实的内存中,vmp代码读写这些真实内存,这些内存在哪里?怎样找到这些内存指针?
我理解的是不是这些内存都是写入在bytecode里的,很难直接从bytecode里识别出这些地址来?
|
能力值:
( LV8,RANK:130 )
|
-
-
66 楼
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
|
能力值:
( LV2,RANK:10 )
|
-
-
67 楼
牛插啊,谢谢LZ
|
能力值:
( LV2,RANK:10 )
|
-
-
68 楼
这个插件很强大的说
|
能力值:
( LV2,RANK:10 )
|
-
-
69 楼
mark一下,以后需要的时候再用
|
能力值:
( LV2,RANK:10 )
|
-
-
70 楼
强大 vmp 分析插件 支持+顶
|
能力值:
( LV2,RANK:10 )
|
-
-
71 楼
非常感谢,仔细消化一下!
|
能力值:
( LV9,RANK:170 )
|
-
-
72 楼
收藏更新了,谢谢分享。
VMP
|
能力值:
( LV2,RANK:10 )
|
-
-
73 楼
单凭楼主这么有耐心打这么多字都必须得顶。
|
能力值:
( LV2,RANK:10 )
|
-
-
74 楼
这真是不得了得好东西。
|
能力值:
( LV2,RANK:10 )
|
-
-
75 楼
让我撞死吧,太牛了
|
|
|