2017-10-21 62 views
1

我試圖檢查一個程序的行爲,該程序調用dlopendlsym:最終目標是設置一個微調函數,用於記錄調用通過dlsym獲得的函數。在macOS上,我如何攔截對dlsym的調用?

通常情況下,要與DYLD_INSERT_LIBRARIES包裝一些功能foo,你寫的東西是這樣的:

void (*real_foo)(void); 

void init() __attribute__((constructor)) { 
    real_foo = dlsym(RTLD_NEXT, "foo"); 
} 

void foo(void) { 
    puts("foo was called"); 
    real_foo(); 
} 

的問題是,當你試圖總結dlsym,你結束了這一點:

void* (*real_dlsym)(void* handle, const char* symbol); 

void init() __attribute__((constructor)) { 
    real_dlsym = dlsym(RTLD_NEXT, "dlsym"); 
} 

void* dlsym(void* handle, const char* symbol) { 
    return real_dlsym(handle, symbol); 
} 

init結束調用自己實現dlsym,這是沒有幫助的。

當我出口不同的產品時,如何獲得「真正的」dlsym?還是有更好的方法來攔截對dlsym的調用?

回答

0

至少在10.12系統上,dlsym實際上是在/usr/lib/system/libdyld.dylib中實現的。它應該工作到dlopen()該文件,然後用返回的句柄調用dlsym()以獲得實際的dlsym()實現。您可能需要額外的mode標誌爲dlopen(),如RTLD_FIRST和/或RTLD_LOCAL。 Sorta像:

void *libdyld_handle = dlopen("/usr/lib/system/libdyld.dylib", RTLD_LAZY); 
    void *dlsym_funcptr = dlsym(libdyld_handle, "dlsym"); 
+0

我不能使用dlsym,因爲它會調用我自己的「實現」它。我不能稱之爲其他任何東西,否則它不會取代真正的dlsym。 – zneak