Сразу предупреждаю, статья рассчитана на продвинутых пользователей, знакомых с программированием.
Итак, начиная с новой 2.0.gamma8 версии, в
RFWarrior добавлены экспортируемые функции, которые может использовать
любой человек в своих собственных программах, причём написанных на
любом языке программирования. В данной статье я опишу подробно как это можно сделать, что это даёт и разумеется приведу примеры готовых программ.
Суть.
Для начала опишу как работает
RFWarrior и в чём, собственно, фишка.
Варриор можно сравнить с WPF - он также пропускает через себя рф траффик и за счёт его модификации выполняет нужные пользователю функции. Фундаментальная разница заключается в том, что варик не пускает соединение через себя, а работает несколько глубже (конкретнее описывать не буду - это сложно). Тем самым он обходит фрост (включая загруженный драйвер фроста) и позволяет модифицировать даже шифрованный траффик.
Чтобы простому пользователю послать свой пакет в обход фроста, пришлось бы повторять всю большую цепочку операций по обходу фроста, которая реализована в варике. Так вот вчера в RFWarrior были добавлены экспортируемые API, которые позволяют простому пользователю-программисту, из своей собственной программы (написанной на любом языке программирования) получать полный контроль над пакетным уровнем RFOnline. При этом, самому пользователю совершенно не нужно обходить фрост, хукать API и так далее.
Экспортируемые функции.
Для того, чтобы воспользоваться описанной выше прелестью, вы должны иметь базовые знания по написанию библиотек, а также импорту (GetProcAddress) и использованию функций из других библиотек. Если вы в этом шарите (или собираетесь начать шарить), расскажу более подробно как это работает.
В библиотеке варриора присутствует следующий ряд экспортируемых функций:
PHP код:
extern "C"
{
// Устанавливает ваш собственный обработчик входящего траффика
int __declspec(dllexport) __stdcall SetRecvHandler(TPacketHandler hndlr);
// Устанавливает ваш собственный обработчик исходящего траффика
int __declspec(dllexport) __stdcall SetSendHandler(TPacketHandler hndlr);
// Получение ТЕКУЩЕГО каллбэка-обработчика входящего и исходящего траффика
TPacketHandler __declspec(dllexport) __stdcall GetRecvHandler();
TPacketHandler __declspec(dllexport) __stdcall GetSendHandler();
// Отсылка пакета игровому серверу
int __declspec(dllexport) __stdcall SendPacketToServer(char* buff, short len);
// Отсылка пакета игровому клиенту
void __declspec(dllexport) __stdcall SendPacketToClient(char* buff, short len);
}
Это список тех функций, которые вы из своей программы можете импортировать и
использовать. Представьте, для того, чтобы послать свой пакет серверу/клиенту или перехватить и ПРАВИТЬ весь игровой траффик, вам нужно всего-лишь экспортировать нужную функцию. Вот в чём соль этого нововведения. Теперь каждый смертный может написать свой чит :)
Немного подробнее о перехвате траффика..
Придуманный механизм похож на работу некоторых Win API, например: SetWindowLong, которая позволяет ставить свой обработчик оконных сообщений. Через функции SetRecvHandler и SetSendHandler вы можете ставить свою функцию-обработчик, которая будет вызываться вариком в момент получения или отсылки пакета. Формат функции обработчика такой:
PHP код:
typedef int (__stdcall *TPacketHandler)(char* packet, int plen);
Определяете любое название своей функции-обработчика и передаете её в импортируемую функцию SetRecvHandler или SetSendHandler, и траффик начинает бежать через ваш обработчик.
Как вы, наверное, уже поняли, импортировать функции надо из уже загруженной в память игры дллки (RFWarrior.dll). То есть обычный LoadLibrary тут не прокатит. Вам нужно аттачить свою дллку к процессу с игрой (а это можно сделать через любой dll-инжектор), а из неё уже искать модуль варика и дёргать из него нужные вам функции.
Я понимаю, что новичкам трудно всё это понять по голому тексту, поэтому попросил Шторма сделать пример (т.к. он был идейным вдохновителем и основным реализатором этой темы :)).
Итак, пример простейшей дллки (на языке Си), которая посредством импортируемых из варика функций, реализует перехват входящего RFOnline траффика в обход фроста:
PHP код:
// Описание формата ВАШЕЙ функции-обработчика входящих пакетов
typedef int (__stdcall *TPacketHandler)(char* packetbuf, int packetlen);
// Описание формата двух функций, которые вы импортируете из модуля RFWarrior.dll
typedef int (__stdcall *TSetRecvHandler)(TPacketHandler hndlr);
typedef TPacketHandler (__stdcall *TGetRecvHandler)();
HINSTANCE mineDLL = 0;
// А вот и ваша функция-обработчик входящего траффика.
// Она будет вызываться каждый раз при получении пакета игровым клиентом.
int __stdcall PacketHandler(char* packetbuf, int packetlen)
{
// Ваш код тут
// packetbuf - пакет
// packetlen - длина пакета
// Возвращаемое значение этой функции определяет пойдёт ли пакет дальше
// в обработчик пакетов самого RFWarrior.
// 0 - не пойдёт
// 1 - пойдёт (то есть пакет будет обработан вариком)
return 1;
}
// Точка входа в вашу DLL
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
// Сохраняем хэндл вашей дллки
if (mineDLL == NULL)
mineDLL = hinstDLL;
// Если DLL-ка в данный момент загружается, то...
if (fwdreason == DLL_PROCESS_ATTACH && mineDLL == hinstDLL) {
// Получаем хэндл модуля RFWarrior.dll
HINSTANCE dll_handle = GetModuleHandle(L"RFWarrior.dll");
// Импортируем функцию, через которую мы поставим свой обработчик пакетов
TSetRecvHandler SetRecvHandler = TSetRecvHandler(GetProcAddress(dll_handle,"SetRecvHandler"));
// Вызываем импортируемую функцию, передаём ей в виде параметра адрес нашей функции-обработчика пакетов
SetRecvHandler(&PacketHandler);
}
// Если ваша DLL выгружается, то зануляем в модуле варика ваш обработчик (чтобы он не вылетел из-за вызова функции по битому указателю)
else if (fwdreason == DLL_PROCESS_DETACH && mineDLL == hinstDLL) {
HINSTANCE dll_handle = GetModuleHandle(L"RFWarrior.dll");
TSetRecvHandler SetRecvHandler = TSetRecvHandler(GetProcAddress(dll_handle,"SetRecvHandler"));
SetRecvHandler(0);
}
return 1;
}
Код абсолютно готовый к использованию, за вас уже всё сделали :) Вам лишь нужно в функции PacketHandler() вставить желаемые махинации со входящими пакетами...
Что конкретно менять во входящих пакетах для достижения того или иного результата, это уже другой вопрос. И ответ на него вы найдёте в процессе изучения RF-траффика или раздела
пакетный уровень RF Online.
Если вы совсем нуб и вам интересно, что НАПРИМЕР вы можете сделать.. конкретный выше код вы
легко можете использовать как фильтр лута, видеть ВСЕ чужие мины (вне зависимости от расы и класса) и ИНВИЗЕРОВ, как программу показывающую заточку персонажей, как программу, информирующую о появление в зоне видимости других игроков.. name-хак, lvl-хак, спидхак и так далее, и тому подобное.. тут можно перечислять до бесконечности :)
Ну что ж, возможно это не последняя статья по данной тематике, может следующим будет статья по поводу написания конкретного чита для каких-то конкретных целей.
Пока изучайте, пользуйтесь этим.
Спасибо за идею и помощь
Stormraider