2009-10-29 9 views
7

na Windows, kilka argumenty są przekazywane do konstruktora DllMain:Linux: Jak uzyskać pełną nazwę obiektu współdzielonego, który został załadowany z konstruktora?

BOOL WINAPI DllMain( 
    __in HINSTANCE hinstDLL, 
    __in DWORD fdwReason, 
    __in LPVOID lpvReserved 
); 

Od hinstDLL mogę uzyskać pełną nazwę pliku samego DLL przy użyciu GetModuleFileName():

LPTSTR str = new TCHAR[256]; 
int libNameLength = GetModuleFileName(hinstDLL, str, 256); 
delete[] str; 

W przykładzie powyżej, str zawiera teraz pełną nazwę załadowanej biblioteki DLL, np. C: \ Windows \ System32 \ MyFile.dll.

na Linuksie, żadne argumenty są przekazywane do konstruktora obiektu dzielonego:

void `__attribute__` ((constructor)) on_load(void); 

Jak mogę uzyskać pełną nazwę pliku DLL w tym przypadku? Dodatkowy kredyt, jeśli twoje rozwiązanie działa również na Macu. :-)

+0

Nie wiem, czy jest dobra droga. Moje pytanie w takich sytuacjach brzmi "Dlaczego chcesz to wiedzieć?". Odzyskując poziom, możesz znaleźć ścieżkę do prawdziwego celu, nie robiąc kroku, który aktualnie Cię blokuje. – Omnifarious

+0

Dobre pytanie. Chcę wiedzieć, ponieważ opracowuję moduł CSP i moduł PKCS # 11 (pliki DLL), które muszą zweryfikować swoją integralność po wczytaniu. Oba pliki DLL są ładowane przez system operacyjny, więc moim punktem wejścia jest konstruktor. Obecnie najlepszym pomysłem na weryfikację integralności pliku DLL jest obliczenie skrótu pliku DLL w konstruktorze, a następnie wysłanie tego skrótu do centralnego serwera, który może zweryfikować poprawność hasza. Jednak potrzebuję nazwy pliku DLL, aby móc obliczyć hash. –

Odpowiedz

3

Myślę, że funkcja dladdr może zrobić, co chcesz. Ze strony podręcznika:

Funkcja dladdr() przyjmuje wskaźnik funkcji i próbuje rozpoznać nazwę i plik , gdzie się znajduje. Informacje te są przechowywane w strukturze Dl_info:

typedef struct { 
    const char *dli_fname; /* Pathname of shared object that 
           contains address */ 
    void  *dli_fbase; /* Address at which shared object 
           is loaded */ 
    const char *dli_sname; /* Name of nearest symbol with address 
           lower than addr */ 
    void  *dli_saddr; /* Exact address of symbol named 
           in dli_sname */ 
} Dl_info; 

Jeśli nie można odnaleźć symbol dopasowania adr, następnie dli_sname i dli_saddr są ustawione na NULL.

dladdr() zwraca 0 w przypadku błędu i niezerową w przypadku powodzenia.

Po prostu podajesz wskaźnik funkcji (jak adres samego konstruktora), a otrzymasz nazwę pliku i kilka innych informacji. Oto niektóre przykładowy kod:

#define _GNU_SOURCE 
#include <dlfcn.h> 
#include <stdio.h> 

__attribute__((constructor)) 
void on_load(void) { 
    Dl_info dl_info; 
    dladdr(on_load, &dl_info); 
    fprintf(stderr, "module %s loaded\n", dl_info.dli_fname); 
} 

EDIT: Wygląda na to funkcja istnieje na OS X, też, z tych samych semantyki.

+0

Doskonała odpowiedź, dziękuję bardzo! –

+0

Tak, jestem tak szczęśliwy, że sposób, w jaki obaj myśleliśmy, nie jest właściwą odpowiedzią. :-) – Omnifarious

+0

Ta metoda nie działa na Androidzie: 'dli_fname' zawiera tylko nazwę pliku, a nie pełną ścieżkę. – 18446744073709551615

1

Jednym z wyjątkowo brzydkich i strasznych sposobów na to jest przeglądanie/proc/pid/map i szukanie mapowania, które obejmuje adres wykonywanej funkcji on_load.

+1

Zacząłem iść wczoraj tą drogą, a ja nie odrzuciłem tego * całkowicie *, ponieważ jest to obecnie jedyne możliwe rozwiązanie, które znam. Wysyła też dreszcze na mój kręgosłup. –

Powiązane problemy