2

我想加载与应用程序工作目录中不同版本的 DLL。为此,我需要挂钩 LoadLibrary 调用,以便在应用程序调用加载 DLL 时,我可以透明地用该 DLL 的较新版本替换它。我尝试使用 NCodeHook 并在我的 DLL 中有以下代码,我使用 NInjectLib 将其注入应用程序,但它在加载 kernel32.dll 时崩溃。任何人都可以告诉我这是注入呼叫的正确方式还是有其他选择。

        // 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
4

3 回答 3

4

我不知道 NCodeHook 库,但要知道的一件重要事情是 LoadLibrary 函数实际上有 2 个版本:LoadLibraryA(LPCSTR)LoadLibraryW(LPCWSTR). 确保挂钩正确的并使用适当的函数定义。您可能还需要挂钩 LoadLibraryExA/LoadLibraryExW

Detours是一个更广为人知的 API 挂钩库。另请参阅本文了解更多挂钩技术。

于 2009-11-05T16:58:00.697 回答
1

kernel32.dll在使用手写的 hooking/detours 库时,我遇到了类似的崩溃问题。我在MinHook 库的讨论页面中找到了对该问题的一个很好的解释:

据我了解,您的 detour 库没有考虑到它尝试挂钩的函数是使用短跳转操作码实现的(显然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;
}
于 2017-08-30T19:02:26.923 回答
-1

有很多与 API 挂钩相关的陷阱。我不知道 NCodeHook 实现的细节,但如果 API 挂钩代码不能正确处理不可写页面,则可能会出现问题。有人会假设库会调用VirtualProtect并且操作系统会正确处理写时复制,但这很难说。

我同意这可能不是解决您的问题的最佳方法的评论。API 挂钩依赖于应用程序二进制接口,它充其量是准文档化的。我不建议将它用于用于生产用途的商业应用程序。

并行程序集肯定会很有用,因为强名称消除了关于需要加载哪个 DLL 的任何歧义。或者,考虑使用LoadLibraryExDLL 和LOAD_WITH_ALTERED_SEARCH_PATH标志的绝对路径。

于 2009-12-10T05:34:34.037 回答