PDA

Просмотр полной версии : Работа с RakNet хуками


Receiver
31.03.2020, 12:15
[CENTER]Вечер в хату, часик в радость, чифир в сладость!

Здеся мы будем говорить от RakNekхуках. Hookв переводе с английского означает перехват.



Перехват (англ. (https://www.blast.hk/redirect/aHR0cHM6Ly9ydS53aWtpcGVkaWEub3JnL3dpa2kvJUQwJTkwJU QwJUJEJUQwJUIzJUQwJUJCJUQwJUI4JUQwJUI5JUQxJTgxJUQw JUJBJUQwJUI4JUQwJUI5XyVEMSU4RiVEMCVCNyVEMSU4QiVEMC VCQQ) hooking) — технология, позволяющая изменить стандартное поведение тех или иных компонентов информационной системы.


Вообщем с помощью хуком мы можем перехватить и модифицировать нужную нам информацию.

Эта информация может исходить как от игрока, так и от сервера.

Гайд рассчитан на людей имеющих хотя бы небольшой опыт работы с SF.

Приступим к регистрации нашего хука:

C++:






SF
->
getRakNet
(
)
->
registerRakNetCallback
(
RakNetScriptHookType
::
ТИП_ХУКА
,
hook_function
)
;




Данная функция регистрирует RakNetхук. Она принимает 2 аргумента: первый - тип хука, второй - функция в которой будет происходить его обработка

Вот все существующие типы RakNet хуков:



RAKHOOK_TYPE_INCOMING_PACKET– Перехватывает приходящие от сервера пакеты.
RAKHOOK_TYPE_INCOMING_RPC– Перехватывает приходящие от сервера RPC.
RAKHOOK_TYPE_OUTCOMING_PACKET– Перехватывает исходящие от игрока пакеты.
RAKHOOK_TYPE_OUTCOMING_RPC – Перехватывает исходящие от игрока RPC.


Регистрация должна происходить в mainloop после инициализации игры:

https://forum.antichat.xyz/attachments/27474258/

В данном случае я буду работать с приходящим от сервера RPC.

Создаём функцию обрабатывающую хук:

C++:






bool
__stdcall
hook_function
(
stRakNetHookParams
*
params
)
// Функция хука всегда принимает один параметр, это stRakNetHookParams
{
if
(
params
->
packetId
==
ScriptRPCEnumeration
::
RPC_ScrClientMessage
)
// RPC_ScrClientMessage это ID RPC. Можно использовать ScriptRPCEnumeration либо сразу указать ID RPC.
{
// Каждый RPC имеет свой список параметров
// В нашем случае RPC_ScrClientMessage имеет параметры: UINT32 dColor, UINT32 dMessageLength, char[] Message
DWORD color
;
// UINT32 dColor // Цвет сообщения
DWORD strlen
;
// UINT32 dMessageLength // Длина сообщения
char
string
[
144
]
;
// char[] Message // Текст сообщения
params
->
bitStream
->
ResetReadPointer
(
)
;
// Сбрасываем указатель чтения
params
->
bitStream
->
Read
(
color
)
;
// Получаем цвет сообщения из битстрима
params
->
bitStream
->
Read
(
strlen
)
;
// Получаем длину сообщения из битстрима
params
->
bitStream
->
Read
(
string
,
strlen
)
;
// Получаем текст и указываем длину сообщения
string
[
strlen
]
=
'\0'
;
// Ну и сверим наше сообщение с каким-нибудь текстом для примера
if
(
!
strcmp
(
string
,
"TestMessage_9812"
)
)
{
// Если вернётся true, то отправим сообщение в чат
SF
->
getSAMP
(
)
->
getChat
(
)
->
AddChatMessage
(
0xFFFFAAAA
,
"> Доброе утро, славяне."
)
;
}
}
return
true
;
}




Все RPC с их параметрами вы найдёте там: https://github.com/BrunoBM16/samp-packet-list/wiki/RPC-List

Компилируем, заходим в игру и проверяем:

https://forum.antichat.xyz/attachments/27474258/

Сообщение придёт быстрее, чем сам текст.

Потому что хук срабатывает до получения сообщения клиентом.

Вот полный код, который у нас получился:

https://forum.antichat.xyz/attachments/27474258/

Поправляйте меня в комментариях

MISTER_GONWIK
31.03.2020, 12:24
Гайд - API SF | Урок 4 - RakNet (https://blast.hk/wiki/tutorials:api_lesson_raknet)

Введение RakNet — это сетевой движок, используемый в SA:MP для обмена данными между игроками и сервером. Клиент отправляет пакет серверу, сервер его обрабатывает и рассылает другим игрокам — таким образом это работает. В этом уроке я покажу, как отправлять свои пакеты и заносить в них данные...

blast.hk


а это?

Receiver
31.03.2020, 12:36
Гайд - API SF | Урок 4 - RakNet (https://blast.hk/wiki/tutorials:api_lesson_raknet)

Введение RakNet — это сетевой движок, используемый в SA:MP для обмена данными между игроками и сервером. Клиент отправляет пакет серверу, сервер его обрабатывает и рассылает другим игрокам — таким образом это работает. В этом уроке я покажу, как отправлять свои пакеты и заносить в них данные...

blast.hk


а это?


не приятная ситуация 😞

H0wDareY0u
31.03.2020, 13:57
не приятная ситуация 😞


Ситуация может стать приятной если добавишь больше примеров по работе с другими пакетами и по сложнее.

loganhackerdff
01.04.2020, 13:29
что такое __stdcall и чем он от CALLBACK отличается?

и сделай урок, как хукать текст из 61rpc (showdialog

)

Shamanije
01.04.2020, 16:15
что такое __stdcall и чем он от CALLBACK отличается?


очищает после себя стэк

Dark_Knight
05.04.2020, 13:10
очищает после себя стэк





что такое __stdcall и чем он от CALLBACK отличается?
и сделай урок, как хукать текст из 61rpc (showdialog
)


а это что по вашему тогда?)

C++:






#define CALLBACK __stdcall

loganhackerdff
05.04.2020, 13:35
а это что по вашему тогда?)

C++:






#define CALLBACK __stdcall





Это фейк 🤔

loganhackerdff
05.04.2020, 13:47
Зайди в вижак, введи CALLBACK и нажми на нем F12.

https://i.imgur.com/i0tzpBT.png


__cdecl — после вызова функции параметры из стэка удаляет вызывающая сторона

__stdcall — после вызова функции параметры из стэка удаляет сама эта функция

__fastcall — похожа на __stdcall, но часть параметров пытается передать через регистры.

Dark_Knight
05.04.2020, 22:01
Спасибо за копипаст вики)

Receiver
06.04.2020, 20:06
Спасибо за копипаст вики)


нет проблем, очень заметно что это вики 👍 👍

Salik_Davince
14.05.2020, 14:05
Как примерно сделать такое - хукнуть RPC - RemoveObject, Создать массив с удаленными файлами, при подключении игрока проверять есть ли удаленный файл в массиве, если есть не синхронизировать RPC

Dark_Knight
14.05.2020, 22:39
Как примерно сделать такое - хукнуть RPC - RemoveObject, Создать массив с удаленными файлами, при подключении игрока проверять есть ли удаленный файл в массиве, если есть не синхронизировать RPC


@Salik_Davince (https://www.blast.hk/members/2149/) Ну как хукнуть показано выше. Вместо массива юзай контейнер(vector, map, list, deque, что тебе угодно).

Потом после чтения делай поиски в контейнере(std::find или std::find_if). Если поиск вернул итератор на элемент следующий за последним(it == end()), то добавляй его в контейнер(методы push_back, insert, etc) и возвращай истину, а если уже вернул другое значение, то возвращай ложь.



чаво
что ты получить?


Только дурак не поймет ход его мыслей.

Kerlosad
02.02.2022, 15:36
как хукнуть RPC SendChatMessage под номером 101?