2015-01-01 131 views
-1

所以我正在注入一個DLL到程序中。我可以通過Process Explorer的幫助來驗證DLL是否被注入。注入後,我正在循環進程中的所有模塊,比較名稱並將注入的dll作爲HMODULE返回。注入DLL不正確HMODULE

然後我GetProcAddress()這個HMODULE在裏面找到一個extern函數,但是由於某些原因這個工作不正常。

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

當我斷點和檢查dllAddress它說:

enter image description here

當我使用LoadLibrary來加載DLL在我現有的程序和使用,作爲一個HMODULE,它的工作。

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

設置斷點檢查dllAddress:

enter image description here

從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; 
} 

回答

0

你可以得到另一個進程中加載​​的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); 
} 
+0

是的,我最初嘗試過,但似乎你不能從DllMain創建一個線程,因爲它打破了程序。所以我去尋找一種方法。 – user616396

+0

您可以按照MSDN的規定(由我多次完成)在'DllMain'內創建線程。唯一的區別是線程不會立即啓動,而是在完成dll的加載之後。您是否嘗試過一個非常簡單的線程進行測試(例如每秒鐘用MessageBox/MessageBeep進行一次(1))? –

+0

我試過從DllMain的一個不結束的while循環,注入DLL的程序凍結直到while循環被轉義。我嘗試了CreatThread()並殺死了程序。 編輯:DllMain在裝載機鎖持有時運行。 – user616396