|
# Включение невидимых стен в играх на CryEngine (пример: "Лицо войны") |
|
|
|
В этом руководстве показано, как активировать отображение невидимых стен (collision proxy) путём патча памяти в CryEngine-игре. Пример основан на билде ПДБ известной игры "Лицо войны". |
|
|
|
## Инструменты |
|
- IDA Pro (с загруженным дампом игры) |
|
- Visual Studio (для создания DLL) |
|
- Инжектор DLL (например, любой публичный) |
|
|
|
## Шаги |
|
|
|
### 1. Поиск функции `CMatInfo::SetName` |
|
В IDA Pro найдите функцию `CMatInfo::SetName`. В контексте данной игры внутри неё встречаются строки: |
|
- `raycast_proxy` |
|
- `collision_proxy` |
|
- `nomaterial_vehicle` |
|
|
|
### 2. Определение целевой инструкции |
|
В самом конце функции есть строка: |
|
```cpp |
|
this->m_Flags |= 0x100400u; |
|
``` |
|
Переключитесь на отображение байт в IDA (Options → General → Number of opcode bytes → укажите, например, 8). |
|
Наведите курсор на начало кода, соответствующего этой операции, и нажмите `Tab`, чтобы увидеть ассемблерное представление. |
|
|
|
Вы увидите инструкцию вида: |
|
``` |
|
.text:0060EC59 81 4E 3C 00 04 10 00 or dword ptr [esi+3Ch], 100400h |
|
``` |
|
Длина инструкции — 7 байт. |
|
|
|
### 3. Что нужно сделать |
|
Заменяем эти 7 байт на NOP (`0x90`), чтобы предотвратить установку флага, отвечающего за поведение невидимых стен. Это можно сделать путём инжекта DLL, которая запишет NOP по нужному адресу. |
|
|
|
### 4. Создание DLL |
|
Создайте проект DLL в Visual Studio и вставьте следующий код, подставив реальный адрес инструкции (в примере `0x0060EC59`). |
|
|
|
```cpp |
|
#include <windows.h> |
|
|
|
void PatchInvisibleWalls() |
|
{ |
|
DWORD oldProtect = 0; |
|
|
|
// Адрес инструкции, которую нужно заменить (0x0060EC59 в примере) |
|
void* patchAddress = (void*)0x0060EC59; |
|
|
|
// Делаем память доступной для записи |
|
VirtualProtect(patchAddress, 7, PAGE_EXECUTE_READWRITE, &oldProtect); |
|
|
|
// Записываем 7 NOP-ов (коды 0x90) |
|
const char nops[] = "\x90\x90\x90\x90\x90\x90\x90"; |
|
WriteProcessMemory(GetCurrentProcess(), patchAddress, nops, sizeof(nops) - 1, NULL); |
|
|
|
// Возвращаем исходные атрибуты защиты |
|
VirtualProtect(patchAddress, 7, oldProtect, NULL); |
|
} |
|
|
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) |
|
{ |
|
if (ul_reason_for_call == DLL_PROCESS_ATTACH) |
|
{ |
|
// Отключаем уведомления о загрузке DLL-потоков |
|
DisableThreadLibraryCalls(hModule); |
|
PatchInvisibleWalls(); |
|
} |
|
return TRUE; |
|
} |
|
``` |
|
|
|
### 5. Использование |
|
Скомпилируйте DLL, затем инжектируйте её в процесс игры любым удобным инжектором (например, Extreme Injector, Xenos и т.п.). |
|
|
|
## Примечания |
|
- Адрес `0x0060EC59` характерен для конкретного билда игры; в вашей версии он может отличаться. Перепроверьте через IDA. |
|
- DLL требуется запускать **только** после полной загрузки игры, иначе патч может не сработать или игра вылетит. |
|
- Инжектор и игра могут требовать прав администратора. |
|
- Вместо DLL можно использовать любой другой способ записи в память процесса (Cheat Engine, LUA-скрипты и т.д.), но DLL-метод наиболее удобен для постоянного использования. |