虚拟机
虚拟机逆向(Virtual Machine Reverse Engineering)是指对软件中自实现的虚拟机(或称解释器)进行反向分析的技术
程序将原本的原生代码或关键逻辑编译成自定义的字节码(bytecode),然后由一个解释器循环(VM loop)执行这些字节码。逆向工程师需要:
识别出虚拟机结构(操作码表、虚拟寄存器、虚拟栈、内存模型等)
提取字节码,并反汇编为人类可读的虚拟指令
理解虚拟指令序列的算法逻辑,以破解保护、提取算法或找到漏洞
虚拟机分类
根据虚拟机的执行模型,通常分为两类
基于栈的虚拟机
操作数隐式地通过一个虚拟栈传递,指令执行时从栈顶弹出操作数,计算结果再压回栈顶
常见例子:Java 虚拟机(JVM)、Python 字节码、.NET CLR
特征:大量 push/pop 指令,运算指令无显式操作数
基于寄存器的虚拟机
操作数显式指定虚拟寄存器索引,结果也存入虚拟寄存器
常见例子:Dalvik (Android)、Lua VM
特征:指令通常包含 “寄存器索引” 字段,如 add r1, r2, r3
实战案例
signal(VM 逆向)

IDA 逆向分析这个 vm_operad() 函数
传入的参数 v4 是 &unk_403040 地址的值

1 | int __cdecl vm_operad(int *a1, int a2) // a1: 字节码数组, a2: 字节码长度 |
程序中的 114 个整数如下
1 | 10, |
第一条指令是 10,即调用 read(Str) 读取输入
之后是 15 组字符变换,最后是 15 组比较指令
目标数组为
1 | 34, 63, 52, 50, 114, |
令输入字符为 x[i],首先是第 0 位
1 | 4,16 temp = x ^ 16 |
方程式
1 | (x ^ 16) - 5 = 34 |
由此得到
| 位置 | 变换 | 目标 | 解 |
|---|---|---|---|
| 0 | (x ^ 16) - 5 |
34 | 7 |
| 1 | (x ^ 32) * 3 |
63 | 5 |
| 2 | (x - 2) - 1 |
52 | 7 |
| 3 | (x + 1) ^ 4 |
50 | 5 |
| 4 | x * 3 - 33 |
114 | 1 |
| 5 | (x - 1) - 1 |
51 | 5 |
| 6 | (x ^ 9) - 32 |
24 | 1 |
| 7 | (x + 81) ^ 36 |
-89 | 2 |
| 8 | (x + 1) - 1 |
49 | 1 |
| 9 | x * 2 + 37 |
-15 | f |
| 10 | (x + 54) ^ 65 |
40 | 3 |
| 11 | (x + 32) * 1 |
-124 | d |
| 12 | x * 3 + 37 |
-63 | 4 |
| 13 | (x ^ 9) - 32 |
30 | 7 |
| 14 | (x + 65) + 1 |
122 | 8 |
所以 flag 就是 flag{757515121f3d478}