Вернуться   CoderX :: Forums > Основные форумы > Полезности
Войти через OpenID

Полезности Исключительно для полезных тем из других разделов.
Темы тут не создаются!
Темы сюда перемещаются из других разделов, и на их старых местах остаются постоянные перенаправления.

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 17.12.2008, 00:18   #1
Пользователь
 
Регистрация: 03.11.2008
Сообщений: 60
Сказал Спасибо: 3
Имеет 107 спасибок в 21 сообщенях
GoldFinch пока неопределено
По умолчанию Радар своими руками

Радар своими руками /16.12.2008/

Введение

В этой статье описывается создание "радара" - кода отображающего других игроков внутри клиента ла2. В ней рассмотрены следующие вопросы: рисование в окне клиента, получение информации об нпс и игроках хранящейся клиенте, перехват входящего пакета, перехват исходящего пакета, отправка пакета клиенту.
В свое время, когда я начинал разбираться с клиентом, я искал подобную статью, так и не нашел. Ну а раз ее нет - значит ее надо написать чтобы она была. Для понимания этой статьи необходимы базовые знания по работе клиента ла2, реверсированию и программированию. Все примеры относятся к клиенту C6, но я думаю клиенты ла2 принципиально не отличаются друг от друга.

1. Общая информация о клиенте ла2

Для начала небольшая вводная об устройстве клиента ла2. Он состоит из 1 .exe модуля и нескольких длл выполняющих строго определенные функции - GUI (nwindow.dll), движок (engine.dll), общие вспомогательные функции (core.dll). Клиент сделан на основе движка unreal engine, написан на VC++ с применением ООП. Длл экспортируют практически все методы основных классов, имена декорированы (mangling), также экспортируются таблицы методов (vftable).

2. Рисование

Основная функция радара - рисовать цели в окне клиента. Для этого нужны функции рисования, и перехват нужного участка кода клиента для вызова кода рисования радара.
Клиент для рисования как правило использует класс FCanvasUtil. Для его использования надо создать экземпляр объекта, после рисования - уничтожить его. Примерный размер объекта не более 256 байт (точное значение неизвестно). В классе FCanvasUtil есть одна нормальная функция рисования
void __thiscall FCanvasUtil::DrawLine(float x1, float y1, float x2,float y2,class FColor color,int unk) ,
где x1..y2 - четыре экранные координаты в пикселах,
color - цвет, dword 0xSSRRGGBB (SS - Saturation),
unk - неизвестный параметр, обычно равнен нулю.
Точки можно рисовать короткими штрихами, окружности аппроксимировать отрезками (или пунктиром).
Рисовать надо вместе с клиентом, в одном из методов xxx::Render(), так чтобы картинка радара рисовалась последней (верхней), порядок вызова методов клиентом неизвестен, но рисование после FPlayerSceneNode::Render() позволяет нарисовать радар правильно.

3. Получение информации о целях

Все объекты на карте поделены в клиенте на категории ("живые",лут,...) и хранятся в нектором списке. Для получения "живых" объектов (игроки,НПС) используется метод
struct User * __thiscall UNetworkHandler::GetNextCreature(float Radius,int PrevID) ,
где Radius - радиус поиска, PrevID - ИД предыдущей цели.
Метод возвращает указатель на структуру содержащую информацию о цели (см. приложение). Метод может возвращать ноль, видимо при отсутствии целей вообще. Метод можно вызывать бесконечное число раз, видимо список объектов цикличен, для того чтобы определить конец списка надо проверять повторы ИД возвращаемых целей. Перебор целей можно начинать как с PrevID=0 так и PrevID=-1 .

4. Получение информации о своем персонаже - перехват S->C пакета

Для получения структуры User по ID объекта надо вызвать метод
struct User * __thiscall UNetworkHandler::GetUser(int ID) .
ИД своего персонажа можно получить перехватив S->C пакет UserInfoPacket (#4). Теоретически этот ID можно получить в клиенте по статическому адресу, но перехват пакета очевиднее.
S->C пакеты обрабатываются в клиенте следующим образом:
В отдельном потоке, в цикле, клиент принимает пакеты вызывая ws2_32.recv(), расшифровывает их, добавляет в очередь пакетов методом
UNetworkHandler::AddNetworkQueue(NetworkPacket *) .
Структура NetworkPacket содержит отдельно ID пакета, размер данных пакета (без ID), данные пакета (без ID).
В методе UNetworkHandler::Tick(float) клиент достает пакеты из очереди методом
UNetworkHandler::DispatchNetworkQueue(NetworkPacke t * *) .
Затем по ID пакета вызывается обработчик пакета, по указателю таблицы обработчиков пакетов. Размер элемента таблицы равен 0x104 байтам - указатель на обработчик и UNICODE-имя пакета. Прототип обработчика пакета:
typedef void (__cdecl TPacketHandler)(UNetworkHandler *,char *data);
где data - указатель на данные пакета, без его ID.
Обработчик пакета дизассемблирует пакет согласно его формату, вызывает соответствующий метод UGameEngine::OnXXX() и записывает информацию о пакете во внутренний лог клиента.
Метод UGameEngine::OnXXX вызывает события в GUI или в движке клиента.
Очевидно, что перехватывать одиночный пакет удобно подменяя указатель на обработчик пакета или указатель на метод UGameEngine в его таблице методов.

5. Управление настройками радара - перехват C->S пакета и отправка пакета клиенту

Внутри клиента можно организовать достаточно удобный интерфейс используя HTML встроенный в клиент.
Для показа диалогового окна пользователю, надо отправить клиенту пакет с HTML-кодом, методом
int __thiscall UGameEngine::OnNpcHtmlMessage(struct User *npc,unsigned short *html,int unk) ,
где npc - указатель на структуру User НПС отправившего сообщение, может быть равен нулю,
html - указатель на UNICIDE-строку с HTML-кодом,
unk - неизвестный параметр, обычно равен нулю.
Если ввод данных производится кнопками, то для перехвата ввода необходимо перехватить пакет RequestBypassToServer. Клиент отправляет пакеты следующим образом:
GUI или движок клиента вызывают соответствующий метод UNetworkHandler, например
int __thiscall UNetworkHandler::RequestBypassToServer(class L2ParamStack &) .
Этот метод передает формат пакета и его данные в неэкспортируемую функцию отправки пакета
void __cdecl SendPacket(UNetworkHandler*,char*,...) .
Функция отправки пакета ассемблирует пакет в буфер согласно его формату, шифрует и отправляет на сервер через ws2_32.send() .
Для перехвата одиночного отправляемого пакета удобно перехватить указатель на метод в таблице методов UNetworkHandler.

Заключение

Я не выкладываю сам исходник радара, в его коде нет ничего сложного, и имея информацию изложенную в этой статье его можно достаточно быстро собрать.
Эта статья больше посвящена частям клиента относящимся к пакетной части клиента. Графическая часть рассмотрена вскользь без какого-либо разбора, движок клиента только упоминается, совсем не рассмотрены GUI и остальные части клиента. Буду рад если кто-нибудь дополнит эту статью или выложит что-то новое. Возможно есть смысл перевести ее на английский.

Приложение. Структуры клиента (С6)
Код:
struct User
{
int _zunk1_12[2];
int user_type; //ZERO for player
int _zunk1_34[2];
int unk_npc_spec;
int id;
unsigned short name[0x30/2];
int race;
int _zunk2;
int _xunk3;
int lvl;
int _xunk4;
int _zunk5;
int states[6];
int hp_max;
int hp;
int mp_max;
int mp;
int _xunk68[3];
int wear[14];
char _zunk9[0xC0];
int Color;
char _unk10[0x70];
APawn *Pawn;
int _zunk11[3];
int _xunk12;
int sp;
int accuracy_;
int critical;
int _xunk13;
int _xunk14;
int patk;
int evasion_;
int matk;
int mdef;
int castspd;
char _unk15[0x6C];
int atkspd;
char _unk16[0x14];
int cp_max;
int cp;
//current size=0x2CC, real size = 0x380
};

class APawn
{
char _unk[0x1BC]; //...
public:
FVector Location;
//...
};

class FVector
{
public:
    float X,Y,Z;
};
----------------------------------------------------
[C] GoldFinch

Спасибо
Arrowdodger за помощь в написании и тестировании радара
Разработчикам BSFG (Abyss) за их радар и его кривую защиту. Кстати код у binkw32.dll тоже хреновый :)

Последний раз редактировалось GoldFinch, 09.05.2009 в 16:10.
GoldFinch вне форума   Ответить с цитированием
За это сообщение GoldFinch нажился 34 спасибками от:
Старый 27.05.2009, 14:22   #2
Пользователь
 
Аватар для Fertis
 
Регистрация: 07.03.2009
Сообщений: 64
Сказал Спасибо: 33
Имеет 2 спасибок в 2 сообщенях
Fertis пока неопределено
По умолчанию

Мб зря апаю тему... но никто неможет ли привести пример, экспорта хотя бы одной функции? Например инфы о своем чаре. Чет поковырялся, половину непонял...
Fertis вне форума   Ответить с цитированием
Старый 28.05.2009, 15:54   #3
Пользователь
 
Аватар для Be3geBJIa3
 
Регистрация: 23.01.2008
Сообщений: 93
Сказал Спасибо: 31
Имеет 65 спасибок в 23 сообщенях
Be3geBJIa3 пока неопределено
По умолчанию

Очень интересная статья, хотелось бы продолжения. Примеры, исходники.
Be3geBJIa3 вне форума   Ответить с цитированием
Старый 28.05.2009, 18:09   #4
Местный
 
Регистрация: 18.02.2008
Сообщений: 141
Сказал Спасибо: 16
Имеет 66 спасибок в 30 сообщенях
ratvier
По умолчанию

Автор выкладывал где-то пример. Я надеюсь, он будет не против, если я его залью сюды.
Вложения
Тип файла: rar l2cc.rar (9.6 Кб, 1286 просмотров)
ratvier вне форума   Ответить с цитированием
За это сообщение ratvier нажился 8 спасибками от:
Старый 29.05.2009, 16:24   #5
Заблокирован
 
Регистрация: 01.10.2007
Сообщений: 76
Сказал Спасибо: 22
Имеет 7 спасибок в 7 сообщенях
Murdoc
По умолчанию

Цитата:
Сообщение от ratvier Посмотреть сообщение
Автор выкладывал где-то пример. Я надеюсь, он будет не против, если я его залью сюды.
э... и что демонстрирует данный пример? у меня он 1 раз подвесил тачку, 2 раза запорол клиента, 2 раза просто не запустился(файл занят) и еще пару раз незапустился с другой ошибкой. и ехе и длл лежали в папке систем клиента.
Murdoc вне форума   Ответить с цитированием
Старый 29.05.2009, 18:07   #6
Пользователь
 
Регистрация: 03.11.2008
Сообщений: 60
Сказал Спасибо: 3
Имеет 107 спасибок в 21 сообщенях
GoldFinch пока неопределено
По умолчанию

Murdoc, там написано, что это POC (proof of concept). Он тестировался на конкретном клиенте С6, и его надо дорабатывать напильником чтобы он заработал на другом клиенте. Кроме того, т.к. это POC, никакой полезной функциональности там нет, а есть только пример работы с API клиента напрямую.
GoldFinch вне форума   Ответить с цитированием
Старый 05.06.2009, 02:11   #7
Новичок
 
Регистрация: 03.03.2009
Сообщений: 12
Сказал Спасибо: 6
Имеет 1 спасибку в 1 сообщении
Arseny пока неопределено
По умолчанию

перед тем как отправить пакет от имени engine.dll надо еще заполнить стек отправки
вчера стал ковырять функцую отправки пакета на сдачу манора - в принципе механизм тот же, что и в других функциях Л2, можно разбить на следующую цепочку:
1. преварительные действия, нас не интересуют в общем-то. Могут интересовать, чтобы подобрать место для перехода на наш код.
2. чтение из стека Л2, подготовка параметров для обработки - самая интересная часть, нас интересует больше всего. Именно в этот момент нам доступны внутренние данные пакетов при получении и перед отправкой, именно этот код нужно дублировать в нашей программе.
3. последующие действия клиента, как правило, не представляют интереса.

Murdoc, у меня этот пример убил клиент Ц4, хотя я почитал как он переписывается под Ц4. Но именно он подтолкнул меня к написанию собственного аналога, и дал кое-какое понимание о внутренней работе клиента и том, что и как надо в нём перехватывать. После чего был написан аналог по механизму работы для Ц4, который опробован на конкретном клиенте, на вин XP и Висте, сама ДЛЛка работает стабильно, программа-приемник периодически вылетает. Сейчас обдумываю как лучше сделать отправку пакета от имени клиента... вариантов два - или создать свой стек и заполнить его, после чего вызвать нужную функцию с указателем на мой стек, или же внедриться в функцию и внаглую прописывать в нужных местах значения(ессно передаются через переменные). Сами проги на дельфи, код, отвечающий за перехват функций клиента - ассемблер... без ассемблера никак вообще тут.
Arseny вне форума   Ответить с цитированием
Старый 05.06.2009, 05:59   #8
Рыцарь
 
Аватар для dmitry501
 
Регистрация: 01.10.2007
Сообщений: 293
Сказал Спасибо: 42
Имеет 50 спасибок в 37 сообщенях
dmitry501 пока неопределено
По умолчанию

Цитата:
Сообщение от Arseny Посмотреть сообщение
перед тем как отправить пакет от имени engine.dll надо еще заполнить стек отправки
вчера стал ковырять функцую отправки пакета на сдачу манора - в принципе механизм тот же, что и в других функциях Л2, можно разбить на следующую цепочку:
1. преварительные действия, нас не интересуют в общем-то. Могут интересовать, чтобы подобрать место для перехода на наш код.
2. чтение из стека Л2, подготовка параметров для обработки - самая интересная часть, нас интересует больше всего. Именно в этот момент нам доступны внутренние данные пакетов при получении и перед отправкой, именно этот код нужно дублировать в нашей программе.
3. последующие действия клиента, как правило, не представляют интереса.
<SKIP>.
Если заинтересовался этой темой пиши в ПМ мне или Sherman - у
Есть небольшие наработки, как раз по С4 и возможен обмен знаниями

Последний раз редактировалось dmitry501, 05.06.2009 в 06:00. Причина: Добавлено сообщение
dmitry501 вне форума   Ответить с цитированием
Старый 28.05.2009, 20:11   #9
Пользователь
 
Регистрация: 03.11.2008
Сообщений: 60
Сказал Спасибо: 3
Имеет 107 спасибок в 21 сообщенях
GoldFinch пока неопределено
По умолчанию

на этом форуме и выкладывал, и не пример радара, и на фасме =)
GoldFinch вне форума   Ответить с цитированием
За это сообщение GoldFinch нажился 2 спасибками от:
Старый 28.05.2009, 21:10   #10
Пользователь
 
Аватар для Fertis
 
Регистрация: 07.03.2009
Сообщений: 64
Сказал Спасибо: 33
Имеет 2 спасибок в 2 сообщенях
Fertis пока неопределено
По умолчанию

на дельфях ниукого небудет примеров? если кто может скиньте плиз, ибо переписать на паскаль несмогу был бы очень признателен
Fertis вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Основные форумы > Полезности


Опции темы
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 14:58.

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!