JQCTF2025 Customize Virtual Machine复现
字数 2178 2025-08-29 22:41:24
JQCTF2025 Customize Virtual Machine 逆向分析与解题教程
1. 题目概述
这是一个基于自定义虚拟机(VM)的逆向工程挑战,主要涉及自修改代码(SMC)和虚拟机逆向分析技术。题目要求参赛者解密并分析一段被混淆的代码,最终获取隐藏的flag。
2. 题目核心逻辑
2.1 基本流程
- 输入一个长度为50的字符串作为flag
- 将flag的每一位与长度为50的
fun_list对应位置的字节数组进行异或操作 - 实现SMC(自修改代码)功能,解密函数
- 使用自定义虚拟机执行解密后的opcode并调用这些函数
2.2 关键数据结构
fun_list: 包含50个字节数组,每个数组对应flag的一个字符data[i]: 对应第i个函数,内容是要参与异或的字节数据
3. 解题思路分析
3.1 SMC解密策略
由于题目使用SMC技术,我们需要通过以下特征来判断解密是否正确:
- 合法函数特征:解密后的函数代码应该是有效的汇编指令
- 非法指令排除:有效函数不应包含特定非法指令
3.2 非法指令列表
合法函数中通常不会包含以下指令(或极其罕见):
| 指令 | 原因 |
|---|---|
hlt |
中止CPU,常用于内核或异常终止 |
cli, sti |
中断控制,通常为内核态指令 |
in, out, ins, outs |
端口IO操作,只用于驱动程序或内核 |
lgdt, lidt, ltr, lmsw等 |
修改全局或中断表,仅限系统级代码 |
rdmsr, wrmsr, rdtsc等 |
访问CPU特权寄存器,仅限特定应用 |
vm*, svm* |
虚拟化指令,仅虚拟机/Hypervisor使用 |
ud2 |
故意制造非法指令,常用于崩溃测试或反调试 |
lock前缀的原子指令 |
除非是多线程同步函数 |
3.3 常见合法指令
解密后的函数可能包含以下常见指令:
push,popmovsub,addcmp,testxor,and,orleaimuljmp,jcc条件跳转call,ret
3.4 Flag格式限制
题目明确说明flag格式为:
- 字符集:
0-9,a-z和_ - 长度:固定50个字符
4. 解题步骤详解
4.1 数据提取
- 从题目提供的文件中提取
fun_list数据 - 确保每个
data[i]对应第i个函数,内容是要参与异或的字节
4.2 爆破策略
由于flag字符集有限且长度固定,可以采用逐字符爆破的方法:
- 对每个位置i (0 ≤ i < 50)
- 尝试所有可能的字符c (0-9, a-z, _)
- 用c与
fun_list[i]进行异或解密 - 检查解密结果是否为合法汇编代码
4.3 使用Capstone反汇编引擎
Capstone是一个强大的反汇编框架,可用于验证解密后的代码是否合法:
from capstone import *
# 初始化Capstone引擎
md = Cs(CS_ARCH_X86, CS_MODE_32)
# 对解密后的字节进行反汇编
for i in md.disasm(decrypted_bytes, 0x1000):
print("0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str))
4.4 爆破代码实现
关键步骤:
- 遍历每个flag位置
- 尝试所有可能的字符
- 解密并反汇编
- 检查第一条指令是否合法
- 记录所有可能的候选字符
def brute_force_char(pos):
possible_chars = []
for c in ALLOWED_CHARS: # 0-9a-z_
decrypted = xor(fun_list[pos], ord(c))
# 使用Capstone反汇编第一条指令
instr = next(md.disasm(decrypted[:15], 0), None)
if instr and is_valid_instruction(instr):
possible_chars.append(c)
return possible_chars
4.5 特殊处理
题目提示:
- 前15个函数都是全部解密
- 后35个函数留了最后一个字节未修改(可能是
ret指令,0xC3)
因此可以推测:
- 最后一个字节异或
0xC3可以得到flag对应位置的字符
5. 工具与技术
5.1 Capstone反汇编引擎
Capstone是一个轻量级、多平台、多架构的反汇编框架:
- 官网: https://github.com/aquynh/capstone
- 支持架构: Arm, Arm64 (AArch64/Armv8), Mips, PPC, Sparc, SystemZ, XCore, X86 (包括X86-64)
- 绑定语言: C/C++, Python, Java, Go等
安装方法:
pip install capstone
5.2 其他技巧
- 指令长度分析:通过观察解密后代码的指令长度分布辅助判断
- 函数序言分析:合法函数通常以
push ebp; mov ebp, esp开头 - 交叉验证:对多个候选字符的解密结果进行比较,选择最合理的
6. 完整解题流程
- 提取
fun_list数据 - 对每个位置进行字符爆破:
- 前15个位置:完整解密并验证
- 后35个位置:假设最后一个字节是
ret(0xC3)
- 组合所有位置的解得到完整flag
- 验证flag的正确性
7. 经验总结
- SMC分析:理解自修改代码的工作原理是关键
- 指令特征:掌握合法与非法指令的区别能大幅提高效率
- 工具使用:熟练使用反汇编工具如Capstone是逆向工程的基础
- 爆破策略:在有限字符集情况下,爆破是有效手段
- 题目提示:注意题目给出的所有提示信息(如flag格式、函数处理差异等)
8. 扩展思考
-
如何防御这种基于指令特征的爆破攻击?
- 增加合法但罕见的指令
- 使用多层加密
- 加入反调试技术
-
更高效的解题方法?
- 结合动态分析,在解密后直接运行代码
- 使用符号执行技术
- 应用机器学习分类器识别合法代码
-
实际应用场景:
- 恶意代码分析
- 软件保护技术研究
- 虚拟机逃逸漏洞挖掘