re-fw-emulate について
ファームウェア解析者向けの QEMU エミュレーションスキルです。ファームウェアのプログラム実行や展開済み rootfs の起動により、動作を観察して仮説を検証します。ユーザーモード・システム全体のエミュレーション、クロスデバッグ、ネットワーク隔離を扱います。
主な機能
- 01ユーザーモードエミュレーションを優先
- 02システム全体のファームウェアを起動
- 03gdb-multiarch でクロスデバッグ
- 04不足する周辺機器を stub またはループバック
- 05エミュレーションのネットワークを隔離
活用シーン
- 01ファームウェアの Web UI やサービス処理を観察
- 02展開済み rootfs を実行
- 03ARM または MIPS のファームウェアプログラムをデバッグ
- 04ファームウェアの動作調査中にネットワークを隔離
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dslsdzc/ rev-skills --skill re-fw-emulateインストール後、Claude Code で/re-fw-emulateを入力して読み込まれたか確認します。
同梱ファイルreferences/commands.mdreferences/gotchas.md
詳細
ファームウェアのシミュレーション(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]] で実現可能な最も軽い方法を先に提示)
手順
順番に実行し、各ステップの結果を記録してください。
-
ユーザー空間シミュレーション(最軽量、優先):
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]] に戻り、シミュレーションに固執しないでください。
-
システム全体のシミュレーション:
# 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 をルートとしてマウント)または initramfs(rootfs_out を cpio でパッケージ化)にします。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"ルートデバイス名はプラットフォームのディスクコントローラーによって異なります(vexpress=mmcblk0、malta の IDE=/dev/sda など。
-Mのプラットフォーム文書を参照してください)。 -
周辺機器がない場合は stub/ループバックを使用:
- ユーザー空間:プログラムが固定アドレス(GPIO/UART レジスター)を mmap してクラッシュする場合 →
straceでアクセス箇所を特定し、LD_PRELOADで偽のレジスター値を返す stub ライブラリを提供します - システム全体:
-deviceで仮想周辺機器(e1000 / virtio など)を接続します。実チップの周辺機器(wifi/ベースバンド)は QEMU ではシミュレートできません → 初期化をスキップするパッチを適用するか、その ioctl を stub します - まずプログラムが初期化のどの段階でクラッシュするか(シリアル出力/ログ)を確認してから、どの部分を stub するか決めます
- ユーザー空間:プログラムが固定アドレス(GPIO/UART レジスター)を mmap してクラッシュする場合 →
-
クロスデバッグ(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]] を参照してください。 -
ネットワークを隔離したシミュレーション:
- ユーザー空間:ネットワークサンドボックスではありません(socket/connect はシステムコールを介してホストのカーネルに転送されます)。制御されたネットワークが必要な場合は、システム全体のシミュレーション方式に切り替えます
- システム全体: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]]