Задать вопрос
@sha-man

Внедрение из 32-битной программы 64-битной dll в 64-битный процесс, возможно ли?

Добрый вечер. Для внедрение dll в сторонний процесс использую метод из книги Рихтера.
Суть этого метода - создать удаленный поток в нужном процессе, в качестве функции указать LoadLibrary
с необходимой dll. Если программа, dll и процесс одинаковой битности, то проблем нет.
А как сделать, чтобы можно было из 32-битной программы также внедрять 64-битные dll в 64-битные процессы?

BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile)
{
    BOOL fOk = false;
    HANDLE hProcess = NULL, hThread = NULL;
    PWSTR pszLibFileRemote = NULL;

    __try {
        // Получаем описатель целевого процесса.
        hProcess = OpenProcess(
            PROCESS_ALL_ACCESS
            /*
            PROCESS_CREATE_THREAD |
            PROCESS_QUERY_INFORMATION |
            PROCESS_VM_OPERATION |
            PROCESS_VM_WRITE |
            PROCESS_VM_READ */,
            FALSE, dwProcessId);
        if (hProcess == NULL) __leave;

        // Определяем, сколько байтов нудно для строки с полным именем DLL.
        int cch = 1 + lstrlenW(pszLibFile);
        int cb = cch * sizeof(WCHAR);

        // Выделяем блок памяти под эту строку.
        pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
        if (pszLibFileRemote == NULL) __leave;

        // Копируем эту строку в адресное пространство удаленного процесса.
        if (!WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, cb, NULL)) __leave;

        // Получем истинный адрес LoadLibraryW в Kernel32.dll
        PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
        if (pfnThreadRtn == NULL) __leave;

        // Создаем удаленный поток, вызывающий LoadLibraryW
        hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
        DWORD err = GetLastError();
        if (hThread == NULL) __leave;

        // Ждем завершение удаленного потока.
        WaitForSingleObject(hThread, INFINITE);

        fOk = TRUE;
    }
    __finally{
        // Очистка.
        if (pszLibFileRemote != NULL) VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);

        if (hThread != NULL) CloseHandle(hThread);

        if (hProcess != NULL) CloseHandle(hProcess);
    }

    return fOk;
}


То есть, каким-то образом надо получить точку входа для функции LoadLibraryW в 64-битном процессе.
// Получем истинный адрес LoadLibraryW в Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");


Подскажите, пожалуйста.
  • Вопрос задан
  • 219 просмотров
Подписаться 2 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
@lexab
Напрямую, так не получится, 64x битный адрес loadlibrary вам ничего не даст в 32х битном процессе. Нужен посредник. Можно использовать com/DCOM . Для обратного случая есть подсистема WOW. В вашем случае видимо придётся написать небольшой х64 лоадер.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы