代码之家  ›  专栏  ›  技术社区  ›  Dr Deo

如何知道堆栈c/c上返回地址的位置++

  •  5
  • Dr Deo  · 技术社区  · 16 年前

    void foo(const char* input)
    {
        char buf[10];
    
        //What? No extra arguments supplied to printf?
        //It's a cheap trick to view the stack 8-)
        //We'll see this trick again when we look at format strings.
        printf("My stack looks like:\n%p\n%p\n%p\n%p\n%p\n% p\n\n"); //%p ie expect pointers
    
        //Pass the user input straight to secure code public enemy #1.
        strcpy(buf, input);
        printf("%s\n", buf);
    
        printf("Now the stack looks like:\n%p\n%p\n%p\n%p\n%p\n%p\n\n");
    }  
    

    有人建议这就是堆栈的样子

    foo的地址= 00401000


    00000000
    00000000

    0012FF80型
    0040108A<--我们要覆盖foo的回信地址。
    00410EDE公司


    -. 为什么作者任意选择最后一个值作为foo()的返回地址?

    -. 值是从底部还是从顶部添加到堆栈中?

    • 除了函数返回地址,我在堆栈上看到的其他值是什么?为什么不填零

    谢谢。

    1 回复  |  直到 16 年前
        1
  •  3
  •   Alex Budovski    16 年前

    上面的那个是上一个EBP( 0012FF80

    1 .

    如果你还记得,开场白是这样的:

    push ebp      ; back up the previous ebp on the stack
    mov ebp, esp  ; set up the new frame pointer
    

    当一个函数被调用时,例如。

    call 0x00401000
    

    当前的EIP被推送到堆栈上(用作返回地址),因此序言后面的堆栈看起来像:

    [ebp+0xc]  ; contains parameter 1, etc
    [ebp+0x8]  ; contains parameter 0
    [ebp+0x4]  ; contains return address
    [ebp]      ; contains prev-EBP
    

    %p ,printf使用从 [ebp+0xc] %第 0012FF80型 )下一个是回信地址。

    再问2)堆栈向下扩展。所以当你 push eax ,从中减去4 esp ,则eax的值移动到[esp],等价于代码:

    push eax
    ;  <=>
    sub esp, 4
    mov [esp], eax
    

    1. 这本书是 编写安全代码
    推荐文章