2015-04-29 70 views
2

給出一個動態鏈接的ELF二進制文件,比如說/bin/lessLinux ELF文件:如何獲取屬於導入函數的共享對象

二進制內部,存在要由共享庫提供的函數的調用,例如strcpy()

如何可以找出從共享庫/共享對象獲得strcp功能? 換句話說,我想獲得func_name/shared_obj_name.so對。

接聽this post,邁克爾·斯萊德說:

ELF文件沒有指定哪些符號來自哪個庫;它 只是添加一個共享庫列表鏈接到ELF二進制文件,並允許鏈接程序找到庫中的符號。

然而,必須有一種方法來收集所需的信息(使用鏈接器)。執行二進制和追蹤它在我的情況下不是一個選項。我試過到目前爲止:

我試圖objdump -T /bin/less | grep strcpy這給了我:

0000000000000000  DF *UND* 0000000000000000 GLIBC_2.2.5 strcpy 
0000000000000000  DF *UND* 0000000000000000 GLIBC_2.3.4 __strcpy_chk 

這既不是unambigious也沒有給我一個.so文件的名稱。

運行ldd /bin/less,返回:

linux-vdso.so.1 => (0x00007ffe8b7fa000) 
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f92c23a5000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f92c1fe0000) 
/lib64/ld-linux-x86-64.so.2 (0x00007f92c25ec000)) 

讓我覺得 「GLIBC_2.2.5」 對應libc.so.6

我如何以編程方式找到相應的共享對象(.so文件)到(導入)功能?

回答

2

如何從共享庫/共享對象中找到strcp函數?

一般而言,您不能:該庫可以在運行時更改。例如,如果我編譯以下來源:

int strcpy(char *a, const char *src) { abort(); } 

$ gcc -fPIC -shared -o foo.so foo.c 

,然後運行您的程序,像這樣:

LD_PRELOAD=./foo.so /bin/less 

然後從中獲取strcpy庫是foo.so。使用LD_PRELOAD這種方式稱爲庫間插,在各種circumstances中有用。

還有其他方法可以將注入除了LD_PRELOAD之外還有一個不同的庫。

如果你是而不是使用任何這樣的機制,並且正在使用GLIBC,那麼你可以要求動態加載器爲你回答這個問題。這裏有一種方法:

LD_DEBUG=bindings ldd -r /bin/less < /dev/null |& egrep '\Wstrcpy\W' 
    26623: binding file /bin/bash [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 
    26633: binding file /lib/x86_64-linux-gnu/libtinfo.so.5 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 
    26633: binding file /bin/less [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `strcpy' [GLIBC_2.2.5] 

上面可以看到,ldd調用bashless作爲獨立的進程,兩者的結合libc.so.6這個特殊符號。

相關問題