2009-11-05 2 views
1

Я хочу загрузить другую версию DLL, чем присутствует в рабочем каталоге приложения. Для этого мне нужно подключить вызов LoadLibrary, чтобы при приеме приложения для загрузки DLL я мог прозрачно заменить его более новой версией этой DLL. Я пробовал использовать NCodeHook и иметь следующий код в своей DLL, который я ввожу в приложение с помощью NInjectLib, но он падает при загрузке kernel32.dll. Может кто-нибудь, пожалуйста, скажите мне, является ли это правильным способом инъекции вызова или есть другие альтернативы.Hooking LoadLibrary API call

 // 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-ад по-прежнему существует (когда-либо слышал о SideBySide Manager?), Но я уверен, что с таким вызовом у вас будет еще хуже. –

+0

Для рабочего примера см. Http://newgre.net/ninjectlib – newgre

+0

http://stackoverflow.com/questions/15381506/stop-or-detection-dll-injection-loadlibrary – user1159258

ответ

3

я не знаю библиотеку NCodeHook, но одна важная вещь, чтобы знать, что есть на самом деле 2 версии LoadLibrary функции: LoadLibraryA(LPCSTR) и LoadLibraryW(LPCWSTR). Удостоверьтесь, что вы зацепили правильный номер и используете соответствующее определение функции. Вам также может потребоваться зацепить LoadLibraryExA/LoadLibraryExW

Detours - это более широко известная библиотека для подключения API. Также см. this article для получения дополнительных методов подключения.

-1

Существует множество подводных камней, связанных с подключением API. Я не знаю специфики реализации NCodeHook, но есть вероятность проблем, если код подключения API неправильно обрабатывает страницы, недоступные для записи. Можно было бы предположить, что библиотека вызовет VirtualProtect и что ОС будет правильно обрабатывать copy-on-write, но это трудно сказать.

Я согласен с комментарием, что это может быть не лучшее решение вашей проблемы. Зацепка API основана на двоичном интерфейсе приложения, который в лучшем случае квазидокументирован. Я бы не рекомендовал его для коммерческого приложения, предназначенного для использования в производстве.

Бок о бок сборок определенно был бы полезен, так как сильное имя устраняет любые двусмысленности, относительно которых должна быть загружена DLL. В качестве альтернативы рассмотрим использование LoadLibraryEx с абсолютным путем к DLL и флагом LOAD_WITH_ALTERED_SEARCH_PATH.

0

У меня были аналогичные проблемы с сбоями в kernel32.dll при использовании рукописной библиотеки hooking/detours. Я нашел хорошее объяснение проблемы в discussion pages в MinHook library:

Насколько я понимаю, ваша библиотека объезда не учитывает возможность того, что функция пытается зацепить реализуются с использованием короткого прыжком опкода (по-видимому, 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; 
}