2010-10-14 65 views
2

我試圖找到一種方法來知道哪個共享庫正在調用我的共享lib函數。情景就是這樣。確定哪些共享lib調用到我的共享中

我已經使用LD_PRELOAD來覆蓋malloc。在我的malloc裏面,我直接將調用轉發給真正的malloc,但是如果調用來自特定的共享庫,我希望在轉發該調用之前進行一些處理。

現在,我想要處理的malloc調用的共享庫在一種插件體系結構中被外部可執行文件加載和調用。我可以通過檢查全局程序_invocation_short_name變量來告訴哪個可執行文件稱爲我的malloc,但我不想處理來自提供插件體系結構的可執行文件的malloc調用,但僅處理來自插件共享庫的可執行文件。

我已經嘗試使用backtrace()和backtrace_symbols()來查看是否可以從後面的跟蹤中獲取插件庫名稱或其中的一部分,但沒有運氣。我從來沒有在那裏得到名字。

有人可以建議如何做到這一點嗎?

Regards,

Alex。

編輯:我忘了提。這是在Linux上。我的糟糕之處在於,我認爲LD_PRELOAD會將其告知。

+0

+1有趣。 – karlphillip 2010-10-14 16:24:34

+0

在什麼平臺上? – ruslik 2010-10-14 16:25:06

回答

0

在Windows上,您可以使用特殊的API(例如CreateToolhelp32Snapshot(),Module32First())來獲取您的進程中加載​​的所有共享庫的列表。

每個這樣的庫將駐留在結構MODULEENTRY32modBaseAddrmodBaseSizemodBaseSize成員指定的存儲器範圍內。

通過檢查調用者的返回地址(可以用一些簡單的內聯彙編完成),您可以將它與那裏的範圍進行比較,這將確切地標識調用者。

+0

我正在尋找使用相同的方法,但在Linux上,但目前爲止找不到同樣的系統調用運氣。有任何想法嗎? – Alex 2010-10-18 05:55:41

1

有沒有簡單的方法來做到這一點,但這種方法可能適合您的需求。

我已經編碼了3個小應用程序,所以你可以按照我的指示。它們是:

  • app:將在您的系統上運行的二進制文件。調用從libmiddleman.so一個函數,它試圖通過的malloc分配一些存儲器()

源代碼:gcc app.c -o app -L. -lmiddle_man

//File: app.c 
#include "libmiddle_man.h"  
#include <stdio.h> 

int main() 
{ 
    do_something(); 

    return 0; 
} 
  • libmiddle_man。所以:出口,簡單地調用一個函數malloc()

源代碼:gcc libmiddle_man.c -o libmiddle_man.so -shared

//File: libmiddle_man.c 
void do_something() 
{ 
    int* tmp = malloc(sizeof(int)); 
} 

也:

//File: libmiddle_man.h 
void do_something(); 
  • libfake_malloc.so:農具和出口我們的malloc()版本在終端上打印了一些東西

源代碼:gcc lbfake_malloc.c -o libfake_malloc.so -shared

//File: libfake_malloc.c 
#include <stdio.h> 
#include <unistd.h> 

void* malloc(size_t size) 
{ 
    printf("fake malloc()\n"); 

    printf("Process ID: %d\n", getpid()); 

    while(1) 
    { 
    } 

    return NULL; 
} 

當你與LD_PRELOAD=libfake_malloc.so ./app執行應用程序,將輸出以下內容:

fake malloc() 
Process ID: 14230 (the PID will be different each time you run the application) 

和應用程序,因爲我們需要它,這樣會掛在那裏。我們將檢查進程內存映射,並確保應用程序都加載了我們的兩個庫。

因此,現在就離開它並打開另一個終端。當您在進程列表中搜索此PID時,它將顯示哪個應用程序正在使用libfake_malloc.so。這不是我們的目標,但它是一個有趣的信息。

ps -aux | grep 14230 

輸出:

karl  14230 97.3 0.0 1648 396 pts/9 R+ 13:57 10:20 ./app 

記住更改爲14230號的任何應用程序返回到您。接下來,我們將檢查進程內存並驗證是否加載了兩個out庫。

cat /proc/14230/maps 

顯示:

00110000-00263000 r-xp 00000000 08:06 2158492 /lib/tls/i686/cmov/libc-2.11.1.so 
00263000-00264000 ---p 00153000 08:06 2158492 /lib/tls/i686/cmov/libc-2.11.1.so 
00264000-00266000 r--p 00153000 08:06 2158492 /lib/tls/i686/cmov/libc-2.11.1.so 
00266000-00267000 rw-p 00155000 08:06 2158492 /lib/tls/i686/cmov/libc-2.11.1.so 
00267000-0026a000 rw-p 00000000 00:00 0 
00584000-00585000 r-xp 00000000 08:07 2921104 /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so 
00585000-00586000 r--p 00000000 08:07 2921104 /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so 
00586000-00587000 rw-p 00001000 08:07 2921104 /home/karl/workspace/shared_libs/who_called_my_shared/libmiddle_man.so 
00605000-00606000 r-xp 00000000 08:07 2921103 /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so 
00606000-00607000 r--p 00000000 08:07 2921103 /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so 
00607000-00608000 rw-p 00001000 08:07 2921103 /home/karl/workspace/shared_libs/who_called_my_shared/libfake_malloc.so 
007e6000-007e7000 r-xp 00000000 00:00 0   [vdso] 
0096a000-00985000 r-xp 00000000 08:06 2142529 /lib/ld-2.11.1.so 
00985000-00986000 r--p 0001a000 08:06 2142529 /lib/ld-2.11.1.so 
00986000-00987000 rw-p 0001b000 08:06 2142529 /lib/ld-2.11.1.so 
08048000-08049000 r-xp 00000000 08:07 2921106 /home/karl/workspace/shared_libs/who_called_my_shared/app 
08049000-0804a000 r--p 00000000 08:07 2921106 /home/karl/workspace/shared_libs/who_called_my_shared/app 
0804a000-0804b000 rw-p 00001000 08:07 2921106 /home/karl/workspace/shared_libs/who_called_my_shared/app 
b77b0000-b77b2000 rw-p 00000000 00:00 0 
b77c9000-b77cc000 rw-p 00000000 00:00 0 
bfb69000-bfb7e000 rw-p 00000000 00:00 0   [stack] 

你會發現,對於libfake_malloc.so該inode ,並加載它的庫(即libmiddle_man.so)的索引節點實際上是2921103 + 1 ,這是。

我有機會在幾臺機器和一些運行Linux的嵌入式設備上進行測試。總而言之,似乎有可能通過分析/proc/pid/maps上可用的信息來發現哪個庫已經加載了你的庫。