PDA

Просмотр полной версии : Как сделать Автологин Интерлюдия?


BIT_hack
01.11.2024, 10:48
В интернете я нашёл информацию о том, что нужно использовать функцию для автологина из Engine.dll. Вот как она выглядит в интерлюдии.

C++:



public
:
virtual
int
__thiscall UNetworkHandler
::
RequestAuthLogin
(
unsigned
short
*
,
unsigned
short
*
,
int
)
;


Этот код на c++я инжектю в игру

C++:



void
Start
(
)
{
HMODULE hModule
=
GetModuleHandleA
(
"engine.dll"
)
;
// Получаем дескриптор загруженной DLL
if
(
hModule
!=
NULL
)
{
FARPROC requestAuthLoginAddr
=
GetProcAddress
(
hModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
if
(
requestAuthLoginAddr
!=
NULL
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
typedef
int
(
__thiscall
*
RequestAuthLoginFunc
)
(
unsigned
short
*
,
unsigned
short
*
,
int
)
;
RequestAuthLoginFunc RequestAuthLogin
=
(
RequestAuthLoginFunc
)
requestAuthLoginAddr
;
unsigned
short
Login
[
]
=
{
'a'
,
'd'
,
'm'
,
'i'
,
'n'
,
0
}
;
unsigned
short
Password
[
]
=
{
'a'
,
'd'
,
'm'
,
'i'
,
'n'
,
0
}
;
int
authType
=
7
;
RequestAuthLogin
(
Login
,
Password
,
authType
)
;
}
}
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
Start
(
)
;
break
;
}
return
TRUE
;
}


Возможно, я не совсем верно подхожу к реализации этой идеи?​

root@localhost:~#
01.11.2024, 10:50
@Rolo (https://forum.antichat.xyz/members/909824/)

Maksim
01.11.2024, 11:21
По идее все правильно, можно еще с тех полей сохранить данные и потом в списке выбирать на какой аккаунт заходить в окошке html например или рядом раскрывающийся список с кнопкой. ?

BIT_hack
01.11.2024, 11:25
По идее все правильно, можно еще с тех полей сохранить данные и потом в списке выбирать на какой аккаунт заходить в окошке html например или рядом раскрывающийся список с кнопкой. ?


Забыл написать в шапке темы - При инжекте выводится сообщение



C++:



MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;


Это значит что dll нашлась и функция тоже



C++:



RequestAuthLogin
(
Login
,
Password
,
authType
)
;


Но при выполнение ее ничего не происходит

Maksim
01.11.2024, 11:28
Забыл написать в шапке темы - При инжекте выводится сообщение



C++:



MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;


Это значит что dll нашлась и функция тоже



C++:



RequestAuthLogin
(
Login
,
Password
,
authType
)
;


Но при выполнение ее ничего не происходит


Может authtype нужен другой? По идее клиент бы написал сообщение, пароль не правильный как минимум или зашел на сервер. ?

BIT_hack
01.11.2024, 11:29
Может authtype нужен другой? По идее он бы написал сообщение, пароль не правильный как минимум или зашел на сервер. ?


Проверял вообще тишина никакой реакции(

Maksim
01.11.2024, 11:31
Проверял вообще тишина никакой реакции(


Хорошо бы в ida посмотреть, что это и какие данные нужны. Может нативная форма подставляет данные с чем то еще, не просто текст.

Вот например с одного форума, может как подсказка из fasm:

Код:



proc RequestAuthLogin uses esi, pLogin:DWORD,pPassword:DWORD,Param:DWORD

Maksim
01.11.2024, 11:48
Наверное так может:

Код:



wchar_t Login[] = L"admin"; // Логин в формате UTF-16
wchar_t Password[] = L"admin"; // Пароль в формате UTF-16
int authType = 7;

int result = RequestAuthLogin((unsigned short*)Login, (unsigned short*)Password, authType);
if (result != 0) {
MessageBoxA(NULL, L"Ошибка входа!", L"", MB_OK);
}

Maksim
01.11.2024, 12:55
Вот еще дополню для it:



Вызываем api функцию клиента.

Код:



int (__fastcall

*UNetworkHandler_RequestAuthLogin)(UNetworkHandler *, int, wchar_t const

* login, wchar_t const * password,int param) = 0;


Код:



(FARPROC&) UNetworkHandler_RequestAuthLogin = GetProcAddress(hEngine, "?RequestAuthLogin@UNetworkHandler@@UAEHPB_W0H@Z");


Код:



(*UNetworkHandler_RequestAuthLogin)(UNH, 0/*что угодно*/, login, password, 0);


Надо изначально получить UNH, это указатель на объект UNetworkHandler в памяти.

Для этого есть конструктор UNH и вызывает на старте клиента.

Код:



?InternalConstructor@UNetworkHandler@@SAXPAX@Z

BIT_hack
01.11.2024, 13:40
Вот еще дополню для it:


Эти обрывки кода не помогут(

Charmant
01.11.2024, 14:30
Но при выполнение ее ничего не происходит


Потому что указатель на UNetworkHandler не передается. Я начинал делать свою реализацию автологина на эпилоге, но пока забросил т.к. лень редактировать интерфейс и окна. Вот простенький пример как можно инициализировать и вызвать RequestAuthLogin:

C++:



class
UNetworkHandler
{
}
;
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
namespace
{
uintptr_t UNetworkOffset
=
0x71d274
;
// для ИЛ клиента смещение будет другим
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
UNetworkAddress
)
;
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}

BIT_hack
01.11.2024, 14:33
Спасибо но откуда вытащить



Потому что указатель на UNetworkHandler не передается. Я начинал делать свою реализацию автологина на эпилоге, но пока забросил т.к. лень редактировать интерфейс и окна. Вот простенький пример как можно инициализировать и вызвать RequestAuthLogin:


Спасибо но откуда взять?

uintptr_t UNetworkOffset = 0x71d274; // для ИЛ клиента смещение будет другим

Charmant
01.11.2024, 14:36
Спасибо но откуда вытащить

Спасибо но откуда взять?
uintptr_t UNetworkOffset = 0x71d274; // для ИЛ клиента смещение будет другим


Найти ссылку в функциях-членах класса. Например:

Maksim
01.11.2024, 15:20
Надо будет auto dumper сделать по маске для получения оффсета от c1 до hf ?

ANZO
01.11.2024, 15:33
Учтите что UNetworkHandler при аттаче библиотеки может не существовать вовсе. Запрашивать RequestAuthLogin нужно после того как клиент загрузился (окно логин-пароль): проще всего перехватывать первый вызов UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z)

BIT_hack
01.11.2024, 15:37
Найти ссылку в функциях-членах класса. Например:



Попробовал на IT и HF не сработало хотя все функции отработали. UNetworkOffset = менял под каждый клиент

C++:



// dllmain.cpp : Определяет точку входа для приложения DLL.
#include "pch.h"
#include "string"
class
UNetworkHandler
{
}
;
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
// Объявление функции RequestLogin
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
;
namespace
{
uintptr_t UNetworkOffset
=
0x3d5ac0
;
// для ИЛ клиента смещение будет другим
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
UNetworkAddress
)
;
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
Init
(
)
;
break
;
}
return
TRUE
;
}

ANZO
01.11.2024, 15:37
Надо будет auto dumper сделать по маске для получения оффсета от c1 до hf ?


Оффсет можно и не искать вовсе, достаточно найти в экспортах того же engine global структуру которая светит в экспорт и где есть ссылка на UNetworkHandler. Сходу не скажу где, но знаю что точно есть такие.

Maksim
01.11.2024, 16:03
Оффсет можно и не искать вовсе, достаточно найти в экспортах того же engine global структуру которая светит в экспорт и где есть ссылка на UNetworkHandler. Сходу не скажу где, но знаю что точно есть такие.


Есть вроде такое:

Код:



?InternalConstructor@UNetworkHandler


Через это наверное можно сделать. ?

Charmant
01.11.2024, 16:03
Попробовал на IT и HF не сработало хотя все функции отработали. UNetworkOffset = менял под каждый клиент

C++:



// dllmain.cpp : Определяет точку входа для приложения DLL.
#include "pch.h"
#include "string"
class
UNetworkHandler
{
}
;
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
// Объявление функции RequestLogin
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
;
namespace
{
uintptr_t UNetworkOffset
=
0x3d5ac0
;
// для ИЛ клиента смещение будет другим
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
UNetworkAddress
)
;
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
Init
(
)
;
break
;
}
return
TRUE
;
}



0x3d5ac0 как смещение UNH выглядит сомнительным. В клиенте ил 746, который скачан у меня, смещение = 0x81F538.

И в DllMain я бы не стал сразу вызывать логин, половина клиента еще не загружена.




C++:



#include "pch.h"
#include "string"
class
UNetworkHandler
{
}
;
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
// Объявление функции RequestLogin
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
;
namespace
{
uintptr_t UNetworkOffset
=
0x81F538
;
// для ИЛ клиента смещение будет другим
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
UNetworkAddress
)
;
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}
DWORD WINAPI
test
(
LPVOID lpParameter
)
{
Sleep
(
7000
)
;
Init
(
)
;
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
,
test
,
NULL
,
0
,
NULL
)
;
if
(
hThread
!=
NULL
)
{
CloseHandle
(
hThread
)
;
}
}
break
;
}
return
TRUE
;
}







Оффсет можно и не искать вовсе, достаточно найти в экспортах того же engine global структуру которая светит в экспорт и где есть ссылка на UNetworkHandler. Сходу не скажу где, но знаю что точно есть такие.


Тоже верно. На самом деле есть несколько способов получить указатель. В моем случае мне было удобнее получать по конкретному смещению

BIT_hack
01.11.2024, 16:16
0x3d5ac0 как смещение UNH выглядит сомнительным. В клиенте ил 746, который скачан у меня, смещение = 0x81F538.
И в DllMain я бы не стал сразу вызывать логин, половина клиента еще не загружена.


В первом случае как вы написали ничего не происходит во втором игра начинает тормозить.

Насчет dll я ее инжектю когда игра уже запущена.

BIT_hack
01.11.2024, 16:23
Charmant (https://forum.antichat.xyz/members/921529/)​Ваш кодс работал для IT

Charmant
01.11.2024, 16:24
В первом случае как вы написали ничего не происходит во втором игра начинает тормозить.
Насчет dll я ее инжектю когда игра уже запущена.


Ну вот судя по этому скрину, если базовый адрес енжины 20000000, то смещение UNH для этой енжины равно 0x77ed80

BIT_hack
01.11.2024, 16:29
Ну вот судя по этому скрину, если базовый адрес енжины 20000000, то смещение UNH для этой енжины равно 0x77ed80


Спасибо чуть позже отпишу нужно ехать срочно!

Maksim
01.11.2024, 16:48
Я правильно понял, можно сделать так без привязки к оффсету?




C++:



#include "pch.h"
#include "string"
class
UNetworkHandler
{
}
;
// Объявление типа для функции RequestAuthLogin
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
// Объявление типа для функции InternalConstructor
typedef
void
(
__stdcall
*
InternalConstructor_fn
)
(
void
*
)
;
// Объявление функции RequestLogin
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
;
namespace
{
uintptr_t UNetworkOffset
=
0
;
// Смещение не используется
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
InternalConstructor_fn fInternalConstructor
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
// Получаем адрес функции InternalConstructor
fInternalConstructor
=
(
InternalConstructor_fn
)
GetProcAddress
(
hEngineModule
,
"?InternalConstructor@UNetworkHandler@@SAXPAX@Z"
)
;
if
(
fInternalConstructor
!=
nullptr
)
{
// Вызов функции InternalConstructor для инициализации UNetwork, если нужно
fInternalConstructor
(
&
UNetwork
)
;
// Проверка на успешное извлечение UNetwork
if
(
UNetwork
!=
nullptr
)
{
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
// Получаем адрес функции RequestAuthLogin
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
// Попытка авторизации
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}
DWORD WINAPI
test
(
LPVOID lpParameter
)
{
Sleep
(
7000
)
;
Init
(
)
;
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
,
test
,
NULL
,
0
,
NULL
)
;
if
(
hThread
!=
NULL
)
{
CloseHandle
(
hThread
)
;
}
}
break
;
}
return
TRUE
;
}

Charmant
01.11.2024, 17:16
Я правильно понял, можно сделать так без привязки к оффсету?



C++:



#include "pch.h"
#include "string"
class
UNetworkHandler
{
}
;
// Объявление типа для функции RequestAuthLogin
typedef
int
(
__fastcall
*
RequestAuthLogin_fn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
// Объявление типа для функции InternalConstructor
typedef
void
(
__stdcall
*
InternalConstructor_fn
)
(
void
*
)
;
// Объявление функции RequestLogin
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
;
namespace
{
uintptr_t UNetworkOffset
=
0
;
// Смещение не используется
UNetworkHandler
*
UNetwork
=
nullptr
;
RequestAuthLogin_fn fRequestAuthLogin
=
nullptr
;
InternalConstructor_fn fInternalConstructor
=
nullptr
;
}
void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
// Получаем адрес функции InternalConstructor
fInternalConstructor
=
(
InternalConstructor_fn
)
GetProcAddress
(
hEngineModule
,
"?InternalConstructor@UNetworkHandler@@SAXPAX@Z"
)
;
if
(
fInternalConstructor
!=
nullptr
)
{
// Вызов функции InternalConstructor для инициализации UNetwork, если нужно
fInternalConstructor
(
&
UNetwork
)
;
// Проверка на успешное извлечение UNetwork
if
(
UNetwork
!=
nullptr
)
{
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
// Получаем адрес функции RequestAuthLogin
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
// Попытка авторизации
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}
}
}
void
RequestLogin
(
const
wchar_t
*
login
,
const
wchar_t
*
password
)
{
if
(
UNetwork
!=
nullptr
&&
fRequestAuthLogin
!=
nullptr
)
{
MessageBox
(
NULL
,
L
"Попытка входа в игру!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
(
UNetwork
,
0
,
login
,
password
,
0
)
;
}
}
DWORD WINAPI
test
(
LPVOID lpParameter
)
{
Sleep
(
7000
)
;
Init
(
)
;
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
,
test
,
NULL
,
0
,
NULL
)
;
if
(
hThread
!=
NULL
)
{
CloseHandle
(
hThread
)
;
}
}
break
;
}
return
TRUE
;
}






Не думаю что так сработает. Вроде смысл в том чтобы перехватывать вызов InternalConstructor и забирать значение UNH, а не самостоятельный вызов этой фунции.

Maksim
01.11.2024, 17:21
Не думаю что так сработает. Вроде смысл в том чтобы перехватывать вызов InternalConstructor и забирать значение UNH, а не самостоятельный вызов этой фунции.


Было бы универсальное решение без поиска оффсета, но вроде в верном направлении.

Где-то упускаю ?

PalevoPWNZ
01.11.2024, 17:32
Если сделаете для ИТ готов приобрести.

Maksim
01.11.2024, 17:38
Если сделаете для ИТ готов приобрести.




Так уже, тут вопрос в другом ?

BIT_hack
01.11.2024, 19:10
Так уже, тут вопрос в другом ?


В интерлюдия не нашел такой функции ?InternalConstructor@UNetworkHandler@@SAXPAX@Z

Maksim
01.11.2024, 19:16
В интерлюдия не нашел такой функции ?InternalConstructor@UNetworkHandler@@SAXPAX@Z


Это было взято с публичного поста, на работе не могу посмотреть и проверить.

Если поискать только так должно найти:

Код:



InternalConstructor@UNetworkHandler

PalevoPWNZ
01.11.2024, 19:18
Если сделаете для ИТ готов приобрести.




Если готовы сделать под ключ, пишите цену в ТГ. Ссылка (https://t.me/terenosadm)

Maksim
01.11.2024, 19:19
Если готовы сделать под ключ, пишите цену в ТГ. Ссылка (https://t.me/terenosadm)


Вам в раздел поиска исполнителя, не здесь.

Ищу исполнителя (https://forum.antichat.xyz/forums/%D0%98%D1%89%D1%83-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D 0%B5%D0%BB%D1%8F.56/)

Поиск исполнителя на платной основе.

mmo-dev.info

BIT_hack
01.11.2024, 19:21
InternalConstructor@UNetworkHandler


Нет в интерлюдии нет такого в HF уже есть я проверил

Maksim
01.11.2024, 19:24
Нет в интерлюдии нет такого в HF уже есть я проверил


Может можно другую функцию из it которая есть и в hf, не хотелось бы каждый раз подбирать под патч свой offset. ?

AmaTo
01.11.2024, 19:37
Готов купить данную функцию под ит (пишите в лс цену)

BIT_hack
01.11.2024, 19:44
Ну вот судя по этому скрину, если базовый адрес енжины 20000000, то смещение UNH для этой енжины равно 0x77ed80


Мне кажется я неправильно высчитываю (опыта мало в этом деле)

Вот я нашел офсет EAX,[DAT_10b1f538] он будет равен 0xb1f538

Самое интересное что твой 0x81F538 работает а мой нет)

crossover
01.11.2024, 20:09
Для локалки пойдет, а как только возьмёте стрикс/смарт/аа пойдет ваша реализация в лес на долго и безвозвратно)

BIT_hack
01.11.2024, 20:10
Для локалки пойдет, а как только возьмёте стрикс/смарт/аа пойдет ваша реализация в лес на долго и безвозвратно)


Надо с чего то начинать)

crossover
01.11.2024, 20:11
Надо с чего то начинать)


100% согласен, это больше было адресовано тем кто желает это купить) что бы не тешили себя надеждами)

BIT_hack
01.11.2024, 20:37
Charmant (https://forum.antichat.xyz/members/921529/)​

Только что заметил отличие у тебя 8 а у меня b 0x81F538 - 0xb1f538

И самое странное, что твой hex работает а мой нет хотя в клиенте у мен b вместо 8)

Maksim
01.11.2024, 20:39
Charmant (https://forum.antichat.xyz/members/921529/)​
Только что заметил отличие у тебя 8 а у меня b 0x81F538 - 0xb1f538
И самое странное, что твой hex работает а мой нет хотя в клиенте у мен b вместо 8)


Может dll накрыта темидой и по этому такая разница.

Попробуй через ghidra сделать декомпил и посмотреть там. ?

Charmant
01.11.2024, 22:10
Мне кажется я неправильно высчитываю (опыта мало в этом деле)
Вот я нашел офсет EAX,[DAT_10b1f538] он будет равен 0xb1f538

Самое интересное что твой 0x81F538 работает а мой нет)


У длл есть базовый адрес. 10b1f538 это база + смещение. В ИЛ енжине базовый адрес 10300000, т.е: 0x10b1f538 - 0x10300000 = 0x81F538



У длл есть базовый адрес. 10b1f538 это база + смещение. В ИЛ енжине базовый адрес 10300000, т.е: 0x10b1f538 - 0x10300000 = 0x81F538


Почитайте про виртуальные адреса (VA) и относительные виртуальные адреса (RVA). Станет понятнее

BIT_hack
01.11.2024, 22:11
Почитайте про виртуальные адреса (VA) и относительные виртуальные адреса (RVA). Станет понятнее


Я раньше этим занимался забыл обязательно почитаю спасибо!

Maksim
01.11.2024, 23:38
Надо будет в ресурсы добавить хотя бы для it с инструкцией поиска offset наглядно в картинке и тексте с исходниками.

Заодно краткую инструкцию по вычислению offset от базового адреса.

Хорошее дело делаем ?

BIT_hack
02.11.2024, 12:42
У меня возник вопрос, связанный с этой же темой.

Есть ли какой-то флаг в L2, который позволяет определить, что окно с интерфейсом полностью загружено и готово к использованию?

òbiòbi верифицированный пользователь.
02.11.2024, 12:59
У меня возник вопрос, связанный с этой же темой.
Есть ли какой-то флаг в L2, который позволяет определить, что окно с интерфейсом полностью загружено и готово к использованию?


Про сам интерфейс не знаю, но дождаться создания основного нативного окна (пропустив при этом сплэшскрин окно) я выкладывал на шарпе (https://forum.antichat.xyz/threads/791708/page-2). Думаю стоит попробовать такой вариант, то есть через do-while ждать указатель на окно

C#:



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
)
;


да и все что делается через событие DLL_PROCESS_ATTACH, стоит (по мимо проверок на nullptr) проверять и что вернула функция GetProcAddress. Возможно функция вернула также nullptr, по сколько dll engine по какой-то причине еще не прогрузилась, и адрес на процедуру RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z был не доступен.

C++:



void
Init
(
)
{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
!=
nullptr
)
{
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
UNetworkAddress
)
;
MessageBox
(
NULL
,
L
"Все данные собраны вход!!!!!"
,
L
""
,
MB_OK
)
;
fRequestAuthLogin
=
(
RequestAuthLogin_fn
)
GetProcAddress
(
hEngineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
RequestLogin
(
L
"admin"
,
L
"admin"
)
;
}
}

òbiòbi верифицированный пользователь.
02.11.2024, 13:08
Ну то есть стоит всегда проверять, что возвращают нативные функции апи винды, дабы понимать что пошло не так и на каком этапе

C++:



{
HMODULE hEngineModule
=
GetModuleHandleW
(
L
"engine.dll"
)
;
if
(
hEngineModule
==
nullptr
)
{
return
MessageBox
(
NULL
,
L
"hEngineModule is null"
,
L
""
,
MB_OK
)
;
}
uintptr_t UNetworkAddress
=
(
reinterpret_cast

(
hEngineModule
)
)
+
UNetworkOffset
;
UNetwork
=
*
reinterpret_cast

(
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"
)
;
}

BIT_hack
02.11.2024, 13:15
Ну то есть стоит всегда проверять, что возвращают нативные функции апи винды, дабы понимать что пошло не так и на каком этапе


Обработку ошибок я сразу сделал.

Ваш варант проверю, только так и получится я думаю но надо еще знать что ожидать while

òbiòbi верифицированный пользователь.
02.11.2024, 13:20
знать что ожидать while


смотреть в документации на сайте майков по определенной функции, к примеру GetProcAddress (https://learn.microsoft.com/ru-ru/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress#return-value) возвращает null в случаи неудачи

стало быть во while цикле продолжаем итерации пока значение будет не null/nullptr

BIT_hack
02.11.2024, 13:24
смотреть в документации на сайте майков по определенной функции, к примеру GetProcAddress (https://learn.microsoft.com/ru-ru/windows/win32/api/libloaderapi/nf-libloaderapi-getprocaddress#return-value) возвращает null в случаи неудачи


Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работе

òbiòbi верифицированный пользователь. (https://forum.antichat.xyz/members/893543/)​

В данный момент я использую Sleep(3000), а затем вызываем функцию входа в игру.

Поскольку у всех разные компьютеры, скорость загрузки окна может быть выше 3000 миллисекунд, и тогда функция не будет выполнена.

Maksim
02.11.2024, 14:01
Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работе

òbiòbi верифицированный пользователь. (https://forum.antichat.xyz/members/893543/)​
В данный момент я использую Sleep(3000), а затем вызываем функцию входа в игру.
Поскольку у всех разные компьютеры, скорость загрузки окна может быть выше 3000 миллисекунд, и тогда функция не будет выполнена.


Как вариант использовать костыль, в коде меню с правой стороны например в HF, можно прописать чтобы переключало некий bool когда загружено в самой dll тогда та уже выполнит те функции которые нужны.

Это как один из вариантов, но возникает вопрос что будет если одно окно загружено и второе не загрузилось ведь не все играют в одно окно, многие и по 5-10 окон.

òbiòbi верифицированный пользователь.
02.11.2024, 14:17
Я не про функции которые я вызываю для них я сделал проверку - Я про процесс и думал может можно перехватить функцию которая сообщает о том что окно готово к работе

òbiòbi верифицированный пользователь. (https://forum.antichat.xyz/members/893543/)​
В данный момент я использую Sleep(3000), а затем вызываем функцию входа в игру.
Поскольку у всех разные компьютеры, скорость загрузки окна может быть выше 3000 миллисекунд, и тогда функция не будет выполнена.


Как и в моем примере, нам нужно из текущего процесса достать MainWindowHandle.

Достать ссылку на текущее окно в теории можно так

C++:



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
;
}
}


Рабочих вариантов не будет, ибо не пишу на плюсах и познания в них у меня околонулевые.

BIT_hack
02.11.2024, 14:32
Как и в моем примере, нам нужно из текущего процесса достать MainWindowHandle.


Активное загруженное окно можно получить и так HWND GetForegroundWindow();

Пока ищу способ может кто-то еще подскажет)



Учтите что UNetworkHandler при аттаче библиотеки может не существовать вовсе. Запрашивать RequestAuthLogin нужно после того как клиент загрузился (окно логин-пароль): проще всего перехватывать первый вызов UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z)


Попустил твое сообщение подскажи как использовать UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z) Из него нужно получить какие-то параметры?

Dara
02.11.2024, 16:16
У меня возник вопрос, связанный с этой же темой.
Есть ли какой-то флаг в L2, который позволяет определить, что окно с интерфейсом полностью загружено и готово к использованию?


Попробуй через класс окна l2UnrealWWindowsViewportWindow

BIT_hack
02.11.2024, 16:46
Попробуй через класс окна l2UnrealWWindowsViewportWindow


Для меня не составляет труда найти окно, сложнее понять, когда оно загружено полностью или, по крайней мере, готово к обработке команд от сервера.

BIT_hack
02.11.2024, 17:21
Пока я сделал так: файл fire.dll загружается непосредственно перед тем, как окно будет готово.

C++:



// Поток для авторизации
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
;
}

Charmant
02.11.2024, 17:57
Активное загруженное окно можно получить и так HWND GetForegroundWindow();
Пока ищу способ может кто-то еще подскажет)

Попустил твое сообщение подскажи как использовать UNetworkHandler::Tick() (?Tick@UNetworkHandler@@UAEXM@Z) Из него нужно получить какие-то параметры?


У клиента есть функция проверки состояния, которая активно используется в nwindow.dll - UL2ConsoleWnd::GetState

Можно воспользоваться этим знанием вот так:




C++:



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

(
hNwindowModule
)
)
+
consoleOffset
;
while
(
UL2ConsoleWndPtr
==
nullptr
)
{
UL2ConsoleWndPtr
=
*
reinterpret_cast

(
pUL2ConsoleWnd
)
;
Sleep
(
300
)
;
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState
*
statePtr
=
reinterpret_cast

(
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
;
}

BIT_hack
02.11.2024, 17:59
У клиента есть функция проверки состояния, которая активно используется в nwindow.dll - UL2ConsoleWnd::GetState


Спасибо большое буду разбираться!

BIT_hack
02.11.2024, 18:13
UL2ConsoleWnd::GetState


Все работает я без тебя бы не разобрался)!

BIT_hack
02.11.2024, 20:31
Вот код автологина для interlude, который требует доработки, но уже работает, особенно благодаря Charmant (https://forum.antichat.xyz/members/921529/)

Логин и пароль берется из файла AutoLogin.ini который должен лежать рядом с dll в вашей папке system игры.

AutoLogin.ini с таким содержимым:

Код:



[AutoLogin]
Login=admin
Password=admin


Код на с++ Visual Studio 2022

C++:



#include "pch.h"
#include
#include
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

(
hNwindowModule
)
)
+
consoleOffset
;
while
(
UL2ConsoleWndPtr
==
nullptr
)
{
UL2ConsoleWndPtr
=
*
reinterpret_cast

(
pUL2ConsoleWnd
)
;
Sleep
(
300
)
;
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState
*
statePtr
=
reinterpret_cast

(
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

(
reinterpret_cast

(
engineModule
)
+
unetworkOffset
)
;
// Получение адреса функции RequestAuthLogin
requestAuthLoginFn
=
(
RequestAuthLoginFn
)
GetProcAddress
(
engineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
}
// Создание потока для авторизации
CreateThread
(
nullptr
,
0
,
TestThread
,
nullptr
,
0
,
nullptr
)
;
}
return
TRUE
;
}


И вот готовые файлы для тех, кто хочет настроить автологин (*Только вход в окно логина*): просто распакуйте архив в системную папку игры interlude и не забудьте изменить логин и пароль в файле AutoLogin.ini.

LifeGame32
02.11.2024, 20:55
если окно не в фокусе. после логина что происходит норм?

BIT_hack
02.11.2024, 20:58
если окно не в фокусе. после логина что происходит норм?


Всё работает нормально проверял, независимо от того, находится ли окно в фокусе или нет. Можно открыть сколько угодно окон, главное — не забывать менять логин и пароль в файле AutoLogin.ini".

BladeRunner
02.11.2024, 22:10
Всё работает нормально проверял, независимо от того, находится ли окно в фокусе или нет. Можно открыть сколько угодно окон, главное — не забывать менять логин и пароль в файле AutoLogin.ini".



это на каждое окно под разных чаров надо каждый раз вбивать логин и пароль?

BIT_hack
02.11.2024, 22:12
это на каждое окно под разных чаров надо каждый раз вбивать логин и пароль?


На данный момент — да, но никто не мешает вам реализовать свои идеи в коде.

ANZO
02.11.2024, 22:27
На данный момент — да, но никто не мешает вам реализовать свои идеи в коде.


CommandLineManager.h

C++:



#pragma once
struct
CommandLineConstants
{
/** Auth login/password set from launcher params (Format: String - e.g. "-authdata login,password") */
static
constexpr
wchar_t
AuthData
[
]
=
L
"authdata"
;
}
;
class
CommandLineManager
{
public
:
/**
* No copying or copy assignment allowed for this class.
*/
CommandLineManager
(
CommandLineManager
const
&
)
=
delete
;
CommandLineManager
&
operator
=
(
CommandLineManager
const
&
)
=
delete
;
/**
* Initialization using a string containing all params
*/
void
Init
(
const
wchar_t
*
lp_cmd_line
)
;
/**
* Initialization using a collection of params
*/
void
Init
(
const
std
::
vector

&
cmd_line_params
)
;
/**
* Checks command line arguments for a matching param
*
* @param param - Parameter to look for in command line arguments
*
* @return True if param is found in command line arguments
*/
bool
HasParam
(
const
std
::
wstring
&
param
)
;
/**
* Retrieves value associated with given command line parameter
*
* @param param - Parameter to look for in command line arguments
*
* @return Value associated with command line parameter
*/
std
::
wstring
GetParamValue
(
const
std
::
wstring
&
param
)
;
/**
* Checks command line arguments for a matching flag param
*
* @param param - Parameter to look for in command line arguments
*
* @return True if param is found in command line arguments and it is a flag param value
*/
bool
HasFlagParam
(
const
std
::
wstring
&
param
)
;
std
::
map

GetCommandLineArgs
(
)
{
return
command_line_args_
;
}
/**
* Singleton
*/
static
CommandLineManager
&
Get
(
)
;
private
:
CommandLineManager
(
)
=
default
;
/** True if command line parser initialized */
static
bool
IsInitialized
;
/** Gets a collection of sub-arguments from a string of one or two arguments */
std
::
vector

GetSubArguments
(
const
std
::
wstring
&
sub_arg_list
)
;
/** Add commandline params from a collection of arguments */
void
AddArguments
(
const
std
::
vector

&
arg_list
)
;
/**
* Adds parameter name to collection of command line parameters
*
* @param param_name - Parameter name to add
*/
void
AddParam
(
const
std
::
wstring
&
param_name
)
;
/** Collections of command line arguments */
std
::
map

command_line_args_
;
}
;


CommandLineManager.cpp

C++:



#include
#include "CommandLineManager.h"
namespace
{
const
std
::
wstring FlagParamValue
=
L
"__FLAG__"
;
const
std
::
wstring UnusedParamValue
=
L
"unused"
;
}
bool
CommandLineManager
::
IsInitialized
=
false
;
CommandLineManager
&
CommandLineManager
::
Get
(
)
{
static
CommandLineManager command_line_manager
;
if
(
!
IsInitialized
)
{
// Support for DLL's
int
arg_count
=
0
;
const
LPWSTR
*
arg_list
=
CommandLineToArgvW
(
GetCommandLine
(
)
,
&
arg_count
)
;
std
::
vector

output
;
output
.
reserve
(
arg_count
)
;
for
(
int
i
=
0
;
i

&
cmd_line_params
)
{
if
(
!
IsInitialized
)
{
std
::
vector

args
;
for
(
std
::
wstring cmd_line_param
:
cmd_line_params
)
{
for
(
const
std
::
wstring
&
arg
:
GetSubArguments
(
cmd_line_param
)
)
{
args
.
push_back
(
arg
)
;
}
}
AddArguments
(
args
)
;
IsInitialized
=
true
;
}
}
std
::
vector

CommandLineManager
::
GetSubArguments
(
const
std
::
wstring
&
sub_arg_list
)
{
std
::
vector

args
;
if
(
const
std
::
wstring
::
size_type sub_arg_equals_pos
=
sub_arg_list
.
find_first_of
(
L
'='
)
;
sub_arg_equals_pos
!=
std
::
wstring
::
npos
)
{
// Add both args
args
.
push_back
(
sub_arg_list
.
substr
(
0
,
sub_arg_equals_pos
)
)
;
args
.
push_back
(
sub_arg_list
.
substr
(
sub_arg_equals_pos
+
1
,
sub_arg_list
.
length
(
)
-
1
)
)
;
}
else
{
// Add single arg
args
.
push_back
(
sub_arg_list
)
;
}
return
args
;
}
void
CommandLineManager
::
AddArguments
(
const
std
::
vector

&
arg_list
)
{
if
(
!
arg_list
.
empty
(
)
)
{
const
std
::
wstring
delimiters
(
L
"-,;\\"
)
;
std
::
wstring param_name
;
bool
bPrevWasParamName
=
false
;
const
int
num_args
=
static_cast

(
arg_list
.
size
(
)
)
;
for
(
int
i
=
0
;
i

0
&&
pos
!=
std
::
wstring
::
npos
)
{
if
(
bPrevWasParamName
)
{
// We have another param name so previous was a flag (no param value)
// Add a value to signify we have a flag param
AddParam
(
param_name
)
;
}
param_name
=
command_line_arg
;
// strip out first part so we're left with just the param name
param_name
.
erase
(
0
,
pos
)
;
if
(
i
==
num_args
-
1
)
{
// Add final flag param
AddParam
(
param_name
)
;
}
bPrevWasParamName
=
true
;
continue
;
}
bPrevWasParamName
=
false
;
// Make sure we're not adding a duplicate
if
(
auto
it
=
command_line_args_
.
find
(
{
param_name
}
)
;
it
==
command_line_args_
.
end
(
)
)
{
if
(
command_line_arg
.
empty
(
)
)
{
// Treat empty param value as a flag
command_line_args_
.
insert
(
{
param_name
,
FlagParamValue
}
)
;
}
else
{
command_line_args_
.
insert
(
{
param_name
,
command_line_arg
}
)
;
}
}
// Clear for next param
param_name
.
clear
(
)
;
}
}
}
void
CommandLineManager
::
AddParam
(
const
std
::
wstring
&
param_name
)
{
// Make sure we're not adding a duplicate
if
(
const
auto
it
=
command_line_args_
.
find
(
{
param_name
}
)
;
it
==
command_line_args_
.
end
(
)
)
{
command_line_args_
.
insert
(
{
param_name
,
FlagParamValue
}
)
;
}
}
bool
CommandLineManager
::
HasParam
(
const
std
::
wstring
&
param
)
{
if
(
const
auto
itr
=
command_line_args_
.
find
(
{
param
}
)
;
itr
!=
command_line_args_
.
end
(
)
)
{
if
(
itr
->
second
!=
UnusedParamValue
)
{
return
true
;
}
}
return
false
;
}
std
::
wstring CommandLineManager
::
GetParamValue
(
const
std
::
wstring
&
param
)
{
if
(
const
auto
itr
=
command_line_args_
.
find
(
{
param
}
)
;
itr
!=
command_line_args_
.
end
(
)
)
{
return
itr
->
second
;
}
return
std
::
wstring
(
)
;
}
bool
CommandLineManager
::
HasFlagParam
(
const
std
::
wstring
&
param
)
{
if
(
const
auto
itr
=
command_line_args_
.
find
(
{
param
}
)
;
itr
!=
command_line_args_
.
end
(
)
)
{
return
itr
->
second
==
FlagParamValue
;
}
return
false
;
}


Пример использования:

C++:



std
::
wstring AutoLogin_Login
;
std
::
wstring AutoLogin_Password
;
if
(
CommandLineManager
::
Get
(
)
.
HasParam
(
CommandLineConstants
::
AuthData
)
)
{
const
std
::
wstring auth_string
=
CommandLineManager
::
Get
(
)
.
GetParamValue
(
CommandLineConstants
::
AuthData
)
;
if
(
std
::
vector

auth_data
=
StringUtils
::
Split
(
auth_string
,
','
)
;
auth_data
.
size
(
)
>=
2
)
{
AutoLogin_Login
=
auth_data
[
0
]
;
AutoLogin_Password
=
auth_data
[
1
]
;
}
}


Могут быть некоторые внешние зависимости, но я думаю вы там поймете что к чему.

BIT_hack
02.11.2024, 23:52
если окно не в фокусе. после логина что происходит норм?


Я увидел твой пост в друг теме и понял о чем ты, но этот код для интерлюдии и HF подойдет, для выше хроник все можно сделать через интерфейс и UGX и будет работать стабильно.

hawking
04.11.2024, 17:47
есть ли способ импортировать функцию RequestLogin внутрь интерфейса, чтобы мы могли использовать ее там?

Таким образом, мы можем записывать/считывать файл автологина внутри интерфейса, и мы можем использовать его для нескольких учетных записей, а не только для одной.

BIT_hack
04.11.2024, 18:41
есть ли способ импортировать функцию RequestLogin внутрь интерфейса, чтобы мы могли использовать ее там?
Таким образом, мы можем записывать/считывать файл автологина внутри интерфейса, и мы можем использовать его для нескольких учетных записей, а не только для одной.


Возможно, в будущем я планирую заниматься этим только под заказ. Или же, если кто-то из ребят захочет помочь, они могут это сделать, но не бесплатно.

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

Пример для High Five, а также можно и для Interlude : Дизайн окон можно сделать любой!

BIT_hack
05.11.2024, 12:17
Я немного поработал над интерфейсом, и вот что у меня получилось!

AlhimN1
08.11.2024, 03:48
Вот код автологина для interlude, который требует доработки, но уже работает, особенно благодаря Charmant (https://forum.antichat.xyz/members/921529/)

Логин и пароль берется из файла AutoLogin.ini который должен лежать рядом с dll в вашей папке system игры.

AutoLogin.ini с таким содержимым:

Код:



[AutoLogin]
Login=admin
Password=admin


Код на с++ Visual Studio 2022

C++:



#include "pch.h"
#include
#include
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

(
hNwindowModule
)
)
+
consoleOffset
;
while
(
UL2ConsoleWndPtr
==
nullptr
)
{
UL2ConsoleWndPtr
=
*
reinterpret_cast

(
pUL2ConsoleWnd
)
;
Sleep
(
300
)
;
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState
*
statePtr
=
reinterpret_cast

(
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

(
reinterpret_cast

(
engineModule
)
+
unetworkOffset
)
;
// Получение адреса функции RequestAuthLogin
requestAuthLoginFn
=
(
RequestAuthLoginFn
)
GetProcAddress
(
engineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
}
// Создание потока для авторизации
CreateThread
(
nullptr
,
0
,
TestThread
,
nullptr
,
0
,
nullptr
)
;
}
return
TRUE
;
}


И вот готовые файлы для тех, кто хочет настроить автологин (*Только вход в окно логина*): просто распакуйте архив в системную папку игры interlude и не забудьте изменить логин и пароль в файле AutoLogin.ini.


решил попробовать - но не работает, вроде как бы и пишет что пароль не подходит, но акк и пароль я точно вписал верно))

мб длинна пароля 4 нуля ему не подходит?

BIT_hack
08.11.2024, 10:37
решил попробовать - но не работает, вроде как бы и пишет что пароль не подходит, но акк и пароль я точно вписал верно))
мб длинна пароля 4 нуля ему не подходит?


Я проверил: ввёл логин из четырёх нулей и пароль — и успешно вошёл в систему.

BIT_hack
08.11.2024, 11:42
+



В файле AutoLogin.ini должно быть указано следующее: если ваш логин и пароль — 0000, то введите их именно так, а если нет, то укажите свои данные.

Код:



[AutoLogin]
Login=0000
Password=0000

AlhimN1
08.11.2024, 12:36
В файле AutoLogin.ini должно быть указано следующее: если ваш логин и пароль — 0000, то введите их именно так, а если нет, то укажите свои данные.

Код:



[AutoLogin]
Login=0000
Password=0000

Dara
08.11.2024, 12:50
Эт же не кодированный .ini, открывай через блокнот или notepad+

AlhimN1
08.11.2024, 12:56
Эт же не кодированный .ini, открывай через блокнот или notepad+



ну он не кодированый

AlhimN1
08.11.2024, 12:59
ага, значит когда я его отредачил он загнулся

вот без редактирования

AlhimN1
08.11.2024, 14:12
В файле AutoLogin.ini должно быть указано следующее: если ваш логин и пароль — 0000, то введите их именно так, а если нет, то укажите свои данные.

Код:



[AutoLogin]
Login=0000
Password=0000



незнаю почему но при любом редактировании хоть нотпадом хоть чем - ломается он, какая там кодировка символов?

AlhimN1
08.11.2024, 14:14
незнаю почему но при любом редактировании хоть нотпадом хоть чем - ломается он, какая там кодировка символов?


ставлю вот так

Код:



[AutoLogin]

Login=admin

Password=0000


и всё-поломка)

BIT_hack
08.11.2024, 14:16
ставлю вот так
[AutoLogin]
Login=admin
Password=0000

и всё-поломка)


UTF-8

AlhimN1
08.11.2024, 14:25
ну ладно, чёто не хотит

мне вот интересно то что для автологина он используется библиотеку енти.длл т.е. как бы есть команда автозаполнения формы логин пароль

я вот делал батник



Код:



l2 -login: -password:


но не работает в таком виде, мб есть вариант впихнуть сюда что то другое что бы акк и пароль уже были заполнены но не нажата кнопка логин

Dara
08.11.2024, 15:08
ну ладно, чёто не хотит

мне вот интересно то что для автологина он используется библиотеку енти.длл т.е. как бы есть команда автозаполнения формы логин пароль

я вот делал батник



Код:



l2 -login: -password:


но не работает в таком виде, мб есть вариант впихнуть сюда что то другое что бы акк и пароль уже были заполнены но не нажата кнопка логин


через батник вроде l2.exe account=admin password=admin

и в l2.ini поле

[Auth]

CmdLineLogin=true

AlhimN1
08.11.2024, 15:37
через батник вроде l2.exe account=admin password=admin
и в l2.ini поле
[Auth]
CmdLineLogin=true


не, чёто не иле не зашло

AlhimN1
08.11.2024, 18:03
вообщем нашел вариант альтернативного 5 строчного кода автологина

Код:



@echo off
start l2.exe
timeout /t 2 /nobreak > nul

powershell -command "$wshell = New-Object -ComObject wscript.shell; $wshell.AppActivate('l2'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('LOGIN'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('{TAB}'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('PASSWORD')"


запуск из бат файла

BIT_hack
08.11.2024, 18:07
вообщем нашел вариант альтернативного 5 строчного кода автологина

Код:



@echo off
start l2.exe
timeout /t 2 /nobreak > nul

powershell -command "$wshell = New-Object -ComObject wscript.shell; $wshell.AppActivate('l2'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('LOGIN'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('{TAB}'); Start-Sleep -Milliseconds 500; $wshell.SendKeys('PASSWORD')"


запуск из бат файла


После этого можешь еще enter в клиент напихать чтобы тыкал до входа в игру))

AlhimN1
08.11.2024, 18:17
После этого можешь еще enter в клиент напихать чтобы тыкал до входа в игру))


мне не нужен был вход, мне нужен был только автоввод логин пароль

я хочу полюбоваться шикарными логин скринами, а потом уже заходить в игру в 2 клика

LifeGame32
16.12.2024, 23:14
ставлю вот так

Код:



[AutoLogin]

Login=admin

Password=0000


и всё-поломка)


наверно иза....

AlhimN1
16.12.2024, 23:36
наверно иза....


ага, там не так просто как хотелось бы)

artuspl
30.12.2024, 16:59
Here's the autologin code for interlude, which needs work but already works, especially thanks to Charmant (https://forum.antichat.xyz/members/921529/)

The login and password are taken from the AutoLogin.ini file, which should be next to the dll in your system folder.

AutoLogin.ini with the following content:

Код:



[AutoLogin]
Login=admin
Password=admin


C++ Visual Studio 2022 code

C++:



#include "pch.h"
#include
#include
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

(
hNwindowModule
)
)
+
consoleOffset
;
while
(
UL2ConsoleWndPtr
==
nullptr
)
{
UL2ConsoleWndPtr
=
*
reinterpret_cast

(
pUL2ConsoleWnd
)
;
Sleep
(
300
)
;
}
Get the address where the current state is recorded
L2ConsoleState
*
statePtr
=
reinterpret_cast

(
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

(
reinterpret_cast

(
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
;
}


And here are the ready-made files for those who want to set up autologin (*Login window only*): just unzip the archive to the interlude system folder of the game and don't forget to change the login and password in the AutoLogin.ini file.



This code works, but how do you find these offsets like `consoleOffset` and `unetworkOffset`? What tool do you use?

LightFusion
30.12.2024, 18:14
This code works, but how do you find these offsets like `consoleOffset` and `unetworkOffset`? What tool do you use?


probably IDA pro or some other debugger, decompiler

artuspl
30.12.2024, 20:07
probably IDA pro or some other debugger, decompiler


Yea I think that's the next level of debugging. Do you have any tutorials or guides anywhere that explain this topic? I was trying to find that offset manually using IDA Pro, but without any luck.

LightFusion
30.12.2024, 20:16
Yea I think that's the next level of debugging. Do you have any tutorials or guides anywhere that explain this topic? I was trying to find that offset manually using IDA Pro, but without any luck.


Find constructor first , manuals are on stackoverflow echange , ida pro forums and on google

artuspl
30.12.2024, 21:23
I have found it, in IDA, but the addresses does not tell me anything, the offset specified in topic is `0x81F538`. The starting address of engine.dll seems to be `10301005`

LightFusion
30.12.2024, 21:34
I have found it, in IDA, but the addresses does not tell me anything, the offset specified in topic is `0x81F538`. The starting address of engine.dll seems to be `10301005`


well thats because its only first part , then u have to find where it is used, in debugger mode.

Charmant
31.12.2024, 10:56
but the addresses does not tell me anything, the offset specified in topic is `0x81F538`.


0x81F538 - это RVA (Relative Virtual Address)

0x10300000 - base image address

0x10b1f538 - это VA (Virtual Address)

Для использования в коде нужен именно RVA offset:




DAT_10b1f538 - это VA для UNetworkHandler

Для получения RVA нужно вычесть из VA базовый адрес (RVA = VA - image base)

UNetworkOffset: 0x10b1f538 - 0x10300000 = 0x81F538.

Точно так же можно получить RVA для любой другой константы или функции.

Blaburger
05.02.2025, 10:55
Код на с++ Visual Studio 2022

C++:



// Тип функции RequestAuthLogin
typedef
int
(
__fastcall
*
RequestAuthLoginFn
)
(
UNetworkHandler
*
,
int
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
.
.
.
.
.
.
.
.
.
// Вызов функции авторизации из игры
requestAuthLoginFn
(
*
unetwork
,
0
,
login
.
c_str
(
)
,
password
.
c_str
(
)
,
0
)
;



Since the function RequestAuthLogin exported from dll with __thiscall the more correct code will be

C++:



typedef
int
(
__thiscall
*
RequestAuthLoginFn
)
(
UNetworkHandler
*
,
const
wchar_t
*
,
const
wchar_t
*
,
int
)
;
requestAuthLoginFn
(
*
unetwork
,
login
.
c_str
(
)
,
password
.
c_str
(
)
,
0
)
;


The __fastcall calling convention also works (with an additional parameter) as Microsoft's implementation in MSVC is very similar to __thiscall.

dina
09.02.2025, 12:00
хотелось бы полноценный гайд для новичков ибо из обрывков кода без навыка кодинга ничего не сделать

LifeGame32
09.02.2025, 15:14
хотелось бы полноценный гайд для новичков ибо из обрывков кода без навыка кодинга ничего не сделать


C моими познаниями с++ Ctrl+C и Ctrl+V тут предостаточно инфы.

готовое решение https://mmo-dev.info/threads/Как-сделать-Автологин-Интерлюдия.30142/post-227591 (https://forum.antichat.xyz/threads/793142/post-227591)

Neo`
15.08.2025, 18:18
Вот код автологина для interlude, который требует доработки, но уже работает, особенно благодаря Charmant (https://forum.antichat.xyz/members/921529/)

Логин и пароль берется из файла AutoLogin.ini который должен лежать рядом с dll в вашей папке system игры.

AutoLogin.ini с таким содержимым:

Код:



[AutoLogin]
Login=admin
Password=admin


Код на с++ Visual Studio 2022

C++:



#include "pch.h"
#include
#include
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

(
hNwindowModule
)
)
+
consoleOffset
;
while
(
UL2ConsoleWndPtr
==
nullptr
)
{
UL2ConsoleWndPtr
=
*
reinterpret_cast

(
pUL2ConsoleWnd
)
;
Sleep
(
300
)
;
}
// получение адреса по которому записывается текущее состояние
L2ConsoleState
*
statePtr
=
reinterpret_cast

(
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

(
reinterpret_cast

(
engineModule
)
+
unetworkOffset
)
;
// Получение адреса функции RequestAuthLogin
requestAuthLoginFn
=
(
RequestAuthLoginFn
)
GetProcAddress
(
engineModule
,
"?RequestAuthLogin@UNetworkHandler@@UAEHPAG0H@Z"
)
;
}
// Создание потока для авторизации
CreateThread
(
nullptr
,
0
,
TestThread
,
nullptr
,
0
,
nullptr
)
;
}
return
TRUE
;
}


И вот готовые файлы для тех, кто хочет настроить автологин (*Только вход в окно логина*): просто распакуйте архив в системную папку игры interlude и не забудьте изменить логин и пароль в файле AutoLogin.ini.


Копирую entry.dll и AutoLogin.ini в папку system - ничего не происходит при запуске, клиент IL, запускаю клиент от имени админа (ну на случай, если прав на что-то не хватит), что я делаю не так?

LifeGame32
15.08.2025, 22:28
Копирую entry.dll и AutoLogin.ini в папку system - ничего не происходит при запуске, клиент IL, запускаю клиент от имени админа (ну на случай, если прав на что-то не хватит), что я делаю не так?


вот готовый вариант.

Auth login interlude

21 Апр 2025

Auth login interlude


LifeGame32 (https://forum.antichat.xyz/members/891965/)

auth login interlude

Клиенты и патчи


тут как пример сорц .dll

Иконка ресурса

Передача данных .uc > .dll.

15 Янв 2025

rGuard,Interface.uc,dsetup


LifeGame32 (https://forum.antichat.xyz/members/891965/)

Клиент разработка

Neo`
15.08.2025, 22:31
вот готовый вариант.

Auth login interlude

21 Апр 2025

Auth login interlude


LifeGame32 (https://forum.antichat.xyz/members/891965/)

auth login interlude

Клиенты и патчи


тут как пример сорц .dll

Иконка ресурса

Передача данных .uc > .dll.

15 Янв 2025

rGuard,Interface.uc,dsetup


LifeGame32 (https://forum.antichat.xyz/members/891965/)

Клиент разработка



Попробовал - не работает.

В общем удалось пофиксить проблему исходников автора, у которого всё получилось, но при изменении ini файла не логинилось (фактически его исходники не читали пароль из ini файла), вот рабочий вариант:

Вы должны нажать кнопку "Мне нравится", чтобы увидеть скрытое содержимое.


Как сделаю финальный исходник (хочу добавить возможность брать не из ini а из флагов при запуске l2.exe, чтобы можно было просто ярлыки сделать на каждого персонажа) - выложу исходник и готовую скомпиленную dll.