-1

So I am injecting a DLL into a program. I can verify that the DLL is injected with help from Process Explorer. After the injection I am looping all modules from the process, comparing the names and return the injected dll as a HMODULE.

Then I GetProcAddress() this HMODULE to find a extern function inside of it, but for some reason this does not work properly.

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

When I breakpoint and check dllAddress it says:

enter image description here

When I use LoadLibrary to load the DLL in my current program and use that as a HMODULE, it does work.

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

Breakpointing to check dllAddress:

enter image description here

The returned HMODULE from the list of HMODULES is not the same as the HMODULE from LoadLibrary. Although the pointer address is the same.

Listing all the modules from the process is done with the code Microsoft provides. I altered it a bit to work with string comparison, but that does not effect the HMODULE type.

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;
}
user616396
  • 35
  • 8

2 Answers2

0

You can get the HMODULE of a DLL loaded within another process but you cannot use it from your process to get the address of a procedure of that HMODULE.

This is due to the fact that each process in Windows has its own memory space. Therefore the HMODULE value of the same DLL loaded in different processes is almost certainly different each time. So once you obtained the HMODULE of your DLL within another process and call GetProcAddress(..) with it, Windows looks within the memory of your application and not within that of the other process. Since the HMODULE is invalid in your application GetProcAddress(..) will fail.

If you want to call a functions within the context of another process you have to use some sort of interprocess communication. To do this you have to have a thread running within the other process to handle those IPCs (which I guess createThread should do).

To achieve this you can use the DllMain(..) function of your injected DLL to execute some code (e.g. call function 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);
}
Lukas Thomsen
  • 3,089
  • 2
  • 17
  • 23
  • Yeah, I tried that initially but it seems you can not create a thread from DllMain as it breaks down the program. Therefore I went looking for a method around it. – user616396 Jan 01 '15 at 20:03
  • You can create threads from within `DllMain` as stated by the MSDN (and done by me several times). The only difference is that the thread does not start immediately but after loading of the dll is done. Did you try a very simple thread for testing (e.g a while(1) with a MessageBox/MessageBeep every second)? – Lukas Thomsen Jan 01 '15 at 21:11
  • I tried a non ending while loop from DllMain, the program that got the DLL injected freezes until the while loop is escaped. I tried CreatThread() and that kills the program. Edit: DllMain runs while the loader lock is held. – user616396 Jan 01 '15 at 21:36
0

Got it working with help from:

RectangleEquals -> Answer

Community
  • 1
  • 1
user616396
  • 35
  • 8