我有这样的结构:
$("URL#news").onload{function()
让我们知道,如果我将struct Books {
char title[50];
char author[50];
};
传递给程序,则在代码的某些部分中,它将向arg1
的方向添加一些字符,因此$title+52
的值是被覆盖(缓冲区溢出)。
现在,我将ASLR添加到我的二进制文件中。通过这种方式,某些方向是随机的,因此我认为不可能实现之前所述的缓冲区溢出。
这是真的吗?还是即使我添加ASLR,结构成员的方向都在一起,缓冲区溢出还是可能的?
答案 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,缓冲区溢出仍将是一个潜在的问题。