[英]Beginning of stack on Linux
我以为我可以通过在main中获取变量的地址并向上舍入到页面边界来获得我的进程堆栈的开始(考虑到我的堆栈增长)。
我将它与/proc/self/maps
报告的边界进行了比较,它总是偏离1,2或3页(每页4096字节),而不是不同的偏移量。 差异随每次运行而变化,以下(混乱,非简约)管道中使用的此C程序证明了差异。
stacksz.c:
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#define CAT "cat /proc/XXXXXXXXXXX/maps"
#define CATP "cat /proc/%ld/maps"
#define MASK ((sizeof(char)<<12)-1)
int main()
{
uintptr_t top = (uintptr_t)&top + MASK & ~MASK;
char cat[sizeof CAT];
sprintf(cat,CATP,(long)getpid());
if(system(cat)) return 1;
printf(" %lx stack\n", top);
return 0;
}
bash管道:
gcc stacksz.c && echo "$(( $(./a.out |grep stack |tr '-' ' ' |cut -d' ' -f2 |sed 's/^/0x/'|tr '\n' -|sed 's/-$//') ))"
我很好奇是否有人能解释这种现象。 该机器是Linux precision 4.15.0-43-generic #46-Ubuntu SMP x86_64
。 `(我在1000次运行中获得了以下偏移分布:
4096 195
8192 490
12288 315
)。
ASLR首先完全随机化虚拟内存中的堆栈位置。 但它做得更多:它还使堆栈指针相对于堆栈映射的顶部随机化!
来自linux的源代码:
unsigned long arch_align_stack(unsigned long sp)
{
if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
sp -= get_random_int() % 8192;
return sp & ~0xf;
}
这里,如果ASLR处于活动状态,则堆栈指针减少0-8192字节,然后对齐16字节。 这解释了1-3页的可变偏移量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.