L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Productivité · SKILL.md

re-fw-emulate

re-fw-emulate

固件仿真:QEMU 用户态/全系统。 触发词:仿真、QEMU、firmadyne、跑固件

Independent GitHub snapshot · Automated classification · Original documentation governs

Ddslsdzc / rev-skillsApache-2.0

Documentation de la Skill

GitHub

name: re-fw-emulate description: > 固件仿真:QEMU 用户态/全系统。 触发词:仿真、QEMU、firmadyne、跑固件 capabilities: [emulation]

固件仿真(QEMU)

何时使用 / 何时不用

  • 用:需要运行固件内程序观察行为/验证假设(固件 web 界面、服务端逻辑)
  • 用:rootfs 已解出、需要整体启动(全系统仿真)
  • 不用:只需静态分析([[re-fw-rootfs]] 已覆盖)
  • 不用:有实物板子且必须真实硬件交互(走 [[re-hardware-io]],硬件提取/接口调试)
  • 不用:目标只是解包看内容(走 [[re-fw-extract]])

工具准备

所有工具先验证再使用。仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则);用户态仿真优先(最轻可行方案)。

qemu-user —— 用户态仿真(最轻)

  • Linux: apt install qemu-user / dnf install qemu-user / pacman -S qemu-user
  • macOS: brew install qemu(含用户态与系统态)
  • Windows/WSL: WSL 内 Linux 版
  • 验证: qemu-arm --version、qemu-mips --version(大端)、qemu-mipsel --version(小端)

qemu-system —— 全系统仿真

  • Linux: apt install qemu-system-arm qemu-system-mips / dnf install qemu-system-arm qemu-system-mips / pacman -S qemu-system-arm qemu-system-mips
  • macOS: brew install qemu
  • Windows/WSL: WSL 内 Linux 版
  • 验证: qemu-system-arm --version

binfmt_misc —— 直接执行交叉程序

  • Linux: apt install binfmt-support qemu-user-static(Debian/Ubuntu 装 qemu-user-static 即自动注册各架构 binfmt 条目;Fedora 用 systemd binfmt 配置);手动注册: update-binfmts --enable qemu-arm(或 /etc/binfmt.d/ 配置文件)
  • macOS/Windows: 不支持,用 qemu-<arch> 显式调用
  • 验证: ls /proc/sys/fs/binfmt_misc/ 可见 qemu-arm 条目;之后可直接执行 ./rootfs_out/usr/sbin/httpd

gdb-multiarch + gdbserver —— 交叉调试

  • Linux: apt install gdb-multiarch / dnf install gdb-multiarch / pacman -S gdb-multiarch;gdbserver: apt install gdbserver(或随 gdb 包提供)
  • macOS: brew install gdb(需 Developer Tools 授权,见 [[re-analyze/platform-tips]] macOS 分支)或 WSL 内 Linux 版
  • Windows/WSL: WSL 内 Linux 版
  • 验证: gdb-multiarch --version

firmadyne —— 全系统自动仿真框架(思路参考,可选装)

  • 安装: git clone https://github.com/firmadyne/firmadyne,依赖 qemu-system-* 与预编译内核(scripts/ 下下载),首次搭建较重
  • 验证: ls sources/ 有 getArch.py 等脚本;which qemu-system-mips
  • 多数单程序分析不需要它——用户态优先([[re-analyze/platform-tips]] 先给最轻可行方案)

操作步骤

按顺序执行,每步记下结果。

  1. 用户态仿真(最轻,优先):

    file rootfs_out/usr/sbin/httpd                    # 确认架构:ARM 32/64、MIPS(BE/EL)、RISC-V
    qemu-arm -L rootfs_out rootfs_out/usr/sbin/httpd  # -L 把 rootfs 当 sysroot(动态库/链接器从 rootfs 加载)
    # 大端 MIPS: qemu-mips -L rootfs_out ...
    # 小端 MIPS: qemu-mipsel -L rootfs_out ...
    

    缺库报错 → 交叉 ldd / readelf -d 看依赖,从 rootfs 补库;Web 服务类程序可加 -E 传环境变量。

    • -strace 记录客户程序系统调用(等效仿真内 strace——排查 mmap/ioctl 崩溃点直接用它)
    • -0 <argv0> 伪造 argv[0](程序按调用名分支时用);-cpu <型号> 指定 CPU(如 qemu-arm -cpu cortex-a9)
    • 跑不起来但静态可分析 → 回 [[re-fw-rootfs]] / [[re-binary-core]],不在仿真上死磕。
  2. 全系统仿真:

    # ARM(vexpress 平台)+ 内核与 initramfs:
    qemu-system-arm -M vexpress-a9 -kernel vmlinuz -initrd initramfs.img -nographic \
      -append "console=ttyAMA0 root=/dev/ram rdinit=/sbin/init"
    # MIPS(malta 平台,大端示例):
    qemu-system-mips -M malta -kernel vmlinuz -initrd initramfs.img -nographic \
      -append "console=ttyS0 rdinit=/sbin/init"
    

    把 rootfs 制作成磁盘镜像(ext2 挂 root)或 initramfs(cpio 打包 rootfs_out);firmadyne 的脚本就是自动化这套流程。 rootfs 已是磁盘镜像时直接挂盘:

    qemu-system-arm -M vexpress-a9 -kernel vmlinuz -drive file=rootfs.ext2,format=raw \
      -nographic -append "console=ttyAMA0 root=/dev/mmcblk0 rdinit=/sbin/init"
    

    root 设备名按平台磁盘控制器定(vexpress=mmcblk0、malta 的 IDE=/dev/sda 等,以 -M 平台文档为准)。

  3. 外设缺失用 stub/回环:

    • 用户态:程序 mmap 固定地址(GPIO/UART 寄存器)崩溃 → strace 定位访问点,LD_PRELOAD 提供 stub 库返回假寄存器值
    • 全系统:-device 挂虚拟外设(e1000 / virtio 等);真实芯片外设(wifi/基带)QEMU 无法模拟 → 打补丁跳过初始化或 stub 该 ioctl
    • 先确定程序初始化到哪一步崩(串口输出/日志),再决定 stub 哪部分
  4. 交叉调试(qemu -g + gdb-multiarch):

    qemu-arm -g 1234 -L rootfs_out rootfs_out/usr/sbin/httpd &   # -g 起 gdbstub
    gdb-multiarch rootfs_out/usr/sbin/httpd
    (gdb) target remote :1234
    

    全系统内:把 gdbserver 放进 rootfs,gdbserver :1234 /usr/sbin/httpd,宿主 target remote <qemu_ip>:1234;调试手法按 [[re-gdb]]。

  5. 网络隔离下仿真:

    • 用户态:不是网络沙箱(socket/connect 经 syscall 转发到宿主内核),需要受控网络时改用全系统方案
    • 全系统:QEMU 不加网络参数会默认建 NIC(e1000)+ user 后端——先显式 -nic none 确认行为,需要受控网络再加 -nic user,restrict=on(用户态 NAT,仅模拟出站)
    • 分析回连/协议前先隔离([[re-analyze/platform-tips]] 最高原则),流量抓包与协议重建转 [[re-protocol]];firmadyne 默认带网卡也需按此原则先行隔离

跨域联合

  • [[re-firmware]]:工作流第 4 步固定调用本技能
  • 架构识别与指令级深挖:ARM(向量表/Thumb/MMIO 外设交叉)→ [[re-arm]];RISC-V(RV32/RV64/ecall)→ [[re-riscv]](选对 qemu- 前先对照)
  • 仿真内动态行为观察 → [[re-tracing]] + [[re-gdb]](默认沙箱内,[[re-analyze/platform-tips]] 最高原则)
  • 固件运行产生通信 → [[re-protocol]];仿真内 ELF 深挖 → [[re-binary-core]]
  • 仿真不成的程序回退静态 → [[re-fw-rootfs]]

常见坑与陷阱

  • 外设寄存器访问崩溃:现象——程序 mmap 固定地址后读 GPIO/UART 寄存器段错误;原因——QEMU 用户态不模拟外设,地址无映射;对策——strace 定位访问点,LD_PRELOAD stub 返回模拟值(步骤 3)
  • 架构选错直接 segfault:现象——qemu-arm 跑 MIPS 程序秒崩;原因——没先 file/readelf 确认架构与字节序(大端 mips ≠ mipsel);对策——步骤 1 先确认,选对 qemu-
  • 网卡型号不符 → 初始化卡死:现象——程序在网卡初始化处挂起不退出;原因——固件按特定芯片初始化,默认挂的 e1000 不匹配,ioctl 无返回;对策——按固件预期加 -device <型号> 等虚拟网卡,或先 -nic none 观察是否跳过(步骤 5)
  • 时间戳/时钟函数陷阱:现象——程序读时间怪异(1970/倒退),行为与真实设备不同;原因——QEMU 虚拟时钟与墙钟不同步;对策——-rtc base=utc 固定,或 stub 掉 clock_gettime 相关调用
  • 网络未隔离就仿真:现象——固件真实回连外网(C2/升级服务器);原因——QEMU 默认就建 NIC + user 后端(restrict=off),跳过显式隔离即联网;对策——全系统仿真显式 -nic none,用户态也非网络沙箱(步骤 5),回连分析前按 [[re-analyze/platform-tips]] 隔离
  • 命令族速查与操作序列见 [[commands]];工具特有坑与版本差异见 [[gotchas]]
Skills enregistrées