9

文章可以在这里找到。

我正在阅读有关粉碎堆栈的内容,并发现自己被困在 example3.c 上。

0x80004a3 <main+19>:    call   0x8000470 <function>
0x80004a8 <main+24>:    addl   $0xc,%esp
0x80004ab <main+27>:    movl   $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>:    movl   0xfffffffc(%ebp),%eax

作者表示我们要从0x80004a80x80004b2跳转,这个跳转是8个字节;作者如何确定这是 8 个字节?我重新创建了代码并将其发送过去objdump,发现它不是 8 个字节(我在 64 位机器上,但我确保使用 32 位进行编译):

8048452:    e8 b5 ff ff ff          call   804840c <function>
8048457:    c7 44 24 1c 01 00 00    movl   $0x1,0x1c(%esp)
804845e:    00 
804845f:    8b 44 24 1c             mov    0x1c(%esp),%eax
8048463:    89 44 24 04             mov    %eax,0x4(%esp)
8048467:    c7 04 24 18 85 04 08    movl   $0x8048518,(%esp)

作者还说“我们怎么知道返回地址要加8?我们先用了一个测试值(比如1) ”他在哪里使用这个测试值呢?

4

2 回答 2

3

我不是这样解释这篇文章的。我理解它的方式是他想修改返回地址以便x = 1;跳过分配,即他想function返回到printf将执行的位置。

正如您在反汇编中看到的那样,分配是 8 个字节 ( c7 44 24 1c 01 00 00 00),因此将返回地址向前移动 8 个字节会将其移过该指令。至于“我们首先使用了测试值”评论..也许他只是意味着他查看了反汇编程序中的代码以找出长度,或者他尝试了不同的偏移量(?)。

于 2012-10-22T08:24:06.403 回答
1

文章中的位移是错误的,应该是10字节。当调用函数(或执行跳转)时,返回地址设置为等于指令指针 + 当前指令大小:

ret = IP + Curr_Inst_size

所以当函数调用返回时,指令指针应该等于0x80004a80x80004a3+调用指令大小):

    0x80004a3 <main+19>:    call   0x8000470 <function>
--> 0x80004a8 <main+24>:    addl   $0xc,%esp            
    0x80004ab <main+27>:    movl   $0x1,0xfffffffc(%ebp)
    0x80004b2 <main+34>:    movl   0xfffffffc(%ebp),%eax

但是,您想将指令指针设置为0x80004b2以跳过赋值,您也不可避免地必须跳过另一条指令(addl $0xc,%esp)才能到达那里,或者换句话说,您需要向(0x80004b2-0x80004a8)指令指针添加字节或 10 个字节跳过这两个指令:

    0x80004a3 <main+19>:    call   0x8000470 <function>
    0x80004a8 <main+24>:    addl   $0xc,%esp            
    0x80004ab <main+27>:    movl   $0x1,0xfffffffc(%ebp)
--> 0x80004b2 <main+34>:    movl   0xfffffffc(%ebp),%eax 

实际指令大小取决于操作数、机器类型等。但在此示例中,addl是 3 个字节长,而movl是 7 个字节长。您可以查看x86 指令集参考以了解确切的指令大小,或者您可以编译和反汇编此代码,您将看到这两条指令有 10 个字节长:

int main()
{
    asm("addl  $0xc,%esp\n\
         movl  $0x1,0xfffffffc(%ebp)");

}

数据库:

0x08048397 <+3>: 83 c4 0c               add    $0xc,%esp
0x0804839a <+6>: c7 45 fc 01 00 00 00   movl   $0x1,-0x4(%ebp)

在示例 3 中,这里这里也有关于这个完全相同的问题的讨论。

于 2012-10-22T09:59:11.057 回答