注入的 DLL 不正确 HMODULE

Injected DLL not correct HMODULE

所以我正在将一个 DLL 注入到一个程序中。我可以在 Process Explorer 的帮助下验证 DLL 是否已注入。注入后,我从进程中循环所有模块,比较名称和 return 注入的 dll 作为 HMODULE。

然后我使用 GetProcAddress() 这个 HMODULE 来在它里面找到一个外部函数,但是由于某些原因这不能正常工作。

HMODULE dllAddress = getModuleAddressFromProc(pid, "NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");

当我断点并检查 dllAddress 时,它说:

当我使用 LoadLibrary 在当前程序中加载 DLL 并将其用作 HMODULE 时,它确实有效。

HMODULE dllAddress = LoadLibrary(L"C:\NewDll.dll");
externCreateThread createThread = (externCreateThread)GetProcAddress(dllAddress, "createThread");

检查 dll 地址的断点:

HMODULES 列表中的 returned HMODULE 与 LoadLibrary 中的 HMODULE 不同。虽然指针地址是一样的

列出进程中的所有模块是使用 Microsoft 提供的代码完成的。我对其进行了一些改动以用于字符串比较,但这不会影响 HMODULE 类型。

HMODULE getModuleAddressFromProc(DWORD pid, string moduleName) {
    HMODULE hMods[1024];
    DWORD cbNeeded;
    HMODULE output;
    unsigned int i;
    HANDLE newHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
    if (EnumProcessModules(newHandle, hMods, sizeof(hMods), &cbNeeded)) {
        for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
            TCHAR szModName[MAX_PATH];
            if (GetModuleFileNameEx(newHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
                string s2 = charToString(szModName);
                if (s2.find(moduleName) != string::npos) {
                    output = hMods[i];
                    break;
                }
            }
        }
    }
    return output;
}

您可以获取另一个进程中加载​​的 DLL 的 HMODULE,但您不能从您的进程中使用它来获取该 HMODULE 的过程的地址。

这是因为 Windows 中的每个进程都有自己的内存 space。因此,在不同进程中加载​​的同一个 DLL 的 HMODULE 值几乎肯定每次都不同。因此,一旦您在另一个进程中获得 DLL 的 HMODULE 并使用它调用 GetProcAddress(..),Windows 就会在您的应用程序的内存中查找,而不是在其他进程的内存中查找。由于 HMODULE 在您的应用程序中无效 GetProcAddress(..) 将失败。

如果你想在另一个进程的上下文中调用函数,你必须使用某种 interprocess communication。为此,您必须在另一个进程中有一个线程 运行 来处理这些 IPC(我想 createThread 应该这样做)。

为此,您可以使用注入的 DLL 的 DllMain(..) 函数来执行一些代码(例如调用函数 createThread(..)):

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module
                    DWORD fdwReason,     // reason for calling function
                    LPVOID lpReserved )  // reserved
{

   switch( fdwReason ) 
   { 
      case DLL_PROCESS_ATTACH:
         createThread(..);
         break;

      case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
         break;

      case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
         break;

      case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
         break;
   }

   return (TRUE);
}

在以下人员的帮助下成功运行:

RectangleEquals -> Answer