Question

I am trying to inject a DLL into an existing process using CreateRemoteThread. The problem is that when the application is started from within Visual Studio 2010 it simply doesn't work.

The DLL Injection works:

  1. When starting it manually (from explorer)

  2. When starting it manually AND attaching the VS 2010 debugger before the injection.

When I select: Start Debugging (F5) in Visual Studio 2010, CreateRemoteThread returns OK. I even placed a breakpoint on LoadLibraryA in the injected process, and it gets hit. So the thread starts, but it doesn't reach the DllMain function. The LoadLibraryA gets executed, but but the module won't get loaded.

The injection code:

void InjectDll(DWORD processId, string dllFile)
{
    HANDLE hProcess = OpenProcess(CREATE_THREAD_ACCESS, FALSE, processId);
    if ( hProcess != NULL )
    {
        int lenWrite = dllFile.length();
        LPVOID allocMem = (LPVOID)VirtualAllocEx(hProcess, NULL, lenWrite, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
        WriteProcessMemory(hProcess, allocMem , dllFile.c_str(), lenWrite, NULL);
        LPTHREAD_START_ROUTINE injector = (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); 

        if(!injector)
            return;
        DWORD threadId;
        HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, injector, allocMem, 0, &threadId);

        DWORD Result = WaitForSingleObject(hThread, 10*1000); //Time out : 10 secondes
        VirtualFreeEx(hProcess, allocMem, lenWrite, MEM_RELEASE);
        CloseHandle(hProcess);
        CloseHandle(hThread);
    }
}

And the DllMain code:

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            HelloWorldMessageBox();
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

Thanks for help!

Edit:

I've used ollyDbg to place a breakpoint on the LoadLibraryA. I've replaced the assembly instruction "ret" to a call to GetLastError, and I got the following value in EAX register: 126. From MSDN System Error Code 126 means ERROR_MOD_NOT_FOUND (The specified module could not be found.). It's very strange that it only happens when Visual Studio runs the injection-app.

Was it helpful?

Solution

Finally I have found the problem!

To get the full module path I used

GetFullPathName("Inj_DLL.dll", MAX_PATH, dll_path, NULL);

which uses the current working directory to determine the file path.

When I start the app manually the working directory is the path of the exe file, but when It's started from Visual Studio it uses the Working Directory from Project Properties->Configuration Properties->Debugging.

Since it was set to "$(ProjectDir)" by default, and the injected dll was in the Debug/Release dir, the dll file couldn't be found, so error 126 ERROR_MOD_NOT_FOUND.

I have changed this property to "$(SolutionDir)$(Configuration)\" and everything works like a charm now.

Thanks anyone who tried to help me with this question, I have discovered some new approaches to debug a non-working application.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top