远程调试 Linux 二进制文件 - 堆栈地址更改?

逆向工程 艾达 linux
2021-06-16 06:40:15

每次我们使用linux_serverIDA Pro远程调试 Linux 二进制文件时,堆栈地址都会改变吗?

我正在使用 IDA Pro 并远程调试一个在 Linux 机器上运行的 linux 二进制文件,我将其linux_server用作dbgsrv.

我注意到当我进入一个子程序时,每次的堆栈地址都不一样。是预期的吗?是因为我在远程调试吗?

2个回答

在现代 Linux 机器上,默认情况下启用 ASLR。因此,当在虚拟内存中创建二进制的进程映像时,堆栈的基地址位于随机偏移处

/*
 * These are the functions used to load ELF style executables and shared
 * libraries.  There is no binary dependent code anywhere else.
 */

#ifndef STACK_RND_MASK
#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
#endif

static unsigned long randomize_stack_top(unsigned long stack_top)
{
    unsigned long random_variable = 0;

    if (current->flags & PF_RANDOMIZE) {
        random_variable = get_random_long();
        random_variable &= STACK_RND_MASK;
        random_variable <<= PAGE_SHIFT;
    }
#ifdef CONFIG_STACK_GROWSUP
    return PAGE_ALIGN(stack_top) + random_variable;
#else
    return PAGE_ALIGN(stack_top) - random_variable;
#endif
}

我们可以用一个简单的程序来测试这个,该程序在函数中打印局部变量的内存地址main()

#include <stdio.h>

int main(void){

        int i = 3;

        printf("%p\n", &i);

        return 0;
}

编译并执行:

$ gcc -m32 -o print_stack_address print_stack_address.c 
$ ./print_stack_address 
0xff9dc78c
$ ./print_stack_address 
0xff832d3c
$ ./print_stack_address 
0xff844c1c
$ ./print_stack_address 
0xff999e0c
$ ./print_stack_address 
0xffd1117c

大多数现代操作系统从不保证堆栈的位置对于不同的进程创建开始是相同的,这主要是操作系统进程创建流程中这些分配的确定性执行的副产品。

此外,在利用过程中,这个事实经常被用来为堆栈地址使用常量值,而这正是 ASLR 所防止的。一段时间以来,堆栈被 ASLR 处理以减轻漏洞利用,并且实际上保证是随机的。