reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
# QEMU 仿真命令速查与操作序列(用户态 / 全系统)
分工:qemu-user(用户态,跑单程序最轻)→ qemu-system(全系统,启动完整固件)→ binfmt_misc(直接执行交叉程序)→ gdb-multiarch(交叉调试)。参数以本机 `qemu-<arch> --help` / `qemu-system-<arch> --help` 为准(版本差异见 [[gotchas]])。
## 命令族速查
### qemu-user —— 用户态仿真
| 用途 | 命令 |
|---|---|
| 架构对应 | `qemu-arm`(32 位)/ `qemu-aarch64` / `qemu-mips`(大端)/ `qemu-mipsel`(小端)/ `qemu-riscv64` 等 |
| 基本运行 | `qemu-arm -L <rootfs> <rootfs>/usr/sbin/httpd` |
| sysroot | `-L <path>`(动态库/链接器从 rootfs 加载;缺 `-L` 报 ld-linux 找不到) |
| 环境变量 | `-E VAR=value`(可多个;Web 服务常传 `-E LD_LIBRARY_PATH=...`) |
| 伪造 argv[0] | `-0 <argv0>`(程序按调用名分支时用) |
| 系统调用日志 | `-strace`(等效仿真内 strace,排查 mmap/ioctl 崩溃点) |
| gdbstub | `-g <port>`(等 gdb 连接,配合 gdb-multiarch) |
| 指定 CPU | `-cpu <型号>`(`-cpu help` 列全部,如 cortex-a9) |
| 限定地址空间 | `-B <size>`(guest 地址空间大小,老内核小空间时用) |
| 启动即暂停 | `-g` 之外可用 `-d in_asm` 反汇编日志(调试/取证) |
### qemu-system —— 全系统仿真
| 用途 | 命令 |
|---|---|
| 平台选择 | `-M vexpress-a9`(ARM)/ `-M malta`(MIPS)/ `-M virt`(通用)——`-M help` 列全部 |
| 内核与 initramfs | `-kernel vmlinuz -initrd initramfs.img` |
| 挂磁盘镜像 | `-drive file=rootfs.ext2,format=raw` |
| 串口到终端 | `-nographic`(`-serial mon:stdio` 变体) |
| 内核参数 | `-append "console=ttyAMA0 root=/dev/ram rdinit=/sbin/init"` |
| 网络(显式添加) | `-netdev user,id=n0 -device e1000,netdev=n0`(用户态 NAT,仅出站) |
| 网络简写 | `-nic user,model=e1000`(新版推荐;`-net` 旧语法已标记弃用) |
| 完全断网 | 显式 `-nic none`(或 `-nodefaults`)——不加网络参数会默认建 NIC + user 后端 |
| 虚拟外设 | `-device virtio-net-pci,netdev=n0` / `-device e1000` 等(`-device help` 列全部) |
| 固定时钟 | `-rtc base=utc`(避免时间怪异,见 [[gotchas]]) |
| 内存 | `-m 256`(按固件需求,常见 64-256MB) |
| gdbstub | `-s`(1234 端口)/ `-S`(启动即暂停等 gdb) |
### binfmt_misc —— 直接执行交叉程序
```sh
# Debian/Ubuntu:apt install binfmt-support qemu-user-static 后自动注册
# 手动注册:update-binfmts --enable qemu-arm(或 /etc/binfmt.d/ 配置文件)
ls /proc/sys/fs/binfmt_misc/ # 可见 qemu-arm 等条目
./rootfs_out/usr/sbin/httpd # 之后可直接执行(等效 qemu-arm -L rootfs_out ...)
# 注意:binfmt 直接执行不带 -L sysroot,动态链接程序仍需设置 QEMU_LD_PREFIX 或先解出依赖
```
### gdb-multiarch + gdbserver —— 交叉调试
```sh
qemu-arm -g 1234 -L rootfs_out rootfs_out/usr/sbin/httpd & # 用户态 gdbstub
gdb-multiarch rootfs_out/usr/sbin/httpd
(gdb) target remote :1234
# 全系统内:rootfs 里放 gdbserver,gdbserver :1234 /usr/sbin/httpd
# 宿主 (gdb) target remote <qemu_guest_ip>:1234
```
## 常用操作序列
### 1. 用户态跑单个固件程序(最轻,优先)
```
file 确认架构与字节序 → qemu-<arch> -L <rootfs> <程序>
→ 缺库:readelf -d 看依赖,从 rootfs 补(或 -E LD_LIBRARY_PATH)
→ 崩溃:加 -strace 看系统调用,定位到 mmap/ioctl 访问点再决定 stub(序列 4)
```
### 2. 全系统启动(initramfs 与磁盘镜像两式)
```
式一(initramfs):cpio 打包 rootfs_out → -kernel vmlinuz -initrd initramfs.img -append "rdinit=/sbin/init"
式二(磁盘镜像):dd/ext2 制作 rootfs.ext2 → -kernel vmlinuz -drive file=rootfs.ext2,format=raw -append "root=/dev/<设备>"
→ 串口看不到输出先核对 console= 参数与 -M 平台(ttyAMA0=ttyS0 因平台而异)
```
### 3. 仿真内交叉调试(用户态 / 全系统)
```
用户态:qemu-arm -g 1234 → gdb-multiarch target remote :1234
全系统:gdbserver 放进 rootfs → 在固件里启动 gdbserver → 宿主 target remote <guest_ip>:1234
→ 调试手法(断点/内存/单步)按 [[re-gdb]]
```
### 4. 外设缺失 stub(GPIO/UART 寄存器崩溃)
```
qemu-<arch> -strace 定位首个崩溃访问(如 mmap 固定地址后读 [addr])
→ LD_PRELOAD 提供 stub 库:该地址返回模拟值(用户态)
→ 全系统:-device 挂虚拟外设(e1000/virtio);真实芯片外设打补丁跳过初始化
→ 先确认程序初始化到哪一步崩(串口输出/日志),再决定 stub 范围
```
### 5. 网络隔离下仿真
```
全系统先 -nic none(不加网络参数会默认建 NIC + user 后端)确认行为 → 需要受控网络再加 -nic user,model=e1000,restrict=on
→ 回连/协议分析前按 [[re-analyze/platform-tips]] 隔离;抓包与协议重建转 [[re-protocol]]
→ firmadyne 默认带网卡,同样先隔离再跑
```
## 实现教训(内化)
- 用户态先行:单程序 80% 场景 qemu-user 足够,别一上来搭全系统
- `-L` 不匹配的典型症状是 ld-linux 报错——先把 sysroot 指对再谈其他
- `-strace` 是仿真内排障第一工具:崩溃/挂起先看系统调用流
- 全系统串口无输出先查 `console=` 与 `-M` 平台匹配(console 设备名因平台/内核而异)
- 仿真是验证手段不是目的:跑不动且静态可分析就回退静态([[re-fw-rootfs]] / [[re-binary-core]])
## 使用注意
- 仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则)
- 架构识别先做([[re-arm]] / [[re-riscv]] / [[re-mips]] 对照),选错 qemu-<arch> 秒崩
- 产物与日志 sha256 入档([[re-triage]] 惯例);仿真结论写 [[re-analyze/analysis-contract]]

View File

@@ -0,0 +1,43 @@
# QEMU 仿真工具特有坑与边界
## 架构与启动
- **架构/字节序选错秒崩**:大端 MIPS(qemu-mips)与小端(qemu-mipsel)互跑直接 Invalid ELF/segfault——先 `file`/`readelf -h` 确认;ARM 32/64(qemu-arm vs qemu-aarch64)同理
- **-L sysroot 不匹配**:缺 `-L` 或指向错误目录 → 报 ld-linux 找不到/加载器版本不符——sysroot 必须含目标架构的 `/lib`、`/usr/lib` 与动态链接器
- **内核与 rootfs 不匹配**:全系统内核必须支持 rootfs 的文件系统与架构(如 ext2 内核没编入 → 挂载失败 Kernel panic)——换内核或换文件系统格式
- **console 参数与平台不匹配**:`console=ttyAMA0`(vexpress)vs `console=ttyS0`(malta)——串口无输出先核对,别先怀疑内核坏了
- **-M 平台与设备模型耦合**:同一内核在不同 -M 平台(vexpress/virt)下设备树不同——换平台要同步换 -append/root 设备名
## 外设与内存
- **用户态不模拟外设**:mmap 固定地址(GPIO/UART 寄存器)后访问直接段错误——`-strace` 定位访问点,LD_PRELOAD stub 返回模拟值(见 [[commands]] 序列 4)
- **网卡型号与固件预期不符导致初始化挂起**:固件按特定芯片初始化时 ioctl 无返回、程序卡死——默认挂的 e1000 未必匹配,按固件预期加 `-device <型号>`/virtio;也可先 `-nic none` 确认是否能跳过网络初始化(见 [[commands]] 序列 5)
- **内存给太小**:固件按真实内存初始化(malloc 上限/分区表),`-m 32` 可能启动失败——常见 64-256MB 起步试
- **时间/时钟怪异**:QEMU 虚拟时钟与墙钟不同步(读时间 1970/倒退)——`-rtc base=utc` 固定,或 stub 掉 clock_gettime 相关调用
## qemu-user 边界
- **只仿真用户态指令**:特权指令/内核路径(驱动 ioctl 真实设备)不工作——需要完整内核行为的程序必须全系统仿真
- **进程模型差异**:qemu-user 对 fork/线程有支持但受限(老版本多线程程序偶发崩溃)——多线程目标优先全系统
- **共享内存/IPC 受限**:POSIX shm、跨进程通信在用户态仿真下不可靠——依赖共享内存的多进程固件走全系统
- **-strace 输出量大**:全量系统调用日志可 GB 级——`-strace` 后管道 grep 目标调用(open/connect/mmap)
## 网络与隔离
- **qemu-system 默认有网络**:未显式声明网络时 QEMU 会自动创建默认 NIC(`e1000`)与 user 模式后端(`type=user,net=10.0.2.0,restrict=off`)——**分析不可信固件必须显式 `-nic none`**(或 `-nodefaults`)才真正无网络;需要受控出站时用 `-nic user,restrict=on` 或隔离 TAP / network namespace
- **qemu-user 不是网络沙箱**:guest 的 socket/connect 经 syscall 转发到宿主内核,可直接访问宿主回环与网络——从 qemu-user 跑出站连接不代表隔离,回连分析同样按 [[re-analyze/platform-tips]] 隔离
- **user 模式不是隔离**:`-nic user` 的 guest 出站直达宿主网络栈——回连分析前仍按 [[re-analyze/platform-tips]] 隔离(断外网/fake DNS),firmadyne 默认网卡同样先隔离
- **guest 内需要 IP 固定**:user 模式 NAT 的 DHCP/地址分配与固件假设不符时程序初始化失败——`-nic user,net=192.168.x.0/24` 定制网段
## 版本差异
- **QEMU 8/9/10/11 世代**:网络配置推荐 `-nic`/`-netdev` 简写(`-net` 旧语法仍兼容但标记弃用);`-device` 支持的外设模型持续扩充;新版对 ARM/MIPS 平台支持更完整(老版可能缺某些 -M 平台)
- **qemu-user 与 qemu-system 分包**:发行版拆分为 qemu-user(各架构用户态)+ qemu-system-<arch>——只装其一会出现"命令不存在";Debian 系 `apt install qemu-user qemu-system-arm qemu-system-mips` 按需装
- **qemu-user-static**:Debian 系含静态链接的 qemu-<arch>-static(binfmt 直接执行用);普通 qemu-user 是动态链接版,无法给宿主上 binfmt 用
- **内核侧**:同 -M 平台下不同版本内核的设备树/驱动行为有差异——固件配套内核缺失时试同架构近版本内核
## 使用注意
- 仿真 = 动态执行,默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则)
- 跑不动且静态可分析就回退静态([[re-fw-rootfs]] / [[re-binary-core]]),不在仿真上死磕
- 仿真结果与真实硬件行为有差距(时序/外设/内核驱动)——涉及硬件交互的结论用 [[re-hardware-io]] 验证