Инъекция Qt dll в процесс

Задача вставить dll, которая содержит QtApp в сторонний процесс. Есть метод который делает инжект dll в процесс, метод работает без ошибок, все функции отрабатывают корректно, и сам метод завершается true. Однако после вставки от самой dll нет никаких признаков и сигналов (хотя должно показаться окно). Вот метод, который делает инъекцию:

 bool WINAPI  InjectDll(__in LPCWSTR lpcwszDll, __in LPCWSTR targetPath) {

        SIZE_T nLength;
        LPTHREAD_START_ROUTINE lpLoadLibraryA = NULL;
        LPVOID lpRemoteString;
        PROCESS_INFORMATION processInformation;

        DWORD pid = (DWORD)_wtoi(lpcwszDll);
        processInformation.hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
        if (!processInformation.hProcess)
        {
            PrintError(LPTSTR("OpenedProcess"));
            return FALSE;
        }

        lpLoadLibraryA = (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"KERNEL32.DLL"), "LoadLibraryA");
        if (!lpLoadLibraryA)
        {
            PrintError(LPTSTR("GetProcAddress"));
          
            CloseHandle(processInformation.hProcess);
            return FALSE;
        }

        nLength = wcslen(targetPath) * sizeof(WCHAR);

        lpRemoteString = (LPVOID)VirtualAllocEx(processInformation.hProcess, NULL, nLength + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if (!lpRemoteString)
        {
            PrintError(LPTSTR("VirtualAllocEx"));

            CloseHandle(processInformation.hProcess);

            return FALSE;
        }

        if (!WriteProcessMemory(processInformation.hProcess, lpRemoteString, (LPVOID)targetPath, nLength + 1, NULL)) {

            PrintError(LPTSTR("WriteProcessMemory"));
            
            VirtualFreeEx(processInformation.hProcess, lpRemoteString, 0, MEM_RELEASE);

            CloseHandle(processInformation.hProcess);

            return FALSE;
        }

        HANDLE hThread = CreateRemoteThread(processInformation.hProcess, NULL, 0, lpLoadLibraryA, lpRemoteString, NULL, NULL);

        if (!hThread)
        {
            PrintError(LPTSTR("CreateRemoteThread"));
            VirtualFreeEx(processInformation.hProcess, lpRemoteString, 0, MEM_RELEASE);
            CloseHandle(processInformation.hProcess);
            return FALSE;
        }

        WaitForSingleObject(hThread, INFINITE);

        CloseHandle(processInformation.hProcess);

        return TRUE;
    }

А вот собственно DllMain (смысл в том, чтобы создать поток, а внутри потока создается QtApp и выполняется какой то рабочий код, для теста сейчас просто показывается окно):

class Worker : public QObject
{
    Q_INVOKABLE void CreateInjectedApp()
    {
        MessageBox(NULL, (LPCWSTR)L"Hello, I'm Worker.", (LPCWSTR)L"Worker launched", MB_OK);
    }
private:
    void Connect()
    {
        QMetaObject::invokeMethod(this, "CreateInjectedApp", Qt::QueuedConnection);
    }

public:
    Worker()
    {
        Connect();
    }
};

class AppThread : public QThread
{
    QPointer<QCoreApplication> m_app;
    void run() override
    {
        int argc;
        char* argv;
        QCoreApplication app(argc, &argv);
        m_app = &app;
        Worker worker;
        app.exec();
    }
public:
    AppThread() {}
    ~AppThread()
    {
        m_app->quit();
        wait();
    }
};

extern "C"
{

_declspec(dllexport) BOOL __stdcall DllMain(HINSTANCE hDllHandle, DWORD reason, LPVOID)
{
    static AppThread* thread;
    switch (reason) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hDllHandle);
        thread = new AppThread;
        thread->start();
        break;
    case DLL_PROCESS_DETACH:
        delete thread;
        break;
    default:
        break;
    }
    return TRUE;
}

}

Dll и код, который делает инжект, зависят от процесса, в который встраивается библиотека. Сама dll скомпилирована и на x86 и на x64. Ось, в которой пытаюсь запустить WINDOWS 10. Версия Qt: Qt 5.12.9

UPD

Попробовал еще плюс 3 разных способа (к тому, что уже описал выше) по созданию QApp в DllMain Способ 1:

static int argc = 1;
static char arg0[] = "";
static char * argv[] = { arg0, nullptr };
Q_GLOBAL_STATIC_WITH_ARGS(QCoreApplication, app, (argc, argv))

extern "C" __declspec(dllexport) void initialize() {
  app->processEvents(); // prime the application instance
}

extern "C"
{

_declspec(dllexport) BOOL __stdcall DllMain(HINSTANCE hDllHandle, DWORD reason, LPVOID)
{
    switch (reason) {
    case DLL_PROCESS_ATTACH:
        initialize();
        break;
    case DLL_PROCESS_DETACH:
        if (QCoreApplication::instance()) QCoreApplication::instance()->quit();
        break;
    default:
        break;
    }
    return TRUE;
}

}

Способ 2:

void guiWorker()
{
  int argc = 1;
  const char dummy[] = "";
  char * argv[] = { const_cast<char*>(dummy), 0 };
  QCoreApplication app(argc, argv);
  app.exec();
}

VOID CALLBACK Start(_In_ ULONG_PTR) {
  std::thread thread { guiWorker };
  thread.detach();
}

extern "C"
{

_declspec(dllexport) BOOL __stdcall DllMain(HINSTANCE hDllHandle, DWORD reason, LPVOID)
{
    switch (reason) {
    case DLL_PROCESS_ATTACH:
        QueueUserAPC(Start, GetCurrentThread(), NULL);
        break;
    case DLL_PROCESS_DETACH:
        if (QCoreApplication::instance()) QCoreApplication::instance()->quit();
        break;
    default:
        break;
    }
    return TRUE;
}

}

Способ 3:

DWORD WINAPI MainLoop(LPVOID) {
    int argc = 0;
    char** argv = nullptr;
    QCoreApplication loop(argc, argv);
    return loop.exec();
}

extern "C"
{

__declspec (dllexport) BOOL __stdcall DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: {
        DWORD thrID;
        CreateThread(0, 0, MainLoop, 0, 0, &thrID);
    } break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

}

Ни один из способов не работает

Есть подозрение, что не работает именно код инжекта, а не dll. Хотя он отрабатывает без ошибок.


Ответы (0 шт):