【问题标题】:Injected DLL not correct HMODULE注入的 DLL 不正确 HMODULE
【发布时间】:2015-01-01 18:47:57
【问题描述】:

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

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

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");

断点检查 dllAddress:

HMODULES 列表中返回的 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;
}

【问题讨论】:

    标签: c++ module loadlibrary dll-injection


    【解决方案1】:

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

    这是因为 Windows 中的每个进程都有自己的内存空间。因此,在不同进程中加载​​的同一个 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);
    }
    

    【讨论】:

    • 是的,我最初尝试过,但您似乎无法从 DllMain 创建线程,因为它会破坏程序。因此,我开始寻找解决方法。
    • 您可以从 DllMain 中创建线程,如 MSDN 所述(我已多次完成)。唯一的区别是线程不会立即启动,而是在 dll 加载完成后启动。您是否尝试了一个非常简单的线程进行测试(例如,每秒使用 MessageBox/MessageBeep 一段时间(1))?
    • 我从 DllMain 尝试了一个非结束的 while 循环,注入 DLL 的程序冻结,直到 while 循环被转义。我尝试了 CreatThread() 并杀死了程序。编辑:DllMain 在加载程序锁被持有时运行。
    【解决方案2】:

    在以下方面的帮助下得到了它:

    RectangleEquals -> Answer

    【讨论】:

      猜你喜欢
      • 2013-11-24
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2018-05-19
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      相关资源
      最近更新 更多