dlsym
dlsym,dlvsym - 從一個動態鏈接庫或者可執行文件中獲取到符號地址。
用法
#include <dlfcn.h>
void *dlsym(void *handle, const char *symbol);
#define _GNU_SOURCE
#include <dlfcn.h>
void *dlvsym(void *handle, char *symbol, char *version);
Link with -ldl.
詳解
函數dlsym()的第一個參數是一個指向已經加載的動態目標的句柄,這個句柄可以是dlopen()函數返回的。
其中symbol參數是一個以null結尾的符號名。
返回值是這個符號加載到內存中的地址。如果這個符號 在指定的目標 或者 在由dlopen(3)裝載指定的目標時自動裝載的其他共享目標中都沒有找到,dlsym()返回NULL指針。(dlsym在這些動態目標中執行廣度優先搜索)。
由於符號的值本身可能實際就是NULL,因此,返回的NULL不能直接用來判斷是否出錯!所以,必須通過dlerror(3)函數以清理掉之前的錯誤狀態,然後調用dlsym(),最後調用dlerror(3),然後將其返回值保存到一個變量,最後檢查是否這個保存的變量值不爲NULL。
handle參數可能使用如下的兩種特殊的僞句柄:
- RTLD_DEFAULT
- 使用默認的共享目標搜索順序來找到要找的符號第一次出現的地方。這個搜索範圍包含可執行文件中的全局符號以及這個可執行文件的依賴項(也就是使用RTLD_GLOBAL標誌動態加載的共享目標)
- RTLD_NEXT
- 在當前搜索順序中找,在當前的目標之後,要找的符號下一次出現的地方。 這就允許向在另一個共享目標中的函數提供一層封裝。這樣一來,在一個預先加載的共享目標中定義的函數中,就可以找到並調用在另一個共享目標中的真函數(其實就是一種劫持呢!!!!)。或者有多層的預加載的時候的下一層!
返回值
成功時,這些函數返回跟symbol關聯的地址。失敗時,返回NULL;錯誤原因可以通過dlerror(3)來判斷。