- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 682
- Реакции
- 18
Здорово, реверсеры. Опять Раст обновился, оффсеты улетели, а ваша паста плачет? Сегодня разберем базу, которую должен знать каждый, кто лезет в GameAssembly.dll — как вытащить BaseNetworkable и правильно собрать цепочку декриптов, чтобы ваш энтити-луп наконец-то ожил.
Шаг 1: Точка входа
Залетаем в IDA, ищем оффсет BaseNetworkable (на момент разбора это
Видим что-то в духе:
Кликаем по XREF, жмем F5 и попадаем в главный роут. Нам нужно найти место, где инициализируется клиентский список сущностей.
Шаг 2: Анализ псевдокода
В мейне ищем вызов функции декрипта. Это выглядит примерно так:
Тут мы видим первую важную часть цепочки: 0xB8 и 0x20.
Функция DecryptClientEntities (в оригинале может быть sub_180E07260) — это наш первый уровень защиты.
Шаг 3: Идем глубже к EntityList
Теперь ищем, куда передается результат v4. Видим вызов StaticFields:
Прыгаем в нее и находим еще один декрипт — DecryptEntityList:
Замечаем новый оффсет: 0x10. Это наш третий шаг в цепочке.
Итог: Собираем Chain для пасты
Теперь у нас есть всё, чтобы построить путь к энтити-лупу:
Для тех, кто пишет на C++, структура будет выглядеть так:
Поздравляю, теперь вы не просто копипастер, а человек, который понимает, откуда берутся эти магические цифры в конфигах. Пока остальные ловят мануалбаны из-за кривых паблик-сурсов, юзеры YouGame реверсят базу сами.
Кто уже пробовал автоматизировать поиск этих декриптов через паттерны?
Шаг 1: Точка входа
Залетаем в IDA, ищем оффсет BaseNetworkable (на момент разбора это
0xBE749E8). Прыгаем по адресу 18BE749E8.Видим что-то в духе:
.data:000000018BE749E8 BaseNetworkable dq 20019B87hКликаем по XREF, жмем F5 и попадаем в главный роут. Нам нужно найти место, где инициализируется клиентский список сущностей.
Шаг 2: Анализ псевдокода
В мейне ищем вызов функции декрипта. Это выглядит примерно так:
v3 = BaseNetworkable;if ( !*(_DWORD *)(BaseNetworkable + 0xE0) ){ il2cpp_runtime_class_init_0(BaseNetworkable, v0); v3 = BaseNetworkable;}v4 = DecryptClientEntities(*(_QWORD *)(*(_QWORD *)(v3 + 0xB8) + 0x20LL), (signed __int64 *)qword_18BE74A00, v1);Тут мы видим первую важную часть цепочки: 0xB8 и 0x20.
Функция DecryptClientEntities (в оригинале может быть sub_180E07260) — это наш первый уровень защиты.
Внутри функции происходит классическая математика EAC-стайл:
do{ v5 = *(_DWORD *)a2; v6 = *(_DWORD *)a2; a2 = (signed __int64 *)((char *)a2 + 4); *((_DWORD *)a2 - 1) = (((v6 << 19) | (v5 >> 13)) ^ 0x84282F0A) - 0x4C772A84; v7 = (_DWORD)a3 == 1; a3 = (unsigned int)(a3 - 1);}while ( !v7 );Шаг 3: Идем глубже к EntityList
Теперь ищем, куда передается результат v4. Видим вызов StaticFields:
v38 = *StaticFields(v41, v4, 0);Прыгаем в нее и находим еще один декрипт — DecryptEntityList:
v5 = DecryptEntityList(*(_QWORD *)(a2 + 0x10), (signed __int64 *)qword_18BE9B480, a3);Замечаем новый оффсет: 0x10. Это наш третий шаг в цепочке.
Итог: Собираем Chain для пасты
Теперь у нас есть всё, чтобы построить путь к энтити-лупу:
- Берем
GameAssembly.dll + BaseNetworkable - Читаем
[[BaseNetworkable + 0xB8] + 0x20] - Прогоняем полученное через DecryptClientEntities
- Прибавляем
0x10, читаем и прогоняем через DecryptEntityList - Получаем базу списка объектов.
Для тех, кто пишет на C++, структура будет выглядеть так:
bn = GameAssembly.dll + BaseNetworkable;bn1 = Read<uint64_t>(bn + 0xB8);bn2 = Read<uint64_t>(bn1 + 0x20);bn3 = DecryptClientEntities(bn2);bn4 = Read<uint64_t>(bn3 + 0x10);bn5 = DecryptEntityList(bn4);bufferlist = bn5 + 0x10; // ListDictionary -> BufferListПоздравляю, теперь вы не просто копипастер, а человек, который понимает, откуда берутся эти магические цифры в конфигах. Пока остальные ловят мануалбаны из-за кривых паблик-сурсов, юзеры YouGame реверсят базу сами.
Кто уже пробовал автоматизировать поиск этих декриптов через паттерны?