15.01.2014, 15:08 | #1 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
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 понятным функционалом. может кто знает что с этим можно сделать? |
15.01.2014, 15:26 | #2 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
4. в конец файла дописывается структура 40 байт:
Код:
fnID: longint; = 66 6E 49 44, fnID собственно fnIDUnk: longint; = 0 fnMD5: array[0..15] of byte; fnDownloadedBytes: uInt64; fnSize: uInt64; |
15.01.2014, 15:43 | #3 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
2 и 5. прошу прощения, присылается все. у меня были пустые обработчики уже сделаны, я просто про них забыл и думал что их нет.
|
19.01.2014, 09:40 | #4 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
все сделал. всем спасибо за помощь.
|
19.01.2014, 15:20 | #5 |
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Дак у нас всегда так с помощью, раньше такое было только на TC а последнее время и Мангос этим страдает.
Такчто скажу за всех: "незачто, обращайтесь исЧо, чем сможем тем поможем". Печалька, чо. Вот иду в очередной раз в рейд (со сниффером конечно а их (сниффов) уже с панд у меня гигами) и думаю .. а нужноль это будет комуто и когдато? Но привычка ... че там без сниффера и на оффе еще делать. /: |
19.01.2014, 15:30 | #6 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
да не, все нормально на самом деле я и не расчитывал особо, т.к. понимал, что маловероятно об этом кто то что то помнит или знает, тема то непопулярная.
насчет снифов - складывай пока, они по любому пригодятся. по моему разумению наиболее ценные снифы последнего билда в транке (в связи с изменяющимися опкодами и пр. структурами). так, последний билд катаклизма уже состоялся, но не знаю как со снифами для него. а по пандам есть мнение, что патчей больше не будет, только новый аддон. это, например, косвенно можно оценить по поступившей информации о продлении пвп сезона. новый сезон открывается обычно с новым пве контентом, поэтому есть такое вот мнение. не берусь конечно просить их (снифы), но с удовольствием взял бы. медленно, но верно, я двигаюсь к ним через классические клиенты и когда нибудь таки доберусь каким снифером можно сейчас пользоваться? тоже бы поснифал, ибо играю довольно много в последнее время. |
20.01.2014, 16:06 | #7 | |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Последний раз редактировалось Konctantin; 20.01.2014 в 16:58. |
|
21.01.2014, 09:48 | #8 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
спасибо, работает снифы потекли рекой
надеюсь близзы не научились палить инжекторы. оно поддерживает два соединения? по формату снифа вижу что да, но сам снифф пока не смотрел, что там. |
21.01.2014, 10:16 | #9 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
RomanRom2, хочу допилить чтобы писался ИД (ConnectionIndex) соединения, но не представляю от куда его вытянуть. Есть какие-то идеи?
|
21.01.2014, 22:10 | #10 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
по спецификации ID соединения может быть любым и в рамках одного сниффа должно быть разным. например 1 и 2, "a" и "b", не важно, лишь бы они были разные. это что касается самого значения.
изначально предполагалось, что тянуть это значение как бы и не откуда... поэтому его можно (и нужно) придумывать самому. а именно "мониторить" соединения и (далее варианты) - например, инкрементировать значение на каждое новое подключение клиента; брать адрес (указатель/поинтер) какого нибудь хендлера этого соединения; получать какой нибудь "хеш" от "ип адрес"+"порт"; тд и тп. |
28.01.2014, 13:50 | #11 | |
YTDB Dev
Регистрация: 01.02.2010
Сообщений: 288
Сказал(а) спасибо: 125
Поблагодарили 97 раз(а) в 53 сообщениях
|
Цитата:
|
|
26.02.2014, 01:29 | #12 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
|
26.02.2014, 16:01 | #14 |
Ученый
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
|
https://github.com/Anubisss/SzimatSzatyor снифер под последний билд
|
26.02.2014, 16:19 | #15 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Интересно, а детектится ли данный сниффер? точнее не спалится ли загрузка сторонней длл?
Судя по сканируемыми адресам точки инжекта не проверяются, а вот безопасна ли сама загрузка дллки? |
27.02.2014, 04:59 | #16 |
Новичок
Регистрация: 02.07.2010
Сообщений: 23
Сказал(а) спасибо: 2
Поблагодарили 20 раз(а) в 12 сообщениях
|
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. |
6 пользователя(ей) сказали cпасибо: | Den (07.03.2014), Konctantin (27.02.2014), Mayss (02.03.2014), RomanRom2 (27.02.2014), SeT (27.02.2014) |
05.03.2014, 20:39 | #17 |
Гость
Сообщений: n/a
|
А в чем преимущество инжектящегося сниффера? Не проще ли просто собирать траффик и разбирать его?
|
05.03.2014, 22:13 | #18 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Сначала о сложностях перехвата трафика:
* Весь трафик зашифрован (имеется в виду заголовки сам опкод и размер пакета) * Есть несколько сессий и переконеты, который шифруются по разному * Переконект это такой пакет. в котором приходят данные о том куда переподключатся (этот пакет надо разбирать) * и еще кажись кое что И так, для того чтобы собрать трафик, надо разшифровать заголовки, отслеживать пакет переконекта, перечитывать ключ сессии, и собирать в кучу кучки пакетов, и еще обрабатывать Large пакеты. теперь по поводу инжектора: для его работы надо всего знать 2 адреса для перехвата, которые ищутся очень легко. ЗЫ. Пакет переконекта постоянно шифруют по разному. ЗЫЫ. С инжектором не надо парится с сжатыми пакетами. |
05.03.2014, 23:02 | #19 |
Гость
Сообщений: n/a
|
Пакет "переконекта" не нужен. Все что нужно для расшифровки новой сессии - сиды для HMAC, они идут в SMSG_AUTH_CHALLENGE (ну второй пакет от сервера).
Со сжатием вроде бы тоже ничего сложного, обычный DEFLATE. А с инжектором остается надеяться, что проверку не добавят. |
05.03.2014, 23:33 | #21 |
Гость
Сообщений: n/a
|
Снифать со всех?
|
05.03.2014, 23:37 | #22 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
я уже не помню что та ми к чему, но помню что обновлять сниффер под новую версию клиента - это гемор еще тот. а вот с инжектором - всего 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); |
06.03.2014, 00:28 | #24 |
Новичок
Регистрация: 02.07.2010
Сообщений: 23
Сказал(а) спасибо: 2
Поблагодарили 20 раз(а) в 12 сообщениях
|
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. |
06.03.2014, 22:31 | #25 | |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
мне кажется Константин слегка преувеличивает сложность перехвата трафика
проблемы с сессиями действительно никакой нет, снифать нужно все сессии. раньше это было две-три сессии последовательных, теперь две параллельных. трафик нужен из обоих. шифрованность трафика тоже как бы не является проблемой, т.к. зная сессионый ключ можно потом делать с собранным RAW все что угодно, вплоть до распаковки варден модулей. со сжатыми данными я, честно говоря, тоже не припомню каких либо проблем. мы собираем тот трафик, который в натуре как бы. причем тут сжатый не сжатый... не понял в общем. снифер типа "инжектор" действительно является самым простым с точки зрения затрат на сбор и обработку непосредственно данных: на выходе имеем готовый расшифрованный сетевой дамп, с которым ничего делать не надо. ибо инжектор перехватывает готовые к отправке/приему буферы, в которых все уже готово, ни больше ни меньше. но он не является безопасным, как об этом говорит Фабиан. опять же, с точки зрения близзов - когда нибудь могут и запалить. безопасным снифером можно считать снифер типа pcap. он никуда не внедряется, ничего не перехватывает из чужого процесса и всякое такое. он работает на сетевом интерфейсе. это безопасно с точки зрения близзов. но на выходе мы имеем RAW, который потом придется декодировать, т.е. совершать какие то телодвижения, напрягаться. тут только можно сказать что то вроде "ах, ужас какой!" один раз сделать декодер и тоже не париться. или сразу делать декодирование на лету, многие сниферы так и делались. но самым прозрачным и безопасным снифером до сих пор остается снифер четвертого поколения, который пока что никто не смог повторить. по правде сказать тут слегка в тему анекдот про неуловимого джо в любом случае залезать в процесс экзешника нам все равно необходимо для того что бы вытащить ключ. пожалуй за исключением инжектора, там ключ по факту не нужен. если только потом, для варден модулей, коль уж мы все равно залезли в процесс, чо бы и не вытащить ключ. времена, когда не нужно было ни того ни другого, прошли. ключ можно было собрать по трафику в до HMAC-овские времена. ну и еще хотел бы добавить, что за мою скоро уже 10ти летнюю практику снифанья никогда инжектор не палился, чего ему и желаю дальше только вот мне никогда такой способ не поддавался Цитата:
но вот что еще меня удивляет. я помню, когда мы делали инжектор (им занимался Deamon), там нужно было не только офсеты для буферов перехватывать, а еще и "патчить" проверки от изменений памяти. итого что то 4-5 проверок снимать. разве этого сейчас делать не нужно? близзы стали так халатно относится к своей интеллектуальной собственности? сомневаюсь. |
|
07.03.2014, 01:16 | #26 | |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Цитата:
выше находится массив с функциями: внутри 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; } единственная ссылка ведет нас сюда Код:
sub_628B9E(1464684354, "creaturecache.wdb", PH_CMSG_CREATURE_QUERY, 0, 0, 1, 0); Код:
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 раза делал дифы баз ИДА. |
|
Пользователь сказал cпасибо: | RomanRom2 (07.03.2014) |
07.03.2014, 02:42 | #27 |
Новичок
Регистрация: 02.07.2010
Сообщений: 23
Сказал(а) спасибо: 2
Поблагодарили 20 раз(а) в 12 сообщениях
|
PH_CMSG_CREATURE_QUERY: Contains a constructor and the destructor at the end:
Код:
CliQueryCreature::CliQueryCreature and CliQueryCreature::~CliQueryCreature 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; } |
2 пользователя(ей) сказали cпасибо: | Konctantin (07.03.2014), RomanRom2 (07.03.2014) |
07.03.2014, 18:02 | #28 | |
Гость
Сообщений: n/a
|
Цитата:
|
|
07.03.2014, 18:11 | #29 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
ну я так и сказал - анекдот про неуловимого джо
- а чо, его никто поймать не может? - да нахер он кому нужен... близзы, к слову, умеют палить проксификаторы. это достоверная информация. они ругаются, но не банят за них, понимают, что в некоторых случаях без такого способа подключения не обойтись. а это вообще говоря один из способов сбора снифов. |
07.03.2014, 19:33 | #30 |
Супер-модератор
Регистрация: 07.03.2010
Сообщений: 647
Сказал(а) спасибо: 100
Поблагодарили 252 раз(а) в 123 сообщениях
|
Ну правильно, стандартные методы-то они игнорируют, вот и приходится пользоваться.
|
14.03.2014, 11:22 | #31 |
RuDB Dev
Регистрация: 01.02.2010
Адрес: localhost
Сообщений: 592
Сказал(а) спасибо: 323
Поблагодарили 283 раз(а) в 122 сообщениях
Записей в дневнике: 2
|
Кто может поделится структурой 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; }; |
09.09.2014, 00:43 | #32 |
WowCore Dev
Регистрация: 31.03.2010
Сообщений: 468
Сказал(а) спасибо: 73
Поблагодарили 106 раз(а) в 70 сообщениях
|
извиняюсь за оффтоп (хотя генерю на сайте хоть какую то активность ), как там нынче с актуальным сниффером?
|
09.09.2014, 09:26 | #33 |
Ученый
Регистрация: 13.03.2010
Сообщений: 110
Сказал(а) спасибо: 55
Поблагодарили 23 раз(а) в 14 сообщениях
|
https://github.com/Anubisss/SzimatSzatyor
Да все также... |
Пользователь сказал cпасибо: | RomanRom2 (09.09.2014) |