2

I'm pretty new to this stuff, so please excuse me if anything I ask is kinda stupid. I'm trying to inject a DLL into a QT application and call some of the QT functions. I got the injection working with notepad.exe or explorer.exe, but everything else I tried (Spotify, some QT apps, skype, ...) wont show my messagebox, although the injection intself doesn't throw any errors.

Here's the code of my injector program:

#include "stdafx.h"
#include "windows.h"
#include <iostream>

using namespace std;
char const path[] = "C:\\InjectedDll.dll";

void setDebugPrivilege()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES privileges;
    privileges.PrivilegeCount = 1;
    privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        std::cout << "Failed to open process." << std::endl;
    }
    if (!LookupPrivilegeValue(0, SE_DEBUG_NAME, &privileges.Privileges[0].Luid))
    {
        std::cout << "Failed to look up privileges." << std::endl;
    }
    if (!AdjustTokenPrivileges(hToken, false, &privileges, sizeof(privileges), 0, 0))
    {
        std::cout << "Failed to adjust token privileges." << std::endl;
    }
    CloseHandle(hToken);
}

int main(int argc, char* argv)
{
    setDebugPrivilege();

    HWND hWnd;
    hWnd = FindWindowA(0, "Spotify");
    if (!hWnd) {
        std::cout << "Could not find editor window." << std::endl;
    }

    DWORD pId;
    GetWindowThreadProcessId(hWnd, &pId);
    if (!pId) {
        std::cout << "Could not find process id." << std::endl;
    }

    HANDLE hProcess;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pId);
    if (!hProcess) {
        std::cout << "Failed to open process." << std::endl;
    }

    HANDLE allocatedAddress;
    allocatedAddress = VirtualAllocEx(hProcess, 0, sizeof(path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(hProcess, (void*)allocatedAddress, (void*)path, sizeof(path), 0);

    HANDLE hRemoteThread;
    hRemoteThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"), allocatedAddress, 0, 0);
    if (!hRemoteThread) {
        std::cout << "Failed to create remote thread: " << GetLastError() << std::endl;
    }

    WaitForSingleObject(hRemoteThread, INFINITE);
    VirtualFreeEx(hProcess, allocatedAddress, sizeof(path), MEM_DECOMMIT);
    CloseHandle(hProcess);

    system("Pause");

    return 0;
}

And here is my basic DLL.h:

#pragma once
#include "windows.h"

#ifdef INJECTEDDLL_EXPORTS
    #define INJECTED_DLL_API __declspec(dllexport)
#else
    #define INJECTED_DLL_API __declspec(dllimport)
#endif

INJECTED_DLL_API LRESULT CALLBACK newWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
INJECTED_DLL_API DWORD WINAPI creation();
INJECTED_DLL_API int WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved);

And DLL.cpp:

#include "injected_dll.h"

DWORD WINAPI creation()
{
    MessageBoxW(HWND_DESKTOP, L"Failed to subclass window.", L"Noez!", MB_OK);
    return TRUE;
}

int WINAPI DllMain(HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)creation, 0, 0, 0);
    }
    return true;
}

So can anyone tell me why this isn't working? I tried both, using MessageBoxA(..) and MessageBoxW(..) and just MessageBox(..), they all worked on notepad.exe, but none worked on the other programs.

  • try MessageBoxW with NULL hWnd. – krusty Apr 8 '16 at 10:19
  • Thanks, but that didn't help either. Also tried to change the LoadLibraryA call to LoadLibraryW and LoadLibrary, both didn't work and the last one made Spotify (which I used for testing) crash... – Joh Apr 8 '16 at 11:11
  • I'd recommend attaching a debugger to the target process prior to injection and configuring your debugger to pause on new thread creation. This will allow you to see if a new thread is actually getting created, and if so, will allow you to step through the thread's code and diagnose the problem. – Jason Geffner Apr 8 '16 at 13:52
  • 1
    Still no luck and both functions succeed...could this be something with 32bit/64bit? I'm compiling the DLL and the injector 64bit, so this should work even with 32bit applications, shouldn't it? EDIT: okay this was in fact the problem, sorry that this didn't come to my mind earlier, I thought 64bit > 32bit works, only the other way around doesn't. Now, lets say I want to support injection into both platforms, how would I do that? Is there no way around offering two seperate .exes and .dlls then? – Joh Apr 11 '16 at 21:21
  • 1
    @Joh A little late but no, you'd have to bundle two different DLLs and two different injectors. It is possible to inject a 64bit DLL into a WOW64ed 32bit process in a 64bit machine, but that's a lot of effort that generally isn't worth it. – NirIzr Jan 29 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.