2013-03-24 61 views
4

我想攔截應用程序對dlsym的調用,我已經嘗試在.so中聲明我正在預加載dlsym,並使用dlsym本身來獲取它的真實地址,但是由於相當明顯的原因,這種行爲並不起作用。如何攔截使用LD_PRELOAD的dlsym調用?

有沒有一種方法比採取進程的內存映射更容易,並且使用libelf來查找加載的libdl.so中dlsym的真實位置?

+0

是爲代碼問題的一部分還是答案?你可以編輯你的問題或張貼它作爲答案。 – ChrisF 2013-03-28 10:32:36

回答

0

http://www.linuxforu.com/2011/08/lets-hook-a-library-function/

從文本:

,一定要提防的函數,稱自己的dlsym(),當你需要調用__libc_dlsym(手柄,符號)的鉤。

extern void *__libc_dlsym (void *, const char *); 
void *dlsym(void *handle, const char *symbol) 
{ 
    printf("Ha Ha...dlsym() Hooked\n"); 
    void* result = __libc_dlsym(handle, symbol); /* now, this will call dlsym() library function */ 
    return result; 
} 
+0

這似乎是段錯誤,我甚至試圖單獨編譯這個代碼,結果相同 – user1588911 2013-03-24 14:03:07

3

我碰到了同樣的問題絆倒與hdante的答案,作爲評論者:調用__libc_dlsym()直接與段錯誤崩潰。閱讀一些glibc的來源後,我想出了下面的技巧作爲一種解決方法:

extern void *_dl_sym(void *, const char *, void *); 
extern void *dlsym(void *handle, const char *name) 
{ 
    /* my target binary is even asking for dlsym() via dlsym()... */ 
    if (!strcmp(name,"dlsym")) 
     return (void*)dlsym; 
    return _dl_sym(handle, name, dlsym); 
} 

注意兩件事情本「解決方案」:

  1. 該代碼繞過這是由(__libc_)dlsym()內部完成鎖定,所以爲了使這個線程安全,你應該添加一些鎖定。
  2. _dl_sym()的第三個參數是調用者的地址,glibc似乎通過堆棧展開來重建此值,但我只是使用函數本身的地址。在內部使用調用者地址來查找調用者所處的鏈接映射,以獲得像RTLD_NEXT這樣的東西(並且,使用NULL作爲thrid參數將使調用失敗,並使用RTLD_NEXT時發生錯誤)。然而,我沒有看過glibc的unwindind功能,所以我不能100%確定上面的代碼會做正確的事情,並且它可能恰好偶然發生。

解決方案到目前爲止存在一些重大缺點:在某些情況下,_dl_sym()與預期的dlsym()的行爲完全不同。例如,試圖解析不存在的符號會退出程序,而不是返回NULL。要解決這個問題,可以使用_dl_sym()剛剛得到的指針原來dlsym()和使用,對於其他一切(如在「標準」 LD_PRELOAD鉤計算策略不掛鉤dlsym在所有):

extern void *_dl_sym(void *, const char *, void *); 
extern void *dlsym(void *handle, const char *name) 
{ 
    static void * (*real_dlsym)(void *, const char *)=NULL; 
    if (real_dlsym == NULL) 
     real_dlsym=_dl_sym(RTLD_NEXT, "dlsym", dlsym); 
    /* my target binary is even asking for dlsym() via dlsym()... */ 
    if (!strcmp(name,"dlsym")) 
     return (void*)dlsym; 
    return real_dlsym(handle,name); 
} 
+0

你的'real_dlsym'有3個參數,但你只需要用'real_dlsym(handle,ptr)'調用它,其中'ptr'不是即使是一個變量。 – lama12345 2014-01-15 08:58:23

+0

@ lama12345:你說的沒錯。我更新了我的答案,以解決這些複製和粘貼錯誤。 – derhass 2014-01-15 09:59:28