3

I have written a program (.DLL) which is to be injected into process.exe.

DLL injector code:

Bool InjectDll(DWORD pID, const char* dllPath) {
    Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (!Proc)
    {
        return false;
    }
    void* LoadLibAddr = (void*)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    void* RemoteString = (void*)VirtualAllocEx(Proc, NULL, strlen(dllPath), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(Proc, (LPVOID)RemoteString, dllPath, strlen(dllPath), NULL);
    HANDLE ret = CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, (LPVOID)RemoteString, CREATE_SUSPENDED, NULL);
    if (ret) {
        return true;
    }
}

DllMain() function of .DLL to be injected:

#include <Windows.h>

extern void vMain();

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )
{
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&vMain, 0, 0, 0);
        return true;
    }
    return false;
}

vMain:

void vMain() {
    CreateConsole();        
    std::cout << "vMain() has executed!\n";
}

The .DLL to be injected works fine when I compile it in visual studio, but when I compile in QT Creator, vMain() never gets executed. The injector, .DLL, and target process are all 32-bit. So I have tried to debug the target process by making the .DLL injector call CreateRemoteThread() with the CREATE_SUSPENDED flag, that way I can set a breakpoint on LoadLibraryA(), resume the thread, step through execution from the breakpoint, and view the return value. However, my breakpoint on LoadLibraryA() isn't being hit.

So I debugged the .DLL injector application to make sure that the remote thread was being created. I confirmed that it is by calling GetThreadID() on the return value of CreateRemoteThread(), outputting it, and viewing that thread in the threadlist of the target process:

ThreadList

Keep in mind the thread is still suspended. Upon further inspection, EIP points to the first instruction in _RtlUserThreadStart(). I set a breakpoint on this instruction. I then resume the suspended thread by calling ResumeThread() from my .DLL injector program. The breakpoint is not hit.

It is noteworthy that the target application does not have any anti-breakpoint mechanism, and breakpoints have worked fine for me apart from this instance.

So how can I figure out what the issue is? Is there a reason my breakpoints are not being hit? Is there a better way to debug the problem?

Invalidation
  • 367
  • 3
  • 7
  • Is `dllPath` a full path? If not then are you sure that it can be reached when run from Qt Creator? – Bogdan Jul 06 '17 at 14:03

1 Answers1

0

When doing console output from inside a DLL, you may need to redirect stdout to the console:

// AllocConsole() instead of CreateConsole()
AllocConsole();
freopen("CONOUT$", "w", stdout); // <====
std::cout << "vMain() has executed!\n";

Additionally, It's not a good idea to create threads inside DllMain() and here's why:

Related question:

I remember I've had some trouble with it in the past and I stopped doing such things as creating threads / windows inside DllMain(), as recommended.

Still, there are cases where it works, but I wouldn't trust it.

That being said, if the above doesn't work, try to call your vMain() directly without a thread and see what happens.

karliwson
  • 3,365
  • 1
  • 24
  • 46