【问题标题】:GDB calling a function that is not in mainGDB 调用不在 main 中的函数
【发布时间】:2018-02-04 12:38:20
【问题描述】:

我的教授给我们分配了一个任务,让我们逐步执行由 c 程序使用 GDB 生成的 x86 指令来查找密码。我们的工作是经历 6 个阶段并找到隐藏在 x86 指令中某处的密码。我能够浏览所有这些,但最后我注意到在 x86 文件中,有一个名为 secret_phase 的函数。我的理解是,如果我们完成了 secret_phase,我们将获得额外的功劳。问题是,从未从主函数调用 secret_phase,所以我什至不知道如何访问它。有没有办法从 GDB 调用 secret_phase 函数?

【问题讨论】:

  • 试试call secret_phase()
  • 它告诉我 - 'secret_phase' 的返回类型未知;将调用转换为其声明的返回类型
  • 在汇编器中调用就行了。
  • @MartinJames:您的“只是”假设 OP 知道如何将新代码链接到已链接的可执行文件中。他们没有目标文件。可行的一件事(考虑到可用工具的初学者知识)是将反汇编复制/粘贴到 asm 源文件中,然后重新组装 + 调用者。 (使用像objconv 这样的反汇编程序,它可以使您可以重新组装反汇编,并在分支目标上带有标签。)或者使用十六进制编辑器编辑二进制炸弹中的call 指令之一,以调用secret_phrase 而不是@987654326 @.

标签: c assembly x86 gdb


【解决方案1】:

如果你是一个乐观主义者,并且希望 secret_phrase,比如说,只是在屏幕上打印秘密短语,那么请执行以下操作:

break main
run
call ((void(*)()) secret_phrase)()

在这里您指定要调用的函数原型,猜测是它不接受任何参数并且不返回任何内容。如果您期望它,例如将密语返回为char*,您可以尝试:

print ((char*(*)()) secret_phrase)()

或任何其他返回类型,但这是猜测。

更严格的方法是跳转到那个函数,可以在任何执行点完成:

break main
run
break secret_phrase
jump secret_phrase

(注意第二个中断,没有它执行将立即继续,并且很可能程序会崩溃,因为您跳转到函数,而不是调用它)。确认后调试器将在 secret_phrase 开始处停止。小心处理stepi,一旦你执行retn 指令,程序很可能会崩溃。但是您将有机会仔细检查该函数。

除此之外,您可能应该从disassemble secret_phrase 开始寻找线索。

【讨论】:

  • 不用jump,你可以set $pc = secret_phrase修改EIP/RIP而不继续执行。顺便说一句,我建议在停在phase1 或其他东西的顶部时做这个“跳跃”,所以当它返回时它会返回到main。尽管您可能没问题,但如果 secret_phrase 自己提示输入而不是查找 main 传递的 args。
猜你喜欢
  • 2018-02-05
  • 2017-01-29
  • 2019-04-25
  • 2014-08-11
  • 1970-01-01
  • 2020-02-13
  • 2017-10-22
  • 1970-01-01
  • 2021-06-11
相关资源
最近更新 更多