本来是想开始 unidbg 的,发现直接上手有点懵,因为它是基于 unidbg 的,unicorn 是一个低级别的通用仿真工具,而 unidbg 是基于它开发的高级工具,专注于 Android Native 层的分析。所以我们还是从 unicorn 开始吧。

Unicorn 是一个轻量级、多平台的 CPU 仿真框架,用于模拟多种架构(如 x86、ARM、MIPS 等)的指令执行。它基于 QEMU,但更易用,常被应用于恶意代码分析、逆向工程和二进制调试。通过它,开发者可以方便地在内存中加载二进制代码,控制其执行,并观察运行状态,适合需要高效模拟和分析的场景。

模拟指令执行这个应该很熟悉了,在 《CSAPP》中,我们也写过一个模拟指令执行的模拟器,虽然我们的输入是字符串流,但是道理是差不过的。没有看过的读者,可以去《学习路线》篇寻找相关资料。

安装

看官方文档:

https://www.unicorn-engine.org/

我们可以先思考一下,unicorn 它是一个仿真工具,我们需要给他提供输入,然后还需要编写代码来观察我们的输入是如何被执行的,执行时的寄存器参数,执行的结果等等。

那么必然,unicorn 会提供一些接口供我们使用,所以我们需要使用什么语言来编写代码呢?

按照官方文档所说的,它支持,C 与 Python。这里作者使用 Python 来作为编程语言。

所以,我们安装也选择 Python 安装方式。安装 Python binding 的最简单方法是通过 pip,只需在提示符下运行以下命令即可(Linux 和 MacOS 需要 sudo 才能获得 root 访问权限)。

pip install unicorn

环境,我们使用 ubuntu,还是虚拟机。

运行

接下来的几篇我们主要目的都是通过一些例子来熟悉 unicorn 提供的一些 API。

这里有一个文档:

https://github.com/kabeor/Unicorn-Engine-Documentation

先来看一个简单的例子,我们的输入是下面两行汇编,目标就是模拟执行这两行 arm 汇编:

# 0x0000000000000000:  37 00 A0 E3    mov r0, #0x37
# 0x0000000000000004:  03 10 42 E0    sub r1, r2, r3

在线汇编/反汇编网站:

https://shell-storm.org/online/Online-Assembler-and-Disassembler/