使用 ASLR 获取随机匿名映射地址
Using ASLR To Get Random Anonmous Mapping Address
在最新的 Ubuntu 16.04 x86_64 系统上考虑此代码 运行:
void main(int argc, char *argv[])
{
while(1) {
char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("%p\n", x);
munmap(x, 1000);
}
}
其输出如下所示:
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
...
我会预料到,提供了零地址提示和全局启用 ASLR 以在此处获取随机地址。
是否可以在随机地址处 mmap() 匿名共享内存?
使用我上面的测试代码的这个稍微修改过的版本:
void main(int argc, char *argv[])
{
if (argc < 2) return;
int iter = strtol(argv[1], NULL, 10);
for(int i = 0; i < iter; i++) {
char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("stack=%p mmap=%p\n", main, x);
munmap(x, 1000);
}
}
并且运行测试4次迭代我得到相同的地址:
$ ./rndmap 3
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
这是我最初的问题 - 为什么映射不是随机地址。我用一次迭代 运行 多次测试来回答我自己的问题 (./rndmap 1),结果如下:
stack=0x559714ce7830 mmap=0x7f6956ac9000
stack=0x55b74b293830 mmap=0x7faafb7c0000
stack=0x564665b22830 mmap=0x7f56baf12000
因此可以得出结论,linux 中的 ASLR 部分负责随机化堆基地址,而不是各个内存映射。这就是每次二进制文件 运行 时地址都会改变的原因,并且对于每个 mmap(),我们都会得到相同的随机基地址。
在最新的 Ubuntu 16.04 x86_64 系统上考虑此代码 运行:
void main(int argc, char *argv[])
{
while(1) {
char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("%p\n", x);
munmap(x, 1000);
}
}
其输出如下所示:
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
0x7f02ca14c000
...
我会预料到,提供了零地址提示和全局启用 ASLR 以在此处获取随机地址。
是否可以在随机地址处 mmap() 匿名共享内存?
使用我上面的测试代码的这个稍微修改过的版本:
void main(int argc, char *argv[])
{
if (argc < 2) return;
int iter = strtol(argv[1], NULL, 10);
for(int i = 0; i < iter; i++) {
char *x = (char *)mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("stack=%p mmap=%p\n", main, x);
munmap(x, 1000);
}
}
并且运行测试4次迭代我得到相同的地址:
$ ./rndmap 3
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
stack=0x5623b6ff3830 mmap=0x7fe8a29b7000
这是我最初的问题 - 为什么映射不是随机地址。我用一次迭代 运行 多次测试来回答我自己的问题 (./rndmap 1),结果如下:
stack=0x559714ce7830 mmap=0x7f6956ac9000
stack=0x55b74b293830 mmap=0x7faafb7c0000
stack=0x564665b22830 mmap=0x7f56baf12000
因此可以得出结论,linux 中的 ASLR 部分负责随机化堆基地址,而不是各个内存映射。这就是每次二进制文件 运行 时地址都会改变的原因,并且对于每个 mmap(),我们都会得到相同的随机基地址。