- 47
- 26
Здравствуйте, уважаемые пользователи форума.
Данное руководство создано с целью восполнить пробел в русскоязычной информации по разработке читов для Minecraft с использованием C++ и JNI (Java Native Interface). Большинство существующих решений основаны на Java, однако они не всегда применимы.
Основная цель этого метода — создание читов для кастомных лаунчеров (например, на кастомных серверах которые используют свою JVM такие как laby mode, vime world, rust в майне (noad) ), которые запрещают вам делать просто моды, или стандартные длл на джаве . В таких условиях инжект нативной C++ DLL библиотеки в процесс лаунчера и последующее взаимодействие с JVM через JNI становится одним из немногих рабочих подходов.
Это не сравнение "что лучше, Java или C++", а инструкция для решения конкретной задачи, где стандартные методы не работают.
**Шаг 1: Подготовка рабочего окружения**
Для работы потребуется следующее программное обеспечение:
1. **IDE для C++:** **Visual Studio 2019/2022** с установленным набором инструментов "Разработка классических приложений на C++".
2. **JDK (Java Development Kit):** Критически важный компонент. Версия JDK **должна соответствовать версии Java, с которой запускается Minecraft**. Неправильный выбор приведет к ошибкам.
* Для Minecraft **1.8 - 1.16.5**: Используйте **JDK 8**.
* Для Minecraft **1.17.x**: Используйте **JDK 16**.
* Для Minecraft **1.18 и новее**: Используйте **JDK 17**.
Найти и скачать нужную версию JDK можно в любом поисковике.
**Настройка проекта в Visual Studio:**
1. Создайте новый проект типа **"Библиотека динамической компоновки (DLL)"**.
2. Откройте **Свойства проекта**.
3. Перейдите в `C/C++ -> Общие -> Дополнительные каталоги включаемых файлов`.
4. Добавьте два пути к установленному JDK:
* `C:\Program Files\Java\jdk-ВЕРСИЯ\include`
* `C:\Program Files\Java\jdk-ВЕРСИЯ\include\win32`
*(Замените `jdk-ВЕРСИЯ` на вашу реальную папку, например, `jdk1.8.0_202`)*.
После этого вы сможете использовать `#include <jni.h>` в вашем коде.
### **Шаг 2: Инициализация JNI и подключение к JVM**
После инжекта нашей DLL в процесс игры, первым делом необходимо получить доступ к окружению JNI. Это делается через поиск активной JVM и присоединение к ней текущего потока.
Базовый код для `dllmain.cpp`:
### **Шаг 3: Обфускация (Vanilla) и ее отсутствие (Forge/Fabric)**
Это ключевой аспект, который определяет сложность разработки.
* **Vanilla Minecraft (чистая версия):** Исходный код игры **обфусцирован**. Это значит, что имена классов, методов и полей заменены на короткие и бессмысленные (например, класс `net.minecraft.entity.player.EntityPlayer` может называться `azy`). Работа напрямую с такими именами крайне затруднительна и требует реверс-инжиниринга.
* **Forge / Fabric:** Данные загрузчики модов в процессе своей работы **деобфусцируют** код игры, возвращая ему осмысленные имена. Это значительно упрощает разработку, так как можно обращаться к классам и полям по их логичным названиям (`thePlayer`, `theWorld`, `posX` и т.д.).
**Рекомендация:** Для обучения и отладки настоятельно рекомендуется использовать клиент с установленным Forge или Fabric.
**Шаг 4: Поиск ключевых классов и полей (fields)**
Имея `g_JniEnv`, мы можем начать взаимодействовать с игрой. Основная задача — получить доступ к объекту игрока и мира.
**Алгоритм получения объекта игрока:**
1. Найти класс `net/minecraft/client/Minecraft` с помощью `recaf, jadx (вам нужно открыть дамп и там искать классы, а уже в классах flied`.
2. Найти его статический метод `getMinecraft()`.
3. Вызвать этот метод, чтобы получить экземпляр класса `Minecraft`.
4. Из этого экземпляра получить поле `thePlayer`.
*Имена `func_...` и `field_...` являются частью MCP (Mod Coder Pack). Для поиска актуальных имен для вашей версии Minecraft используйте онлайн-базы данных MCP-маппингов.*
**Шаг 5: Работа с обфусцированным кодом: Дампинг**
Если ваша цель — ванильный клиент или сервер с собственными модами без деобфускации, вам потребуется провести анализ.
Основной метод — **дампинг классов**. С помощью спецаильных утилит (например, Java Class Dumper...) можно выгрузить все загруженные в JVM классы в виде `.class` файлов. Далее эти файлы открываются в декомпиляторе (JD-GUI, Luyten, Recaf) для анализа их логики и поиска нужных полей и методов по косвенным признакам (например, по используемым строковым константам или числовым значениям).
### **Пример реализации: функция FullBright (максимальная яркость)**
Простая функция, отключающая тени и делающая мир полностью освещенным.
**Заключение**
Данное руководство описывает лишь базовые шаги для начала работы. Дальнейшее развитие включает в себя изучение рендеринга (ESP) через хукинг OpenGL/DirectX, перехват Java-методов для создания более сложных функций (Killaura, Aimbot) и работу со списком сущностей в мире.
Надеюсь, эта информация будет полезной для ваших исследований.
**Отказ от ответственности:** Вся информация предоставлена исключительно в образовательных и исследовательских целях. Автор не несет ответственности за ее использование, которое может привести к блокировке игровых аккаунтов.
Данное руководство создано с целью восполнить пробел в русскоязычной информации по разработке читов для Minecraft с использованием C++ и JNI (Java Native Interface). Большинство существующих решений основаны на Java, однако они не всегда применимы.
Основная цель этого метода — создание читов для кастомных лаунчеров (например, на кастомных серверах которые используют свою JVM такие как laby mode, vime world, rust в майне (noad) ), которые запрещают вам делать просто моды, или стандартные длл на джаве . В таких условиях инжект нативной C++ DLL библиотеки в процесс лаунчера и последующее взаимодействие с JVM через JNI становится одним из немногих рабочих подходов.
Это не сравнение "что лучше, Java или C++", а инструкция для решения конкретной задачи, где стандартные методы не работают.
**Java Native Interface (JNI)** — это стандартный механизм в платформе Java, который позволяет Java-коду взаимодействовать с приложениями и библиотеками, написанными на других языках, таких как C и C++.
В нашем случае JNI выступает в роли "моста". Процесс Minecraft работает в виртуальной машине Java (JVM). Наш чит, написанный на C++, будет представлять собой внешнюю DLL-библиотеку. JNI позволит этой библиотеке после инжекта в процесс "достучаться" до JVM, находить Java-классы игры, читать значения их полей (координаты, здоровье) и вызывать их методы (атака, прыжок).
В нашем случае JNI выступает в роли "моста". Процесс Minecraft работает в виртуальной машине Java (JVM). Наш чит, написанный на C++, будет представлять собой внешнюю DLL-библиотеку. JNI позволит этой библиотеке после инжекта в процесс "достучаться" до JVM, находить Java-классы игры, читать значения их полей (координаты, здоровье) и вызывать их методы (атака, прыжок).
**Шаг 1: Подготовка рабочего окружения**
Для работы потребуется следующее программное обеспечение:
1. **IDE для C++:** **Visual Studio 2019/2022** с установленным набором инструментов "Разработка классических приложений на C++".
2. **JDK (Java Development Kit):** Критически важный компонент. Версия JDK **должна соответствовать версии Java, с которой запускается Minecraft**. Неправильный выбор приведет к ошибкам.
* Для Minecraft **1.8 - 1.16.5**: Используйте **JDK 8**.
* Для Minecraft **1.17.x**: Используйте **JDK 16**.
* Для Minecraft **1.18 и новее**: Используйте **JDK 17**.
Найти и скачать нужную версию JDK можно в любом поисковике.
**Настройка проекта в Visual Studio:**
1. Создайте новый проект типа **"Библиотека динамической компоновки (DLL)"**.
2. Откройте **Свойства проекта**.
3. Перейдите в `C/C++ -> Общие -> Дополнительные каталоги включаемых файлов`.
4. Добавьте два пути к установленному JDK:
* `C:\Program Files\Java\jdk-ВЕРСИЯ\include`
* `C:\Program Files\Java\jdk-ВЕРСИЯ\include\win32`
*(Замените `jdk-ВЕРСИЯ` на вашу реальную папку, например, `jdk1.8.0_202`)*.
После этого вы сможете использовать `#include <jni.h>` в вашем коде.
### **Шаг 2: Инициализация JNI и подключение к JVM**
После инжекта нашей DLL в процесс игры, первым делом необходимо получить доступ к окружению JNI. Это делается через поиск активной JVM и присоединение к ней текущего потока.
Базовый код для `dllmain.cpp`:
Базовый код для `dllmain.cpp`::
#include <Windows.h>
#include <jni.h>
JavaVM* g_JavaVM = nullptr;
JNIEnv* g_JniEnv = nullptr;
DWORD WINAPI MainCheatThread(HMODULE hModule) {
// 1. Получаем указатель на созданную виртуальную машину Java
jsize vmCount;
if (JNI_GetCreatedJavaVMs(&g_JavaVM, 1, &vmCount) != JNI_OK || vmCount == 0) {
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
// 2. Присоединяем текущий поток к JVM для получения рабочего окружения JNIEnv
if (g_JavaVM->AttachCurrentThread((void**)&g_JniEnv, nullptr) != JNI_OK) {
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
// --- Начиная с этого момента, g_JniEnv является валидным указателем ---
// --- Здесь будет размещена основная логика чита ---
while (!(GetAsyncKeyState(VK_DELETE) & 1)) {
// Главный цикл работы чита
// Здесь будут вызываться функции
Sleep(15);
}
// 3. Отсоединяем поток от JVM перед выгрузкой библиотеки
g_JavaVM->DetachCurrentThread();
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)MainCheatThread, hModule, 0, nullptr));
}
return TRUE;
}
### **Шаг 3: Обфускация (Vanilla) и ее отсутствие (Forge/Fabric)**
Это ключевой аспект, который определяет сложность разработки.
* **Vanilla Minecraft (чистая версия):** Исходный код игры **обфусцирован**. Это значит, что имена классов, методов и полей заменены на короткие и бессмысленные (например, класс `net.minecraft.entity.player.EntityPlayer` может называться `azy`). Работа напрямую с такими именами крайне затруднительна и требует реверс-инжиниринга.
* **Forge / Fabric:** Данные загрузчики модов в процессе своей работы **деобфусцируют** код игры, возвращая ему осмысленные имена. Это значительно упрощает разработку, так как можно обращаться к классам и полям по их логичным названиям (`thePlayer`, `theWorld`, `posX` и т.д.).
**Рекомендация:** Для обучения и отладки настоятельно рекомендуется использовать клиент с установленным Forge или Fabric.
**Шаг 4: Поиск ключевых классов и полей (fields)**
Имея `g_JniEnv`, мы можем начать взаимодействовать с игрой. Основная задача — получить доступ к объекту игрока и мира.
**Алгоритм получения объекта игрока:**
1. Найти класс `net/minecraft/client/Minecraft` с помощью `recaf, jadx (вам нужно открыть дамп и там искать классы, а уже в классах flied`.
2. Найти его статический метод `getMinecraft()`.
3. Вызвать этот метод, чтобы получить экземпляр класса `Minecraft`.
4. Из этого экземпляра получить поле `thePlayer`.
C++:
// 1. Находим класс Minecraft (точки заменяются на слеши)
jclass minecraftClass = g_JniEnv->FindClass("net/minecraft/client/Minecraft");
// 2. Находим статический метод getMinecraft().
// "func_71410_x" — это MCP-имя для версии 1.8.9. Для других версий оно может отличаться.
// "()Lnet/minecraft/client/Minecraft;" — это JNI-сигнатура метода.
jmethodID getMinecraftMethod = g_JniEnv->GetStaticMethodID(minecraftClass, "func_71410_x", "()Lnet/minecraft/client/Minecraft;");
// 3. Вызываем метод
jobject minecraftInstance = g_JniEnv->CallStaticObjectMethod(minecraftClass, getMinecraftMethod);
// 4. Находим и получаем поле thePlayer
// "field_71439_g" — MCP-имя для thePlayer
jfieldID playerField = g_JniEnv->GetFieldID(minecraftClass, "field_71439_g", "Lnet/minecraft/client/entity/EntityPlayerSP;");
jobject playerInstance = g_JniEnv->GetObjectField(minecraftInstance, playerField);
*Имена `func_...` и `field_...` являются частью MCP (Mod Coder Pack). Для поиска актуальных имен для вашей версии Minecraft используйте онлайн-базы данных MCP-маппингов.*
Получив `playerInstance`, вы можете получить доступ к его полям.
* `posX`, `posY`, `posZ` (тип `double`) - Координаты.
* `motionX`, `motionY`, `motionZ` (тип `double`) - Вектор движения.
* `onGround` (тип `boolean`) - Находится ли игрок на земле.
* `hurtTime` (тип `int`) - Таймер с момента получения урона.
* `inventory` (тип `InventoryPlayer`) - Инвентарь игрока.
Для доступа к ним используется `g_JniEnv->GetFieldID()` для получения ID, а затем `g_JniEnv->GetDoubleField()`, `g_JniEnv->GetBooleanField()` и т.д. для чтения значения.
* `posX`, `posY`, `posZ` (тип `double`) - Координаты.
* `motionX`, `motionY`, `motionZ` (тип `double`) - Вектор движения.
* `onGround` (тип `boolean`) - Находится ли игрок на земле.
* `hurtTime` (тип `int`) - Таймер с момента получения урона.
* `inventory` (тип `InventoryPlayer`) - Инвентарь игрока.
Для доступа к ним используется `g_JniEnv->GetFieldID()` для получения ID, а затем `g_JniEnv->GetDoubleField()`, `g_JniEnv->GetBooleanField()` и т.д. для чтения значения.
**Шаг 5: Работа с обфусцированным кодом: Дампинг**
Если ваша цель — ванильный клиент или сервер с собственными модами без деобфускации, вам потребуется провести анализ.
Основной метод — **дампинг классов**. С помощью спецаильных утилит (например, Java Class Dumper...) можно выгрузить все загруженные в JVM классы в виде `.class` файлов. Далее эти файлы открываются в декомпиляторе (JD-GUI, Luyten, Recaf) для анализа их логики и поиска нужных полей и методов по косвенным признакам (например, по используемым строковым константам или числовым значениям).
### **Пример реализации: функция FullBright (максимальная яркость)**
Простая функция, отключающая тени и делающая мир полностью освещенным.
C++:
// ... (после получения minecraftInstance)
// Получаем объект настроек gameSettings
jfieldID settingsField = g_JniEnv->GetFieldID(minecraftClass, "field_71474_y", "Lnet/minecraft/client/settings/GameSettings;");
jobject settingsInstance = g_JniEnv->GetObjectField(minecraftInstance, settingsField);
// Получаем класс GameSettings
jclass settingsClass = g_JniEnv->GetObjectClass(settingsInstance);
// Получаем поле gammaSetting (яркость)
jfieldID gammaField = g_JniEnv->GetFieldID(settingsClass, "field_74333_g", "F"); // "F" - сигнатура для типа float
// Устанавливаем новое значение
g_JniEnv->SetFloatField(settingsInstance, gammaField, 100.0f);
// При деактивации функции следует восстановить оригинальное значение.
**Заключение**
Данное руководство описывает лишь базовые шаги для начала работы. Дальнейшее развитие включает в себя изучение рендеринга (ESP) через хукинг OpenGL/DirectX, перехват Java-методов для создания более сложных функций (Killaura, Aimbot) и работу со списком сущностей в мире.
Надеюсь, эта информация будет полезной для ваших исследований.
**Отказ от ответственности:** Вся информация предоставлена исключительно в образовательных и исследовательских целях. Автор не несет ответственности за ее использование, которое может привести к блокировке игровых аккаунтов.