2009-11-05 203 views
1

我想加載與應用程序的工作目錄中存在的不同版本的DLL。爲此,我需要掛鉤LoadLibrary調用,以便在應用程序調用以加載DLL時,我可以透明地將其替換爲該DLL的較新版本。我嘗試使用NCodeHook,並在我的DLL中使用NInjectLib注入到應用程序中,但在加載kernel32.dll時崩潰。任何人都可以告訴我,這是否是注入電話的正確方式,或者是否有其他選擇。掛鉤LoadLibrary API調用

 // CodeHook.cpp : Defines the entry point for the DLL application. 
// 

#include "stdafx.h" 
#include <NCodeHookInstantiation.h> 
#include "CodeHook.h" 

#ifdef _MANAGED 
#pragma managed(push, off) 
#endif 

typedef HMODULE (WINAPI *LoadLibraryFPtr)(LPCTSTR dllName); 

#pragma data_seg("SHARED") 
LoadLibraryFPtr origFunc = NULL; 
#pragma data_seg()   

#pragma comment(linker, "/section:SHARED,RWS") 


HMODULE WINAPI LoadLibraryHook(LPCTSTR dllName) 
    { 
    if (origFunc != NULL) 
    { 
    return origFunc(dllName); 
    } 
    } 



BOOL APIENTRY DllMain(HMODULE hModule, 
         DWORD ul_reason_for_call, 
         LPVOID lpReserved 
    ) 
{ 
    return TRUE; 
} 

CODEHOOK_API void Initialize (void) 
{ 
NCodeHookIA32 nch; 
origFunc = nch.createHookByName("kernel32.dll", "LoadLibrary", LoadLibraryHook); 
} 

#ifdef _MANAGED 
#pragma managed(pop) 
#endif 
+0

我會強烈建議,以避免這樣的做法。 DLL-Hell仍然存在(曾經聽說過SideBySide Manager?),但我敢打賭,你會通過這樣的電話讓事情變得更糟。 – 2009-11-05 19:29:22

+0

有關工作示例,請參閱http://newgre.net/ninjectlib – newgre 2010-03-12 22:35:37

+0

http://stackoverflow.com/questions/15381506/stop-or-detection-dll-injection-loadlibrary – user1159258 2013-03-13 09:38:43

回答

3

我不知道NCodeHook庫,但一個重要的是要知道的是,其實有2個版本LoadLibrary函數的:LoadLibraryA(LPCSTR)LoadLibraryW(LPCWSTR)。確保鉤住正確的並使用適當的功能定義。您可能還需要掛鉤LoadLibraryExA/LoadLibraryExW

Detours是一個更廣泛已知的API掛鉤庫。另請參閱this article瞭解更多掛鉤技巧。

-1

有很多與API掛鉤有關的陷阱。我不知道有關NCodeHook實現的細節,但如果API掛鉤代碼沒有正確處理不可寫頁面,則可能會出現問題。人們會認爲圖書館會撥打VirtualProtect,操作系統會正確處理寫入時複製,但很難說。

我同意評論這可能不是您的問題的最佳解決方案。 API掛鉤依賴於應用程序二進制接口,該接口充其量是準文檔。我不會推薦它用於供生產使用的商業應用程序。

並行程序集肯定會有用,因爲強名稱可以消除有關哪個DLL需要加載的任何歧義。或者,考慮使用LoadLibraryEx以及DLL的絕對路徑和LOAD_WITH_ALTERED_SEARCH_PATH標誌。

0

使用手寫掛鉤/繞行庫時,我在kernel32.dll中遇到類似的崩潰問題。我發現這個問題的一個很好的解釋中的MinHook librarydiscussion pages

據我所知,你的彎路庫沒有考慮,它試圖鉤的功能是使用短跳轉碼實現的可能性(顯然LoadLibrary(Ex)W就是這樣實現的)。這將導致不同的字節在掛接期間需要被替換。

使用MinHook我的LoadLibrary和朋友掛鉤工作對我來說:

HMODULE WINAPI LoadLibraryA_replacement(_In_ LPCTSTR lpFileName) 
{ 
    // do your stuff 
    return loadLibraryA_original(lpFileName); 
} 

bool installLoadLibraryHook() 
{ 
    // Initialize MinHook. 
    if (MH_Initialize() != MH_OK) 
    return false; 

    if (MH_CreateHook(&LoadLibraryA, &LoadLibraryA_replacement, 
     reinterpret_cast<LPVOID*>(&loadLibraryA_original)) != MH_OK) 
    return false; 

    if (MH_EnableHook(&LoadLibraryA) != MH_OK) 
    return false; 

    // same for LoadLibraryW, LoadLibraryExW, LoadLibraryExA 

    return true; 
}