【问题标题】:Determining return address of function on ARM Cortex-M series在 ARM Cortex-M 系列上确定函数的返回地址
【发布时间】:2020-06-10 10:24:11
【问题描述】:

我想在 Keil 中确定一个函数的返回地址。我在 Keil uvision 的调试模式下打开了反汇编部分。显示的是一些像这样的汇编代码:

我的目的是通过在微控制器上使用缓冲区溢出向微控制器注入一个简单的二进制代码。see: Buffer overflow 我想确定“测试”函数的返回地址。是一定要知道怎么看汇编代码还是有什么技巧可以找到返回地址?

我是组装新手。

【问题讨论】:

  • 在 ARM 上,返回 value 将在 r0 中,函数将返回的地址将保存在 lr 中(查找 bx lrpop {pc} 指令)。
  • 您绝对需要了解您使用的处理器的最少组装。 BTW 为什么你需要知道退货地址?你打算用它做什么?
  • 嗯,我正在研究硬件安全。我正在尝试通过受益于微控制器的缓冲区溢出来进行代码注入。
  • 恐怕在ARM上这样一个简单的函数你无法覆盖被调用函数的返回地址,因为它大多在寄存器LR(R14)中。
  • @thebusybee:请注意,该函数确实推送lr并将其弹出回pc(直接因为它不需要bx进行拇指交互操作),因此您可以在堆栈内存中覆盖它.

标签: c assembly arm memory-address keil


【解决方案1】:

调用函数时,R14 将被调用(“BL”或“BLX”)指令后面的地址覆盖。如果该函数不调用任何其他函数,R14 将经常在其持续时间内保留返回地址。此外,如果函数尾调用另一个函数,尾调用可以用分支(“B”或“BX”)替换,其中 R14 保存原始调用者的返回地址。如果一个函数对另一个函数进行非尾调用,则有必要在此之前的某个时间将 R14 保存在“某处”(通常是堆栈,但可能保存到另一个先前使用的调用者保存的寄存器),并检索该值稍后从堆栈中取出,但如果启用优化,保存 R14 的位置通常是不可预测的。

一些编译器可能有一种模式,可以将东西堆叠到足以使用的程度,但代码将非常依赖于编译器。最有可能成功的技术可能是:

extern int getStackAddress(uint8_t **addr);  // Always returns zero
void myFunction(...whavever...)
{
  uint8_t *returnAddress;
  if (getStackAddress(&returnAddress)) return; // Put this first.
}

getStackAddress 是一个机器代码函数,它将 R14 存储到 R0 中的地址,将 R0 加载为零,然后分支到 R14。可能会遵循的代码序列相对较少,如果代码检查存储在returnAddress 中的地址处的指令并识别其中一个代码序列,它将知道myFunction 的返回地址存储在适合所讨论的序列的位置。例如,如果它看到:

    test r0,r0
    be ...
    pop {r0,pc}

它会知道调用者的地址在堆栈中是第二个。同样,如果它看到:

    cmp r0,#0
    bne somewhere:
somewhere: ; Compute address based on lower byte of bne
    pop {r0,r1,r2,r4,r5,pc}

那么它就会知道调用者的地址是第六个。

编译器可以使用一些指令来测试寄存器是否为零,一些编译器可能使用be,而其他编译器使用bne,但对于上面的代码,编译器可能会使用上述模式,所以计算pop 指令中设置了多少位将揭示堆栈上的返回地址的下落。直到运行时才知道这个测试是否真的有效,但如果它声称可以识别返回地址,它实际上应该是正确的。

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      R14 或其他名称LR 保存返回地址。在左侧,您可以在图片中看到它。是0x08000287

      【讨论】:

      • 在这种情况下,返回地址被压入堆栈并将从堆栈中使用。当时在寄存器窗口中的 lr 突出显示的行上是此处回答的地址,但是 BL 指令将更改 LR 的内容。如果您的目标是更改返回地址,那么您需要修改这段特定代码的堆栈。对你的目标是什么感到困惑,只是为了了解地址是什么(注意实际地址是0x080000287&0xFFFFFFFE),还是与返回有关的东西?
      猜你喜欢
      • 2016-12-01
      • 1970-01-01
      • 2013-10-14
      • 2017-06-07
      • 1970-01-01
      • 2012-03-03
      • 2015-03-10
      • 2015-04-20
      • 2012-06-15
      相关资源
      最近更新 更多