- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 538
- Реакции
- 14
Пытаюсь завести одну старую интернал базу под Осаду. Код обновил, оффсеты подтянул, всё вроде взлетает, но ловлю стабильный Corrupted Memory Kick через пару минут после захода.
Подозрение падает на реализацию хука. Родная либа из сурса не прижилась, поэтому пришлось по-быстрому вкинуть костыльный трамплин через RWX. Есть подозрение, что BattlEye (BE) триггерится именно на манипуляции с памятью в этом блоке или на сам факт наличия исполняемых страниц вне легитных модулей.
Собственно, сам кусок кода с инициализацией хука:
Если кто-то ковырял R6S недавно, посоветуйте адекватную альтернативу этому методу. Юзать VMT хуки или стоит смотреть в сторону .pdata / манипуляций с импортами? Ну или ткните носом, если дело вообще в инжекторе, хотя юзаю ручной маппинг без зашкваров.
Интересно, насколько сейчас BE в Осаде чувствителен к патчингу кода в рантайме, если возвращать оригинальные протекты сразу после записи.
Подозрение падает на реализацию хука. Родная либа из сурса не прижилась, поэтому пришлось по-быстрому вкинуть костыльный трамплин через RWX. Есть подозрение, что BattlEye (BE) триггерится именно на манипуляции с памятью в этом блоке или на сам факт наличия исполняемых страниц вне легитных модулей.
Собственно, сам кусок кода с инициализацией хука:
Код:
inline void init()
{
void* entity_call = reinterpret_cast<void*>(ImageBase + 0x45374B0);
void* trampoline = VirtualAlloc(nullptr, 32, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!trampoline) return;
memcpy(trampoline, entity_call, 12);
uint8_t* t = (uint8_t*)trampoline;
t[12] = 0x48; t[13] = 0xB8;
*(void**)(&t[14]) = (uint8_t*)entity_call + 12;
t[22] = 0xFF; t[23] = 0xE0;
uint32_t oldProtect;
utils::syscall::vm_protect(reinterpret_cast<uintptr_t>(entity_call), 12, PAGE_EXECUTE_READWRITE, &oldProtect);
uint8_t* dst = (uint8_t*)entity_call;
dst[0] = 0x48; dst[1] = 0xB8;
*(void**)(&dst[2]) = reinterpret_cast<void*>(hk::entity);
dst[10] = 0xFF; dst[11] = 0xE0;
utils::syscall::vm_protect(reinterpret_cast<uintptr_t>(entity_call), 12, oldProtect, &oldProtect);
original_entity_hook = trampoline;
}
- Использование PAGE_EXECUTE_READWRITE (RWX) — это моментальный флаг для античита. BattlEye активно сканирует память на такие атрибуты.
- Прямая перезапись кода в секции .text без учета integrity checks. BE проверяет целостность кода игры, и такие патчи в 12 байт палятся на раз-два.
- Использование классического VirtualAlloc для трамплина. Нужно либо искать кодеквэйв (code cave) внутри легитных модулей, либо юзать более скрытые методы инъекции.
Если кто-то ковырял R6S недавно, посоветуйте адекватную альтернативу этому методу. Юзать VMT хуки или стоит смотреть в сторону .pdata / манипуляций с импортами? Ну или ткните носом, если дело вообще в инжекторе, хотя юзаю ручной маппинг без зашкваров.
Интересно, насколько сейчас BE в Осаде чувствителен к патчингу кода в рантайме, если возвращать оригинальные протекты сразу после записи.