Показать сообщение отдельно

  #4  
Старый 02.04.2024, 23:19
Vintik
Познавший АНТИЧАТ
Регистрация: 18.08.2017
Сообщений: 1,568
С нами: 4598023

Репутация: 183


По умолчанию

Да, привет!

Ты всё понял верно, шаги у тебя правильные.

На самом деле, нужно понять на каком моменте что-то ломается.

Цитата:
Сообщение от UnknownPerson  

Код успешно регистрирует клиентскую команду и при использовании ее в игре краша нет, но и хандлер ничего не выполняет, а служит обычной "заглушкой"
Шаг первый. Нужно проверить, работает ли твоя заглушка. В консоль твоей программы выпиши адрес области, которая выделяется VirtualAllocEx (эта же функция и возвращает этот адрес). После инъекции, уже при работе программы, открываешь Cheat Engine (CE), дальше Memory Viewer, дальше Ctrl + G и вставляй этот адрес. У тебя должна открыться твоя же функция (те байты, которые ты написал). Выбираешь любой из них (любую строку) и нажимаешь F5 (либо ПКМ и «Break and trace instructions»). А теперь попробуй ввести в чат команду, которую ты зарегистрировал. CE должен будет остановить твою игру, а в меню Memory Viewer появится активная кнопка «Продолжить» (как при паузе). Если так, то это оно! Значит игра проходит через твою заглушку.

Цитата:
Сообщение от UnknownPerson  

Но игра вызывает краш после ввода команды и попытки выполнить этот код. Хочу также подметить, что в ассемблере я не силен от слова совсем
Шаг второй. Я думаю, что в ASM коде мало кто силён. Если шаг первый успешно выполнен, то единственная задача — правильно написать функцию, не сломав при этом значения регистров и программный стек. Прототип твоей функции следующий:

C++:





Код:
void
__cdecl
handler
(
const
char
*
)
;


И никто не мешает тебе в отдельной программе (не основной!) написать на C++ ту функцию, которая тебе нужна:

C++:





Код:
// создаёшь прототипы своих функций (я не знаю какие аргументы там)
typedef
void
(
__thiscall
*
AddEntry
)
(
int
,
int
,
const
char
*
,
int
,
int
,
int
)
;
int
SampDll
;
// получаешь адрес модуля samp.dll
void
__cdecl
handler
(
const
char
*
arg
)
{
if
(
strlen
(
arg
)
==
0
)
reinterpret_cast

(
SampDll
+
0x67460
)
(
SampDll
+
0x26E8C8
,
8
,
"text"
,
0x0
,
0xFFFFFF
,
0xFFFFFF
)
;
.
.
.
}


А дальше компилируешь это всё дело в x32. Можешь в коде где-то в
Код:
main()
написать
[CODE]
std::cout Only Bytes») и вставить в массив. Всю неприятную работу по созданию ASM кода выполнит компилятор. Если изначальные прототипы функций (не только твоей, но и тех, что ты вызываешь внутри) верны, то краша быть не должно.

Цитата:
Сообщение от Спойлер  

Даже при краше пишет адрес краша («Exception at address ...»), так ты можешь посмотреть, где и что конкретно вызывает краш.
upd.

Чтобы получить адрес модуля
Код:
samp.dll
воспользуйся этой функцией (это можно делать как внутри твоего вызова каждый раз, так и один раз при запуске):

C++:





Код:
DWORD
GetProcId
(
const
char
*
procname
)
{
PROCESSENTRY32 pe
;
HANDLE hSnap
;
pe
.
dwSize
=
sizeof
(
PROCESSENTRY32
)
;
hSnap
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPPROCESS
,
NULL
)
;
if
(
Process32First
(
hSnap
,
&
pe
)
)
{
do
{
if
(
strcmp
(
pe
.
szExeFile
,
procname
)
==
0
)
break
;
}
while
(
Process32Next
(
hSnap
,
&
pe
)
)
;
}
return
pe
.
th32ProcessID
;
}
HMODULE
GetModuleHandleExtern
(
const
char
*
szModuleName
,
DWORD dwProcessId
)
{
if
(
!
szModuleName
||
!
dwProcessId
)
{
return
NULL
;
}
HANDLE hSnap
=
CreateToolhelp32Snapshot
(
TH32CS_SNAPMODULE
,
dwProcessId
)
;
if
(
hSnap
==
INVALID_HANDLE_VALUE
)
{
return
NULL
;
}
MODULEENTRY32 me
;
me
.
dwSize
=
sizeof
(
MODULEENTRY32
)
;
if
(
Module32First
(
hSnap
,
&
me
)
)
{
while
(
Module32Next
(
hSnap
,
&
me
)
)
{
if
(
!
strcmp
(
me
.
szModule
,
szModuleName
)
)
{
CloseHandle
(
hSnap
)
;
return
me
.
hModule
;
}
}
}
CloseHandle
(
hSnap
)
;
return
NULL
;
}


Использование:





Код:
HMODULE SampDll
=
GetModuleHandleExtern
(
"samp.dll"
,
GetProcId
(
"gta_sa.exe"
)
)
;
// HMODULE — это обычный указатель, который занимает 4 байта в x32. Поэтому можешь использовать C-cast: (unsigned int)SampDll


Будут еще вопросы — пиши.
 
Ответить с цитированием