ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Как сделать Автологин Интерлюдия? (https://forum.antichat.xyz/showthread.php?t=793142)

Maksim 01.11.2024 20:39

Цитата:

Сообщение от BIT_hack

Charmant
Только что заметил отличие у тебя 8 а у меня b 0x81F538 - 0xb1f538
И самое странное, что твой hex работает а мой нет хотя в клиенте у мен b вместо 8)

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

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

Charmant 01.11.2024 22:10

Цитата:

Сообщение от BIT_hack

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

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

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

Цитата:

Сообщение от Charmant

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

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

BIT_hack 01.11.2024 22:11

Цитата:

Сообщение от Charmant

Почитайте про виртуальные адреса (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

Цитата:

Сообщение от BIT_hack

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

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

Цитата:

Сообщение от òbi

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

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

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

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

Цитата:

Сообщение от BIT_hack

знать что ожидать while

смотреть в документации на сайте майков по определенной функции, к примеру GetProcAddress возвращает null в случаи неудачи

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

BIT_hack 02.11.2024 13:24

Цитата:

Сообщение от òbi

смотреть в документации на сайте майков по определенной функции, к примеру GetProcAddress возвращает null в случаи неудачи

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

òbiòbi верифицированный пользователь.

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

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

Maksim 02.11.2024 14:01

Цитата:

Сообщение от BIT_hack

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

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

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

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

òbiòbi верифицированный пользователь. 02.11.2024 14:17

Цитата:

Сообщение от BIT_hack

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

òbiòbi верифицированный пользователь.
В данный момент я использую 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

Цитата:

Сообщение от òbi

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

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

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

Цитата:

Сообщение от ANZO

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

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

Dara 02.11.2024 16:16

Цитата:

Сообщение от BIT_hack

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

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

BIT_hack 02.11.2024 16:46

Цитата:

Сообщение от Dara

Попробуй через класс окна 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

Цитата:

Сообщение от BIT_hack

Активное загруженное окно можно получить и так 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

Цитата:

Сообщение от Charmant

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

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

BIT_hack 02.11.2024 18:13

Цитата:

Сообщение от Charmant

UL2ConsoleWnd::GetState

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

BIT_hack 02.11.2024 20:31

Вот код автологина для interlude, который требует доработки, но уже работает, особенно благодаря Charmant

Логин и пароль берется из файла 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

Цитата:

Сообщение от LifeGame32

если окно не в фокусе. после логина что происходит норм?

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

BladeRunner 02.11.2024 22:10

Цитата:

Сообщение от BIT_hack

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

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

BIT_hack 02.11.2024 22:12

Цитата:

Сообщение от BladeRunner

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

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

ANZO 02.11.2024 22:27

Цитата:

Сообщение от BIT_hack

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

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

Цитата:

Сообщение от LifeGame32

если окно не в фокусе. после логина что происходит норм?

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

hawking 04.11.2024 17:47

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

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

BIT_hack 04.11.2024 18:41

Цитата:

Сообщение от hawking

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

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

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

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

BIT_hack 05.11.2024 12:17

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

AlhimN1 08.11.2024 03:48

Цитата:

Сообщение от BIT_hack

Вот код автологина для interlude, который требует доработки, но уже работает, особенно благодаря Charmant

Логин и пароль берется из файла 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

Цитата:

Сообщение от AlhimN1

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

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

BIT_hack 08.11.2024 11:42

Цитата:

Сообщение от AlhimN1

+

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

Код:


Код:

[AutoLogin]
Login=0000
Password=0000


AlhimN1 08.11.2024 12:36

Цитата:

Сообщение от BIT_hack

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

Код:


Код:

[AutoLogin]
Login=0000
Password=0000



Dara 08.11.2024 12:50

Цитата:

Сообщение от AlhimN1

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

AlhimN1 08.11.2024 12:56

Цитата:

Сообщение от Dara

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

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

AlhimN1 08.11.2024 12:59

ага, значит когда я его отредачил он загнулся

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

AlhimN1 08.11.2024 14:12

Цитата:

Сообщение от BIT_hack

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

Код:


Код:

[AutoLogin]
Login=0000
Password=0000


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

AlhimN1 08.11.2024 14:14

Цитата:

Сообщение от AlhimN1

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

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

Код:


Код:

[AutoLogin]

Login=admin

Password=0000

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

BIT_hack 08.11.2024 14:16

Цитата:

Сообщение от AlhimN1

ставлю вот так
[AutoLogin]
Login=admin
Password=0000

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

UTF-8

AlhimN1 08.11.2024 14:25

ну ладно, чёто не хотит

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

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



Код:


Код:

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


Время: 22:35