简体   繁体   English

在Linux上开始堆栈

[英]Beginning of stack on Linux

I thought I could get the beginning of my process stack by taking the address of a variable in main and rounding up to a page boundary (considering that my stack grows down). 我以为我可以通过在main中获取变量的地址并向上舍入到页面边界来获得我的进程堆栈的开始(考虑到我的堆栈增长)。

I compared this to the boundary reported by /proc/self/maps and it's always off by 1, 2, or 3 pages (4096 bytes per page), never by a different offset. 我将它与/proc/self/maps报告的边界进行了比较,它总是偏离1,2或3页(每页4096字节),而不是不同的偏移量。 The difference varies with each run and this C program used in the following (messy, not minimalistic) pipeline demonstrates the difference. 差异随每次运行而变化,以下(混乱,非简约)管道中使用的此C程序证明了差异。

stacksz.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 pipeline: bash管道:

gcc stacksz.c && echo "$(( $(./a.out |grep stack |tr '-' ' ' |cut -d' ' -f2 |sed 's/^/0x/'|tr '\n' -|sed 's/-$//') ))"

I'm curious if anyone can explain this phenomenon. 我很好奇是否有人能解释这种现象。 The machine is Linux precision 4.15.0-43-generic #46-Ubuntu SMP x86_64 . 该机器是Linux precision 4.15.0-43-generic #46-Ubuntu SMP x86_64 ` ( I got the following offset distribution in a 1000 runs: `(我在1000次运行中获得了以下偏移分布:

4096 195
8192 490
12288 315

). )。

ASLR first completely randomizes the stack location in the virtual memory. ASLR首先完全随机化虚拟内存中的堆栈位置。 But it does more: It also randomizes the stack pointer relative to the top of the stack mapping! 但它做得更多:它还使堆栈指针相对于堆栈映射的顶部随机化!

From the linux source code: 来自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;
}

Here, if ASLR is active, the stack pointer is reduced by 0-8192 bytes and then 16 bytes aligned. 这里,如果ASLR处于活动状态,则堆栈指针减少0-8192字节,然后对齐16字节。 This explains the variable offset of 1-3 pages. 这解释了1-3页的可变偏移量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM