Гайд [Гайд] Разработка читов для Minecraft на C++ с использованием JNI

Jadddxxx

Потрачен
Автор темы
66
63
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Здравствуйте, уважаемые пользователи форума.

Данное руководство создано с целью восполнить пробел в русскоязычной информации по разработке читов для 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-классы игры, читать значения их полей (координаты, здоровье) и вызывать их методы (атака, прыжок).



**Шаг 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()` и т.д. для чтения значения.

**Шаг 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) и работу со списком сущностей в мире.

Надеюсь, эта информация будет полезной для ваших исследований.

**Отказ от ответственности:** Вся информация предоставлена исключительно в образовательных и исследовательских целях. Автор не несет ответственности за ее использование, которое может привести к блокировке игровых аккаунтов.
 

Jadddxxx

Потрачен
Автор темы
66
63
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Для разработчиков читов для кастомных серверов (Vime World, Rust Ex Remake, Rust me (не получиться так ведь ВМП стоит).)
Тот-же вайм блокирует любые подключения к jvm.dll - java.dll
Как обойти ? Легко.
Пример -
пример:
bool CheckJavaSignature() {
    HANDLE hProcess = GetCurrentProcess();
    HMODULE hModules[1024];
    DWORD cbNeeded;
   
    if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) {
        for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
            BYTE buffer[8];
            SIZE_T bytesRead;
           
            if (ReadProcessMemory(hProcess, hModules[i], buffer, sizeof(buffer), &bytesRead)) {
                if (bytesRead >= 8 &&
                    buffer[0] == 0xCA && buffer[1] == 0xFE &&
                    buffer[2] == 0xBA && buffer[3] == 0xBE &&
                    buffer[4] == 0x00 && buffer[5] == 0x00) {
                    return true;
                }
               
                if (bytesRead >= 4 &&
                    buffer[0] == 0xCA && buffer[1] == 0xFE &&
                    buffer[2] == 0xBA && buffer[3] == 0xBE) {
                    return true;
                }
            }
        }
    }
    return false;
}
говорю сразу, для всех проектов может не подойти ведь это стандартные сигнатуры jvm .
Пояснения для чайников -
Так как вайм чекает ДЛЛ , мы берем и подключаемься к джаве через главную сигнатуру :)
Почему 2 сигны ?
Ведь что-бы вам не искать на разных версиях официальных стоит 2 разных сигны. Тоесть если одна не ворк будет 2 юзаться

Здравствуйте, уважаемые пользователи форума.

Данное руководство создано с целью восполнить пробел в русскоязычной информации по разработке читов для 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-классы игры, читать значения их полей (координаты, здоровье) и вызывать их методы (атака, прыжок).



**Шаг 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()` и т.д. для чтения значения.

**Шаг 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) и работу со списком сущностей в мире.

Надеюсь, эта информация будет полезной для ваших исследований.

**Отказ от ответственности:** Вся информация предоставлена исключительно в образовательных и исследовательских целях. Автор не несет ответственности за ее использование, которое может привести к блокировке игровых аккаунтов.
Скоро выйдет полноценный видео урок по созданию читов.
на 40 минут либо же 1 час.
Обговорим все тонкости создания читов, дампинга, реверс инженеринга, поиск классов и так далее.
 
Последнее редактирование:

vindarix

Известный
73
12
Начиная со снапшотов обновления Mounts of Mayhem обфускацию официально убирают 🥰
 
  • Нравится
Реакции: Jadddxxx

fiksalka

Новичок
1
0
Будет очень круто если ты выпустишь видео-гайд на создание чита на Rustex remake 🫶
 

Jadddxxx

Потрачен
Автор темы
66
63
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Будет очень круто если ты выпустишь видео-гайд на создание чита на Rustex remake 🫶
на ремейке главные классы по типу entity и client грузяться в рантайме из skuff.dll
На это видео не будет, ведь там платные проходки, максимум это сделать заказ на этот проект за немаленькую сумму и предоставленые проходки.
 
  • Нравится
Реакции: fiksalka

RealMikoto

Новичок
1
0
@Jadddxxx можешь подсказать на каком языке лучше писать читы на Майнкрафт и какой язык лучше начать учить (как первый)
 

Jadddxxx

Потрачен
Автор темы
66
63
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
@Jadddxxx можешь подсказать на каком языке лучше писать читы на Майнкрафт и какой язык лучше начать учить (как первый)
Изучай сразу самый сложный язык с++, только он тебе пригодиться в жизни, луа, пайтон, джава (тут я ахуел, но джава ладно норм язык), котлин - хуйня.
Если ты хочешь зарабатывать много, и дохуя - с++. (либо линейка с, c#,C,C god )))
 
  • Эм
  • Нравится
Реакции: вайега52 и Hamster_

HomanzINC

Новичок
3
0
Здравствуйте, уважаемые пользователи форума.

Данное руководство создано с целью восполнить пробел в русскоязычной информации по разработке читов для 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-классы игры, читать значения их полей (координаты, здоровье) и вызывать их методы (атака, прыжок).



**Шаг 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()` и т.д. для чтения значения.

**Шаг 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) и работу со списком сущностей в мире.

Надеюсь, эта информация будет полезной для ваших исследований.

**Отказ от ответственности:** Вся информация предоставлена исключительно в образовательных и исследовательских целях. Автор не несет ответственности за ее использование, которое может привести к блокировке игровых аккаунтов.

Ты бы хотя-бы оставил статью с информацией по сигнатурам раз уж делаешь гайд, что за чек магик валю для чего это что за кринж ;D
 
Последнее редактирование:

HomanzINC

Новичок
3
0
@Jadddxxx можешь подсказать на каком языке лучше писать читы на Майнкрафт и какой язык лучше начать учить (как первый)
Если ты хочешь писать читы для ванильного майнкрафта (Не кастомные лаунчеры) изучай Java так как на этом языке и пишутся читы для кубов
C++ JNI(Используется для доступа к джава коду игры из натива так как в кастом лаунчере ты не сможешь загрузить свой мод или версию как это делается на ванильных кубах
 

Jadddxxx

Потрачен
Автор темы
66
63
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Ты бы хотя-бы оставил статью с информацией по сигнатурам раз уж делаешь гайд, что за чек магик валю для чего это что за кринж ;D
гайд во первых не полноценный, и он рассказывает только про базу, как вообще взаимодействовать с майном через jni,
и хоманз научись сначала есп не в одном потоке делать, а потом уже высирай мне эту хуйню здесь.

Если ты хочешь писать читы для ванильного майнкрафта (Не кастомные лаунчеры) изучай Java так как на этом языке и пишутся читы для кубов
C++ JNI(Используется для доступа к джава коду игры из натива так как в кастом лаунчере ты не сможешь загрузить свой мод или версию как это делается на ванильных кубах
Джава для майна это мертвый язык, слишком тут много долбаебов и пастеров, джаву лучше использовать для андроид приложений, а не для майна
 

HomanzINC

Новичок
3
0
гайд во первых не полноценный, и он рассказывает только про базу, как вообще взаимодействовать с майном через jni,
и хоманз научись сначала есп не в одном потоке делать, а потом уже высирай мне эту хуйню здесь.


Джава для майна это мертвый язык, слишком тут много долбаебов и пастеров, джаву лучше использовать для андроид приложений, а не для майна
У меня esp многопоточный, так ты же рассказываешь про базу разве сигнатуры это не база? камон
1763725612442.png