环境搭建:QEMU系统模式与用户模式安装、交叉编译工具链配置
说实话,环境搭建这步看着简单,但坑是真不少。我见过太多人卡在这一步,折腾两三天还没跑起来第一个程序。咱们今天就把这事彻底搞定。
先看整体架构,心里有个谱:
2.1 QEMU 安装:两种模式,两种用法
QEMU 这东西,说白了就是个硬件模拟器。它有两种工作模式,咱们都得装。
核心区别一句话:用户模式只管跑单个程序,系统模式模拟一整套设备。
用户模式(User Mode)
这种模式最轻量。你拿一个 ARM 编译好的 ELF 文件,直接就能在 x86 机器上跑。不需要启动内核,不需要挂载文件系统。我个人习惯用这个模式做 Fuzz 测试——快,省事。
# 安装 ARM 32位和64位用户模式支持
sudo apt update
sudo apt install qemu-user qemu-user-static
# 验证安装
qemu-arm --version
qemu-aarch64 --version
小技巧:装完以后试试 qemu-arm /bin/ls,如果能列出目录,说明环境通了。我第一次装完就卡在这步——忘了装 binfmt-support,结果系统不认识 ARM 格式。
系统模式(System Mode)
做 Pwn 漏洞利用的时候,我建议用系统模式。为什么?因为很多漏洞需要完整的操作系统环境才能触发——比如内核交互、设备驱动、网络协议栈。用户模式模拟不了这些。
# 安装系统模式支持
sudo apt install qemu-system-arm qemu-system-aarch64
# 验证
qemu-system-arm --version
qemu-system-aarch64 --version
注意:系统模式安装包比较大(约 200MB),因为包含了各种板级支持包。如果你磁盘空间紧张,可以只装需要的架构:sudo apt install qemu-system-arm 就够了。
2.2 交叉编译工具链配置
交叉编译,说白了就是在 x86 机器上编译出 ARM 能跑的代码。这里我踩过不少坑,咱们一步步来。
安装 gcc-arm-linux-gnueabihf
这是 ARM 32 位硬浮点工具链。为什么选 gnueabihf 而不是 gnueabi?因为现在大部分 ARM 设备都支持硬件浮点,性能更好。
# 安装 ARM 32位工具链
sudo apt install gcc-arm-linux-gnueabihf
# 安装 ARM 64位工具链
sudo apt install gcc-aarch64-linux-gnu
# 验证
arm-linux-gnueabihf-gcc --version
aarch64-linux-gnu-gcc --version
验证小实验:写个 hello.c,交叉编译试试:
# hello.c
#include <stdio.h>
int main() {
printf("Hello from ARM!\n");
return 0;
}
# 编译
arm-linux-gnueabihf-gcc -o hello_arm hello.c
# 查看文件类型
file hello_arm
# 输出:ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV)
工具链对比表
| 工具链名称 | 目标架构 | 浮点支持 | 适用场景 |
|---|---|---|---|
| gcc-arm-linux-gnueabihf | ARM 32位 | 硬件浮点(VFP) | 嵌入式设备、IoT Fuzz |
| gcc-arm-linux-gnueabi | ARM 32位 | 软件浮点 | 老旧设备兼容 |
| gcc-aarch64-linux-gnu | ARM 64位 | 硬件浮点(NEON) | 手机、服务器 Pwn |
| gcc-riscv64-linux-gnu | RISC-V 64位 | 硬件浮点 | 新兴架构 Fuzz |
我的经验:做 Fuzz 测试时,我一般用 gnueabihf。但如果你遇到段错误或者浮点异常,试试换成 gnueabi——有些老设备确实不支持硬浮点。
2.3 目标系统镜像准备
系统模式需要完整的操作系统镜像。这里我推荐两种方式:
方式一:使用预构建镜像(推荐新手)
从官方仓库下载现成的 Debian/Ubuntu ARM 镜像,省时省力。
# 下载 ARM 32位 Debian 镜像
wget https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2
wget https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress
wget https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress
# 启动
qemu-system-arm -M vexpress-a9 \
-kernel vmlinuz-3.2.0-4-vexpress \
-initrd initrd.img-3.2.0-4-vexpress \
-drive file=debian_wheezy_armhf_standard.qcow2,if=sd \
-append "root=/dev/mmcblk0p2 console=ttyAMA0" \
-nographic
我曾经踩过的坑:下载的镜像版本和内核版本不匹配,启动时直接 kernel panic。解决办法:统一从同一个源下载,别混搭。另外,-M 参数指定机器类型,vexpress-a9 是最通用的,别乱改。
方式二:自己构建镜像(推荐进阶)
用 debootstrap 从零构建,灵活度高,可以定制软件包。
# 安装 debootstrap
sudo apt install debootstrap
# 构建 ARM 32位根文件系统
sudo debootstrap --arch=armhf --foreign bullseye \
/mnt/arm-rootfs http://deb.debian.org/debian
# 复制 qemu-arm-static 到根文件系统
sudo cp /usr/bin/qemu-arm-static /mnt/arm-rootfs/usr/bin/
# 进入 chroot 环境完成安装
sudo chroot /mnt/arm-rootfs /debootstrap/debootstrap --second-stage
为什么需要 qemu-arm-static?debootstrap 在宿主机上运行,但安装脚本是 ARM 格式的。qemu-arm-static 充当解释器,让宿主机能执行 ARM 指令。没有这步,debootstrap 会报 "Exec format error"。
2.4 环境验证清单
装完别急着走,跑一遍这个清单,确保万无一失:
- 用户模式验证:
qemu-arm /bin/true返回 0 - 系统模式验证:能启动到登录提示符
- 交叉编译验证:编译的 ARM 程序能在 QEMU 用户模式下运行
- 网络连通性:系统模式下
ping 8.8.8.8通 - SSH 连接:能从宿主机 SSH 进 QEMU 虚拟机
我的习惯:每次搭建新环境,我都会写一个自动化脚本,把这 5 步验证跑一遍。省得后面 Fuzz 跑了一天才发现环境有问题,白费功夫。