executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-armARM 架构逆向(非 Android):Cortex-M/A 向量表、Thumb/ARM 切换、AAPCS 调用约定、位置相关代码重定位、MMIO 外设寄存器交叉。 触发词:ARM、arm32、Cortex-M、Cortex-A、Thumb、AAPCS、嵌入式逆向、裸机固件、stm32、向量表。
Independent GitHub snapshot · Automated classification · Original documentation governs
.so(走 [[re-android-native]])所有工具先验证再使用。静态分析可免沙箱;qemu 动态执行默认沙箱 + 网络隔离([[re-analyze/platform-tips]] 最高原则)。
apt install ghidra / pacman -S ghidrabrew install --cask ghidra;Windows: 官方 zipanalyzeHeadless -help(headless 模式)或 GUI 导入 ARM ELFapt install binutils 等);macOS: brew install binutils 或 LLVM 系 readelf;Windows: WSL 内readelf --versionbinwalk --version、unblob --versionapt install qemu-user / dnf install qemu-user / pacman -S qemu-userbrew install qemu(含用户态);Windows/WSL: WSL 内 Linux 版qemu-arm、64 位为 qemu-aarch64;-L <rootfs> 指定动态库/链接器来源,-strace 跟踪系统调用qemu-arm --version、qemu-aarch64 --versionqemu-system-arm -machine mps2-an385(Cortex-M3)等板级模型(-s -S 接 gdb),或 [[re-emulation]] 用 Unicorn 逐指令apt install gdb-multiarch(该包在 Debian/Ubuntu 及其衍生的官方仓库有);Fedora dnf install gdb(官方 gdb 支持多目标、可调裸机 ARM;arm-none-eabi-gdb 不在 Fedora 官方仓库,如需嵌入式专用工具链用官方预编译 ARM 工具链);Arch pacman -S gdb(官方 gdb 已内置 multiarch)brew install gdb(需 Developer Tools 授权,见 [[re-analyze/platform-tips]] macOS 分支)或 WSL 内 Linux 版;Windows/WSL: WSL 内 Linux 版gdb-multiarch --version;Fedora/Arch gdb --version;载入裸机固件后 set architecture armv7-m 再 file 加载,info registers 确认qemu-system-arm -s -S 或 qemu-arm -g <port>按顺序执行,每步结果存档;动态执行默认沙箱。
架构与字节序确认:
file target.bin # "ARM"=32 位(含 Thumb)、"AArch64"=64 位;MSB/LSB 端序提示
file target.elf
readelf -h target.elf # Machine=ARM / AArch64;Data=little-endian / big-endian
readelf -A target.elf | head # Tag_ABI_VFP_args: 1=硬浮点(HFABI)、0=软浮点;EABI 版本
EF_ARM_ABI_FLOAT_HARD(0x400) 硬浮点 / EF_ARM_ABI_FLOAT_SOFT(0x200) 软浮点(对应坑 5)入口定位:
msr vbar_el1/el2/el3, Xt 及其地址构造序列;reset entry 本身由实现/SoC 启动配置决定(平台可提供 core reset vector base 配置),不能假定固定在 0AArch32 Thumb/T32 函数边界(Thumb/ARM 切换):
nm / readelf -s 中 Thumb 函数为奇地址)、BL 目标、向量表项、虚表函数指针项都带 Thumb 位bx rN / blx rN:按目标寄存器位 0 切换状态(1=Thumb);blx 立即数形式直接切到 ARM 态目标R_ARM_THM_CALL 判定,超距由链接器插 veneer);超限时链接器插入 veneer 跳板(形态如 ldr pc, =addr、movw+movt+bx),看到片状跳板序列不要当业务逻辑;veneer 也用于 ARM↔Thumb 状态切换$a/$t/$d 决定反汇编状态,映射符号丢失后会按错误状态反汇编——用 arm-none-eabi-objdump -d -M force-thumb 强制 Thumb,或交给 Ghidra 按 TMode 启发式切换基址 / 重定位(加载地址 vs 链接地址):
readelf -l):VMA 即链接地址;加载地址看 LMA / p_paddrAAPCS 调用约定识别:
push {r4-r11, lr},尾部 pop {..., pc}(借 LR 同时恢复 PC);叶子函数(无嵌套调用)常不 push LR,直接 bx lrreadelf -A 的 Tag_ABI_VFP_args 区分(混用时最易错,见坑 5)stp x29, x30, [sp, #-16]!外设寄存器交叉(MMIO xref):
ldr rN, [pc, #imm] 从函数尾部立即数池取地址 → str/ldr 访问外设;手工算池地址时注意 Thumb 态 PC=当前+4、ARM 态 +8,且按 4 字节对齐movw/movt + bx、ldr pc 跳板,被当成业务逻辑分析;原因——BL 立即数只能覆盖 ARM ±32MB / Thumb ±16MB,超限链接器插 veneer;对策——识别短跳板形态(结尾 bx/ldr pc 且目标为远地址)后跳过,继续跟踪最终目标;跨状态(Thumb↔ARM)调用同样经 veneerpush {..., lr} 与 bl 前后 LR 赋值点重建调用关系;异常入口现场恢复序列(入栈 8 字 r0-r3/r12/LR/PC/xPSR,PC 在 [sp,#0x18])用于确认异常处理函数readelf -A 的 Tag_ABI_VFP_args 与 e_flags 的 0x400/0x200 位定 ABI,再看参数实际落在哪组寄存器:首参从 s0-s15/d0-d7 收 = 硬浮点,从 r0-r3 收 = 软浮点。关键:-mfloat-abi=softfp 是"软浮点调用约定 + 允许 VFP 指令"——它照样发射 vmov/vadd/vcmp 等浮点指令,参数却仍走整数寄存器(实测:vmov s0, r1 把 r1 搬进 s0),所以浮点指令出现频率不能佐证 float ABI,只能佐证"代码用了 VFP"