【问题标题】:dlsym() returns strange address of symboldlsym() 返回符号的奇怪地址
【发布时间】:2012-08-07 15:23:41
【问题描述】:

1)。直接打印函数地址:

printf("strerror=%p, strerror_r=%p\n", strerror, strerror_r);
strerror=0x8049ec0, strerror_r=0x8049e20

2)。 dlsym 版本:

rtldDefault= dlopen(0, RTLD_NOW | RTLD_GLOBAL);
dlsym(rtldDefault, "strerror_r"); ==> strerror_r=0xb76544e0

但是

dlsym(rtldDefault, "strerror"); ==> strerror=0x8049ec0

3)。其他:

dlsym((void*)0, "strerror_r") ==> strerror_r=0xb76544e0
dlsym((void*)-1, "strerror_r") ==> strerror_r=0xb76544e0

如何使用dlsym() 获得strerror_r=0x8049e20

我已经先打印了strerror_r的地址,然后调用dlsym()。

strerror_r=0xb76544e0 是错误的地址,我用这个地址调用 strerror_r 什么都不做。

【问题讨论】:

  • 我想strerror 可能实际上在某处被调用,因此已经解决,而strerror_r 尚未被调用,dlsym 正在给你一个蹦床函数的地址。尝试同时调用它们(仅一次)并查看是否有任何变化。
  • 很难说..也许把它喂给readelf可以给出一些提示
  • 您可以在调试器中查看地址。我猜其中一个只包含跳转到真正的功能。

标签: c symbols dlsym


【解决方案1】:

如果你看/usr/include/string.hstrerror_r的声明:

/* strerror'. There are 2 flavors ofstrerror_r' 的可重入版本,GNU 返回字符串 并且可能会或可能不会使用提供的临时缓冲区和 POSIX 之一 它将字符串填充到缓冲区中。 要使用 POSIX 版本,-D_XOPEN_SOURCE=600 或 -D_POSIX_C_SOURCE=200112L 没有 -D_GNU_SOURCE 是必需的,否则 GNU 版本是 首选。 */
[然后是一些相当混乱的声明]

使用gcc -save-temps 和默认配置编译示例程序,我得到以下预编译声明:

extern int strerror_r (int __errnum, char *__buf, size_t __buflen) 
    __asm__ ("" "__xpg_strerror_r") __attribute__ ((__nothrow__ , __leaf__))
    __attribute__ ((__nonnull__ (2)));

所以看起来strerror_r 函数链接到符号__xpg_strerror_r

确实,检查生成的二进制objdump -t a.out | grep strerror

00000000      DF *UND*  00000000  GLIBC_2.3.4 __xpg_strerror_r

所以,问你的问题,只需dlsym(rtldDefault, "__xpg_strerror_r")

【讨论】:

  • 感谢您的友好解释。但是为什么 dlsym(rtldDefault, "strerror_r"); ==> strerror_r=0xb76544e0
  • @DavidChyi:你是什么意思?为什么它的地址比另一个高得多?或者为什么它与 _xpg_strerror_r 不同?它们是不同的,因为它们是不同的功能,或者更准确地说,是不同的_symbols。它可能要高得多,因为正如 Useless 在他的评论中所说,这个函数从未被调用过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 2019-07-05
  • 2017-07-04
  • 2018-03-11
  • 2019-07-27
相关资源
最近更新 更多