Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Копаем клиент (http://mangos.ytdb.ru/forumdisplay.php?f=35)
-   -   XFER (http://mangos.ytdb.ru/showthread.php?t=7790)

RomanRom2 15.01.2014 15:08

XFER
 
понадобилось мне тут прикрутить таки эту фичу на сервере :)
правда нужна она мне в другом проекте, ну да не важно...

сижу, курю, ничего не понимаю...
объявлено несколько опкодов, XFER_INIT, XFER_DATA, XFER_ACCEPT, XFER_RESUME, XFER_CANCEL.

клиент 1.12.1, посылаю ему XFER_INIT в формате:
Код:

    FileNameLength: byte;
    FileName: string;
    FileSize: uInt64;
    FileMD5: array [0..15] of byte;

... и не понимаю следующего:
1. даунлоадинг на клиенте запускается (появляется этот синенький фон от эльфов) только если имя файла в структуре равно 'Patch', 5 байт. с другим именем фона эльфов не появляется, просто "кнопка" Connecting заменяется на Downloading.

2. никакие опкоды клиент не посылает. никаких ACCEPT, RESUME и уж тем более CANCEL я не наблюдал. если во время даунлоадинга патча нажать кнопку "Cancel", то клиент просто закрывает соединение и все. когда ж они посылаются?

3. непонятно с именем файла. указывать нужно обязательно Patch, при этом клиент создает файл wow-patch.mpq. как же тогда получались всякие WoW-1.9.1.4983-to-1.9.2.4996-enGB-patch.exe и/или их даулоадеры? зачем тогда указывать имя файла, если работает только одно единственное? :) или быть может там есть и другие варианты?

4. клиент создает wow-patch.mpq сразу того размера, который указан в структуре, только на 40 байт больше. почему? как он понимает, что файл не докачен и посылает опкод XFER_RESUME?

5. после посылки INIT нужно слать последовательно XFER_DATA любыми блоками, при этом клиент так же не присылает никаких подтверждающих опкодов, но при этом правильно показывает процент прогресса. т.е. по сути отправка патча заключается в посылке двух опкодов, сначала INIT, затем нескольких DATA. остальное клиент все сделает сам. это действительно работает и странно тогда, зачем нужны ACCEPT, RESUME, CANCEL.

есть мнение, что сервер должен посылать файл-архив MPQ, внутри которого тот самый экзешник. но я помню еще у вада на wowemu был сделан XFER, и у клиентов оседали патчи с правильными именами. надо блин достать из архивов и проснифать чтоли...

поиск по имеющимся у меня сорцам эмуляторов тех времен показал, что везде реализованы опкоды INIT и DATA, с именем файла Patch. так же реализованы обработчики ACCEPT, RESUME и CANCEL c понятным функционалом.

может кто знает что с этим можно сделать?

RomanRom2 15.01.2014 15:26

4. в конец файла дописывается структура 40 байт:
Код:

fnID: longint; = 66 6E 49 44, fnID собственно
fnIDUnk: longint; = 0
fnMD5: array[0..15] of byte;
fnDownloadedBytes: uInt64;
fnSize: uInt64;


RomanRom2 15.01.2014 15:43

2 и 5. прошу прощения, присылается все. у меня были пустые обработчики уже сделаны, я просто про них забыл и думал что их нет.

RomanRom2 19.01.2014 09:40

все сделал. всем спасибо за помощь.

YuruY 19.01.2014 15:20

Дак у нас всегда так с помощью, раньше такое было только на TC а последнее время и Мангос этим страдает.
Такчто скажу за всех: "незачто, обращайтесь исЧо, чем сможем тем поможем". :pardon:



Печалька, чо. Вот иду в очередной раз в рейд (со сниффером конечно а их (сниффов) уже с панд у меня гигами) и думаю .. а нужноль это будет комуто и когдато? :sorry:
Но привычка ... че там без сниффера и на оффе еще делать. /:

RomanRom2 19.01.2014 15:30

да не, все нормально :) на самом деле я и не расчитывал особо, т.к. понимал, что маловероятно об этом кто то что то помнит или знает, тема то непопулярная.

насчет снифов - складывай пока, они по любому пригодятся. по моему разумению наиболее ценные снифы последнего билда в транке (в связи с изменяющимися опкодами и пр. структурами). так, последний билд катаклизма уже состоялся, но не знаю как со снифами для него. а по пандам есть мнение, что патчей больше не будет, только новый аддон. это, например, косвенно можно оценить по поступившей информации о продлении пвп сезона. новый сезон открывается обычно с новым пве контентом, поэтому есть такое вот мнение.

не берусь конечно просить их (снифы), но с удовольствием взял бы. медленно, но верно, я двигаюсь к ним через классические клиенты и когда нибудь таки доберусь :)

каким снифером можно сейчас пользоваться? тоже бы поснифал, ибо играю довольно много в последнее время.

Konctantin 20.01.2014 16:06

Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 100 сообщение(ий)):
У вас нет прав чтобы видеть скрытый текст, содержащейся здесь.

RomanRom2 21.01.2014 09:48

спасибо, работает :) снифы потекли рекой :)
надеюсь близзы не научились палить инжекторы. оно поддерживает два соединения? по формату снифа вижу что да, но сам снифф пока не смотрел, что там.

Konctantin 21.01.2014 10:16

RomanRom2, хочу допилить чтобы писался ИД (ConnectionIndex) соединения, но не представляю от куда его вытянуть. Есть какие-то идеи?

RomanRom2 21.01.2014 22:10

по спецификации ID соединения может быть любым и в рамках одного сниффа должно быть разным. например 1 и 2, "a" и "b", не важно, лишь бы они были разные. это что касается самого значения.

изначально предполагалось, что тянуть это значение как бы и не откуда... поэтому его можно (и нужно) придумывать самому. а именно "мониторить" соединения и (далее варианты) - например, инкрементировать значение на каждое новое подключение клиента; брать адрес (указатель/поинтер) какого нибудь хендлера этого соединения; получать какой нибудь "хеш" от "ип адрес"+"порт"; тд и тп.

YuruY 28.01.2014 13:50

Цитата:

а по пандам есть мнение, что патчей больше не будет, только новый аддон. это, например, косвенно можно оценить по поступившей информации о продлении пвп сезона. новый сезон открывается обычно с новым пве контентом, поэтому есть такое вот мнение.
Какраз под новый "полусезон" на птр поставили 5.4.7 (чеб еще разок опкоды не сменить, а может еще не раз).

RomanRom2 26.02.2014 01:29


YuruY 26.02.2014 05:11


SeT 26.02.2014 16:01

https://github.com/Anubisss/SzimatSzatyor снифер под последний билд

Konctantin 26.02.2014 16:19

Интересно, а детектится ли данный сниффер? точнее не спалится ли загрузка сторонней длл?

Судя по сканируемыми адресам точки инжекта не проверяются, а вот безопасна ли сама загрузка дллки?

Fabian 27.02.2014 04:59

another sniffer written in C# by me can be found on https://github.com/Arctium/Arctium-Tools
As far as I know the addresses NetClient::Send and NetClient::ProcessMessage are not scanned by things like warden so the injection is save atm.

mityada 05.03.2014 20:39

А в чем преимущество инжектящегося сниффера? Не проще ли просто собирать траффик и разбирать его?

Konctantin 05.03.2014 22:13

Сначала о сложностях перехвата трафика:
* Весь трафик зашифрован (имеется в виду заголовки сам опкод и размер пакета)
* Есть несколько сессий и переконеты, который шифруются по разному
* Переконект это такой пакет. в котором приходят данные о том куда переподключатся (этот пакет надо разбирать)
* и еще кажись кое что

И так, для того чтобы собрать трафик, надо разшифровать заголовки, отслеживать пакет переконекта, перечитывать ключ сессии, и собирать в кучу кучки пакетов, и еще обрабатывать Large пакеты.

теперь по поводу инжектора:
для его работы надо всего знать 2 адреса для перехвата, которые ищутся очень легко.

ЗЫ. Пакет переконекта постоянно шифруют по разному.

ЗЫЫ. С инжектором не надо парится с сжатыми пакетами.

mityada 05.03.2014 23:02

Пакет "переконекта" не нужен. Все что нужно для расшифровки новой сессии - сиды для HMAC, они идут в SMSG_AUTH_CHALLENGE (ну второй пакет от сервера).

Со сжатием вроде бы тоже ничего сложного, обычный DEFLATE.

А с инжектором остается надеяться, что проверку не добавят.

Konctantin 05.03.2014 23:15

только как вы будете знать с какой сессси снифать трафик?

mityada 05.03.2014 23:33

Снифать со всех?

Konctantin 05.03.2014 23:37

я уже не помню что та ми к чему, но помню что обновлять сниффер под новую версию клиента - это гемор еще тот. а вот с инжектором - всего 2 оффсета.

Вот к примеру:
Код:

       
FILL_OFFSET(17688, 0x3988D7, 0x3965BB, 0xE7080C);
FILL_OFFSET(17898, 0x399B6A, 0x3979B2, 0xE73344);
FILL_OFFSET(17930, 0x39A93E, 0x398786, 0xE75344);
FILL_OFFSET(17956, 0x39A66A, 0x398482, 0xE75344);

я читаю еще и локаль, для имени снифа

Konctantin 05.03.2014 23:42

Есть еще способ, без инжекта, отладчиком - 2 HW бряка на отправку и приемку и читаем данные c помощью ReadProcessMemory

Fabian 06.03.2014 00:28

I think the easiest and still secure way is to do it over a dll injection.
I use Netclient::ProcessMessage and Netclient::Send atm, but I should use NetClient::OneMessageReady too because some smsg opcodes won't be catched over ProcessMessage, but the most will be and the most important...

Of course you can just capture the tcp packets and decrypt them later, but for this you always need the sessionkey (easy to get). anf if one packet is fucked up or you forget to decrypt it, all future packets can't be decrypted, because the crypt stuff is out of sync then.

RomanRom2 06.03.2014 22:31

мне кажется Константин слегка преувеличивает сложность перехвата трафика :)

проблемы с сессиями действительно никакой нет, снифать нужно все сессии. раньше это было две-три сессии последовательных, теперь две параллельных. трафик нужен из обоих.

шифрованность трафика тоже как бы не является проблемой, т.к. зная сессионый ключ можно потом делать с собранным RAW все что угодно, вплоть до распаковки варден модулей.

со сжатыми данными я, честно говоря, тоже не припомню каких либо проблем. мы собираем тот трафик, который в натуре как бы. причем тут сжатый не сжатый... не понял в общем.

снифер типа "инжектор" действительно является самым простым с точки зрения затрат на сбор и обработку непосредственно данных: на выходе имеем готовый расшифрованный сетевой дамп, с которым ничего делать не надо. ибо инжектор перехватывает готовые к отправке/приему буферы, в которых все уже готово, ни больше ни меньше. но он не является безопасным, как об этом говорит Фабиан. опять же, с точки зрения близзов - когда нибудь могут и запалить.

безопасным снифером можно считать снифер типа pcap. он никуда не внедряется, ничего не перехватывает из чужого процесса и всякое такое. он работает на сетевом интерфейсе. это безопасно с точки зрения близзов. но на выходе мы имеем RAW, который потом придется декодировать, т.е. совершать какие то телодвижения, напрягаться. тут только можно сказать что то вроде "ах, ужас какой!" :) один раз сделать декодер и тоже не париться. или сразу делать декодирование на лету, многие сниферы так и делались.

но самым прозрачным и безопасным снифером до сих пор остается снифер четвертого поколения, который пока что никто не смог повторить. по правде сказать тут слегка в тему анекдот про неуловимого джо :)

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

времена, когда не нужно было ни того ни другого, прошли. ключ можно было собрать по трафику в до HMAC-овские времена.

ну и еще хотел бы добавить, что за мою скоро уже 10ти летнюю практику снифанья никогда инжектор не палился, чего ему и желаю дальше :) только вот мне никогда такой способ не поддавался :(

Цитата:

Сообщение от Konctantin (Сообщение 32545)
для его работы надо всего знать 2 адреса для перехвата, которые ищутся очень легко.

ну вот как? каааааак? :) с чего начинать, куда смотреть... расскажите методу, плиз.

но вот что еще меня удивляет. я помню, когда мы делали инжектор (им занимался Deamon), там нужно было не только офсеты для буферов перехватывать, а еще и "патчить" проверки от изменений памяти. итого что то 4-5 проверок снимать. разве этого сейчас делать не нужно? близзы стали так халатно относится к своей интеллектуальной собственности? сомневаюсь.

Konctantin 07.03.2014 01:16

Вложений: 1
Цитата:

ну вот как? каааааак? с чего начинать, куда смотреть... расскажите методу, плиз.
Ну я не спец в этом, а ищу их можна сказать по строке "ClientServices.cpp"
выше находится массив с функциями:
http://ru-mangos.ru/attachment.php?a...1&d=1394143403

внутри NetClient__ProcessMessage0 - находится функция ту которую мы ищем.
Код:

signed int __thiscall NetClient__ProcessMessage0(void *this, int a2, int a3, int a4)
{
  void *v4; // edi@1
  bool v5; // zf@1
  int v7; // [sp+4h] [bp-18h]@2
  int v8; // [sp+8h] [bp-14h]@2
  int v9; // [sp+Ch] [bp-10h]@2
  int v10; // [sp+10h] [bp-Ch]@2
  int v11; // [sp+14h] [bp-8h]@2
  int v12; // [sp+18h] [bp-4h]@2

  v4 = this;
  sub_798A6B();
  v5 = *((_DWORD *)v4 + 339) == 5;
  dword_10AB260 += a4 + 2;
  if ( v5 )
  {
    v10 = -1;
    v8 = a3;
    v11 = a4;
    v9 = 0;
    v12 = 0;
    v7 = (int)off_D298E8;
    NetClient__ProcessMessage(a2, &v7, 0);
    v7 = (int)off_D298E8;
    sub_408F9E(&v7);
  }
  sub_79B357();
  return 1;
}

это приемка пакетов, а отправка тоже по строке ("creaturecache.wdb"):
единственная ссылка ведет нас сюда
Код:

  sub_628B9E(1464684354, "creaturecache.wdb", PH_CMSG_CREATURE_QUERY, 0, 0, 1, 0);
а в PH_CMSG_CREATURE_QUERY

Код:

void __cdecl PH_CMSG_CREATURE_QUERY(int a1)
{
  char v1; // [sp+0h] [bp-14h]@1
  int v2; // [sp+10h] [bp-4h]@1

  sub_6909BB(&v1);
  v2 = *(_DWORD *)a1;
  NetClient__Send_d(&v1);
  sub_690F91(&v1);
}

int __cdecl NetClient__Send_d(int a1)
{
  int result; // eax@1
  void *v2; // eax@2

  result = sub_A65D94();
  if ( result )
  {
    v2 = (void *)sub_A65D94();
    result = sub_79A82A(v2, a1, 2);            // NetClient__Send
  }
  return result;
}

int __thiscall sub_79A82A(void *this, int a2, int a3)
{
  int v3; // ebx@1
  int v4; // eax@1
  int v6; // [sp+Ch] [bp-18h]@1
  int v7; // [sp+10h] [bp-14h]@1
  int v8; // [sp+14h] [bp-10h]@1
  int v9; // [sp+18h] [bp-Ch]@1
  int v10; // [sp+1Ch] [bp-8h]@1
  int v11; // [sp+20h] [bp-4h]@1

  v11 = -1;
  v3 = (int)this;
  v4 = *(_DWORD *)a2;
  v6 = (int)off_D298E8;
  v7 = 0;
  v8 = 0;
  v9 = 0;
  v10 = 0;
  (*(void (__stdcall **)(int *))(v4 + 8))(&v6);
  v11 = 0;
  NetClient__Send2(v3, (int)&v6, a3);
  v6 = (int)off_D298E8;
  return sub_408F9E(&v6);
}

Способы примитивные, но хз... как-то так и ищу.
Последние 2 раза делал дифы баз ИДА.

Fabian 07.03.2014 02:42

PH_CMSG_CREATURE_QUERY: Contains a constructor and the destructor at the end:
Код:

CliQueryCreature::CliQueryCreature and CliQueryCreature::~CliQueryCreature
or Player before the Cli, but I don't remember.

The construcor contains an offset (vtable) which points to functions for read the data from CDataStore, read the netmessage (opcode) as uint32.

your 'NetClient__ProcessMessage0' is 'NetClient::HandleData'
your 'sub_79A82A' has JamClientMessage and CONNECTION_ID as args and is named ::Send too you ::Send2 just have CDataStore as first arg.

NetClient__Send_d is used a few times too yea, but it calls the netClient functions, so..
NetClient__Send_d:
Код:

int __cdecl ClientServices::Send(JamClientMessage *a1)
{
  int result; // eax@1
  void *v2; // eax@2

  result = ClientServices::Connection();
  if ( result )
  {
    v2 = (void *)ClientServices::Connection();
    result = NetClient::Send(v2, a1, 2); // NetClient::Send(JamClientMessage *,CONNECTION_ID)
  }
  return result;
}

there is another ClientServices::Send function for the old stuff which calls 'NetClient::Send(CDataStore *,CONNECTION_ID)' instead of the JamClientmessage stuff.

mityada 07.03.2014 18:02

Цитата:

Сообщение от RomanRom2 (Сообщение 32552)
но самым прозрачным и безопасным снифером до сих пор остается снифер четвертого поколения, который пока что никто не смог повторить. по правде сказать тут слегка в тему анекдот про неуловимого джо :)

Ну это уже лишнее... Я вот играю в WoW через Wine и собираю пакеты tcpdump, в этом случае уже очень сложно спалить факт перехвата траффика, если вообще возможно. А настоящие параноики могут и где-нибудь на роутере траффик собирать.

RomanRom2 07.03.2014 18:11

ну я так и сказал - анекдот про неуловимого джо :)
- а чо, его никто поймать не может?
- да нахер он кому нужен...

близзы, к слову, умеют палить проксификаторы. это достоверная информация. они ругаются, но не банят за них, понимают, что в некоторых случаях без такого способа подключения не обойтись. а это вообще говоря один из способов сбора снифов.

LordJZ 07.03.2014 19:33

Цитата:

Сообщение от RomanRom2 (Сообщение 32557)
...
близзы, к слову, умеют палить проксификаторы. это достоверная информация. они ругаются, но не банят за них, понимают, что в некоторых случаях без такого способа подключения не обойтись. а это вообще говоря один из способов сбора снифов.

Ну правильно, стандартные методы-то они игнорируют, вот и приходится пользоваться.

Konctantin 14.03.2014 11:22

Кто может поделится структурой JamClientMessage?
На сколько я понимаю там что-то на подобии такого:
Код:

struct JamClientMessage
{
    void *vTable {
        void Release();
        void WriteData();
        void WriteOpcode();
        void Unk2();
        void Unk3();
    };
    DWORD m_unk4; 
    DWORD m_unk8;
    DWORD m_unk12;
    DWORD m_unk16;
    DWORD m_unk20;
    DWORD m_unk24;
    DWORD m_unk28;
};


RomanRom2 09.09.2014 00:43

извиняюсь за оффтоп (хотя генерю на сайте хоть какую то активность :mosking:), как там нынче с актуальным сниффером?

SeT 09.09.2014 09:26

https://github.com/Anubisss/SzimatSzatyor
Да все также...


Текущее время: 03:17. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS