簡體   English   中英

Printf符號解析

[英]Printf Symbol Resolution

我正在編寫一個程序,它使用ptrace(singlestep,getregs,pick_text,opcodes比較等)跟蹤二進制文件(elf)的所有系統調用和調用。

到目前為止,我已成功跟蹤系統調用和簡單調用,如用戶定義的函數。

但是由於ptrace,我沒能從我選擇的地址中獲得printf符號的名稱。

我的問題是:對於printf,strlen等動態鏈接函數,如何在elf文件中檢索地址中符號的名稱?

通過簡單的調用,它很容易,我運行.strtab部分,當地址匹配時,我返回相應的str。

但對於printf,符號在.strtab中已知,但地址為“0”。

objdump -d以某種方式成功將對printf的調用與其地址相關聯。

你有什么主意嗎 ?

我想你可能需要閱讀更多有關動態鏈接的內容。 我們以strlen作為示例符號,因為printf有點特殊(強化的東西)。

您的問題是(我認為)您想要獲取符號的地址並將其轉換回地址。 您正在嘗試通過解析正在調試的程序的ELF文件來執行此操作。 這適用於程序中的符號,但不適用於動態鏈接符號(如strlen 你想知道如何解決這個問題。

原因是strlen等符號的地址不在您的ELF程序中。 它們是在程序加載時動態解析的未解析引用。 事實上,現代Linux將(我相信)以隨機順序和隨機地址加載動態庫(其中包含可重定位的名稱位置無關代碼),因此在程序加載之前將不知道這些符號的位置。

對於使用dlopen()打開的庫(即您在程序中自己加載的位置),可以使用dlsym() ;來檢索這些符號的地址。 如果它們在編譯/鏈接時鏈接到程序中並不是很好。

在gcc上,要解決一般符號的位置,請使用gcc擴展名dladdr() 從手冊頁:

   The function dladdr() takes a function pointer and tries to
   resolve name and file where it is located.   Information  is
   stored in the Dl_info structure:

       typedef struct {
           const char *dli_fname;  /* Pathname of shared object that
                                      contains address */
           void       *dli_fbase;  /* Address at which shared object
                                      is loaded */
           const char *dli_sname;  /* Name of nearest symbol with address
                                      lower than addr */
           void       *dli_saddr;  /* Exact address of symbol named
                                      in dli_sname */
       } Dl_info;

   If no symbol matching addr could be found, then dli_sname and
   dli_saddr are set to NULL.

   dladdr() returns 0 on error, and nonzero on success.

我相信這對你有用。

有關詳細信息,我建議您查看ltrace跟蹤庫調用的源代碼 ,以及backtrace_symbols (和此處 )的工作原理; 請注意,特別是對於非全局符號,這將是不可靠的,並注意注釋重新添加-r dynamic到鏈接行。

您可能還想查看addr2line及其來源

暫無
暫無

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

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