缓冲区分配不是字大小的倍数

时间:2013-08-30 21:36:23

标签: c memory-management gdb stack buffer-overflow

我写了一个小程序来理解堆栈的结构。

#include <stdio.h>

void function(int a, int b, int c) {
    char buffer1[5];
    char buffer2[10];

    int *ret = buffer1 + 13;
    (*ret) += 8;
}

int main() {
    int x = 0;
    function(1,2,3);
    x = 1;
    printf("x = %d\n",x);
    return 0;
}

直到现在我已经知道堆栈遵循以下模式

    ------------------
    |    arguments   |  High
    ------------------
    | return address |
    ------------------
    |       ebp      |
    ------------------
    |     buffer1    |
    ------------------
    |     buffer2    |  Low
    ------------------

我还了解到,如果我们分配5个字节的数据,程序会分配8个(因为它必须是字长的倍数)。

转储函数function的汇编程序代码:

0x08048414 <+0>:    push   %ebp
0x08048415 <+1>:    mov    %esp,%ebp
0x08048417 <+3>:    sub    $0x20,%esp
0x0804841a <+6>:    lea    -0x9(%ebp),%eax
0x0804841d <+9>:    add    $0xd,%eax
0x08048420 <+12>:   mov    %eax,-0x4(%ebp)
0x08048423 <+15>:   mov    -0x4(%ebp),%eax
0x08048426 <+18>:   mov    (%eax),%eax
0x08048428 <+20>:   lea    0x8(%eax),%edx
0x0804842b <+23>:   mov    -0x4(%ebp),%eax
0x0804842e <+26>:   mov    %edx,(%eax)
0x08048430 <+28>:   leave  
0x08048431 <+29>:   ret    

汇编程序转储结束。

现在我在gdb下运行程序,我明白了,

(gdb) x/x $ebp
    0xbffff318: 0xbffff348
(gdb) x/x buffer1
    0xbffff30f: 0xfc73e461
(gdb) x/x buffer2
    0xbffff305: 0x0108049f

这是我的疑问,当所有内容都以多个单词大小分配时,buffer1buffer2之间的区别如何10

此外,%ebp与9之间的buffer1有何不同?

这到底发生了什么?

注意

  • 考虑堆栈从高到低
  • Wordsize = 4
  • 我正在使用英特尔处理器,Ubuntu 12.04,32bit并使用

    gcc -o stack -g -fno-stack-protector -O0 main.c

构建。

1 个答案:

答案 0 :(得分:0)

  

这是我的疑问,当所有内容以多个单词大小分配时,buffer1和buffer2之间的区别如何是0x10。

首先,更正:buffer1buffer2之间的差异为10,而不是0x1016)。

其次,并非所有都是以多个单词分配的。 帧大小可以被至少8整除,以保持堆栈与doubles正确对齐,但各个局部变量只能根据其对齐要求进行对齐是(字符和字符缓冲区为1)。