找出指针是指向堆栈,堆还是程序文本?

fad*_*bee 20 c pointers

有没有办法找出指针是否指向以下位置:

  • 堆栈
  • 或者程序(如果是的话,哪个部分例如elf .text)?

此外,这可以移植(Linux 64/32位,OSX和Windows 7+)吗?

跟进:

我不是想弄清楚是不是有些东西已被malloc.

我想有效地将​​void*指针与程序中的函数区分开来,从void*指针到堆栈或堆上的数据.

这适用于用C编写的语言运行库,而不是"普通"C程序.

到目前为止,这个答案是最有用的:检查某些东西是否已被malloced

Dio*_*lis 35

您无法以便携方式执行所需操作,因为C语言标准未将堆栈,程序区域和堆指定为不同区域.它们的位置取决于处理器体系结构,操作系统,加载器,链接器和编译器.试图猜测指针指向的位置是打破C提供的抽象,所以你可能不应该这样做.

然而,有一些方法可以编写能够对特定环境进行正确猜测的代码.您可以通过检查现有对象的地址并查找模式来实现.考虑以下程序.

#include <stdlib.h>
#include <stdio.h>

void
function()
{
    int stack2;

    printf("stack2:  %15p\n", &stack2);
}

int
main(int argc, char *argv[])
{
    int stack;
    void *heap = malloc(1);
    void *heap2 = malloc(1);

    printf("program: %15p\n", main);
    printf("heap:    %15p\n", heap);
    printf("heap2:   %15p\n", heap2);
    printf("stack:   %15p\n", &stack);
    function();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过检查其输出,您可以看到一个模式,例如x64 Linux上的以下模式.

program:        0x400504
heap:          0x1675010
heap2:         0x1675030
stack:    0x7fff282c783c
stack2:   0x7fff6ae37afc
Run Code Online (Sandbox Code Playgroud)

从上面你可以确定(可能)堆从0x1675010增长,低于它的任何东西都是程序代码(或静态数据,你没有提到),并且堆栈以不可预测的方式增长(可能是由于堆栈)随机化)围绕一个非常大的地址,如0x7fff282c783c.

将其与32位Intel Linux下的输出进行比较:

program:       0x804842f
heap:          0x804b008
heap2:         0x804b018
stack:        0xbf84ad38
stack2:       0xbf84ad14
Run Code Online (Sandbox Code Playgroud)

Microsoft Windows和32位Microsoft C编译器:

program:        01271020
heap:           002E3B00
heap2:          002E3B10
stack:          0024F978
stack2:         0024F964
Run Code Online (Sandbox Code Playgroud)

Windows Cygwin下的gcc:

program:        0040130B
heap:           00A41728
heap2:          00A417A8
stack:          0028FF44
stack2:         0028FF14
Run Code Online (Sandbox Code Playgroud)

英特尔32位FreeBSD下的gcc:

program:       0x8048524
heap:          0x804b030
heap2:         0x804b040
stack:        0xbfbffb3c
stack2:       0xbfbffb1c
Run Code Online (Sandbox Code Playgroud)

英特尔64位FreeBSD下的gcc:

program:        0x400770
heap:        0x801006058
heap2:       0x801006060
stack:    0x7fffffffdaec
stack2:   0x7fffffffdabc
Run Code Online (Sandbox Code Playgroud)

SPARC-64 FreeBSD下的gcc:

program:        0x100860
heap:         0x40c04098
heap2:        0x40c040a0
stack:     0x7fdffffe9ac
stack2:    0x7fdffffe8dc
Run Code Online (Sandbox Code Playgroud)

PowerPC运行MacOS X:

program:          0x1ed4
heap:           0x100120
heap2:          0x100130
stack:        0xbffffba0
stack2:       0xbffffb38
Run Code Online (Sandbox Code Playgroud)

PowerPC运行Linux:

program:      0x10000514
heap:         0x100c6008
heap2:        0x100c6018
stack:        0xbff45db0
stack2:       0xbff45d88
Run Code Online (Sandbox Code Playgroud)

运行NetBSD的StrongARM:

program:          0x1c5c
heap:             0x5030
heap2:            0x5040
stack:        0xefbfdcd0
stack2:       0xefbfdcb4
Run Code Online (Sandbox Code Playgroud)

和运行Linux的ARMv6:

program:          0x842c
heap:           0xb63008
heap2:          0xb63018
stack:        0xbe83eac4
stack2:       0xbe83eaac
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,可能性是无穷无尽的.

  • 你有没有忘记创建`heap2`的代码行? (2认同)