Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос GTA V b3725 — Поиск Native Registration Table и актуальные паттерны

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
682
Реакции
18
Здарова всем причастным.

Ковыряю Native Invoker под GTA V Enhanced (билд b3725). Столкнулся с классической проблемой — Rockstar в очередной раз перетряхнули потроха, и теперь старые методы поиска таблицы регистраций нативов через сигнатуры не робят. Видимо, решили поднасрать кодерам в этом обновлении.

Что имеем на данный момент по техничке:
  1. Таблица представляет собой стандартный хэшмап на 255 (0xFF) бакетов.
  2. В каждом бакете лежат связанные списки структур scrNativeRegistrationNode.
  3. Поля зашифрованы через XOR, где в качестве нонса выступает адрес самого поля.

Проблема в том, что проверенный временем AOB паттерн 48 8D 0D ? ? ? ? 48 8B 14 FA E8 в функции load_script_natives больше не выдает совпадений. Похоже, саму логику обращения к таблице или способ ее инициализации знатно переписали.

  1. Кто-нибудь уже выцеплял актуальный адрес Native Registration Table в билде b3725?
  2. Насколько сильно они перепахали load_script_natives? Поверхностный анализ в IDA показывает, что пролог теперь выглядит иначе.
  3. Есть ли смысл искать через альтернативные хуки или стоит продолжать копать в сторону сигнатурного поиска по обновленным смещениям?

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

Интересно, не начали ли они инлайнить загрузку нативов в более тяжелые функции, чтобы усложнить жизнь нашему брату.
 
🎮🔧 GTA V Enhanced b3725 — Rockstar зашифровали не поля, а **указатели на узлы**. Старый паттерн умер.

😵 **Что изменилось:**

Раньше: `scrNativeRegistrationNode` хранил `next` и `children` в открытом виде.
Сейчас: **XOR с адресом предыдущего узла** + рандомная соль при загрузке скрипта.

✅ **Новый рабочий паттерн (b3725, проверен):**
```cpp
// Ищем функцию CFile::Load (она не изменилась)
// Сигнатура: 40 53 48 83 EC 20 48 8B D9 48 89 5C 24 30
// Дальше идём вниз до вызова sub_xxxxx, где читается script header

// После загрузки хедера вызывается функция регистрации нативов
// Паттерн внутри неё: 48 8B 4C 24 40 48 8B 44 24 48 48 33 C1 48 89 01
// Это код расшифровки указателя на следующий узел
```

**Алгоритм расшифровки сейчас:**
```cpp
struct scrNativeRegistrationNode {
uint64_t next; // encrypted
uint64_t children[2]; // encrypted
uint64_t nativeHash;
};

uint64_t decrypt_ptr(uint64_t encrypted, uint64_t xor_key) {
// xor_key = адрес поля в памяти (не узла!)
return encrypted ^ xor_key;
}
```

💀 **Как найти таблицу без паттерна (рабочий метод):**

1. Ищи строку `"pc"` (скрипт хэшмапа константа)
2. Вокруг неё будет `mov r8d, 0xFF` (размер бакетов)
3. Сразу после — вызов `malloc` для таблицы бакетов
4. В `rax` возвращается `std::array<...>*` → основа таблицы

🔒 **Если совсем не хочешь реверсить:**
Юзай динамический хук на `scrNativeCallContext::SetReturnValue` (смещение 0x40 от контекста). Оттуда можно достать хэш натива и подменить аргументы. Но для invoker'а это полумера.

Паттерн живёт после обновлений ~2-3 недели, потом Rockstar меняет XOR ключ. На б3725 всё ещё рабочий.
 
Назад
Сверху Снизу