|
|
|
Uoext. Расширяя Возможности Клиента, We do what EA can't. |
|
|
Destruction |
17.11.2010, 13:09
|
Группа: Администраторы Наличность: 7
Пользователь №: 1.833
|
Цитата(Warstone @ 17.11.2010, 13:04) На самом деле - надо проверять... Надо знать как руководит протоколом Разор и Инжа. Узнать это можно, поэтому, в теории, эти фишки можно обходить. А можно просто запрещать использовать Разор или Инжу.
Что касается инжекта.. Если с ним будет получаться такая цепочка: server <-> injection <-> твоя тулза <-> клиент То инжект в этой цепочке очень легко выцепить. Ты можешь любым способом поменять пакеты которые отсылает клиент/сервер (и соответственно научить работать с изменениями клиент/сервер) и в результате, либо тихонько следить за инжекторами (например 1 неправильный пакет - инжа детектед), либо просто блокировать (хотя бы доп. шифрование накрутить и инжа уже ничего не поймет) возможность использования инжы. В любом случае будут умельцы которые будут использовать софт, но делится они врятли станут (не выгодно, т.к. повлечет обновление защиты, которое ко всей прочей радости может оказаться прозрачным для клиента).
--------------------
Discord: tatikom
|
|
|
|
Warstone |
12.12.2010, 3:50
|
Группа: Модераторы Наличность: 0
Пользователь №: 10.905
Возраст: 25
|
Некоторые люди сильно ругали меня за то, что не видно - что делается. Такое ощущение, что я ввожу народ в заблуждение. Возможно. Что-бы развеять подозрения - собранная "демонстрационная" версия: http://ifolder.ru/20756056Для работы этой... "демки" необходим клиент версии 6.0.Х (просто потому что основная часть протокола писалась с него), освобожденный от шифрования (через UO_Rice, например), а так-же сервер настроенный на 127.0.0.1:2593 (Значения пока зашиты внутри). Файл ProtocolShower.plg необходимо положить в папку Plugins вашего клиента (папку надо будет создать). Инструкции к запуску: Запускаете UOLoader.exe, который есть в архиве, в появившейся простейшей форме, указываете путь декриптованного ехе от установленного клиента и жмете кнопку запустить. Что должно произойти: Должен появиться запускающийся клиент, но помимо его - еще одно консольное окно, где в последствии будет идти лог переданных пакетов между клиентом и сервером. Да, демка простейшая, так как на данный момент и показывать-то нечего.
--------------------
Do. Or do not. There is no Try! © Master Joda, Dagobah, Star Wars: Episode V.
|
|
|
|
Warstone |
12.12.2010, 23:49
|
Группа: Модераторы Наличность: 0
Пользователь №: 10.905
Возраст: 25
|
Итак... Хотелось-бы немного рассказать об API и послушать ваши замечания. Все, что я сейчас расскажу не является истиной в последней инстанции и может быть изменено. Итак - погнали. На данный момент система предоставляет возможность использовать плагины для перехвата, анализа и подмены протокола UO версии 6-х клиентов. Плагины - это обыкновенные dll библиотеки с дополнительными правилами "игры". Вот код простейшего плагина на Delphi: Код library HelloWorld;
uses PluginsShared in '..\ProtocolExtender\PluginsShared.pas', uMain in 'HelloWorld\uMain.pas';
{$E plg} exports InitializationProc; begin end. Как видно из кода, плагин должен экспортировать процедуру InitializationProc, через которую и идет начальное "общение" с "хостом". Текущее представление юнита PluginsShared: Код unit PluginsShared;
interface
const PF_REGISTERPACKETHANDLER: Cardinal = 1; PF_UNREGISTERPACKETHANDLER: Cardinal = 2; PF_REGISTERPACKETTYPE: Cardinal = 3; // Not supported right now. Reserved for futher use. PF_SENDPACKET: Cardinal = 4;
type TPacketHandler = function (Data: Pointer; var Size:Cardinal; var Send: Boolean; IsFromServerToClient: Boolean):Boolean stdcall; (** Send - Send this package to reciver. Result - If true - this event breaks bubbling. If Send = false then Result forced to true. **)
RAPIFunc = record FuncType: Cardinal; Func: Pointer; End; PAPIFunc=^RAPIFunc;
TInitializationProc = procedure (anAPIFunc: PAPIFunc) stdcall;
TRegisterPacketHandler = procedure(Header:Byte; Handler: TPacketHandler) stdcall; TUnRegisterPacketHandler = procedure(Header: Byte; Handler: TPacketHandler) stdcall; TRegisterPacketType = procedure(Header:Byte; Size:Word) stdcall; TSendPacket = function(Packet: Pointer; Length: Cardinal; ToServer, Direct: Boolean; var Valid: Boolean):Boolean; stdcall;
implementation
end. Как видно из этого модуля, InitializationProc имеет только один параметр - ссылку на передаваемую функцию API. Механизм инициализации плагина следующий: - Плагин загружается через LoadLibrary. - Вызывается InitializationProc(nil). На этом этапе плагин может сделать какую-нибудь подготовительную работу перед приемом API. - Передается весь набор API через последовательный вызов InitializationProc. - Вызывается InitializationProc(nil). На этом этапе плагин может и должен установить обработчики пакетов (Путем вызов RegisterPacketHandler). Больше InitializationProc вызываться не будет. Инициализация плагинов происходит во время обращения клиента к login.cfg. Это гарантирует что клиент еще ни разу не подключался к серверу. Ну и на последок еще 3 файла: Утилитарный класс-помошник: Код unit PluginAPI;
interface
uses PluginsShared;
type TPluginInitialization = procedure;
TPluginApi = class private FRegisterPacketHandler: TRegisterPacketHandler; FUnRegisterPacketHandler: TUnRegisterPacketHandler; FSendPacket: TSendPacket; protected procedure RegisterAPIFunc(anAPIDescriptor: PAPIFunc); public procedure RegisterPacketHandler(Header:Byte; Handler: TPacketHandler); procedure UnRegisterPacketHandler(Header:Byte; Handler: TPacketHandler); function SendPacket(Packet: Pointer; Length: Cardinal; ToServer, Direct: Boolean; var Valid: Boolean):Boolean; end;
procedure InitializationProc (anAPIFunc: PAPIFunc) stdcall;
var API : TPluginApi; PluginInitialization : TPluginInitialization; Initialized : Boolean; Initialazing : Boolean;
implementation
uses SysUtils;
// Procedures
procedure InitializationProc (anAPIFunc: PAPIFunc) stdcall; begin API.RegisterAPIFunc(anAPIFunc); If anAPIFunc = nil Then Begin If not Initialazing Then Initialazing := True else Begin Initialazing := False; If Assigned(PluginInitialization) Then PluginInitialization(); Initialized := True; End; End; end;
// TPluginApi
procedure TPluginApi.RegisterAPIFunc(anAPIDescriptor: PAPIFunc); begin If anAPIDescriptor = nil Then Exit; If anAPIDescriptor^.FuncType = PF_REGISTERPACKETHANDLER Then FRegisterPacketHandler := anAPIDescriptor^.Func Else If anAPIDescriptor^.FuncType = PF_UNREGISTERPACKETHANDLER Then FUnRegisterPacketHandler := anAPIDescriptor^.Func Else If anAPIDescriptor^.FuncType = PF_SENDPACKET Then FSendPacket := anAPIDescriptor^.Func end;
procedure TPluginApi.RegisterPacketHandler(Header:Byte; Handler: TPacketHandler); begin If @FRegisterPacketHandler = nil Then Raise Exception.Create('RegisterPacketHandler not supplied by host'); FRegisterPacketHandler(Header, Handler); end;
procedure TPluginApi.UnRegisterPacketHandler(Header:Byte; Handler: TPacketHandler); begin If @FUnRegisterPacketHandler = nil Then Raise Exception.Create('UnRegisterPacketHandler not supplied by host'); FUnRegisterPacketHandler(Header, Handler); end;
function TPluginApi.SendPacket(Packet: Pointer; Length: Cardinal; ToServer, Direct: Boolean; var Valid: Boolean):Boolean; begin If @FSendPacket = nil Then Raise Exception.Create('SendPacket not supplied by host'); Result := FSendPacket(Packet, Length, ToServer, Direct, Valid); end;
initialization API := TPluginApi.Create; PluginInitialization := nil; finalization API.Free; end. Полный пример HelloWorld.plg(основной фаил): Код library HelloWorld;
uses PluginsShared in '..\ProtocolExtender\PluginsShared.pas', PluginAPI in 'Common\PluginAPI.pas', uMain in 'HelloWorld\uMain.pas';
{$E plg} exports InitializationProc; begin end. Ну и uMain.pas: Код unit uMain;
interface
implementation
uses Windows, WinSock, PluginAPI;
var HelloWorldPacket: Array [0..56] of Byte;
function HelloHandler(Data: Pointer; var Size:Cardinal; var Send: Boolean; IsFromServerToClient: Boolean):Boolean stdcall; var isValid: Boolean; begin API.UnRegisterPacketHandler($3A, @HelloHandler); API.SendPacket(@HelloWorldPacket, 57, False, True, isValid); Result := False; end;
procedure Init; var sDummy: String; Begin API.RegisterPacketHandler($3A, @HelloHandler);
// Filling Hello world packet ZeroMemory(@HelloWorldPacket, 57); PByte(@HelloWorldPacket)^ := $1C; //Header (1Byte) PWord(Cardinal(@HelloWorldPacket) + 1)^ := htons(57); // SizeOfpacket (2Bytes) PCardinal(Cardinal(@HelloWorldPacket) + 3)^ := $FFFFFFFF; //Serial (4Bytes) PWord(Cardinal(@HelloWorldPacket) + 7)^ := $FFFF; // Graphic (2Bytes) PByte(Cardinal(@HelloWorldPacket) + 9)^ := $00; // MessageType (1Byte) PWord(Cardinal(@HelloWorldPacket) + 10)^ := htons($03B2); // Hue (2Bytes) PWord(Cardinal(@HelloWorldPacket) + 12)^ := htons($0003); // Font (2Bytes) sDummy := 'System'; CopyMemory(PChar(Cardinal(@HelloWorldPacket) + 14), @sDummy[1], 6); // Name (30Bytes) sDummy := 'Hello World!' + #0; CopyMemory(PChar(Cardinal(@HelloWorldPacket) + 44), @sDummy[1], 12); // Message (Various) End;
initialization PluginInitialization := @Init; end. Пожелания, предложения, помидоры? ЗЫ: Текущую версию ProtocolExtender'а выложу чуть позже.
--------------------
Do. Or do not. There is no Try! © Master Joda, Dagobah, Star Wars: Episode V.
|
|
|
|
Warstone |
13.12.2010, 0:01
|
Группа: Модераторы Наличность: 0
Пользователь №: 10.905
Возраст: 25
|
Да, ну и дальнейшие планы:
1) Переделать инициализацию на вызов не по "одной процедуре", а все сразу скопом.
2) Дать возможность указывать протокол в плагине (поддержка любого протокола любой версии, если вы напишите "протокольный плагин") Можно указывать протокол, который не следует стандарту "Если длинна пакета не известна, то она пишется во 2-м и 3-м байте пакета" 3) Криптование со стороны клиента и сервера (Шифрованный клиент к нешифрованному серверу и наоборот). 4) Распаковка/Запаковка zlib'ом пакета с Гампами (и других пакетов, если такие будут) 5) Доработка утилитарных классов. В частности для чтения/записи пакетов.
6) Механизм отслеживания "оригинальных" и "измененных" Серийников для того, чтобы можно было удобно и безопасно спавнить айтемы и мобайлы в мире через прокси, а не через сервер Частично сделан. Всего будет 3 механизма: 1) Статический (Администратор сервера выделяет большой пул серийников, пул задается в конфиге перехватчика) 2) Серверный (Сервер, по запросу, предоставляет маленькие пулы серийников, пулы получаются через расширение протокола) 3) Проксируемый (Перехватчик выдает незанятые серийники, если сервер их занимает, начинается трансляция серийников из серверный в клиентские и обратно) Пока сделан механизм 1. 7) Получение плагинов с сервера и инкапсуляция своего протокола внутрь УО'шного для управления системой с сервера. (Собственно это была основная цель данного проекта. Дать возможность держателям серверов "дописывать" поведение клиента в зависимости от своих пожеланий) 8) Механизм временных событий (стандартные средства тут не работают).
9) Механизм синхронизации с другими потоками клиента (необходимо для реализации перехвата API в плагинах) Синхронизация сделана через 2-х ступенчатую систему изменения Interlocked переменных.
999) Оптимизация протокола УО для большей эффективности передачи данных и снижению нагрузки на канал.
--------------------
Do. Or do not. There is no Try! © Master Joda, Dagobah, Star Wars: Episode V.
|
|
|
|
Wap |
22.12.2010, 17:39
|
Администратор Форума
Сообщений: 3.003
Регистрация: 22.12.2006 Группа: Администраторы Наличность: 31650
Пользователь №: 9.227
|
Потестил "демонстрационную" версию. Запускает клиент нормально, коннектится нормально, играть вроде можно, лог пакетов идет. Короче говоря, никаких проблем не обнаружено. (Клиент: 6.0.13.0; Эмулятор: SphereServer 0.56b, одна из последних сборок). По коду сказать нечего, я не программист. (IMG: style_emoticons/default/smile.gif) P.s. А нет, рано порадовался, что проблем совсем нет. При закрытии клиента крестиком гарантировано вылетает вот такое: Сообщение отредактировал wap - 22.12.2010, 17:55
--------------------
|
|
|
|
Warstone |
24.12.2010, 13:05
|
Группа: Модераторы Наличность: 0
Пользователь №: 10.905
Возраст: 25
|
Цитата(wap @ 22.12.2010, 17:39) Потестил "демонстрационную" версию. Запускает клиент нормально, коннектится нормально, играть вроде можно, лог пакетов идет. Короче говоря, никаких проблем не обнаружено. (Клиент: 6.0.13.0; Эмулятор: SphereServer 0.56b, одна из последних сборок). По коду сказать нечего, я не программист. (IMG: style_emoticons/default/smile.gif) P.s. А нет, рано порадовался, что проблем совсем нет. При закрытии клиента крестиком гарантировано вылетает вот такое: Угу. Правильно. Оно и должно. Это связано с тем, что по закрытию процесса я не убиваю там консоль. Короче, это баг, но он фича. Цитата(Ozzy Osbourne @ 23.12.2010, 1:50) А что поддержки более ранних версий клиента можно не ждать?
Вообще - я сильно их не люблю. Правда это не значит что нельзя. В плагинах будет возможность (уже сейчас есть) переопределить протокол, как вам хочется. То есть берете маны по протоколу 2.0.3 клиента и перебиваете длинны пакетов. А вообще, в PluginsShared сейчас уже 13 или 14 номер под API забит
--------------------
Do. Or do not. There is no Try! © Master Joda, Dagobah, Star Wars: Episode V.
|
|
|
|
StaticZ |
7.1.2011, 16:50
|
Разработчик проекта "Квинтэссенция"
Сообщений: 2.155
Регистрация: 15.6.2009 Группа: Пользователи Наличность: 0 Из: РФ, Москва
Пользователь №: 11.948
|
наконец-то!!, уже солидный проект с сайтом (IMG: style_emoticons/default/smile.gif) будем надеятся что не забьеш и доведеш проект до конца. ЗЫ Еслиб был шарп или С++ присоединился, но от дельфи как-то уже отвык и нос немног воротит... Хотя плагины мона ведь на си писать.. так что могу подсобить с чем-то, правда сильно на меня не рассчитывай - сам знаешь я и так весь перегружен своим проектом
--------------------
RP сервер UO: Quintessence, а также ПО: EssenceUCS, EssenceUDK, CentrEd+, Fiddler+ и др.Game isn't a dream, it is the reality, reality which is coming while we dream...
|
|
|
|
StaticZ |
7.1.2011, 16:59
|
Разработчик проекта "Квинтэссенция"
Сообщений: 2.155
Регистрация: 15.6.2009 Группа: Пользователи Наличность: 0 Из: РФ, Москва
Пользователь №: 11.948
|
Цитата(Warstone @ 7.1.2011, 16:55) Ну плагины действительно на чем угодно можно писать (уже сейчас).
Недельки через две попробую ченить замутить, щас дел много (IMG: style_emoticons/default/mad.gif) а кстати могу еще помочь с расширением для ранки и енкриптом протокола (если еще не сделал).
--------------------
RP сервер UO: Quintessence, а также ПО: EssenceUCS, EssenceUDK, CentrEd+, Fiddler+ и др.Game isn't a dream, it is the reality, reality which is coming while we dream...
|
|
|
|
StaticZ |
15.1.2011, 5:13
|
Разработчик проекта "Квинтэссенция"
Сообщений: 2.155
Регистрация: 15.6.2009 Группа: Пользователи Наличность: 0 Из: РФ, Москва
Пользователь №: 11.948
|
Цитата(Warstone @ 15.1.2011, 4:29) Волонтеров нету (внезапно).
Вопрос сообществу: Некоторые аспекты автоматического декрипта вынуждают поддерживать клиенты только версий старше 6.0.6.0 примерно... (Фактически - с тех пор, как появился 0xEF пакет. То есть новый механизм Сида и версии)
Сейчас склоняюсь к тому, что-бы внести директиву компиляции. Что-то типа CLIENC - если она будет, то программа попытается определить шифрование и работать с шифрованным протоколом со стороны клиента. Если нету - то считается что шифрование снято.
Так-же будет директива SRVENC которая отвечает за шифрование со стороны сервера (Вообще - за возможность шифрования, так как те настройки, которые есть в ShardSertup в последствии будут автоматом получаться с сервера на логин стадии, а есть-ли шифрование со стороны сервера - будет выполнено в виде настройки именно в этом модуле).
ну я предлагал свою помощь, а ты говориш нет (IMG: style_emoticons/default/smile.gif) директивы компиляции - бред... конечно для разработки может и прикольно, но для пользователей нет.. лучше уш передать два параметра в качестве аргументов или взять из инишника (1е предпочтительнее т.к. например позволит запускать один и тотже ехе с разными параметрами для разных серверов и не плодить сто пятсот одинаковых ехе шников + пара ярлыков или батников для ламеров для запуска).. А вообще наличие шифрования или его отсутсвия можно автоматически определить )
--------------------
RP сервер UO: Quintessence, а также ПО: EssenceUCS, EssenceUDK, CentrEd+, Fiddler+ и др.Game isn't a dream, it is the reality, reality which is coming while we dream...
|
|
|
|
Warstone |
15.1.2011, 15:23
|
Группа: Модераторы Наличность: 0
Пользователь №: 10.905
Возраст: 25
|
Цитата ну я предлагал свою помощь, а ты говориш нет Когда я это говорил? Цитата А вообще наличие шифрования или его отсутсвия можно автоматически определить Да, но если у тебя версия до 6.0.5.0, то снять автоматом шифрование - ты не сможешь. Ключи нужны. Или версию читать из ехе (где она там зашита - хз). Как результат - шифрование есть, но оно не снимается... Все идут лесом. Цитата 1е предпочтительнее т.к. например позволит запускать один и тотже ехе с разными параметрами для разных серверов и не плодить сто пятсот одинаковых ехе шнико Ты, видно, вообще не смотрел как работает эта система... Она не меняет ехе. Она подключает в АП ехе свою длл. Поэтому не 100500 ехе, а 100500 длл, это раз. Второе - в планах конфиг сервера получать с сервера. То есть конфигурацией приложения будет заниматься исключительно сервер, а не ини. Никаких ини - это не "еще одна макро система". Хотя я, наверно, понял о чем ты... По идеи можно и без дириктив компиляции... Хотя все-таки Вариант с дириктивами я, наверно, оставлю. Для тех, кто захочет оттюнинговать само ядро, что-бы оно быстрее работало/меньше занимало и т.д.
--------------------
Do. Or do not. There is no Try! © Master Joda, Dagobah, Star Wars: Episode V.
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|