如何使用rop打印寄存器值(面向返回编程)?

时间:2013-04-12 00:00:27

标签: assembly x86 buffer-overflow

我有一个用于构建rop代码的赋值,该代码使用printf寄存器中的值调用edx

我被困住了。我知道printf功能的地址,我有工具可以查找小工具。

我正在尝试构建一个类似于:

的堆栈
  

someROPCode,printf_address,ret_address,ropCodeThatWrite_EDX_Value(printf argument)。

我试过:someROPCode = add esp 0xc,re t(跳过printf func,这样我就可以在堆栈上写edx个值了

ret_address=doesn't matter

ropCodeThatWrite_EDX_Value =我想过类似:push eaxpush edxret(我不能仅使用push edx,因为我认为这会导致无限循环(我是新来的)但现在我被卡住了(很明显这不是那种方式)。

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

ROP用于绕过非可执行堆栈。为了成功利用,还需要规避其他安全措施。对于本练习,我们将重点关注ROP并假设您没有ASLR等进行简单设置。特别是我们假设您可以轻松访问堆栈指针和函数地址。

我们想调用printf("%d\n", edx)。使用普通的32位x86 cdecl调用约定,我们需要在堆栈上使用这两个参数。格式字符串很简单,但我们必须将edx放入内存中。由于我们无法编写任何代码,因此我们需要找到为我们执行此操作的现有指令。 C库是一个很好的候选者。发现适当的代码是困难的部分。使用objdump我找到了以下有希望的片段:

   2e535:       89 54 24 04             mov    DWORD PTR [esp+0x4],edx
   2e539:       ff 55 14                call   DWORD PTR [ebp+0x14]

这会将edx放在正确位置的堆栈上,并通过函数指针调用函数。一定是我的幸运日,因为所说的指针是使用ebp来解决的,并且很容易设置它的值,因为标准函数结尾常常pop ebp; ret。我在附近发现了一对这样的一对,偏移2e6C1。显然call不会返回到我们的代码,因此它会在完成打印后做未定义的事情(很可能会崩溃)。如果这困扰你,你将不得不找到一个更合适的代码片段。不要忘记将C库的加载地址添加到您找到的偏移量中。

因此,所需的堆栈布局如下所示:

  • esp+00hpop ebp; ret
  • 的地址
  • esp+04hesp+00h(地址printf地址偏移-0x14
  • esp+08h:将edx置于堆栈并调用函数指针
  • 的代码地址
  • esp+0Chesp+18h(格式字符串的地址)
  • esp+10hedx
  • 的占位符
  • esp+14hprintf
  • 的地址
  • esp+18h:格式字符串%d\n

我希望这足以说明这个想法,以便您能够找到适合您特定设置的解决方案。