Assembly 检查内存地址是否在当前进程内';s堆栈空间

Assembly 检查内存地址是否在当前进程内';s堆栈空间,assembly,x86,segmentation-fault,callstack,ptrace,Assembly,X86,Segmentation Fault,Callstack,Ptrace,我在调试器中添加了一个功能(我使用Ptrace操作跟踪进程以及libbfd/libopcode),以释放堆栈,并确定每个调用分配的堆栈空间与静态派生的局部变量大小之间是否存在差异,同时打印每个帧的地址和局部堆栈大小 我的一般方法是取基指针中的地址(EBP/RBP),递增指针应该包含存储的帧指针,取消对该地址的引用,使用PTRACE\u PEEKDATA检查该地址并重复,直到我取消对占用堆栈外部区域的地址的引用 我知道如何检查代码/数据段寄存器,但理想情况下,我希望有一种方法来检查我是否仍在调用堆

我在调试器中添加了一个功能(我使用Ptrace操作跟踪进程以及libbfd/libopcode),以释放堆栈,并确定每个调用分配的堆栈空间与静态派生的局部变量大小之间是否存在差异,同时打印每个帧的地址和局部堆栈大小

我的一般方法是取基指针中的地址(
EBP
/
RBP
),递增指针应该包含存储的帧指针,取消对该地址的引用,使用
PTRACE\u PEEKDATA
检查该地址并重复,直到我取消对占用堆栈外部区域的地址的引用

我知道如何检查代码/数据段寄存器,但理想情况下,我希望有一种方法来检查我是否仍在调用堆栈中,即使分段已被W^X内存页或其他不可执行的堆栈更改

简言之,当我移出堆栈时,如何检查(在一般情况下)而不触发一般保护故障


(顺便说一句,我意识到我是在假设检查地址的页段是这里的理想方法的基础上操作的——也许还有另一种更简单的方法可以确定地址是否在当前进程的堆栈空间内)C标准不提供任何可移植的方式来访问特定于操作系统或特定于硬件的信息或功能(system()除外)。如果你的C程序依赖于上述信息/功能,那么它的可移植性就很差


如果您坚持使用POSIX功能,您可能会在某种程度上提高可移植性,但这种改进只会是对符合POSIX的操作系统的改进。对所有其他人来说,这将是改善的反面。同样,在Linux上也可能有您可以使用的东西(特定的函数、工具或库)。我不能马上告诉你这样的情况。您需要做进一步的研究或等待其他答案。

我查看了打印正在运行的进程堆栈内容的命令代码。此代码从
链接映射
结构中获取基址,并将其存储在字段
l\u addr
中。此字段设置在函数
readLinkMap()
中:


是的,但是在一个完美的世界中,会有一个不依赖于/proc的任何信息的可移植解决方案。C标准不提供任何可移植的方式来访问特定于操作系统或特定于硬件的信息或功能(除了
system()
)。如果你的C程序依赖于上述信息/功能,那么它的可移植性就很差。如果您坚持使用POSIX功能,您可能会在某种程度上提高可移植性,但这种改进只会是对符合POSIX的操作系统的改进。对所有其他人来说,这将是进步的反面。就这样吧。有图书馆把它抽象出来吗?我不知道。请参阅POSIX API和工具。您介意将其转化为答案吗?
static void readLinkMap(int pid, ElfN_Addr base, struct link_map *lm, 
                        char *name, unsigned int namelen)
{
  /* base address */
  lm->l_addr = (ElfN_Addr) ptrace(PTRACE_PEEKDATA, pid,
                                  base + offsetof(struct link_map,l_addr), 0);
  /* next element of link map chain */
  if (-1 != (long) lm->l_addr || !errno)
    lm->l_next = (struct link_map *) ptrace(PTRACE_PEEKDATA, pid,
                                            base + offsetof(struct link_map, l_next), 0);
  if ((-1 == (long) lm->l_addr || -1 == (long) lm->l_next) && errno) {
    perror("ptrace");
    quit("can't read target.");
  }

  loadString(pid, base + offsetof(struct link_map, l_name), name, namelen);
}