C中的地址空间布局随机化和结构

时间:2018-10-17 15:35:43

标签: c memory struct buffer-overflow aslr

我有这样的结构:

 $("URL#news").onload{function()

让我们知道,如果我将struct Books { char title[50]; char author[50]; }; 传递给程序,则在代码的某些部分中,它将向arg1的方向添加一些字符,因此$title+52的值是被覆盖(缓冲区溢出)。

现在,我将ASLR添加到我的二进制文件中。通过这种方式,某些方向是随机的,因此我认为不可能实现之前所述的缓冲区溢出。

这是真的吗?还是即使我添加ASLR,结构成员的方向都在一起,缓冲区溢出还是可能的?

3 个答案:

答案 0 :(得分:5)

您提到的特定溢出仍然可能。

除位域外,结构的各域在内存中顺序排列(之间可能有填充)。 C standard的6.7.2.1p15节对此进行了详细说明:

  

在结构对象中,非位字段成员和   位域所在的单元的地址会增加   声明它们的顺序。指向结构的指针   经过适当转换的对象指向其初始成员(或   如果该成员是位域,则指向它所在的单元   居住),反之亦然。内部可能有未命名的填充   一个结构对象,但不是在它的开始。

因此,在这种情况下,author字段将始终跟随title字段,而不管struct Books类型的对象位于哪个特定地址。唯一可能的差异可能是填充量,但是除非您在结构中添加或删除字段,否则这可能不会改变。

答案 1 :(得分:2)

ASLR不会影响正在编译的内容。编译器在编译时选择结构的布局,并将其硬编码在生成的目标代码中。

此外,C标准要求将连续的struct成员以它们在struct定义中出现的顺序排列在内存中(在成员之间使用未指定的填充,但这在编译时是固定的)

答案 2 :(得分:2)

我认为您误解了ASLR(地址空间布局随机化)的影响:ASLR随机地将进程的不同虚拟内存区域(可执行文件,堆栈,堆,数据,库等)的位置安排为不同执行。它不会更改同一虚拟内存区域中元素的相对位置。


以下面的简单程序为例:

int main(void) {
    struct {
        char a[10];
        char b[10];
    } myvar;

    printf("a: %p\n", &myvar.a);
    printf("b: %p\n", &myvar.b);

    return 0;
}

以下是ASLR 已禁用的程序的虚拟内存:

0x555555554000     0x555555555000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x555555754000     0x555555755000 r--p     1000 0      /home/marco/test/test [read only data]
0x555555755000     0x555555756000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffffffde000     0x7ffffffff000 rw-p    21000 0      [stack] <-- myvar is here

输出(禁用ASLR):

$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a

这是启用了ASLR 的同一程序:

0x559fefcbe000     0x559fefcbf000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x559fefebe000     0x559fefebf000 r--p     1000 0      /home/marco/test/test [read only data]
0x559fefebf000     0x559fefec0000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffe3bb5e000     0x7ffe3bb7f000 rw-p    21000 0      [stack] <-- myvar is here

输出(已启用ASLR):

$ ./test
a: 0x7ffe3bb5e080
b: 0x7ffe3bb5e08a
$ ./test 
a: 0x7ff4abdeea80
b: 0x7ff4abdeea8a
$ ./test 
a: 0x7efa6b8fa080
b: 0x7efa6b8fa08a

您的变量仍将位于某个连续虚拟内存块中,并且这些字段的相对位置不会改变完全没有使用ASLR,连续数组仍将是连续数组:它们将从内存中的不同位置开始。

由于struct字段在内存中通常是连续的(并遵循它们的声明顺序),这意味着即使使用ASLR,缓冲区溢出仍将是一个潜在的问题

>