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
如何使用strerror_r=0x8049e20
获取dlsym()
?
我先打印了strerror_r的地址,然后调用dlsym()。
strerror_r = 0xb76544e0是错误的地址,我用这个地址调用strerror_r什么都不做。
答案 0 :(得分:1)
如果您查看strerror_r
中/usr/include/string.h
的声明:
/ *
strerror'. There are 2 flavors of
strerror_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")
。