ARM bx 指令分支到未指定为参数的地址

逆向工程 手臂
2021-06-15 20:49:02

我正在调试运行 FreeRTOS 的 ARM cortex M4 (STM32F4)。在汇编 FreeRTOS 函数内部vPortSVCHandler,有一条分支指令

bx r14

使用 GDB,我逐条指令执行,发现 r14 (lr) 包含0xfffffffd紧接在 bx 指令执行之前的(不是有效地址)。

出于某种原因,GDB 没有遵循(挂起)bx指令si,但我仍然可以step通过 openOCD。我发现分支到的函数实际上是地址处的有效函数0x08012abc

从 ARM 文档开始bx,它的参数应该是一个包含要跳转到的地址的寄存器。

显然,我误解了或查看了错误的文档。

我尝试lr在分支指令之前使用 GDB 进行调整在分支后不久将其更改为0x00xfffffff7导致硬故障。

这个分支指令如何在以 值调用时0xfffffffd导致分支到有效函数在0x08102abc

1个回答

FFFFFFFFCortex-M 中使用周围用于 异常返回 (ECX_RETURN)。当前定义的值:

  1. 0xFFFFFFF1 - 返回处理程序模式,从主堆栈恢复状态

  2. 0xFFFFFFF9 - 返回线程模式,从主堆栈恢复状态

  3. 0xFFFFFFFD - 返回线程模式,从进程堆栈中恢复状态

所以实际的分支地址取自堆栈(MSP 或 PSP,取决于值的低位)。有关更多详细信息,请参阅链接的文档。

由于 GDB 主要用于用户模式调试,因此它不期望这种恶作剧,并且可能会尝试在LR自然失败的值处设置断点OpenOCD 知道异常并且能够正确执行。