简体   繁体   English

Printf符号解析

[英]Printf Symbol Resolution

I'm writing a little program which trace all the syscall and calls of a binary file (elf) using ptrace (singlestep, getregs, pick_text, opcodes comparison, etc). 我正在编写一个程序,它使用ptrace(singlestep,getregs,pick_text,opcodes比较等)跟踪二进制文件(elf)的所有系统调用和调用。

So far I've succeed to trace syscalls and simple calls like user defined functions. 到目前为止,我已成功跟踪系统调用和简单调用,如用户定义的函数。

But I failed to get the name of the printf symbol from the address I pick thanks to ptrace. 但是由于ptrace,我没能从我选择的地址中获得printf符号的名称。

My question is: For dynamic linked function as printf, strlen, etc, how can I retrieve in the elf file the name of the symbol from the address ? 我的问题是:对于printf,strlen等动态链接函数,如何在elf文件中检索地址中符号的名称?

With simple calls it's kind of easy, I run through the .strtab section and when an address match I return the corresponding str. 通过简单的调用,它很容易,我运行.strtab部分,当地址匹配时,我返回相应的str。

But for printf, the symbol is known in the .strtab but has the address "0". 但对于printf,符号在.strtab中已知,但地址为“0”。

objdump -d somehow succeed to link a call to printf with its address. objdump -d以某种方式成功将对printf的调用与其地址相关联。

Do you have any idea ? 你有什么主意吗 ?

I think you may need to read up a little more about dynamic linking. 我想你可能需要阅读更多有关动态链接的内容。 Let's take strlen as an example symbol as printf is a bit special (fortification stuff). 我们以strlen作为示例符号,因为printf有点特殊(强化的东西)。

Your problem is (I think) that you want to take the address of a symbol and translate that back into an address. 您的问题是(我认为)您想要获取符号的地址并将其转换回地址。 You're trying to do this by parsing the ELF file of the program you are debugging. 您正在尝试通过解析正在调试的程序的ELF文件来执行此操作。 This works with symbols that are in your program, but not with dynamically linked symbols such as strlen . 这适用于程序中的符号,但不适用于动态链接符号(如strlen And you want to know how to resolve that. 你想知道如何解决这个问题。

The reason for that is that the address of symbols such as strlen are not held within your ELF program. 原因是strlen等符号的地址不在您的ELF程序中。 They are instead unresolved references that are resolved dynamically when the program loads . 它们是在程序加载时动态解析的未解析引用。 Indeed modern Linux will (I believe) load dynamic libraries (which contain relocatable aka position independent code) in a randomised order and at randomised addresses, so the location of those symbols won't be known until the program loads. 事实上,现代Linux将(我相信)以随机顺序和随机地址加载动态库(其中包含可重定位的名称位置无关代码),因此在程序加载之前将不知道这些符号的位置。

For libraries that you have opened with dlopen() (ie where you are doing the loading yourself in the program), you can retrieve the address of such symbols using dlsym() ; 对于使用dlopen()打开的库(即您在程序中自己加载的位置),可以使用dlsym() ;来检索这些符号的地址。 that's not much good if they are linked into the program at compile/link time. 如果它们在编译/链接时链接到程序中并不是很好。

On gcc, to resolve the position of symbols in general, use the gcc extension dladdr() . 在gcc上,要解决一般符号的位置,请使用gcc扩展名dladdr() From the man page: 从手册页:

   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.

I believe that will work for you. 我相信这对你有用。

For further information, I suggest you look at the source to ltrace which traces library calls, and how backtrace_symbols (and here ) works; 有关详细信息,我建议您查看ltrace跟踪库调用的源代码 ,以及backtrace_symbols (和此处 )的工作原理; note that particularly for non-global symbols this is going to be unreliable, and note the comment re adding -r dynamic to the link line. 请注意,特别是对于非全局符号,这将是不可靠的,并注意注释重新添加-r dynamic到链接行。

You might also want to look at addr2line and its source . 您可能还想查看addr2line及其来源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM