#include "pch.h"
#include <windows.h>
#include <string>
extern "C" void __declspec(dllexport) __stdcall function1()
{
Stub for exporting L2.exe (From customer crits!)
}
namespace {
enum L2ConsoleState {
Loading = 0,
Unknown = 1,
Login = 2,
CharCreate = 3,
CharSelect = 4,
InGame = 5
};
class UL2ConsoleWnd {};
UL2ConsoleWnd* UL2ConsoleWndPtr = nullptr;
uintptr_t consoleOffset = 0x3663bc; for IL client
}
Defining the UNetworkHandler class
class UNetworkHandler {};
Function type: RequestAuthLogin
typedef int(__fastcall* RequestAuthLoginFn)(UNetworkHandler*, int, const wchar_t*, const wchar_t*, int);
Offset for UNetworkHandler in engine.dll
const uintptr_t unetworkOffset = 0x81F538;
Global variables for storing pointers
UNetworkHandler** unetwork = nullptr;
RequestAuthLoginFn requestAuthLoginFn = nullptr;
Function for authorization
static void RequestLogin(const std::wstring& login, const std::wstring& password) {
Verifying pointer initialization
if (!unetwork || !requestAuthLoginFn) {
return;
}
Calling the Authorization Function from the Game
requestAuthLoginFn(*unetwork, 0, login.c_str(), password.c_str(), 0);
}
A function to read a string from an INI file
static void ReadIniString() {
std::wstring login;
std::wstring password;
wchar_t buffer[256] = { 0 };
Reading the login and password from the ini file
GetPrivateProfileStringW(L"AutoLogin", L"Login", L"", buffer, _countof(buffer), L".\\AutoLogin.ini");
login = buffer;
Reading the login and password from the ini file
GetPrivateProfileStringW(L"AutoLogin", L"Login", L"", buffer, _countof(buffer), L".\\AutoLogin.ini");
password = buffer;
Calling the Authorization Function
RequestLogin(login, password);
}
static void L2StatusLoad() {
HMODULE hNwindowModule = nullptr;
while (hNwindowModule == nullptr)
{
hNwindowModule = GetModuleHandleW(L"nwindow.dll");
Sleep(1000);
}
Getting a valid pointer to the UL2ConsoleWnd
uintptr_t pUL2ConsoleWnd = (reinterpret_cast<uintptr_t>(hNwindowModule)) + consoleOffset;
while (UL2ConsoleWndPtr == nullptr)
{
UL2ConsoleWndPtr = *reinterpret_cast<UL2ConsoleWnd**>(pUL2ConsoleWnd);
Sleep(300);
}
Get the address where the current state is recorded
L2ConsoleState* statePtr = reinterpret_cast<L2ConsoleState*>(UL2ConsoleWndPtr + 0x38);
while (true)
{
L2ConsoleState currentState = *statePtr;
switch (currentState)
{
case L2ConsoleState::Loading:
MessageBoxW(NULL, L"load", L"L2ConsoleState", MB_OK);
ReadIniString();
exit;
break;
case L2ConsoleState::Login:
MessageBoxW(NULL, L"lobby", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharCreate:
MessageBoxW(NULL, L"Creation of Enchantment", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::CharSelect:
MessageBoxW(NULL, L"char selection", L"L2ConsoleState", MB_OK);
break;
case L2ConsoleState::InGame:
MessageBoxW(NULL, L"in-game", L"L2ConsoleState", MB_OK);
break;
}
Sleep(5000);
}
}
Flow for authorization
static DWORD WINAPI TestThread(LPVOID lpParameter) {
L2StatusLoad();
return 0;
}
DLL Entry Point
extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
Disable Library Function Call Tracking
DisableThreadLibraryCalls(hModule);
Getting the engine.dll Module
HMODULE engineModule = GetModuleHandleW(L"engine.dll");
if (engineModule) {
Getting the UNetworkHandler Address
unetwork = reinterpret_cast<UNetworkHandler**>(reinterpret_cast<uintptr_t>(engineModule) + unetworkOffset);
Getting the address of the RequestAuthLogin function
requestAuthLoginFn = (RequestAuthLoginFn)GetProcAddress(engineModule, "? RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z");
}
Create a flow for authorization
CreateThread(nullptr, 0, TestThread, nullptr, 0, nullptr);
}
return TRUE;
}