发布于: 2025-10-11最后更新: 2026-7-4字数 2675阅读时长 7 分钟

什么是 VMP?

vmp就是把真实机器指令转为自定义的虚拟指令, 然后交由虚拟机解释器去执行
 

名词解释

操作码(Opcode)
— 指令要执行的“动作”,
 
操作数(Operand)
— 这个动作所作用的数据(或数据的地址)
 
示例:ADD R0, R1, R2
ADD 就是操作码, R0, R1, R2就是操作数, R0 是目标寄存器,R1R2 是源操作数寄存器

VMP 的基本流程

C/C++ 源代码 ↓ (编译器) 机器指令(真实指令) ↓ (VMP 虚拟化) 虚拟指令(自定义指令集) ↓ 虚拟机解释器执行

VMP 转化的步骤

编译生成真实指令

 

指令抓取与分析

VMP 工具会在编译好的程序里找到这些指令,把它们解析出来(控制流、寄存器使用、数据依赖等)。
 

转换为虚拟指令

真实指令
虚拟指令
MOV EAX, 5
PUSH_IMM 5
ADD EAX, 3
ADD_IMM 3
RET
VM_RET

真实指令

notion image

虚拟指令

加密与打包

所有虚拟指令序列通常会:
  • 被加密(防止直接读出);
  • 混淆顺序;
  • 隐藏在数据段或动态解密中。
 

插入虚拟机解释器

在程序运行时,真实 CPU 并不执行原始代码,而是执行一个 虚拟机解释器(VM Engine)
解释器从虚拟代码区读出虚拟指令,逐条“翻译执行”,从而实现了和原来一样的逻辑。

虚拟机执行流程

Fetch(取指阶段)

vPC指向虚拟代码的指针, 就是虚拟的pc寄存器, 取指从vpc寄存器取出指令vInsn

Decode(译码阶段)

取出vInsn之后,就开始解析翻译
具体来说就是对32位的数据进行切分, 就是对二进制进行切分, 提取操作码Opcode和操作数Operand
比如ADD R0, R1, R2
ADD 就是操作码, R0, R1, R2就是操作数

Execute(执行阶段)

译码得到:操作码Opcode和操作数Operand
执行就是switch(Opcode) 做不同的执行处理

PCUpdate(更新阶段)

阶段
汇编指令
功能
对应虚拟机行为
Fetch
LDR W12, [X0]
从内存中取指令
vInsn = *vPC
Decode
一系列 AND
提取操作码和字段
解析 vOpcode、vXn、vXd、imm 等
Execute
LDRSW → ADD → BR
根据操作码跳转执行
switch(vOpcode) 执行对应虚拟操作
PCUpdate
ADD → STR
更新虚拟 PC
vPC = vPC + 4
PCUpdate(更新)之后,又继续下一轮的Fetch

实际案例执行流程

Fetch(取指)

从vPC取出vInsn 指令

Decode(译码)

把vInsn 指令的二进制切分得到操作码, 操作数, 等等

Execute(执行)

switch(vOpcode)跳转到不同的地方执行

PCUpdate(更新)

更新完继续下一个取指

需要注意不一定是顺序执行

VMState(虚拟机状态结构体)

通过 VMState,虚拟指令可以:
  1. 操作虚拟寄存器(vX0~vX31)
  1. 访问或修改虚拟 PC(vPC)
  1. 控制调度逻辑(vFlag)
  1. 实现跳转和函数调用(vAddrJump、vAddrReturn)
可以把 VMState 理解为虚拟机“CPU 的寄存器 + 内存状态”,是虚拟机执行每条指令的环境和上下文。
 
 

VMP的逆向

完全参考


Loading...
写了个找base64编码算法特征的ida脚本

写了个找base64编码算法特征的ida脚本


Lsposed hook框架lsplant

Lsposed hook框架lsplant


公告
 
花有重开日, 人无再少年~