2012-08-10 100 views
0

1)。直接打印功能地址:dlsym()返回符號的奇怪地址

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=0x8049e20dlsym()

我已經打印出strerror_r的地址,然後調用dlsym()。

strerror_r = 0xb76544e0是錯誤的地址,我用這個地址調用strerror_r只是什麼都不做。

+0

我想可能'strerror'實際上是在某處調用的,因此已經解決了,而'strerror_r'沒有被調用,'dlsym'給了你一個蹦牀函數的地址。嘗試調用它們(只是一次),看看是否有任何變化。 – Useless 2012-08-10 10:31:28

+0

很難說..也許餵它到'readelf'可以給一些提示 – 2012-08-10 10:46:21

+0

你可以看看調試器中的地址。我猜想其中一個除了跳轉到真正的功能外沒有其他任何東西。 – 2012-08-10 10:51:21

回答

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")

+0

感謝您的親切解釋。但爲什麼dlsym(rtldDefault,「strerror_r」); ==> strerror_r = 0xb76544e0 – 2012-08-10 11:10:27

+0

@DavidChyi:你什麼意思?爲什麼它比另一個更高的地址?或者爲什麼它不同於__xpg_strerror_r?它們不同,因爲它們是不同的功能,或者更確切地說,不同的_symbols_。這可能要高得多,因爲正如無用在他的評論中所說的那樣,這個功能從來沒有被調用過。 – rodrigo 2012-08-10 11:17:59