• Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
  • Зарегистрироваться
  • Войти
GameHackLab[RU]
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
  • Зарегистрироваться
  • Войти

Вылетает игра

Запланировано Прикреплена Закрыта Перенесена Взлом игр (вопросы и ответы)
1 Сообщения 1 Posters 165 Просмотры
Загружаем больше сообщений
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • F
    Fler
    отредактировано Fler 10 мар. 2024 г., 08:07 3 окт. 2024 г., 07:57

    Добрый день!
    Есть игра, в которой я написал бота (твиновода). Он работает хорошо, за исключением вылетов.

    Вылеты не привязаны к действиям персонажей. Бот может проработать 5 минут, а может несколько часов. В отладчике я поймал момент вылета, там по стеку вызовов вообще не моя функция и не мой id потока. Судя по всему вылетает сама игра из за внедрения кода. Но на античит я не думаю, потому что я создавал свой сервер с чистой версией клиента - тоже самое.

    Сейчас мой код устроен так: я выделяю память в процессе, записываю туда мой код, запускаю поток и жду его завершения.
    Для завершения потока я пробовал использовать сначала RET, затем нашел функцию ExitThread в процессе. Разницы никакой - и так и так вылетает одинаково.

    Еще заметил нюанс, что на более слабом ПК вылеты происходят чаще.

    У меня вот предположение, что может быть проблема решится, если я не буду создавать свой поток, а буду использовать игровой. То есть, использовать JMP на адрес моего кода, затем возвращаться обратно. Только я не понимаю как это реализовать. Какой поток надо найти чтобы так сработало? Я не понимаю, помогите!

    Вот код C++:

    bool ProcessReader::sendPacket(size_t size, void* packetData) {
        if (GameSession == 0) {
            std::cout << u8"GameSession не установлен.\n";
            return false;
        }
    
        DWORD processId = pid;
        if (processId == 0) {
            std::cout << u8"Не удалось найти процесс ElementClient.exe." << std::endl;
            return false;
        }
    
        LPVOID remotePacketData = VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (!remotePacketData) {
            std::cout << u8"Не удалось выделить память в удалённом процессе." << std::endl;
            return false;
        }
    
        SIZE_T bytesWritten;
        if (!WriteProcessMemory(hProcess, remotePacketData, packetData, size, &bytesWritten) || bytesWritten != size) {
            std::cout << u8"Не удалось записать данные пакета в удалённый процесс." << std::endl;
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            return false;
        }
    
        DWORD sendPacketAddress = baseAddress + SENDPACKET;
    
        DWORD remoteKernel32Base = GetRemoteModuleBaseAddress(processId, L"ntdll.dll");
        if (remoteKernel32Base == 0) {
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            return false;
        }
    
        DWORD remoteExitThreadAddr = remoteKernel32Base + RTLEXITUSERTHREAD;
        if (remoteExitThreadAddr == 0) {
            std::cout << u8"Не удалось вычислить адрес ExitThread в удалённом процессе." << std::endl;
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            return false;
        }
    
        // Код-стаб для вызова функции игровой, который я записываю в память.
        BYTE codeStub[] = {
            0xB9, 0, 0, 0, 0,        // mov ecx, GameSession       ; ECX = GameSession
            0x68, 0, 0, 0, 0,        // push size                  ; Параметр size
            0x68, 0, 0, 0, 0,        // push remotePacketData      ; Параметр packetData
            0xB8, 0, 0, 0, 0,        // mov eax, SENDPACKET_ADDRESS
            0xFF, 0xD0,              // call eax
            0x83, 0xC4, 0x08,        // add esp, 8                 ; Очистка стека
            0x6A, 0x00,              // push 0    
            0xB8, 0, 0, 0, 0,        // mov eax, ExitThread_ADDRESS
            0xFF, 0xD0               // call eax
        };
    
        // Заполняю параметры в код-стабе
        *(DWORD*)(codeStub + 1) = (DWORD)GameSession;                  // ECX = GameSession
        *(DWORD*)(codeStub + 6) = (DWORD)size;                          // Параметр size
        *(DWORD*)(codeStub + 11) = (DWORD)remotePacketData;            // Параметр packetData
        *(DWORD*)(codeStub + 16) = sendPacketAddress;                  // Адрес функции SENDPACKET
        *(DWORD*)(codeStub + 28) = remoteExitThreadAddr;               // Адрес функции ExitThread
    
        LPVOID remoteCode = VirtualAllocEx(hProcess, NULL, sizeof(codeStub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        if (!remoteCode) {
            std::cout << u8"Не удалось выделить память для код-стаба в удалённом процессе." << std::endl;
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            return false;
        }
    
        if (!WriteProcessMemory(hProcess, remoteCode, codeStub, sizeof(codeStub), &bytesWritten) || bytesWritten != sizeof(codeStub)) {
            std::cout << u8"Не удалось записать код-стаб в удалённый процесс." << std::endl;
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, remoteCode, 0, MEM_RELEASE);
            return false;
        }
    
        HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)remoteCode, NULL, 0, NULL);
        if (!hThread) {
            std::cout << u8"Не удалось создать удалённый поток." << std::endl;
            VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
            VirtualFreeEx(hProcess, remoteCode, 0, MEM_RELEASE);
            return false;
        }
    
        WaitForSingleObject(hThread, INFINITE);
    
        VirtualFreeEx(hProcess, remotePacketData, 0, MEM_RELEASE);
        VirtualFreeEx(hProcess, remoteCode, 0, MEM_RELEASE);
        CloseHandle(hThread);
    
        return true;
    }
    
    
    1 ответ Последний ответ Ответить Цитировать 0
    1 из 1
    • Первое сообщение
      1/1
      Последнее сообщение