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

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

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

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

      Вылеты не привязаны к действиям персонажей. Бот может проработать 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
      • Первое сообщение
        Последнее сообщение