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

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

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

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

跟进:

我不是要试图找出是否有某些东西被malloc。

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

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

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

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

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

 #include  #include  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; } 

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

 program: 0x400504 heap: 0x1675010 heap2: 0x1675030 stack: 0x7fff282c783c stack2: 0x7fff6ae37afc 

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

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

 program: 0x804842f heap: 0x804b008 heap2: 0x804b018 stack: 0xbf84ad38 stack2: 0xbf84ad14 

Microsoft Windows和32位Microsoft C编译器:

 program: 01271020 heap: 002E3B00 heap2: 002E3B10 stack: 0024F978 stack2: 0024F964 

Windows Cygwin下的gcc:

 program: 0040130B heap: 00A41728 heap2: 00A417A8 stack: 0028FF44 stack2: 0028FF14 

英特尔32位FreeBSD下的gcc:

 program: 0x8048524 heap: 0x804b030 heap2: 0x804b040 stack: 0xbfbffb3c stack2: 0xbfbffb1c 

英特尔64位FreeBSD下的gcc:

 program: 0x400770 heap: 0x801006058 heap2: 0x801006060 stack: 0x7fffffffdaec stack2: 0x7fffffffdabc 

SPARC-64 FreeBSD下的gcc:

 program: 0x100860 heap: 0x40c04098 heap2: 0x40c040a0 stack: 0x7fdffffe9ac stack2: 0x7fdffffe8dc 

PowerPC运行MacOS X:

 program: 0x1ed4 heap: 0x100120 heap2: 0x100130 stack: 0xbffffba0 stack2: 0xbffffb38 

PowerPC运行Linux:

 program: 0x10000514 heap: 0x100c6008 heap2: 0x100c6018 stack: 0xbff45db0 stack2: 0xbff45d88 

StrongARM运行NetBSD:

 program: 0x1c5c heap: 0x5030 heap2: 0x5040 stack: 0xefbfdcd0 stack2: 0xefbfdcb4 

和运行Linux的ARMv6:

 program: 0x842c heap: 0xb63008 heap2: 0xb63018 stack: 0xbe83eac4 stack2: 0xbe83eaac 

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

你可以确定一般来说堆栈和堆的位置,不过它的大小将是另一个故事……

 void *heap_locations; void *stack_location; void determine_locations (int any_int) { free(heap_location = malloc(248)); stack_location = &any_int; } int main(int argc, char *argv[]) { determine_locations(argc); . . . return 0; } 

有点粗鲁,你不会知道任何一个的扩展方向或大小,除非你正在处理指定的平台。