VMprotect简介
作者:互联网
VMP简单介绍
VMprotect是一款虚拟机保护软件,是目前最为流行的保护壳之一,与其他类型保护软件不同的是,它使用的是虚拟机保护技术,侧重点在于保护所指定的函数,增加逆向分析的复杂度
虚拟机保护特征
- 将由编译器生成的本地代码(Native Code)转换成字节码(Bytecode)
- 将控制权交给虚拟机,由虚拟机来控制执行
- 转换后的字节码非常难以阅读,增加了破解的复杂性
虚拟机其实就是一个字节码解释器,它循环的读取指令并执行,并且它只有一个入口和一个出口(VM_EXIT)。通过静态分析,可以分析出整个执行引擎的完整代码。
全部选项开启后的结果:
- 虚假跳转
- 垃圾指令
大量的fake jcc(虚假跳转)和垃圾指令使原来十分简单的代码变得十分复杂
VMP的Handler
VMP是基于堆栈的虚拟机(Stack-Based VirtualMachine)
虚拟机指令并不显式的使用某个参数,而是先将参数压入堆栈,然后直接从堆栈中读取
表达式:
Add eax,ecx
可以翻译为:
Push ecx
Push eax
Add
Pop eax
无论push 进来的是谁,Add指令总是读取并弹出堆栈中存放的值,然后Add算出结果再压入堆栈
VMP指令分类
汇编指令转换到虚拟机的指令体系的过程中,被最大限度的化简和归类了,VMP中的指令大体分为5类:
- 算术运算和移位运算
- 堆栈操作
- 内存操作
- 系统相关(无法模拟指令)
- 逻辑运算
其中最复杂的是逻辑运算指令
逻辑运算指令
Vmp的逻辑运算指令:nor。这个指令在电路门中叫NOR门,它由三条指令组成,即not not and,与NAND门一样,用它可以模拟 not and xor or这四条逻辑运算指令
转换公式:
P(a,b)=~a & ~b
not(a)=P(a,a)
and(a,b)=P(P(a,a),P(b,b))
or(a,b)=P(P(a,b),P(a,b))
xor(a,b)=P(P(P(a,b),P(b,b)),P(a,b))
寄存器轮转
VMP将所有寄存器都存放在了堆栈的结构中(VM_CONTEXT
结构中的每一项代表一个寄存器或者临时变量。但在运行过程中,其中的项所映射的真实寄存器都是不固定的,可以把它比作一个齿轮,每做完一个动作,部分项的映射就互换了一下位置,或者执行完一段指令齿轮就按不固定的方向和度数转动了一下,然后全部的项映射就改变了 )
VMP
在生成字节码的过程中,维护了一份结构中每一项所映射的真实寄存器,但这只是存在于编译过程,而在运行时是没有明确的信息的。这直接导致了分析和识别的难度。
字节码加密和随机效验
VMP把解码算法分布到了Dispatch和每个Handler中,只有在取指令和取数据时才会解密,而每个解码的算法也都是不同的,并且它的Seed每次解密都会变化。
要写出字节码的逆算法不是不可以,但是复杂度太高,有些得不偿失,所以如果想要修改数据,还是使用HOOK的方式比较轻松
HOOK注意点:
HOOK方式得解决代码检测问题,VMP注册版除了会加密字节码以外,还会随机对一段代码做检测,如果有错将无法进行
VMP注册版中有一条叫指令(calchash),就是用来做检测的,VMP会在编译好的字节码中加一些自己的指令,每次执行都会随机对一段代码生成Hash结果,然后与另一个随机的数相加,结果必须为0,否则就会出错。如果要爆破或者修改VMP 的代码,还需要处理这个过程
VMP作者原则
最简单的正向设计,导致最困难的逆向分析
标签:逻辑运算,VMprotect,简介,虚拟机,指令,堆栈,VMP,字节 来源: https://blog.csdn.net/CSNN2019/article/details/114042760