【问题标题】:How to call a function in ASM without call or jump?如何在不调用或跳转的情况下调用 ASM 中的函数?
【发布时间】:2016-05-18 01:43:49
【问题描述】:

我目前正在尝试调用这个名为“super_secret_function”的函数,该函数在文件 main.c 中的 main 之外定义。我正在使用 ASM,无法使用 jmp 或 call 来访问此“super_secret_function”。 main 内部是一个名为 stack_hack 的函数,我可以通过该函数更改地址以达到超级机密函数。

使用 GDB,我已经能够确定“super_secret_function”的地址,并通过从函数中跳转到它来成功调用它。如何操作指针的返回值以返回该地址?

.globl stack_hack

stack_hack: 
pushq  %rbp       # push the base pointer on the stack
movq  %rsp, %rbp  # move the previous stack pointer to the new base poi

##MyCode
movq  $0x00000000004005b4, %rbp
jmp   *%rbp
##EndMyCode 

movq %rbp, %rsp   # move the stack pointer to the base pointer
popq %rbp         # pop the base pointer and load it into %rbp
ret               # pop the instruction pointer into %rip

【问题讨论】:

  • 什么是“指针的返回值”?
  • 至少,ret 从堆栈中获取一个值并使用它来更改 IP。您如何更改堆栈上的内容,是否可以利用它将您 to 带到某个地方,而不是 某个地方返回?提示:实际上并没有你想象的那么难。 :)
  • 非常感谢。我将目的地移动到 %rax 中,在弹出 rbp 后,我将 %rax 推入堆栈并返回
  • 不要这样做。它搞砸了返回地址预测器堆栈,并将降低您的性能。只需使用 call/jmp 指令。 CPU 知道这意味着什么,并针对该场景进行了优化。
  • @RaymondChen 我很确定这是家庭作业,而不是实际练习;性能很可能不是问题。 :)

标签: c assembly x86-64


【解决方案1】:

因为这听起来像是一项家庭作业,所以我不会给你一个确切的答案,但我会尽力为你指明正确的方向。

您说不能使用jmpcall,但函数末尾的ret 也会更新程序计数器。你如何影响它更新程序计数器的值?

【讨论】:

  • TBH 我非常卡住。我曾尝试将 %rbp 放入 %rsp,但这也导致了失败。
  • 1) 函数末尾的ret 是从哪里获取值的? 2) 你怎么能影响这个? (提示:第一个问题已在您的代码清单中得到解答。)
  • 获取值rax并放入rip
  • 不,这不是ret 所做的。阅读评论并重试。
  • 也许我不理解 ret。它应该返回旧堆栈指针的值吗?
【解决方案2】:

注意您自己的示例代码和注释:

        ret       # pop the instruction pointer into %rip

ret 指令将弹出到 %rip 中的数据在哪里?

【讨论】:

    【解决方案3】:

    在加载 %rax 中的地址后修复,在 ret 之前弹出 %rbp 后我将 %rax 推入堆栈

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-22
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      相关资源
      最近更新 更多