簡體   English   中英

檢查內存地址是否在當前進程的堆棧空間內

[英]Check if an memory address is within the current process's stack space

我在調試器中添加了一個功能(我正在使用Ptrace來操縱跟蹤的進程以及libbfd / libopcodes)以展開堆棧,並確定每個CALL分配的堆棧空間與靜態派生的局部變量大小之間是否存在差異,沿途打印每幀的地址和本地堆棧大小。

我的一般方法是將地址保存在基本指針( EBP / RBP )中,將指針增加到應包含存儲的幀指針,取消引用該地址,使用PTRACE_PEEKDATA對其進行檢查,然后重復進行直到我取消引用占用該地址以外的區域的地址為止。堆。

我知道如何檢查代碼/數據段寄存器,但是理想情況下,我希望使用一種方法檢查我是否仍在調用堆棧中,即使該段已被W ^ X內存頁或其他無法執行的堆棧更改了。

簡而言之,在不觸發常規保護故障的情況下,如何檢查(通常情況下)移出堆棧的時間?

(順便說一句,我意識到我是在假設檢查地址的頁面段是此處的理想方法的假設下運行的;也許存在另一種更簡單的方法來確定地址是否在當前進程的堆棧空間內)

C標准不提供任何可移植的方式來訪問特定於OS或特定於硬件的信息或功能(也許對system()除外)。 如果您的C程序依賴於上述信息/功能,那么注定它的可移植性很差。

如果您堅持使用POSIX功能,則可能會在某種程度上提高可移植性,但是這種改進只會是POSIX兼容OS的改進。 對於所有其他方面,這與改進相反。 同樣,您可能會在Linux上始終使用某些東西(特定的功能,工具或庫)。 副手,我不能指出你這樣。 您需要做進一步的研究或等待其他答案。

我查看了pstack命令的代碼,該命令正在打印正在運行的進程的堆棧內容。 此代碼從link_map結構獲取基地址,並將其存儲在字段l_addr 該字段在readLinkMap()函數內部設置:

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM