CreateRemoteThread - ERROR_ACCES_DENIED

Я думаю, что мой код наконец работает сейчас. Единственная проблема в том, что по какой-то причине, хотя я открыл процесс с PROCESS_ALL_ACCESS, CreateRemoteThread возвращает ошибку: ERROR_ACCESS_DENIED.

Ошибка была получена с помощью GetLastError, и она выдавала '5', что переводится как ERROR_ACCESS_DENIED.

#include <iostream>
#include <windows.h>
#include <TlHelp32.h>

char* dllPath = "C:\\Users\\Kalist\\Desktop\\Projects\\DLL\\bin\\Debug\\DLL.dll";
char* ProcToInject = "calc.exe";

int main(){
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if(procSnap == INVALID_HANDLE_VALUE){
        std::cout << "Snapshot function failed" << std::endl;
    }

    DWORD procID = 0;
        if(Process32First(procSnap, &pe32)){
            do{
               if(!strcmp(pe32.szExeFile, ProcToInject)){
                    procID = pe32.th32ProcessID;
                    break;
               }
            }while(Process32Next(procSnap, &pe32));
        }
    CloseHandle(procSnap);

    if(procID != 0){

        HANDLE procAccess = OpenProcess(PROCESS_ALL_ACCESS, false, procID);
        if(procAccess == NULL){
            std::cout << "OpenProcess error: " << GetLastError() << std::endl;
        }

        LPVOID remoteString = (LPVOID)VirtualAllocEx(procAccess, NULL, strlen(dllPath)+1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        if(remoteString == NULL){
            std::cout << "VirtualAllocEx error: " << GetLastError() << std::endl;
        }

        bool memoryWritten = WriteProcessMemory(procAccess, (LPVOID)remoteString, dllPath, strlen(dllPath)+1, NULL);
        if(memoryWritten == 0){
            std::cout << "WriteProcessMemory error: " << GetLastError() << std::endl;
        }

        LPVOID getLibAdd = (LPVOID)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
        if(getLibAdd == NULL){
            std::cout << "GetProcAddress error: " << GetLastError() << std::endl;
        }

        HANDLE remoteThread = CreateRemoteThread(procAccess, NULL, 0, (LPTHREAD_START_ROUTINE)getLibAdd, (LPVOID)remoteString, 0, NULL);
        if(remoteThread == NULL){
            std::cout << "CreateRemoteThread error: " << GetLastError() << std::endl;
        }
        CloseHandle(procAccess);
    }else{
        std::cout << "Failed to retrieve procID" << std::endl;
    }
}

2 ответа

Вы получите эту ошибку при попытке позвонить CreateRemoteThread из 32-разрядного процесса, но где целевой процесс является 64-разрядным процессом. Держу пари, это то, что вы делаете.

Чтобы внедрить в 64-битный процесс, вам нужно, чтобы ваш инжекторный процесс также был 64-битным. И, очевидно, как я уверен, вы уже знаете, что DLL, которую вы вводите, также должна быть 64-битной.

Для чего это стоит, вам не нужно просить так много, когда вы звоните OpenProcess, Я считаю, что все, что вам нужно, это:

PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION 
  | PROCESS_VM_WRITE | PROCESS_VM_READ

Код, который вы написали, предполагает, что процесс, код выполняется, DLL, которую вы вводите, и calc.exe имеют одинаковую разрядность.

Если это не указано, вызов не будет выполнен. Это связано с ограничением параметра.

Следующая цитата из документации CreateRemoteThread.

Указатель на определяемую приложением функцию типа LPTHREAD_START_ROUTINE, которая должна выполняться потоком и представляет начальный адрес потока в удаленном процессе. Функция должна существовать в удаленном процессе. Для получения дополнительной информации см. ThreadProc.

Допущение кода обусловлено следующим:

В LoadLibraryAФункция находится в другом rva при сравнении x86 и x64, потому что загружается другой файл, когда у вас процесс x86 против процесса x64. Разные Kernel32.dllфайлы также загружаются по другому базовому адресу при сравнении процесса x86 с процессом x64. Адрес, по которому вы вернетесь, с GetProcAddr является rva + dll base address.

В настоящее время я программирую инжектор, который также будет поддерживать x86 - x64, и проверил, что все адреса, которые передаются, находятся в области действия целевого процесса. Также я открываю процесс с PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_READ| PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION. Но у меня все еще есть эта проблема.

Это связано с тем, что длина указателя x86 составляет 32 бита. Параметр lpStartAddress из CreateRemoteThreadэто указатель. Это означает, что вы никогда не сможете вызвать все функции цели x64, потому что указатель на функцию будет ограничен 32-разрядным. Это, в свою очередь, означает, что вы можете вызывать максимум все функции внутри адресуемой области x86 из процесса x86 в целевом процессе x64.

Другие вопросы по тегам