2014-11-16 36 views
3

在我的C共享庫中,我想要dlopen()另一個共享庫並檢索此庫所導出符號的列表。如何以編程方式列出ELF共享庫符號

有沒有辦法以編程方式做到這一點,而無需運行nm/objdump?

作爲第二個問題:我如何檢索dlopen()後加載的第二個庫的基地址 - 不知道任何符號的名稱(所以我不能運行dlsym!),而不讀取/ proc /自/地圖?

我曾嘗試以下:

struct link_map *imagehandle = (struct link_map*)dlopen(libraryname, RTLD_LOCAL | RTLD_LAZY); 
void * fbase = (void*) imagehandle->l_addr; 
printf("base addr is %p",fbase) 

這將打印

「基地addr是0x6862696c」

然而,該庫沒有位於有:

[/ proc/pid/maps輸出:]

b6d27000-b6d28000 r-xp 00000000 1f:01 1581  mysecondlib.so 
b6d28000-b6d29000 r--p 00000000 1f:01 1581  mysecondlib.so 
b6d29000-b6d2a000 rw-p 00001000 1f:01 1581  mysecondlib.so 

有人建議l_addr不是實際的庫基址,而是可執行頭的偏移量 - 但我不確定如何找到該頭地址。

回答

2

是的,你絕對可以通過編程獲得符號表。我建議不要在SO上運行dlopen(),而是通過mmap自己打開它,甚至只是自己將文件讀入連續內存。一旦它在內存中,您可以通過以下文檔輕鬆遍歷SO的每個部分:http://linux.die.net/man/5/elf。 sh_type等於SHT_SYMTAB(符號表)的部分是您正在查找的部分。

如果你仍然需要找到一個加載的SO的基地址,我沒有找到一種方法從我的經驗中獲得它從dlopen()。我發現的最好方法是在SO中的已知符號上調用dladdr(),該函數填充包含dli_fbase成員的Dl_info結構,該成員是符號來自的模塊的基址。如果你確實不知道這個SO的任何符號,你可以使用dl_iterate_phdr(http://linux.die.net/man/3/dl_iterate_phdr),它將遍歷你的進程中所有加載的SO,併爲每個結構提供一個dl_phdr_info結構實例。該結構體包含名稱,基地址(dlpi_addr)和程序標題數組。

相關問題