原恒星Stack0中的填充和对齐

原恒星Stack0中的填充和对齐,c,memory-alignment,exploit,C,Memory Alignment,Exploit,今天早上我完成了关于protostar的练习。该示例是一个使用gets的简单堆栈溢出。我在x86-64上使用gcc编译了代码,并启用了堆栈保护器和ASLR #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { volatile int modified; char buffer[64]; modifie

今天早上我完成了关于protostar的练习。该示例是一个使用gets的简单堆栈溢出。我在x86-64上使用gcc编译了代码,并启用了堆栈保护器和ASLR

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    volatile int modified;
    char buffer[64];

    modified = 0;
    gets(buffer);

    if(modified != 0) {
        printf("you have changed the 'modified' variable\n");
    } else {
        printf("Try again?\n");
    }
}
因此,0x7FFFFFDADC-0x7fffffffdacf是13个字节

0000000000400504 <main>:
400504: 55                      push   %rbp
400505: 48 89 e5                mov    %rsp,%rbp
400508: 48 83 ec 60             sub    $0x60,%rsp
40050c: 89 7d ac                mov    %edi,-0x54(%rbp)
40050f: 48 89 75 a0             mov    %rsi,-0x60(%rbp)
400513: c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
40051a: 48 8d 45 b0             lea    -0x50(%rbp),%rax
40051e: 48 89 c7                mov    %rax,%rdi
400521: e8 ea fe ff ff          callq  400410 <gets@plt>
0000000000 400504:
400504:55推送%rbp
400505:4889E5MOV%rsp%rbp
400508:48 83 ec 60子$0x60,%rsp
40050c:89 7d ac mov%edi,-0x54(%rbp)
40050f:48 89 75 a0 mov%rsi,-0x60(%rbp)
400513:c7 45 fc 00移动$0x0,-0x4(%rbp)
40051a:48 8d 45 b0 lea-0x50(%rbp),%rax
40051e:48 89 c7 mov%rax,%rdi
400521:e8 ea fe ff ff callq 400410
现在,看看上面的目标代码,我们可以看到GCC在堆栈
sub$0x60,%rsp
上为缓冲区和修改区分配了96个字节

(gdb) p &modified
$3 = (volatile int *) 0x7fffffffdadc

(gdb) p &buffer[63]
$12 = 0x7fffffffdacf ""
然后,它将目标索引和源索引从%rbp移动到地址-0x54和-0x60中。这样做的目的是什么?这些寄存器的作用是什么

接下来,我可以看到modified被设置为0,带有
movl$0x0,-0x4(%rbp)
,其中距离基指针4个字节。因此,缓冲区的结尾和修改后的第一个字节之间有12个字节

(gdb) p &modified
$3 = (volatile int *) 0x7fffffffdadc

(gdb) p &buffer[63]
$12 = 0x7fffffffdacf ""

因此,我的问题是:为什么GCC在modified和buffer之间插入12个字节的对齐方式,使modified 16个字节对齐,而不仅仅是8个字节对齐,这将使它与x86-64上的字边界对齐

堆栈对齐由平台ABI控制,而不仅仅由特定类型对齐控制。在您的例子中,堆栈对齐是16字节,这在x86_64平台中很常见


您可以搜索x86_16 ABI问题,例如:

堆栈对齐由平台ABI控制,而不仅仅是由特定的类型对齐控制。在您的例子中,堆栈对齐是16字节,这在x86_64平台中很常见

您可以搜索x86_16 ABI问题,如: