【问题标题】:Understanding how parameters are passed to functions in Assembly了解如何将参数传递给 Assembly 中的函数
【发布时间】:2017-03-31 05:16:18
【问题描述】:

我正在阅读这篇writeup,了解如何执行ret2libc 漏洞利用。它指出传递给函数的参数存储在ebp+8

现在,如果我使用一个简单的 C 程序

#include <stdlib.h>

int main() {
  system("/bin/sh");
}

并编译它: gcc -m32 -o test_sh test_sh.c

看看它的反汇编 objdump -d -M intel test_sh

0804840b <main>:
 804840b:       8d 4c 24 04             lea    ecx,[esp+0x4]
 804840f:       83 e4 f0                and    esp,0xfffffff0
 8048412:       ff 71 fc                push   DWORD PTR [ecx-0x4]
 8048415:       55                      push   ebp
 8048416:       89 e5                   mov    ebp,esp
 8048418:       51                      push   ecx
 8048419:       83 ec 04                sub    esp,0x4
 804841c:       83 ec 0c                sub    esp,0xc
 804841f:       68 c4 84 04 08          push   0x80484c4
 8048424:       e8 b7 fe ff ff          call   80482e0 <system@plt>
 8048429:       83 c4 10                add    esp,0x10
 804842c:       b8 00 00 00 00          mov    eax,0x0
 8048431:       8b 4d fc                mov    ecx,DWORD PTR [ebp-0x4]
 8048434:       c9                      leave  
 8048435:       8d 61 fc                lea    esp,[ecx-0x4]
 8048438:       c3                      ret    
 8048439:       66 90                   xchg   ax,ax
 804843b:       66 90                   xchg   ax,ax
 804843d:       66 90                   xchg   ax,ax
 804843f:       90                      nop

线

804841f:       68 c4 84 04 08          push   0x80484c4

将字符串“/bin/sh”的地址压入堆栈。之后立即调用system@plt 函数。那么如何从上述输出到达ebp+8

我们将不胜感激!

【问题讨论】:

  • 简单的 C 程序并使用 system 似乎很奇怪,这将创建一个 fork
  • 阅读与您的系统(和 C 编译器)相关的 ABIcalling conventions
  • 另外,使用gcc -m32 -S -fverbose-asm 获取.s 汇编文件。
  • 这不是在汇编中将参数传递给函数的方式,这是一种特殊的调用约定,称为cdecl。 Pascal 会做不同的事情,一些函数可以优化为使用寄存器而不是在堆栈中放置参数。

标签: c assembly


【解决方案1】:

传递给函数的参数存储在 ebp+8 中。

这是从 被调用 函数的角度来看,而不是从 调用 函数的角度来看。调用函数在ebp+8 有自己的参数,而您的main() 不使用它的任何参数,因此,您在main() 中看不到任何ebp+8 的使用。

你可以看到ebp+8的用法如下:

  • 尝试编写第二个带参数的函数,并从main() 调用它,而不是调用system()。您仍然不会在 main() 中看到对 ebp+8 的任何使用,但您会看到它在您的第二个函数中使用。

  • 尝试声明您的main() 以接受其char** argv 参数,然后尝试将argv[0] 发送到printf()

【讨论】:

    【解决方案2】:

    你不知道,因为 EBP + 8 仅在 system@plt 中的序言之后才相关,并且在创建新的过程框架之后。

    push    ebp
    mov     ebp, esp
    

    此时在 system@plt 中,由 EBP + 8 指向的内存位置的内容将等于 0x80484C4。

    【讨论】:

      猜你喜欢
      • 2013-06-03
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 2021-05-22
      • 2017-07-11
      • 2020-08-26
      相关资源
      最近更新 更多