Как развивается индустрия мультиплеера GTA V?
Привет. С момента публикации моего последнего сообщения на этом канале прошёл почти месяц. Поэтому сегодня я хотел бы подробнее рассмотреть GTA V и всё, что её окружает.Полагаю, каждый, кто хоть немного интересуется индустрией мультиплеера GTA V, уже слышал о происходящем. Как и следовало ожидать, в преддверии выхода GTA VI компания T2 начала предпринимать меры против неофициальных мультиплеерных платформ, таких как alt:V, RAGE MP и другие. Например, по имеющейся информации, T2 сначала потребовала от RAGE MP объявить о закрытии мастер-листа серверов, а затем — всей инфраструктуры проекта. Мы не будем обсуждать или пытаться предсказывать, какой стратегии T2 придерживается в отношении FiveM и какие меры она может предпринять против alt:V и RAGE MP.
В свете описанных выше событий я начал изучать архитектуру GTA V и её мультиплеерных платформ. Для этого я исследовал исходный код FiveM, а также в образовательных целях провёл реверс-инжиниринг нескольких других решений с закрытым исходным кодом.
Первое, на что я обратил внимание, — наличие в FiveM закрытого кода и проприетарных библиотек. Наиболее значимыми компонентами являются legitimacy.dll, adhesive.dll и отдельная прослойка совместимости ros.dll.
Первый плагин, legitimacy.dll, необходим для аутентификации через Discord, инициализации Steam SDK для последующего использования и применения нескольких простых патчей памяти, необходимых для совместимости с загрузчиком игры. Эти функции относительно легко заменить или полностью исключить без серьёзных последствий. Однако более сложные задачи, которые я первоначально приписывал legitimacy.dll, на самом деле выполняются библиотекой ros.dll.
Прослойка ros.dll подменяет встроенные TLS-сертификаты и данные доверия, обеспечивая локальную эмуляцию ROS — Rockstar Online Services. Среда прав доступа ROS содержит такую информацию, как идентификатор учётной записи Rockstar, хеш компьютера, срок действия прав, идентификатор приобретённой версии игры, издание — Steam, Epic или Rockstar, — бонусы за предзаказ и другие права доступа.
Эмуляция прав ROS позволяет запускать игру без прохождения полного стандартного процесса через Rockstar Games Launcher, Social Club, Steam или Epic Games Launcher, хотя некоторые компоненты Social Club SDK по-прежнему могут загружаться внутри игры.
Другие мультиплеерные платформы обычно используют иной подход. Вместо подмены сертификата и локальной эмуляции среды ROS они запускают необходимые сервисы Rockstar стандартным способом. На практике это означает запуск Rockstar Games Launcher, Social Club и, при необходимости, Steam или Epic Games Launcher с последующим подключением собственного мультиплеерного слоя к уже аутентифицированному процессу GTA V.
Такой подход сохраняет исходную цепочку проверки прав доступа, однако добавляет дополнительные зависимости и делает процесс запуска более громоздким.
Наконец, мы подходим ко второй задаче ros.dll: предотвращению отложенного сбоя, связанного с Arxan — комплексом программной защиты, который по своему назначению, хотя и не по реализации, можно сравнить с VMProtect.
GTA V использует Arxan TransformIT для защиты AES-ключа, применяемого при расшифровке прав доступа через функцию TFIT_init_wbaes_cbc_iAES4. Arxan также используется для обфускации или мутации критически важного кода, проверки контрольных сумм отдельных функций, обнаружения отладчиков и восстановления защищённых участков кода перед их выполнением.
Без ros.dll исследованная сборка GTA V примерно через 128 секунд запускает отложенную задачу проверки целостности. После этого защищённый диспетчер переходит по намеренно нарушенному пути выполнения, формирует адрес в неисполняемой области памяти и завершает процесс из-за нарушения DEP.
Второй плагин с закрытым исходным кодом — adhesive.dll. Он реализует функции античита и проверки целостности клиента, включая создание аттестационных данных, которые могут проверяться сервером для отклонения клиентов, запущенных без ожидаемого античит-компонента.
Технически удалить этот плагин возможно только при одновременном изменении соответствующих серверных проверок. При этом будут утрачены все гарантии безопасности, которые он обеспечивает.
Таким образом, мой вывод заключается в том, что создание собственной мультиплеерной платформы концептуально возможно, однако по-прежнему представляет собой масштабную инженерную задачу. Особенно если учитывать, что многие функции движка могут вызываться по хешам или через таблицы виртуальных функций.
Для более ранних частей GTA уже существует множество мультиплеерных решений, хотя реверс-инжиниринг их движков зачастую был ещё сложнее. Тем не менее сообщество смогло справиться с этой задачей.
Если T2 не удастся прийти к соглашению с сообществом, я опасаюсь, что значительная часть этой индустрии уйдёт в подполье и будет полагаться на реверс-инжиниринг, бинарные патчи или утёкшие версии GTA V.
P. S.
В ходе исследования мы также установили, каким образом FiveM интегрирует свой слой синхронизации с GTA V. В качестве транспортного уровня он использует ENet для передачи пакетов через сервер, одновременно задействуя существующие механизмы синхронизации GTA Online для чтения и применения деревьев синхронизации:
JavaScript:
auto objIt = m_savedEntities.find(msg.GetObjectId());
rage::netObject* obj = objIt->second;
rage::netSyncTree* syncTree = obj->GetSyncTree();
rage::datBitBuffer rlBuffer(
const_cast<uint8_t*>(msg.GetCloneData().data()),
msg.GetCloneData().size()
);
syncTree->ReadFromBuffer(2, 0, &rlBuffer, nullptr);
На принимающей стороне синхронизированное состояние применяется к объекту следующим образом:
// Применяем синхронизированное состояние к объекту.
JavaScript:
syncTree->ApplyToObject(obj, nullptr);
// Вызываем обработчик, выполняемый после применения состояния.
JavaScript:
obj->PostSync();
Вся система деревьев синхронизации в GTA V реализована с использованием наследования и спроектирована достаточно грамотно. Поэтому для добавления новой сетевой сущности в основном требуется реализовать соответствующую виртуальную логику сериализации и применения состояния, а затем передавать её координаты или любые другие необходимые данные.
Ниже приведён список типов сущностей, которые уже поддерживают синхронизацию:
JavaScript:
enum class NetObjEntityType
{
#if defined(STATE_FIVE) || defined(GTA_FIVE)
Automobile = 0,
Bike = 1,
Boat = 2,
Door = 3,
Heli = 4,
Object = 5,
Ped = 6,
Pickup = 7,
PickupPlacement = 8,
Plane = 9,
Submarine = 10,
Player = 11,
Trailer = 12,
Train = 13,
Max = 14,
#elif defined(STATE_RDR3) || defined(IS_RDR3)
Animal = 0,
Automobile = 1,
Bike = 2,
Boat = 3,
Door = 4,
Heli = 5,
Object = 6,
Ped = 7,
Pickup = 8,
PickupPlacement = 9,
Plane = 10,
Submarine = 11,
Player = 12,
Trailer = 13,
Train = 14,
DraftVeh = 15,
StatsTracker = 16,
PropSet = 17,
AnimScene = 18,
GroupScenario = 19,
Herd = 20,
Horse = 21,
WorldState = 22,
WorldProjectile = 23,
Incident = 24,
Guardzone = 25,
PedGroup = 26,
CombatDirector = 27,
PedSharedTargeting = 28,
Persistent = 29,
Max = 30,
#else
Max = 0,
#endif
};