繁体   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