Может dll накрыта темидой и по этому такая разница.Charmant
Только что заметил отличие у тебя 8 а у меня b 0x81F538 - 0xb1f538
И самое странное, что твой hex работает а мой нет хотя в клиенте у мен b вместо 8)
Посмотреть вложение 79175
У длл есть базовый адрес. 10b1f538 это база + смещение. В ИЛ енжине базовый адрес 10300000, т.е: 0x10b1f538 - 0x10300000 = 0x81F538Мне кажется я неправильно высчитываю (опыта мало в этом деле)
Вот я нашел офсет EAX,[DAT_10b1f538] он будет равен 0xb1f538
Самое интересное что твой 0x81F538 работает а мой нет)
Почитайте про виртуальные адреса (VA) и относительные виртуальные адреса (RVA). Станет понятнееУ длл есть базовый адрес. 10b1f538 это база + смещение. В ИЛ енжине базовый адрес 10300000, т.е: 0x10b1f538 - 0x10300000 = 0x81F538
Я раньше этим занимался забыл обязательно почитаю спасибо!Почитайте про виртуальные адреса (VA) и относительные виртуальные адреса (RVA). Станет понятнее
Про сам интерфейс не знаю, но дождаться создания основного нативного окна (пропустив при этом сплэшскрин окно) я выкладывал на шарпе. Думаю стоит попробовать такой вариант, то есть через do-while ждать указатель на окноУ меня возник вопрос, связанный с этой же темой.
Есть ли какой-то флаг в L2, который позволяет определить, что окно с интерфейсом полностью загружено и готово к использованию?
var splashWindowHandler = IntPtr.Zero;
// Waiting for splash window handler
do
{
process.Refresh();
splashWindowHandler = process.MainWindowHandle;
}
while (splashWindowHandler == IntPtr.Zero);
var mainWindowHandler = IntPtr.Zero;
// Waiting for main window handler
do
{
process.Refresh();
if (splashWindowHandler != process.MainWindowHandle)
{
mainWindowHandler = process.MainWindowHandle;
}
}
while (mainWindowHandler == IntPtr.Zero);
void Init()
{
HMODULE hEngineModule = GetModuleHandleW(L"engine.dll");
if (hEngineModule != nullptr)
{
uintptr_t UNetworkAddress = (reinterpret_cast<uintptr_t>(hEngineModule)) + UNetworkOffset;
UNetwork = *reinterpret_cast<UNetworkHandler**>(UNetworkAddress);
MessageBox(NULL, L"Все данные собраны вход!!!!!", L"", MB_OK);
fRequestAuthLogin = (RequestAuthLogin_fn)GetProcAddress(hEngineModule, "?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z");
RequestLogin(L"admin", L"admin");
}
}
{
HMODULE hEngineModule = GetModuleHandleW(L"engine.dll");
if (hEngineModule == nullptr) {
return MessageBox(NULL, L"hEngineModule is null", L"", MB_OK);
}
uintptr_t UNetworkAddress = (reinterpret_cast<uintptr_t>(hEngineModule)) + UNetworkOffset;
UNetwork = *reinterpret_cast<UNetworkHandler**>(UNetworkAddress);
MessageBox(NULL, L"Все данные собраны вход!!!!!", L"", MB_OK);
fRequestAuthLogin = (RequestAuthLogin_fn)GetProcAddress(hEngineModule, "?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z");
if (fRequestAuthLogin == nullptr) {
return MessageBox(NULL, L"fRequestAuthLogin is null", L"", MB_OK);
}
RequestLogin(L"admin", L"admin");
}
Обработку ошибок я сразу сделал.Ну то есть стоит всегда проверять, что возвращают нативные функции апи винды, дабы понимать что пошло не так и на каком этапе
смотреть в документации на сайте майков по определенной функции, к примерузнать что ожидать while
Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работесмотреть в документации на сайте майков по определенной функции, к примеруВы не можете просматривать ссылку пожалуйста воспользуйтесь следующими ссылками Вход или Регистрациявозвращает null в случаи неудачи
Посмотреть вложение 79183
Как вариант использовать костыль, в коде меню с правой стороны например в HF, можно прописать чтобы переключало некий bool когда загружено в самой dll тогда та уже выполнит те функции которые нужны.Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работе
òbi
В данный момент я использую Sleep(3000), а затем вызываем функцию входа в игру.
Поскольку у всех разные компьютеры, скорость загрузки окна может быть выше 3000 миллисекунд, и тогда функция не будет выполнена.
Как и в моем примере, нам нужно из текущего процесса достать MainWindowHandle.Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работе
òbi
В данный момент я использую Sleep(3000), а затем вызываем функцию входа в игру.
Поскольку у всех разные компьютеры, скорость загрузки окна может быть выше 3000 миллисекунд, и тогда функция не будет выполнена.
HWND hCurWnd = nullptr;
do
{
hCurWnd = FindWindowEx(nullptr, hCurWnd, nullptr, nullptr);
DWORD checkProcessID = 0;
GetWindowThreadProcessId(hCurWnd, &checkProcessID);
if (checkProcessID == GetCurrentProcessId())
{
//
}
} while (hCurWnd != nullptr);
// OR
HWND hWnd;
for (;;)
{
DWORD a;
GetWindowThreadProcessId((hWnd = GetActiveWindow()), &a);
if ((a != GetCurrentProcessId()))
{
hWnd = NULL;
continue;
}
}
Активное загруженное окно можно получить и так HWND GetForegroundWindow();Как и в моем примере, нам нужно из текущего процесса достать MainWindowHandle.
Попустил твое сообщение подскажи как использовать UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z) Из него нужно получить какие-то параметры?Учтите что UNetworkHandler при аттаче библиотеки может не существовать вовсе. Запрашивать RequestAuthLogin нужно после того как клиент загрузился (окно логин-пароль): проще всего перехватывать первый вызов UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z)
Попробуй через класс окна l2UnrealWWindowsViewportWindowУ меня возник вопрос, связанный с этой же темой.
Есть ли какой-то флаг в L2, который позволяет определить, что окно с интерфейсом полностью загружено и готово к использованию?
Для меня не составляет труда найти окно, сложнее понять, когда оно загружено полностью или, по крайней мере, готово к обработке команд от сервера.Попробуй через класс окна l2UnrealWWindowsViewportWindow
// Поток для авторизации
static DWORD WINAPI TestThread(LPVOID lpParameter) {
// Получение модуля fire.dll
HMODULE fireStart = GetModuleHandleW(L"fire.dll");
// Цикл, который выполняется, пока не будет получен handle
while (!fireStart) {
Sleep(100); // 100 миллисекунд
// Повторно получить handle
fireStart = GetModuleHandleW(L"fire.dll");
}
Sleep(1000);// 1000 миллисекунд
// Вызов функции авторизации
RequestLogin(login, password);
return 0;
}
У клиента есть функция проверки состояния, которая активно используется в nwindow.dll - UL2ConsoleWnd::GetStateАктивное загруженное окно можно получить и так HWND GetForegroundWindow();
Пока ищу способ может кто-то еще подскажет)
Попустил твое сообщение подскажи как использовать UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z) Из него нужно получить какие-то параметры?
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc; // для IL клиента
}
DWORD WINAPI init(LPVOID lpParameter)
{
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
// получение валидного указателя на UL2ConsoleWnd
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
// просто пример получения текущего состояния в цикле
// можно сделать отдельной функцией и получать состояние по необходимости
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::Loading:
MessageBoxW(NULL, L"загрузка", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::Login:
MessageBoxW(NULL, L"лобби", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharCreate:
MessageBoxW(NULL, L"cоздание чара", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharSelect:
MessageBoxW(NULL, L"выбор чара", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"в игре", L"L2ConsoleState", MB_OK);
break;
}
Sleep(5000);
}
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);
{
HANDLE hThread = CreateThread(NULL, 0, init, NULL, 0, NULL);
if (hThread != NULL)
{
CloseHandle(hThread);
}
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Спасибо большое буду разбираться!У клиента есть функция проверки состояния, которая активно используется в nwindow.dll - UL2ConsoleWnd::GetState
[AutoLogin]
Login=admin
Password=admin
#include "pch.h"
#include <windows.h>
#include <string>
extern "C" void __declspec(dllexport) __stdcall function1()
{
//Заглушка для экспорта L2.exe (От крита клиента!)
}
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc; // для IL клиента
}
// Определение класса UNetworkHandler
class UNetworkHandler {};
// Тип функции RequestAuthLogin
typedef int(__fastcall* RequestAuthLoginFn)(UNetworkHandler*, int, const wchar_t*, const wchar_t*, int);
// Смещение для UNetworkHandler в engine.dll
const uintptr_t unetworkOffset = 0x81F538;
// Глобальные переменные для хранения указателей
UNetworkHandler** unetwork = nullptr;
RequestAuthLoginFn requestAuthLoginFn = nullptr;
// Функция для авторизации
static void RequestLogin(const std::wstring& login, const std::wstring& password) {
// Проверка инициализации указателей
if (!unetwork || !requestAuthLoginFn) {
return;
}
// Вызов функции авторизации из игры
requestAuthLoginFn(*unetwork, 0, login.c_str(), password.c_str(), 0);
}
// Функция для чтения строки из INI-файла
static void ReadIniString() {
std::wstring login;
std::wstring password;
wchar_t buffer[256] = { 0 };
// Чтение логина и пароля из ini-файла
GetPrivateProfileStringW(L"AutoLogin", L"Login", L"", buffer, _countof(buffer), L".\\AutoLogin.ini");
login = buffer;
// Чтение логина и пароля из ini-файла
GetPrivateProfileStringW(L"AutoLogin", L"Login", L"", buffer, _countof(buffer), L".\\AutoLogin.ini");
password = buffer;
// Вызов функции авторизации
RequestLogin(login, password);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
// получение валидного указателя на UL2ConsoleWnd
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::Loading:
// MessageBoxW(NULL, L"загрузка", L"L2ConsoleState", MB_OK);
ReadIniString();
exit;
break;
case L2ConsoleState::Login:
//MessageBoxW(NULL, L"лобби", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharCreate:
//MessageBoxW(NULL, L"cоздание чара", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharSelect:
//MessageBoxW(NULL, L"выбор чара", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::InGame:
// MessageBoxW(NULL, L"в игре", L"L2ConsoleState", MB_OK);
break;
}
Sleep(5000);
}
}
// Поток для авторизации
static DWORD WINAPI TestThread(LPVOID lpParameter) {
L2StatusLoad();
return 0;
}
// Точка входа DLL
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
// Отключение отслеживания вызовов функций библиотеки
DisableThreadLibraryCalls(hModule);
// Получение модуля engine.dll
HMODULE engineModule = GetModuleHandleW(L"engine.dll");
if (engineModule) {
// Получение адреса UNetworkHandler
unetwork = reinterpret_cast<UNetworkHandler**>(reinterpret_cast<uintptr_t>(engineModule) + unetworkOffset);
// Получение адреса функции RequestAuthLogin
requestAuthLoginFn = (RequestAuthLoginFn)GetProcAddress(engineModule, "?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z");
}
// Создание потока для авторизации
CreateThread(nullptr, 0, TestThread, nullptr, 0, nullptr);
}
return TRUE;
}
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?