CreateRemoteThread не работает в 64-разрядной версии Windows7 для 32-разрядных приложений

У меня есть код, который внедряет dll в процесс. Процесс, выполняющий функцию внедрения, всегда находится в той же архитектуре (x86 или x64), что и внедряемый процесс. Но по какой-то причине вызов функции CreateRemoteThread не работает в 64-разрядной ОС Win7, когда процессы внедрения и внедрения имеют архитектуру x86. Удивительно, когда ОС Win10 64bit. 32 битные процессы работают нормально. Код также хорошо работает для 64-разрядной версии Win7 с 64-разрядными процессами и для 32-разрядной версии Win7 с 32-разрядными процессами.

Я искал в Интернете возможную причину, и все, что я смог найти, это то, что в Win7 иногда возникают проблемы с сеансами процессов. Я не думаю, что это так, поскольку и внедряющий, и внедряемый процессы являются «пользовательскими» сеансами.

При запуске GetLastError() я получаю 5 (ERROR_ACCESS_DENIED)

Это моя функция инъекции:

    DWORD Inject(DWORD PID, const char *dllname)
    {
        HANDLE hThread = NULL;
        BOOL writeSucceed = false;
        int cch = 0;

        cout << "Injector.dll : Injecting " << dllname << " to " << PID << endl;
        DWORD hLibModule;

        HMODULE hKernel32 = GetModuleHandle (TEXT ("Kernel32"));
        void *hProcess = OpenProcess (PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
                                      PROCESS_VM_WRITE, false, PID);  

        cch = strlen (dllname) + 1;

        void *pLibRemote = VirtualAllocEx (hProcess, NULL, cch, MEM_COMMIT,
            PAGE_READWRITE);

        writeSucceed = WriteProcessMemory (hProcess, pLibRemote, (void *) dllname, cch, NULL);

        hThread = CreateRemoteThread (hProcess, NULL, 0,
                                            (PTHREAD_START_ROUTINE)
                                            GetProcAddress (hKernel32,
                                            "LoadLibraryA"),
                                            pLibRemote, 0, NULL);

        WaitForSingleObject (hThread, INFINITE);
        GetExitCodeThread( hThread, &hLibModule );
        CloseHandle (hThread);

        VirtualFreeEx (hProcess, pLibRemote, sizeof (dllname), MEM_RELEASE);

        hThread = CreateRemoteThread (hProcess, NULL, 0,
                                     (PTHREAD_START_ROUTINE) GetProcAddress (hKernel32,
                                     "FreeLibrary"),
                                     (void *) hLibModule, 0, NULL);
        WaitForSingleObject (hThread, INFINITE);
        CloseHandle (hThread);
        return 0;
    }

Is there some special treatment I should do in code for Windows 7?

person user3551678    schedule 19.06.2019    source источник
comment
Что дает GetLastError() в случае сбоя CreateRemoteThread?   -  person Gaurav Sehgal    schedule 19.06.2019
comment
@GauravSehgal Я отредактировал пост. Метод GetLastError() возвращает 5.   -  person user3551678    schedule 19.06.2019
comment
5 означает ACCESS DENIED, в какой процесс вы пытаетесь внедрить? Проверьте с другими процессами (возможно, они запущены с более низкими привилегиями).   -  person Gaurav Sehgal    schedule 19.06.2019
comment
@GauravSehgal Я внедряю различные процессы, но в основном тестирую Java-приложение. Я запускаю от имени администратора. Я думаю дело не в этом, т.к. при запуске точно такой же java в 64 битном режиме все работает нормально.   -  person user3551678    schedule 19.06.2019
comment
Это должно быть что-то связанное с несоответствием 32-64. Дважды проверьте, что процессы и dll, которые вы пытаетесь внедрить, имеют одинаковую архитектуру. Также имейте в виду перенаправление wow64, проверьте с помощью procmon, чтобы определить, получают ли доступ к какой-либо dll или ее зависимым dll из 64-битного местоположения (system32).   -  person Gaurav Sehgal    schedule 19.06.2019
comment
Поэтому я внес некоторые изменения, чтобы изолировать проблему. Я создал очень простой внедренный dll-код, который печатает только «Я внутри!», и я переключился с java на простое консольное приложение C без кода, кроме getChar(), чтобы консоль оставалась открытой. Все еще используя функцию впрыска выше. Я все еще использую приведенный выше код для инъекции и никаких изменений. Этот вопрос ранее задавался без ответа: social.msdn.microsoft.com/Forums/ie/en-US/   -  person user3551678    schedule 22.06.2019


Ответы (1)


Проблема была в том, что мне пришлось добавить PROCESS_QUERY_INFORMATION к OpenProcess флагам. Это было очень сложно, так как если вы не включите этот флаг, он все равно будет работать везде, кроме случая 64-битной ОС Win7 и 32-битного приложения.

person user3551678    schedule 23.06.2019