Экран выбора персонажа / выбор персонажа

gbcdev96

Путник
Пользователь
Сообщения
66
Розыгрыши
0
Репутация
0
Реакции
1
Баллы
31
Привет, я хотел бы узнать, какой экран отвечает за выбор персонажа, и как я могу узнать индекс или информацию о выбранном персонаже в данный момент. Это возможно? Я искал информацию о коде в Ghidra в core.dll и nwindow.dll, но не нашел ничего подходящего. Буду рад, если кто-нибудь сможет мне помочь.

Для начала я хотел бы просто получить информацию о выбранном персонаже.
 
Решение
Оставлю ато забуду))
Для интерлюдии, получим index выбранного персонажа.

SelChar.webp

Исходник DLL:
C++:
#include "pch.h"
#include <iostream>
#include <string> 
#include <sstream> 
#include <Windows.h>

namespace { // Анонимное пространство имен, ограничивает область видимости переменных

    // Перечисление для состояний окна Lineage 2
    enum class L2ConsoleState {
        Loading = 0,  // Загрузка
        Unknown = 1,  // Неизвестно
        Login = 2,    // Вход в аккаунт
        CharCreate = 3,// Создание персонажа
        CharSelect = 4,// Выбор персонажа
        InGame = 5    // В игре
    };

    class UL2ConsoleWnd; // Предварительное объявление структуры окна консоли L2

    UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr; //...
CharacterSelectWnd.uc модул в интерфейс и ui6.ugx (по спомени) вообще не вярно, я мешал с CharacterCreateMenu
 
Привет, я хотел бы узнать, какой экран отвечает за выбор персонажа, и как я могу узнать индекс или информацию о выбранном персонаже в данный момент. Это возможно? Я искал информацию о коде в Ghidra в core.dll и nwindow.dll, но не нашел ничего подходящего. Буду рад, если кто-нибудь сможет мне помочь.

Для начала я хотел бы просто получить информацию о выбранном персонаже.
В engine.dll можно (ну, если нет защит, которьіе не дадут так сделать, конечно :loltt0:) пакет CharacterSelectionInfo
(если не ошибаюсь з названием, могу заплужить в єтом месте, короче, имеется ввиду пакет, которьіе сервер шлет после вьібора сервера со списком персонажей) ловить, там индекс будет.
 
Привет, я хотел бы узнать, какой экран отвечает за выбор персонажа, и как я могу узнать индекс или информацию о выбранном персонаже в данный момент. Это возможно? Я искал информацию о коде в Ghidra в core.dll и nwindow.dll, но не нашел ничего подходящего. Буду рад, если кто-нибудь сможет мне помочь.

Для начала я хотел бы просто получить информацию о выбранном персонаже.
Посмотрите в коде интерфейса uc, там видно как получать индекс каждого персонажа при выборе.
Через кастомную dll можно например показать сообщение с индексом.
Переведите только из int в string.

 
  • Люблю это
Реакции: Rolo

    Rolo

    Баллов: 10
    Воистину молвите!
Оставлю ато забуду))
Для интерлюдии, получим index выбранного персонажа.

SelChar.webp

Исходник DLL:
C++:
#include "pch.h"
#include <iostream>
#include <string> 
#include <sstream> 
#include <Windows.h>

namespace { // Анонимное пространство имен, ограничивает область видимости переменных

    // Перечисление для состояний окна Lineage 2
    enum class L2ConsoleState {
        Loading = 0,  // Загрузка
        Unknown = 1,  // Неизвестно
        Login = 2,    // Вход в аккаунт
        CharCreate = 3,// Создание персонажа
        CharSelect = 4,// Выбор персонажа
        InGame = 5    // В игре
    };

    class UL2ConsoleWnd; // Предварительное объявление структуры окна консоли L2

    UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr; // Указатель на экземпляр UL2ConsoleWnd
    const uintptr_t consoleOffset = 0x3663bc; // Смещение в памяти до адреса UL2ConsoleWnd
    const uintptr_t stateOffset = 0x38;       // Смещение в структуре UL2ConsoleWnd состояния окна игры
    const uintptr_t selectedCharacterNumOffset = 0x48; // Смещение в структуре UL2ConsoleWnd index выбранного персонажа
    bool consoleCreated = false; // Флаг, указывающий, была ли уже создана консоль
}

// Создает консоль, если она еще не создана
void CreateConsole() {
    if (!consoleCreated) {
        AllocConsole(); // Создаем окно консоли
        FILE* fDummy;
        freopen_s(&fDummy, "CONOUT$", "w", stdout); // Перенаправляем стандартный вывод в консоль
        freopen_s(&fDummy, "CONIN$", "r", stdin);   // Перенаправляем стандартный ввод в консоль
        std::cout << "Console created" << std::endl; // Выводим сообщение о создании консоли
        consoleCreated = true; // Устанавливаем флаг, что консоль создана
    }
}

// Функция инициализации (запускается в отдельном потоке)
DWORD WINAPI init(LPVOID lpParameter) {
    HMODULE hNwindowModule = nullptr; // Дескриптор модуля nwindow.dll
    while ((hNwindowModule = GetModuleHandleW(L"nwindow.dll")) == nullptr) { // Ждем загрузки nwindow.dll
        Sleep(1000); // Задержка 1 сек.
    }

    uintptr_t pUL2ConsoleWnd = reinterpret_cast<uintptr_t>(hNwindowModule) + consoleOffset; // Вычисляем адрес UL2ConsoleWnd

    while ((UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd)) == nullptr) { // Ждем, пока UL2ConsoleWndPtr не будет установлен
        Sleep(300); // Задержка 300 мс
    }
    // Получаем указатели на состояние консоли и номер выбранного персонажа, используя смещения
    L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + stateOffset);
    int* SelectedCharacterNum = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + selectedCharacterNumOffset);

    int lastSelectedChar = -1; // Переменная для отслеживания последнего выбранного персонажа

    while (true) { // Бесконечный цикл
        if (*statePtr == L2ConsoleState::CharSelect) // Если текущее состояние консоли - выбор персонажа
        {
            if (!consoleCreated) // Создаем консоль, если она еще не создана
                CreateConsole();

            int currentSelectedChar = *SelectedCharacterNum; // Получаем текущий выбранный номер персонажа

            if (currentSelectedChar != lastSelectedChar) // Если выбранный номер персонажа изменился
            {
                lastSelectedChar = currentSelectedChar; // Обновляем последний выбранный номер
                std::cout << "SelectedCharacterNum = " << currentSelectedChar << std::endl; // Выводим сообщение с номером выбранного персонажа
            }
        }

        Sleep(100); // Задержка 100 мс
    }
    return 0;
}

// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: // При присоединении DLL к процессу
        DisableThreadLibraryCalls(hModule); // Отключаем уведомления о событиях потока для данной DLL
        if (HANDLE hThread = CreateThread(nullptr, 0, init, nullptr, 0, nullptr)) { // Создаем отдельный поток для функции init
            CloseHandle(hThread); // Закрываем дескриптор потока, поток продолжит работу в фоне
        }
        break;
    }
    return TRUE; // Возвращаем TRUE при успехе
}
 
Решение
Оставлю ато забуду))
Для интерлюдии, получим index выбранного персонажа.

Посмотреть вложение 83853

Исходник DLL:
C++:
#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>
#include <Windows.h>

namespace { // Анонимное пространство имен, ограничивает область видимости переменных

    // Перечисление для состояний окна Lineage 2
    enum class L2ConsoleState {
        Loading = 0,  // Загрузка
        Unknown = 1,  // Неизвестно
        Login = 2,    // Вход в аккаунт
        CharCreate = 3,// Создание персонажа
        CharSelect = 4,// Выбор персонажа
        InGame = 5    // В игре
    };

    class UL2ConsoleWnd; // Предварительное объявление структуры окна консоли L2

    UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr; // Указатель на экземпляр UL2ConsoleWnd
    const uintptr_t consoleOffset = 0x3663bc; // Смещение в памяти до адреса UL2ConsoleWnd
    const uintptr_t stateOffset = 0x38;       // Смещение в структуре UL2ConsoleWnd состояния окна игры
    const uintptr_t selectedCharacterNumOffset = 0x48; // Смещение в структуре UL2ConsoleWnd index выбранного персонажа
    bool consoleCreated = false; // Флаг, указывающий, была ли уже создана консоль
}

// Создает консоль, если она еще не создана
void CreateConsole() {
    if (!consoleCreated) {
        AllocConsole(); // Создаем окно консоли
        FILE* fDummy;
        freopen_s(&fDummy, "CONOUT$", "w", stdout); // Перенаправляем стандартный вывод в консоль
        freopen_s(&fDummy, "CONIN$", "r", stdin);   // Перенаправляем стандартный ввод в консоль
        std::cout << "Console created" << std::endl; // Выводим сообщение о создании консоли
        consoleCreated = true; // Устанавливаем флаг, что консоль создана
    }
}

// Функция инициализации (запускается в отдельном потоке)
DWORD WINAPI init(LPVOID lpParameter) {
    HMODULE hNwindowModule = nullptr; // Дескриптор модуля nwindow.dll
    while ((hNwindowModule = GetModuleHandleW(L"nwindow.dll")) == nullptr) { // Ждем загрузки nwindow.dll
        Sleep(1000); // Задержка 1 сек.
    }

    uintptr_t pUL2ConsoleWnd = reinterpret_cast<uintptr_t>(hNwindowModule) + consoleOffset; // Вычисляем адрес UL2ConsoleWnd

    while ((UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd)) == nullptr) { // Ждем, пока UL2ConsoleWndPtr не будет установлен
        Sleep(300); // Задержка 300 мс
    }
    // Получаем указатели на состояние консоли и номер выбранного персонажа, используя смещения
    L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + stateOffset);
    int* SelectedCharacterNum = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + selectedCharacterNumOffset);

    int lastSelectedChar = -1; // Переменная для отслеживания последнего выбранного персонажа

    while (true) { // Бесконечный цикл
        if (*statePtr == L2ConsoleState::CharSelect) // Если текущее состояние консоли - выбор персонажа
        {
            if (!consoleCreated) // Создаем консоль, если она еще не создана
                CreateConsole();

            int currentSelectedChar = *SelectedCharacterNum; // Получаем текущий выбранный номер персонажа

            if (currentSelectedChar != lastSelectedChar) // Если выбранный номер персонажа изменился
            {
                lastSelectedChar = currentSelectedChar; // Обновляем последний выбранный номер
                std::cout << "SelectedCharacterNum = " << currentSelectedChar << std::endl; // Выводим сообщение с номером выбранного персонажа
            }
        }

        Sleep(100); // Задержка 100 мс
    }
    return 0;
}

// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: // При присоединении DLL к процессу
        DisableThreadLibraryCalls(hModule); // Отключаем уведомления о событиях потока для данной DLL
        if (HANDLE hThread = CreateThread(nullptr, 0, init, nullptr, 0, nullptr)) { // Создаем отдельный поток для функции init
            CloseHandle(hThread); // Закрываем дескриптор потока, поток продолжит работу в фоне
        }
        break;
    }
    return TRUE; // Возвращаем TRUE при успехе
}

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

?SelectedCharacterNum@UL2ConsoleWnd@@UAEXH@Z

 
Оставлю ато забуду))
Для интерлюдии, получим index выбранного персонажа.

Посмотреть вложение 83853

Исходник DLL:
C++:
#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>
#include <Windows.h>

namespace { // Анонимное пространство имен, ограничивает область видимости переменных

    // Перечисление для состояний окна Lineage 2
    enum class L2ConsoleState {
        Loading = 0,  // Загрузка
        Unknown = 1,  // Неизвестно
        Login = 2,    // Вход в аккаунт
        CharCreate = 3,// Создание персонажа
        CharSelect = 4,// Выбор персонажа
        InGame = 5    // В игре
    };

    class UL2ConsoleWnd; // Предварительное объявление структуры окна консоли L2

    UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr; // Указатель на экземпляр UL2ConsoleWnd
    const uintptr_t consoleOffset = 0x3663bc; // Смещение в памяти до адреса UL2ConsoleWnd
    const uintptr_t stateOffset = 0x38;       // Смещение в структуре UL2ConsoleWnd состояния окна игры
    const uintptr_t selectedCharacterNumOffset = 0x48; // Смещение в структуре UL2ConsoleWnd index выбранного персонажа
    bool consoleCreated = false; // Флаг, указывающий, была ли уже создана консоль
}

// Создает консоль, если она еще не создана
void CreateConsole() {
    if (!consoleCreated) {
        AllocConsole(); // Создаем окно консоли
        FILE* fDummy;
        freopen_s(&fDummy, "CONOUT$", "w", stdout); // Перенаправляем стандартный вывод в консоль
        freopen_s(&fDummy, "CONIN$", "r", stdin);   // Перенаправляем стандартный ввод в консоль
        std::cout << "Console created" << std::endl; // Выводим сообщение о создании консоли
        consoleCreated = true; // Устанавливаем флаг, что консоль создана
    }
}

// Функция инициализации (запускается в отдельном потоке)
DWORD WINAPI init(LPVOID lpParameter) {
    HMODULE hNwindowModule = nullptr; // Дескриптор модуля nwindow.dll
    while ((hNwindowModule = GetModuleHandleW(L"nwindow.dll")) == nullptr) { // Ждем загрузки nwindow.dll
        Sleep(1000); // Задержка 1 сек.
    }

    uintptr_t pUL2ConsoleWnd = reinterpret_cast<uintptr_t>(hNwindowModule) + consoleOffset; // Вычисляем адрес UL2ConsoleWnd

    while ((UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd)) == nullptr) { // Ждем, пока UL2ConsoleWndPtr не будет установлен
        Sleep(300); // Задержка 300 мс
    }
    // Получаем указатели на состояние консоли и номер выбранного персонажа, используя смещения
    L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + stateOffset);
    int* SelectedCharacterNum = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(UL2ConsoleWndPtr) + selectedCharacterNumOffset);

    int lastSelectedChar = -1; // Переменная для отслеживания последнего выбранного персонажа

    while (true) { // Бесконечный цикл
        if (*statePtr == L2ConsoleState::CharSelect) // Если текущее состояние консоли - выбор персонажа
        {
            if (!consoleCreated) // Создаем консоль, если она еще не создана
                CreateConsole();

            int currentSelectedChar = *SelectedCharacterNum; // Получаем текущий выбранный номер персонажа

            if (currentSelectedChar != lastSelectedChar) // Если выбранный номер персонажа изменился
            {
                lastSelectedChar = currentSelectedChar; // Обновляем последний выбранный номер
                std::cout << "SelectedCharacterNum = " << currentSelectedChar << std::endl; // Выводим сообщение с номером выбранного персонажа
            }
        }

        Sleep(100); // Задержка 100 мс
    }
    return 0;
}

// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH: // При присоединении DLL к процессу
        DisableThreadLibraryCalls(hModule); // Отключаем уведомления о событиях потока для данной DLL
        if (HANDLE hThread = CreateThread(nullptr, 0, init, nullptr, 0, nullptr)) { // Создаем отдельный поток для функции init
            CloseHandle(hThread); // Закрываем дескриптор потока, поток продолжит работу в фоне
        }
        break;
    }
    return TRUE; // Возвращаем TRUE при успехе
}
Как это запустить?
 
Как это запустить?
1. Скопилить в DLL (Visual Studio 2020+ or gcc) в какойнибудь `L2ConsoleHook.dll` (x32)
2. Скачать например
3.
Код:
./InjectorCLIx86.exe <path_to>/L2.exe <path_to>/L2ConsoleHook.dll
4. Запустить & Profit.

.

Тут вариантов приличное количество как и в выборе тулсета, так и в выборе куда непосредственно хукать. Если не хотим менять L2.exe на прямую то можно делать косвенно через thirdparty .dll's ака `vorbis.dll`, `ogg.dll` которые подгружаются сами игрой.

Вот пара хороших туториалов 👇

 
Последнее редактирование:
1. Скопилить в DLL (Visual Studio 2020+ or gcc) в какойнибудь `L2ConsoleHook.dll` (x32)
2. Скачать например
3.
Код:
./InjectorCLIx86.exe <path_to>/L2.exe <path_to>/L2ConsoleHook.dll
4. Запустить & Profit.

.

Тут вариантов приличное количество как и в выборе тулсета, так и в выборе куда непосредственно хукать. Если не хотим менять L2.exe на прямую то можно делать косвенно через thirdparty .dll's ака `vorbis.dll`, `ogg.dll` которые подгружаются сами игрой.

Вот пара хороших туториалов 👇

А есть какая-нибудь hello world dll чтобы до компила понять что все запускается? Чтобы messagebox для теста показать?
 
А есть какая-нибудь hello world dll чтобы до компила понять что все запускается? Чтобы messagebox для теста показать?
dll не исполняемый файл. Тебе нужно ее заинжектить \ добавить в таблицу импортов, чтобы она у тебя заработала. https://mmo-dev.info/threads/Гайд-по-подключению-dll-экстендера.1880/
 
dll не исполняемый файл. Тебе нужно ее заинжектить \ добавить в таблицу импортов, чтобы она у тебя заработала. https://mmo-dev.info/threads/Гайд-по-подключению-dll-экстендера.1880/
Я это понимаю но перед тем как компилить и подключал и понимать правильно ли все я бы хотел хоть что-то подключить и проверить как оно работает. Dll да это подключаемая библиотека к исполняемому файлу
 
Я это понимаю но перед тем как компилить и подключал и понимать правильно ли все я бы хотел хоть что-то подключить и проверить как оно работает. Dll да это подключаемая библиотека к исполняемому файлу
C++:
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI Main(LPVOID lpParam) {
    MessageBoxA(0, "Success", "OK", MB_OK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(NULL, 0, Main, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        // Очистка ресурсов
        break;
    }
    return TRUE;
}
Если я тебя понял, ты просто хочешь попробовать поподключать длл, тогда попробуй вот такое. При инжекте должно выкинуть месседж бокс. Компиль в х86\32 режиме
 
C++:
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI Main(LPVOID lpParam) {
    MessageBoxA(0, "Success", "OK", MB_OK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(NULL, 0, Main, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        // Очистка ресурсов
        break;
    }
    return TRUE;
}
Если я тебя понял, ты просто хочешь попробовать поподключать длл, тогда попробуй вот такое. При инжекте должно выкинуть месседж бокс. Компиль в х86\32 режиме
1) Скомпилил под x86
2) Открываю CFF Explorer -> L2.exe -> Import myTestDll.dll

Ошибка
invalid PE file. Possible reason: no Export Table present
 
1. Скопилить в DLL (Visual Studio 2020+ or gcc) в какойнибудь `L2ConsoleHook.dll` (x32)
2. Скачать например
3.
Код:
./InjectorCLIx86.exe <path_to>/L2.exe <path_to>/L2ConsoleHook.dll
4. Запустить & Profit.

.

Тут вариантов приличное количество как и в выборе тулсета, так и в выборе куда непосредственно хукать. Если не хотим менять L2.exe на прямую то можно делать косвенно через thirdparty .dll's ака `vorbis.dll`, `ogg.dll` которые подгружаются сами игрой.

Вот пара хороших туториалов 👇

3 шаг

Loaded VA for NtUserBlockInput = 0x75FB4A10
Loaded VA for NtUserQueryWindow = 0x75FB1100
Loaded VA for NtUserGetForegroundWindow = 0x75FB13C0
Loaded VA for NtUserBuildHwndList = 0x75FB11C0
Loaded VA for NtUserFindWindowEx = 0x75FB16C0
Loaded VA for NtUserGetClassName = 0x75FB1790
Loaded VA for NtUserInternalGetWindowText = 0x75FB1620
Loaded VA for NtUserGetThreadState = 0x75FB1000
Usage: InjectorCLIx86.exe <process name> <dll path> [nowait]
Usage: InjectorCLIx86.exe pid:<process id> <dll path> [nowait]

Потом запускать игру?
Я запустил и ничего не произошло

DLL, которую я скомпилил под x86 имеет код

C++:
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI Main(LPVOID lpParam) {
    MessageBoxA(0, "Success", "OK", MB_OK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(NULL, 0, Main, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        // Очистка ресурсов
        break;
    }
    return TRUE;
}
 
1) Скомпилил под x86
2) Открываю CFF Explorer -> L2.exe -> Import myTestDll.dll

Ошибка
invalid PE file. Possible reason: no Export Table present
C++:
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
extern "C" __declspec(dllexport) void InstallHook();



void InstallHook() {
    HANDLE hProcess = GetCurrentProcess();
    HMODULE hEngineModule = GetModuleHandleW(L"engine.dll");
  
}

DWORD WINAPI Main(LPVOID lpParam) {
    InstallHook();
    MessageBoxA(0, "Success", "OK", MB_OK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(NULL, 0, Main, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        // Очистка ресурсов
        break;
    }
    return TRUE;
}

InstallHook - будущая функция для реализации твоего функционала. Добавил ее в таблицу экспорта, теперь должно присоеденить файл
Для прямого инжекта -
 
C++:
#include "pch.h"
#include <Windows.h>
#include <stdio.h>
extern "C" __declspec(dllexport) void InstallHook();



void InstallHook() {
    HANDLE hProcess = GetCurrentProcess();
    HMODULE hEngineModule = GetModuleHandleW(L"engine.dll");
 
}

DWORD WINAPI Main(LPVOID lpParam) {
    InstallHook();
    MessageBoxA(0, "Success", "OK", MB_OK);
    return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hModule);
        CreateThread(NULL, 0, Main, NULL, 0, NULL);
        break;
    case DLL_PROCESS_DETACH:
        // Очистка ресурсов
        break;
    }
    return TRUE;
}

InstallHook - будущая функция для реализации твоего функционала. Добавил ее в таблицу экспорта, теперь должно присоеденить файл
Для прямого инжекта -
An error occurred while injection "Dll1.dll" into "L2.exe"

System.Exception: The injection method used returned NULL (injection failed)
 
Как это запустить?

В Visual Studio 2022 выберите язык C++ и создайте файл с расширением *.dll. Затем просто скопируйте и вставьте код, который я предоставил, и соберите проект в режиме x86.

1740663001279.webp

После этого можешь использовать «CFF Explorer» или «Extreme Injector» для внедрения dll в процесс игры во время её работы. Более подробную информация на этом видео:



У меня тоже есть свой Injector но в свободном доступе его нет
 
Назад
Сверху