PDA

Просмотр полной версии : Централизованый формат снифов


Konctantin
20.07.2010, 18:34
Редакция от 31 июля 2011, 13:13, версия 3.1


1. RAW.

1.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'RAW'.
byte version[2]; // 0x01, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40];
uint unixTime;
uint tickCount;
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

1.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint sessionID;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;


2. PKT.

2.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'PKT'
byte version[2]; // 0x01, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40]; // может быть заполнено нулями
uint unixTime;
uint tickCount;
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

2.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint sessionID;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;
, где
- data включает в себя Opcode, выравненный до uint
- dataLength равен размеру data



3. Имя файла.

3.1. имя файла
имя может быть произвольным и удобным каждому из разработчиков.

3.2. расширение файла
обязательно .raw или .pkt



Редакция от 25 июля 2010, 21:00, версия 3.0


1. RAW.

1.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'RAW'.
byte version[2]; // 0x00, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40];
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

1.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint unixTime;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;


2. PKT.

2.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'PKT'
byte version[2]; // 0x00, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40]; // может быть заполнено нулями
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

2.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint unixTime;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;
, где
- data включает в себя Opcode, выравненный до uint
- dataLength равен размеру data



Предложения
SnifferID:
0 - Wad // 2005 и ранее
1 - Nomad // 2005 и ранее
2 - WoWCore // 2006
3 - Mangos (TOM_RUS) // 2006
4 - User456 // 2007
5 - Delfin // 2007
6 - Burlex // 2007
7 - WCell // 2008
8 - Kobold // 2009
9 - abdula123 // 2010
10 - Konctantin/LordJZ // 2010
11 - Йоха // 2010

Konctantin
23.07.2010, 12:26
Вот появилось свободное время, и хотелось бы продолжить дискуссию.

Мне как-то не очень понравилась мысль о создании своего формата снифа. Лучше немножко доработать существующий.

Сразу объясню почему:
1) Зачем плодить кучу форматов, потом писать конвертеры, потом опять чего-то. Это все лишний код.
2) Хоть снифы и не нужны широкому кругу пользователей, да и используются фактически только в определенными людьми, позиция многоформатности теряет свой смысл. Свой собственный формат следует вводить только в том случае, если хочется кардинально выделить свой "продукт" и сделать его "уникальным". В нашем случае это ненужно.

Я изначально за обобщенный, централизованный формат.
Давайте в этой тебе оставим свои "за" и "против" и согласуем надо а что не надо.

Саму архитектуру формата можно разделить на 3 уровня:
1. Имя файла
2. Заголовок
3. Тело

1) Как уже говорил RomanRom2, имя файла должно носить информационных характер.
[build]_[datetime(yyyy-MM-dd_HH-mm-ss-ffff)]_[SessionIndex]_[LogIndex]_[RealmIP].[pkt | raw]
Я бы предложил стандартный формат (yyyy-MM-dd_HH-mm-ss-ffff), если есть какие-то нюансы с формированием даты, хотелось бы услышать. (это более читабельно)
FirstClientOpcode - я даже не знаю, по большему счету будет всего 2 варианта, или же это CMSG_AUTH_SESSION или CMSG_REDIRECTION_AUTH_PROOF и особой информационной составляющей не носит, так как у меня раз получилось 4 сессии
фактически вышло получилось бы следующее:
ххх_CMSG_AUTH_SESSION_ххх
ххх_CMSG_REDIRECTION_AUTH_PROOF_ххх
ххх_CMSG_REDIRECTION_AUTH_PROOF_ххх
ххх_CMSG_REDIRECTION_AUTH_PROOF_ххх

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

2) Заголовок, я думаю вполне хватит и вот этого:

[PKT | RAW]
Version
ClientBuild
ClientLanguage
SessionKey


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

3) и само тело снифа.

(byte)Direction;
(uint)UnixTime
(uint)TickCount
(uint)Opcode
(byte)Flags // для того чтобы выделять что это за пакет (опционально, тоже можно договорится о спецификации)
(uint)Data.Length
(byte[])Data


Жду продолжения дискуссии, а в первый пост потом можно написать результат (готовый централизованный формат снифа)

TOM_RUS
23.07.2010, 12:31
Писать разные сессии в отдельнный файл очень не удобно. Теоретически это одна сессия, и все пакеты в ней взаимосвязаны. В таком случае теряется последовательность пакетов, а она для меня очень важна.

Konctantin
23.07.2010, 12:35
я же писал:
это опционально, но желательно, если запись в отдельный файл

RomanRom2
23.07.2010, 22:20
выскажусь и я.

согласен с "архитектурой":
1. Имя файла
2. Заголовок
3. Тело

итак, давайте рассматривать потенциальный будущий формат 3.0;
1.
===
имя файлы, как я уже говорил - носит рекомендательный характер. по этому пункту мы скорее всего не договоримся, тут почему то кому что нравится. но позволю себе высказаться по этому поводу. за 5 лет снифанья и использования снифов выработались следующие ... "пожелания", назовем это так. визуально удобно, когда при вгляде на файлы идентифицируется сразу:
- билд клиента
- откуда снифф, название реалма. при некоторых обстоятельствах, но по факту почти не нужно.
- что бы снифы все располагались по порядку
- поле "имя аккаунта" реально не пригодилось.

итак, что получается:
12604_4C497974.PKT

теперь поговорим о формате "дата снифа". опять же, опираясь на опыт прошлых лет, полная читабельная дата в имени файла вроде yyyy-MM-dd_HH-mm-ss-ffff нафиг не нужна. по трем причинам как минимум:
- дату файла можно посмотреть у самого файла. обычно эти даты совпадают :)
- смотреть на файлы и видеть дату реально не пригодилось. важнее вот билдом клиента больше всего оперируем при обработке. например сразу видно, что вот эти сниффы будет парсить вот этим снифером. не важно какая дата снифов.
- ну длиновато имя файла получается :)

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

в связи с вышесказанным считаю запись UnixDateTime(Now) самой оптимальной. к слову сказать, это повелось еще во времена динозавров - такое поле использовал еще wad в своем снифере :) но это так, лирическое отступление.

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

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

вторая сессия может быть начата в ту же секунду что и первая и тогда имя файла для второй сессии будет одинаковым. т.е. получается что то вроде такого тогда:
12604_4C497974_[1].PKT
12604_4C497974_[2].PKT
именно по этой причине в имени файла у меня появились номера опкодов. я просто посчитал что это гораздо прикольней, чем просто 1, 2, ...
12604_4C497974_[01ED].PKT
12604_4C497974_[0512].PKT
и поскольку у нас всего два (в последнем катаклизме три) варианта, мы прекрасно знаем, что 01ED - первая сессия и обычно не несет в своем сниффе никакой полезной информации и я такие снифы просто удаляю. а 0512 - вторая сессия, которая нам и нужна.

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

по поводу SessionIndex_LogIndex. собственно опкод это и есть SessionIndex, а LogIndex честно говоря не знаю - зачем делать разные файлы для одной сессии. ну раз такое нужно, что ж, ничего в этом такого нет - делайте. и помечайте. получится что то вроде:
12604_4C497974_[01ED].PKT
12604_4C497974_[0512_1].PKT
12604_4C497999_[0512_2].PKT
12604_4C499376_[0512_3].PKT
...
только смысла опять же не очень понимаю. время ведь тоже меняется.

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

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

2.
===
по второму пункту полностью поддерживаю. к существующему заголовку версии 2.1 нужно добавить только ClientLanguage. оно реально нужно для автоматического определения языка при парсинге респонсов.
3 байта: [PKT | RAW]
2 байта: Version
2 байта: ClientBuild
4 байта: ClientLanguage. варианты [enUS] [enGB] [ruRU], т.е. прям с клиентского пакета (они там наоборот, SUne, BGne, URur).
40 байт: SessionKey

но хочу предложить сюда, скажем, 8 байт DevelopersData
3 байта: [PKT | RAW]
2 байта: Version
2 байта: ClientBuild
4 байта: ClientLanguage
8 байт: DevelopersData
40 байт: SessionKey
пусть сюда каждый разработчик складывает все что ему хочется, что ему удобно. и это поле не поддается какому либо форматированию.
да и вообще, FutureFields можно сказать.
поле является обязательным (наличие), но требований к полю нет никаких. такой вот прикол :censored:

3.
===
данные. заголовок каждого чанка данных:
предложенная структура
(byte)Direction;
(uint)UnixTime
(uint)TickCount
(uint)Opcode
(byte)Flags
(uint)Data.Length
(byte[])Data

от текущей отличается выделенными полями.
два вопроса:
1. зачем в заголовке опкод? он ведь в самом чанке. плюс у raw мы не можем знать опкод.
2. для чего поле Flags?
я просто предлагаю здесь ничего не менять. инфы более чем достаточно.

LordJZ
23.07.2010, 22:38
Ну Flags у нашего сниффера только требуется (вроде я не видел больше), а опкод у нас отдельно выделен, не в самом чанке он — не удобно нам по-другому. Просто в коде неудобно.

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

RomanRom2
23.07.2010, 22:52
ну так ответов на вопросы нет.
1. зачем опкод? в данном случае вопрос по другому: в чем неудобство опкода в чанке?
я просто рассматриваю чанк как
- опкод
- данные, соответствующие этому опкоду
т.е. вполне закономерно и логически законченная сущность. чанк. задумайтесь :)
а размер чанка - в заголовке. по этому полю в заголовке удобно "пробегать" по снифу.
2. для чего флаг чанка? что там в нем? какие флаги бывают? для чего используются?

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

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

LordJZ
23.07.2010, 23:00
У опкода разная длина, плюс мы между модулями сниффа переносим чистые данные, без опкодов, поэтому и пишем в лог чистые данные. А чтобы читать чанк с опкодом, нужно знать направление пакета, прочитать опкод нужной длины, а затем данные. И зачем? Гораздо проще прочитать 4 байта опкода (учитывая, что сейчас 2 байта из них не используются вообще) и потом уже Х байт чистых данных.

Флаги у нас сейчас такие:
0x01 — пакет был создан искусственно, и подставной отправитель о нем не знает
0x02 — пакет был остановлен искусственно, и получатель его не принял
0x04 — пакет был вытащен из хвоста другого пакета (таких 85%)
0x08 — пакет был получен по-частям

Konctantin
23.07.2010, 23:15
в общем это нужно предварительно решить, в один снифф мы сессии пишем или в разные.
я думаю надо писать в 1 файл.

RomanRom2
23.07.2010, 23:18
У опкода разная длина, плюс мы между модулями сниффа переносим чистые данные, без опкодов, поэтому и пишем в лог чистые данные. А чтобы читать чанк с опкодом, нужно знать направление пакета, прочитать опкод нужной длины, а затем данные. И зачем? Гораздо проще прочитать 4 байта опкода (учитывая, что сейчас 2 байта из них не используются вообще) и потом уже Х байт чистых данных.

все равно недоумеваю. вы ведь это не руками делаете, это делает программа :) один раз написал и всё.
тем более непонятна следующая вещь: ну вот к примеру я, прежде чем работать с опкодом, читаю заголовок. ПОЛНОСТЬЮ. соответственно с направлением и вообще со всеми атрибутами. а вы как то частично его читаете?

ну хорошо. допускаю, что заголовок чанка можно привести к формату:
(byte)Direction;
(uint)UnixTime (время)
(uint)TickCount (точное время)
(uint)Data.Length (длина Data, опкод сюда не входит. или входит???)
(uint)Opcode (для RAW тут FFFFFFFF)
(byte[])Data (данные без опкода)
возможно это действительно немного удобнее и универсальней, в плане выравнивания полей. я за выравнивание. и за такой вот на мой взгляд логический порядок полей.

Флаги у нас сейчас такие:
0x01 — пакет был создан искусственно, и подставной отправитель о нем не знает
0x02 — пакет был остановлен искусственно, и получатель его не принял
0x04 — пакет был вытащен из хвоста другого пакета (таких 85%)
0x08 — пакет был получен по-частям
это у вас какие то число проксевые заморочки. ChunkDevelopersData.
может быть такой тип данных и в чанк включить? 4х байт нам хватит?

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

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

добавлено:
вот сейчас подумал, что DevelopersData чисто информативные поля. например если вы сюда будете складывать жизненноважные данные, то например мои снифы не сможете обработать/распарсить. например если вы каким то специальным образом обрабатываете пакеты с флагом
0x04 — пакет был вытащен из хвоста другого пакета (таких 85%)
то я такие пакеты просто не помечаю. я его собираю весь на этапе первого куска и сюда же и складываю в снифф.
т.е. например:

- C.пакеты
- S.пакеты
- S.01F6 жирный. но от него пришел то кусочек 1420 байт. бегу по всему снифу и собираю все все все куски и складываю в pkt уже готовый и полный пакет.
а все те пакеты, которые встречались пока я собирал эти недостающие куски в pkt будут записаны позже. так работает мой декодер raw-to-pkt.

т.е. если вам очень нужны такие пакеты, то у меня их просто не будет. кстати, а зачем они вам потом в готовом pkt?
мне вот снифы нужны для:
- наполнения базы респонсов, справочников и т.п., где нужны полностью собранные и законченные пакеты.
- наполнения заселения. тут я парсю пакеты А9 по сути только.
- ну и конечно же посмотреть, в какой последовательности что когда отсылается, для реализации какой либо системы. тоже не вижу, зачем нужно знать, что конкретно этот 01F6 был "вытащен из хвоста другого пакета" :) ну серьезно :) расскажите? мне интересно.

LordJZ
23.07.2010, 23:18
А зачем? Тем более, что в нашей реализации этого тупо не получится сделать

LordJZ
23.07.2010, 23:21
все равно недоумеваю. вы ведь это не руками делаете, это делает программа :) один раз написал и всё.
тем более непонятна следующая вещь: ну вот к примеру я, прежде чем работать с опкодом, читаю заголовок. ПОЛНОСТЬЮ. соответственно с направлением и вообще со всеми атрибутами. а вы как то частично его читаете?

ну хорошо. допускаю, что заголовок чанка можно привести к формату:
(byte)Direction;
(uint)UnixTime (время)
(uint)TickCount (точное время)
(uint)Data.Length (длина Data, опкод сюда не входит. или входит???)
(uint)Opcode
(byte[])Data (данные без опкода)
возможно это действительно немного удобнее и универсальней, в плане выравнивания полей. я за выравнивание. и за такой вот на мой взгляд логический порядок полей.Длина именно Data.Length — т.е. размер данных, который должен быть прочитан. Размер из пакета вообще не используется.
это у вас какие то число проксевые заморочки. ChunkDevelopersData.
может быть такой тип данных и в чанк включить? 4х байт нам хватит?
Да можно вообще включить один байт как размер этой самый DevelopersData — тогда всем одновременно станет хорошо. И назвать ее как-нибудь SpecialData.
в HeaderDevelopersData, имхо, можно сложить.
тоже не знаю зачем оно вам так необходимо, когда эти данные можно легко прямо со снифа считать :declare: просто не придумаю, где оно мне могло бы пригодится...А зачем их считать со сниффа, если можно положить количество пакетов в файл, тем самым на 100% исключив ошибки?

RomanRom2
23.07.2010, 23:43
А зачем? Тем более, что в нашей реализации этого тупо не получится сделать
не понял, что зачем и что не получится сделать?

Длина именно Data.Length — т.е. размер данных, который должен быть прочитан. Размер из пакета вообще не используется.
ммм... мне казалось что размер из пакета - это то что будут ожидать клиент/сервер и это именно тот размер, который должен быть прочитан. если вы не используете размер из пакета, то откуда вы знаете, какой размер данных должен быть прочитан? не уловлю.

Да можно вообще включить один байт как размер этой самый DevelopersData — тогда всем одновременно станет хорошо. И назвать ее как-нибудь SpecialData.
можно.

А зачем их считать со сниффа, если можно положить количество пакетов в файл, тем самым на 100% исключив ошибки?
а какие ошибки, собственно? :pardon:
у меня вот очень просто все, пока есть данные в файле, я их читаю.
если чтото завершилось с ошибкой (чтение заголовка или чтение уже данных), я такой чанк вообще не обрабатываю. и заканчиваю обработку вообще, т.к. обычно это случается в момент END_OF_FILE.

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

Konctantin
23.07.2010, 23:45
зачем нужно знать, что конкретно этот 01F6 был "вытащен из хвоста другого пакета" ну серьезно расскажите? мне интересно.
в итоге, они все равно складываются и записываются как один пакет, этот флаг ставится в самом процессе пакета, что знать что с ним делать дальше.

Konctantin
23.07.2010, 23:47
не понял, что зачем и что не получится сделать?
это был ответ на мой пост http://ru-mangos.ru/showpost.php?p=11158&postcount=9

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

LordJZ
23.07.2010, 23:51
не понял, что зачем и что не получится сделать?Это я Konctantin отвечал, до того как вы свой пост отправили...
ммм... мне казалось что размер из пакета - это то что будут ожидать клиент/сервер и это именно тот размер, который должен быть прочитан. если вы не используете размер из пакета, то откуда вы знаете, какой размер данных должен быть прочитан? не уловлю.
У нас так получилось (и, я считаю, правильно), что переводом tcp траффика в классы типа Packet занимается один модуль, а собственно складыванием пакетов в файл — другой модуль, не имеющий самих данных из tcp пакета — т.е. только полезные данные. А размер там не нужен — есть byte[], у кого есть Length.
а какие ошибки, собственно? :pardon:
у меня вот очень просто все, пока есть данные в файле, я их читаю.
если чтото завершилось с ошибкой (чтение заголовка или чтение уже данных), я такой чанк вообще не обрабатываю. и заканчиваю обработку вообще, т.к. обычно это случается в момент END_OF_FILE.

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

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

это был ответ на мой пост http://ru-mangos.ru/showpost.php?p=11158&postcount=9
это можно сделать, правда с реконструкцией, а то наша система "немножко" зависит от самих коннектов.
Для каждого соединения создаются свои экземпляры
всё, понял.
у меня сейчас тоже так же, свои экземпляры. но мне кажется это удобнее, чем в один файл писать.
на самом деле один файл со всеми сессиями нужно записать только один раз, что бы понять в какой последовательности слать пакеты, что бы реализовать эту фичу у себя на сервере.
но задайте честно себе вопрос. а вы правда будете использовать эту фичу у себя на сервере? :)
лично мне и из разных файлов понятно стало, что когда слать и что когда ожидать. ну это в общем личное.

У нас так получилось (и, я считаю, правильно), что переводом tcp траффика в классы типа Packet занимается один модуль, а собственно складыванием пакетов в файл — другой модуль, не имеющий самих данных из tcp пакета — т.е. только полезные данные. А размер там не нужен — есть byte[], у кого есть Length.
спору нет, я тоже считаю правильным, что каждый должен заниматься только своим делом. вот ваш byte[], у которого есть Length, собственно этот самый Length - кем, когда и из чего заполняется? наверняка так или иначе - из размера опкода =)))

Дак зачем лишний раз обрабатывать исключение? Мы сделаем фиксированное количество байт в файле, и потом туда можно будет что-то приписать. Например, ту же подпись.
хмм... ну тут я опять в недоумении. это ж программа. всегда бывают исключения :)
смотрите:
- в вашем случае лишние данные, их подсчет, запись, потом их чтение. опять подсчет при чтении, сравнение. ну и что делать, если вдруг они не совпадут? реально (к примеру) один байт в конце потерялся, у последнего чанка. а снифф 50 мегов. все в помойку?
- в моем случае читаем до тех пор, пока не возникнет END_OF_FILE. всё :)

LordJZ
24.07.2010, 00:12
...
спору нет, я тоже считаю правильным, что каждый должен заниматься только своим делом. вот ваш byte[], у которого есть Length, собственно этот самый Length - кем, когда и из чего заполняется? наверняка так или иначе - из размера опкода =)))byte[] заполняется из пакета, с размером Size (от клиента/сервера) минус размер опкода, и потом уже измеряется размер этого byte[] по надобности. Но мы за это не отвечаем.
хмм... ну тут я опять в недоумении. это ж программа. всегда бывают исключения :)
смотрите:
- в вашем случае лишние данные, их подсчет, запись, потом их чтение. опять подсчет при чтении, сравнение. ну и что делать, если вдруг они не совпадут? реально (к примеру) один байт в конце потерялся, у последнего чанка. а снифф 50 мегов. все в помойку?
- в моем случае читаем до тех пор, пока не возникнет END_OF_FILE. всё :)Нет, почему. PacketCount-же не определяет количество байт. Он определяет количество пакетов, чтобы уже после пакетов можно было засунуть подпись, не позволяющую отвалиться/поменяться какому-либо байту.

Konctantin
24.07.2010, 00:32
давайте не спорится, это 1 из вариантов использования DevelopersData

Konctantin
25.07.2010, 00:36
итог на сегодня, текста много, а результата так и не видно... пора уже бы и договорится...

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

так что господа, давайте подобьем итоги, и придем к какому-то консенсусу.

формат:
1) имя (мы ни к чему не договоримся, да и на чтение файла это не повлияет) по этому оставим как есть, пусть каждый пишет что хочет, но давайте оставим расширения файлов [PKT | RAW].

2) вариант:
[PKT | RAW]
Version
ClientBuild
ClientLanguage
DevelopersData
SessionKey
думаю вполне подойдет, если у кого-то что-то созреет, то поле DevelopersData (8 байт) к вашим услугам

3)
(byte)Direction;
(uint)UnixTime
(uint)TickCount
(uint)Opcode
(byte)ChunkDevelopersData
(uint)Data.Length
(byte[])Data

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

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

ЗЫ. Если мы столько будем споить и принимать решения, то позор нам всем, и никогда жить в нашей стране хорошо (я про весь СНГ) мы не будем, так как наш менталитет нам этого не даст..

RomanRom2
25.07.2010, 15:49
ок. по пунктам:

1.
согласен. имя файла - на свое усмотрение. расширение файла обязательно либо .pkt либо .raw.

2.
Header, bytes[3] (R,A,W; P,K,T;)
HeaderVersion, word (3.0)
ClientBuild, uint, (число)
ClientLanguage, uint
DevelopersData, uint64
SessionKey, bytes[40]

несколько слов о полях:
- HeaderVersion. в дампе это должно выглядеть "младший байт, старший байт", т.е. так:
0000000000: 50 4B 54 00 03 CB 2D 89 │ 9D 6F C4 9B 85 20 75 6D PKT☺☻╦-ЙЭo─ЫЕ um

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

3.
(byte) Direction; для серверных чанков 0хFF, для клиентских 0хСС.
(uint) UnixTime; UnixDateTime(Now).
(uint) TickCount; GetTickCount();
(byte) ChunkDevelopersData; нам точно одного байта хватит? мы же хотели переменную длину заюзать?
(uint) PKT.Length; длина данных, ВКЛЮЧАЯ Opcode
(uint) PKT.Opcode
(byte[]) PKT.Data

несколько слов о полях:
- ChunkDevelopersData
существуют два варианта реализации - с переменной длиной и с фиксированной. лично я за фиксированную длину, читать данные проще. т.е. давайте выберем один из вариантов:
1.
(uint64) ChunkDevelopersData (8 байт нам точно должно хватить на долго, учитывая что разработчиков сниферов по пальцем можно пересчитать)
2.
(byte) ChunkDevelopersData.Length
(bytes[])ChunkDevelopersData.Data

второй вариант представляется мне гиморным в плане пробегания по снифу. представьте, что бы прочитать следующий чанк нужно
1. по первому варианту:
- прочитать хидер, 1+4+4+8+4+4 байт
- прочитать PKT.Data размером PKT.Length-4 байт
2. по второму варианту:
- прочитать часть хидера, 1+4+4+1 байт
- прочиать ChunkDevelopersData.Data размером ChunkDevelopersData.Length байт
- дочитать хидер, 4+4 байт
- прочитать PKT.Data размером PKT.Length-4 байт

в общем я за первый вариант с фиксированной длиной ChunkDevelopersData. вопрос только в ее длине. 4 или 8 байт?

- PKT
формат записи пакета я настоятельно предлагаю в естественном и привычном исполнении:
- длина, включая опкод
- опкод
- данные опкода

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

еще предлагаю ввести поле SnifferID в заголовок снифа.
все вы прекрасно понимаете, что поля DevelopersData каждой командой могут быть использованы на свое усмотрение. и если бы мы собрали такую информацию, то SnifferID помог бы понять, что именно находится в DevelopersData. и на стадии утверждения документа принять разработать и принять эти ID. ну например:
1 - WoWCore
2 - TOM_RUS
3 - Konctantin, LordJZ and Co.
и так далее.



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

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

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

- в срок до 31 июля включительно мы должны разработать и утвердить документ, описывающий формат 3.0, который всех бы удовлетворил.
- в срок до 7 августа включительно будет проходить ревью документа.
- 8 августа состоится релиз документа.
- и еще один момент. ревью проводится среди каких то людей. кто у нас будет ревьюить? :) всем по моему пофигу, кроме 2-3 человек. но все же я хотел бы пригласить на ревью следющих людей:
- Konctantin
- LordJZ
- TOM_RUS
- RomanRom2
- VDm
- Deamon
- Nomad
- abdula123
- user456
- Aven
- йоха

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



на самом деле многие сейчас могут сказать, чо вы ерундой страдаете, что бы создать какой то сраный формат из 10 байт. быстренько обсудили и сделали.

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

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



итак, один из финальных вариантов документа.

1. RAW.
1.1. заголовок снифа.
- Header, bytes[3]
R,A,W

- HeaderVersion, word
3.0
0000000000: 50 4B 54 00 03 CB 2D 89 │ 9D 6F C4 9B 85 20 75 6D PKT☺☻╦-ЙЭo─ЫЕ um

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

- ClientLanguage, uint
enGB, ruRU. актуальная на данную сессию локализация клиента. может быть добыта из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами

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

- SessionKey, bytes[40]
ключ текущей сессии.

1.2. заголовок чанка
- Direction, byte
для серверных чанков 0хFF, для клиентских 0хСС.

-UnixTime, uint
стандартная функция UnixDateTime(Now).

- TickCount, uint
стандартная функция GetTickCount().

- ChunkDevelopersData, bytes[8]
вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.

- RAW.Length, unit
длина данных, которые были "пойманы" снифером и подлежат записи в файл.

- RAW.Data, bytes[]
пойманные данные

2. PKT.
2.1. заголовок снифа.
- Header, bytes[3]
P,K,T

- HeaderVersion, word
3.0
0000000000: 50 4B 54 00 03 CB 2D 89 │ 9D 6F C4 9B 85 20 75 6D PKT☺☻╦-ЙЭo─ЫЕ um

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

- ClientLanguage, uint
enGB, ruRU. актуальная на данную сессию локализация клиента. может быть добыта из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами

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

- SessionKey, bytes[40]
ключ текущей сессии. для PKT может быть равно нулю.

2.2. заголовок чанка
- Direction, byte
для серверных чанков 0хFF, для клиентских 0хСС.

-UnixTime, uint
стандартная функция UnixDateTime(Now).

- TickCount, uint
стандартная функция GetTickCount().

- ChunkDevelopersData, bytes[8]
вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.

- PKT.Length, unit
длина игровых данных, ВКЛЮЧАЯ Opcode.

- PKT.Opcode, unit
значение опкода, выравненное до 32х бит.

- PKT.Data, bytes[]
игровые данные опкода

Konctantin
25.07.2010, 15:56
все же я хотел бы пригласить на ревью следющих людей:
может ветку вынести из админки?

RomanRom2
25.07.2010, 15:58
может ветку вынести из админки?
естесственно. сделаешь?

Konctantin
25.07.2010, 16:03
сделал

Konctantin
25.07.2010, 16:06
я со всем согласен http://ru-mangos.ru/showpost.php?p=11319&postcount=21

RomanRom2
25.07.2010, 16:12
ок, на всякий случай, давайте я выпишу оставшиеся на данный момент нерешенные вопросы, помимо финального варианта документа.

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

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

3. - PKT
формат записи пакета я настоятельно предлагаю в естественном и привычном исполнении:
- длина, включая опкод
- опкод
- данные опкода

4. еще предлагаю ввести поле SnifferID в заголовок снифа.
все вы прекрасно понимаете, что поля DevelopersData каждой командой могут быть использованы на свое усмотрение. и если бы мы собрали такую информацию, то SnifferID помог бы понять, что именно находится в DevelopersData. и на стадии утверждения документа принять разработать и принять эти ID. ну например:
1 - WoWCore
2 - TOM_RUS
3 - Konctantin, LordJZ and Co.
и так далее.

Konctantin
25.07.2010, 16:24
2. - ChunkDevelopersData
фиксированная длинна
- длина, включая опкод
это мне не очень нравится, по причине того, что потом надо производить еще одну математическую операцию, по вычислению длинны данных, в которых уже нет самого опкода. А фактически пользы от этого не вижу...

LordJZ
25.07.2010, 16:24
Оформил.
1. RAW.
1.1. заголовок снифа.
— byte[3] Header — R,A,W
— word HeaderVersion — 3.0
0000000000: 50 4B 54 00 03 CB 2D 89 ¦ 9D 6F C4 9B 85 20 75 6D PKTOOT-ЙЭo-ЫЕ um
— uint ClientBuild — число, актуальная на данную сессию версия клиента. билд может быть добыт из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами
— uint ClientLanguage — enGB, ruRU. актуальная на данную сессию локализация клиента. может быть добыта из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами
— ui64 CDevelopersData — вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.
— byte[40] CSessionKey — ключ текущей сессии.

1.2. заголовок чанка
— byte Direction — для серверных чанков 0хFF, для клиентских 0хСС.
— uint UnixTime — стандартная функция UnixDateTime(Now).
— uint TickCount — стандартная функция GetTickCount().
— word ChunkDevelopersData — вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.
— uint RAW.Length — длина данных, которые были "пойманы" снифером и подлежат записи в файл.
— byte[]RAW.Data — пойманные данные

2. PKT.
2.1. заголовок снифа.
— byte[3] Header — P,K,T
— word HeaderVersion — 3.0
0000000000: 50 4B 54 00 03 CB 2D 89 ¦ 9D 6F C4 9B 85 20 75 6D PKTOOT-ЙЭo-ЫЕ um
— uint ClientBuild — число, актуальная на данную сессию версия клиента. билд может быть добыт из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами
— uint ClientLanguage — enGB, ruRU. актуальная на данную сессию локализация клиента. может быть добыта из VersionInfo экзешника, из бинарных данных экзешника, из сетевого трафика, иными способами
— ui64 DevelopersData — вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.
— byte[40] SessionKey — ключ текущей сессии. для PKT может быть равно нулю.

2.2. заголовок чанка
— byte Direction — для серверных чанков 0хFF, для клиентских 0хСС.
— uint UnixTime — стандартная функция UnixDateTime(Now).
— uint TickCount — стандартная функция GetTickCount().
— word ChunkDevelopersData — вспомогательные данные на усмотрение разработчика. это поле не может быть использовано для хранения данных, которые могут влиять на чтение снифа.
— uint PKT.Length — длина игровых данных, ВКЛЮЧАЯ Opcode.
— uint PKT.Opcode — значение опкода, выравненное до 32х бит.
— bytes[] PKT.Data — игровые данные опкода


RomanRom2:
1) Пока нету. В нашей реализации я не представляю, как это делать
2) Давайте с фиксированной. Плюс, не надо аж 8 байт к каждому пакету. 2 хватит, имхо. В моей цитате стоит word.
3) Согласен
4) Согласен

Nomad
25.07.2010, 16:29
2. - ChunkDevelopersData
я за плавающую длину. "сложность парсинга" одного байта для писателей
серверов и сниферов звучит несерьезно :)


3. - PKT
формат записи пакета я настоятельно предлагаю в естественном и привычном исполнении:
- длина, включая опкод
- опкод
- данные опкода

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

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

4. еще предлагаю ввести поле SnifferID в заголовок снифа.
это лучше куда-нить в п.2, к дев данным.

LordJZ
25.07.2010, 16:31
В случае не фиксированной длины DevelopersData, сами эти данные имхо лучше засунуть в самый конец заголовка файла/чанка, чтобы была возможность читать структурами, а уже потом вручную дочитывать динамические данные.

Konctantin
25.07.2010, 16:39
я за плавающую длину. "сложность парсинга" одного байта для писателей
серверов и сниферов звучит несерьезно
это только лишний геморой

user456
25.07.2010, 16:44
Господи, ну сделайте короткий хедер, в котором к примеру оффсет (или фиксированно с адреса там 20) на структуру блоков и длина структуры, затем оффсет данных. В самой структуре отложить типы полей, возможно с названиями (ну примерно как близзы юзают для структур в dbc, да и вообще многие структуры бд так делают). Позволит забыть на долгие годы изменения в структуре пакетов.
Насчет однобайтового признака: wad как-то юзал RECV/SEND, я предпочитал SMSG/CMSG. Временами спасало если какой-то сбой происходил. Вероятность что каша совпадет с таким признаком нулевая. И если сбой произошел то не теряется весь файл до конца, просто ищеш следующий признак.

RomanRom2
25.07.2010, 16:50
фиксированная длинна
RomanRom2:
1) Пока нету. В нашей реализации я не представляю, как это делать
2) Давайте с фиксированной. Плюс, не надо аж 8 байт к каждому пакету. 2 хватит, имхо. В моей цитате стоит word.
3) Согласен
4) Согласен
ок,
1) вопрос пока открыт.
2) решили фиксированную. 16 бит нам точно хватит? может уж все же 32? мало ли чего запихать сюда понадобится, значением больше чем 65535. еще один какой нибудь тиккаунт... винты сейчас у всех вроде большие.
3) решили. см. ниже...
4) тогда предлагаю его поместить прямо перед SessionKey.

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

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

2. давайте думать, логически завершенные данные, это все же опкод+данные. это законченная еденица сущности, чтоли. формат любого опкода можно представить как из двух полей:
- ID
- DATA, соответствующая этому ID
никто же не пилит А9 на составлящие. там ведь еще круче:
- ID = 0xA9
- DATA
- ObjectsCount
- UpdateType
- UpdateType = 1 (create from Object)
- свой набор данных
- UpdateType = 2 (update Fields)
- свой набор данных
- UpdateType = 3 (create for self)
- свой набор данных
, где (например)
свой набор данных UpdateType = 3
- ObjectType = 1 (item)
- свой набор данных ObjectType = 1
- ObjectType = 2 (container)
- свой набор данных ObjectType = 2
- ObjectType = 3 (unit)
- свой набор данных ObjectType = 3
- ObjectType = 4 (player)
- свой набор данных ObjectType = 4
, где (например)
свой набор данных ObjectType = 4
- свой move-block
- в завимости от флагов плюс дополнительные данные

а у ObjectType = 1 такие флаги вообще не встречаются и соответственно данных нет...
ну короче не грузись :) я хотел сказать, что логически законченную еденицу данных нельзя разделять, да чото увлекся :)

эти две причины достаточно убедительны для тебя?

VDm
25.07.2010, 16:56
Создайте, где-нибудь Wiki-страницу формата.
На форуме минимальные отличия в описании формата не видны совершенно.

Nomad
25.07.2010, 16:57
это только лишний геморой

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

RomanRom2
25.07.2010, 16:59
а если я хочу имя аккауна своего агента держать? чтобы знать, кому пистонить за не вычищеный кеш и пр? тут уж вариант с доп данными в конце файла интереснее звучит. писать туда оффсет своего блока данных.
у тебя есть CMSG_AUTH_SESSION с именем аккунта :secret:

LordJZ
25.07.2010, 17:00
32 бита на DevelopersData при каждом пакете и 64 в заголовке файла — согласен

VDm
25.07.2010, 17:19
Если никак не получается решить для всего формата сразу, давайте хотя-бы определимся с заголовком:
struct FileHeader
{
byte signature[3]; // 'PKT' | 'RAW'.
word version; // == 0x0003 - для версии 3.0.
byte snifferID; // Распределить уникальные номера.
uint build; // Номер сборки клиента, обратите внимание, тип uint (4 байта).
byte language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40]; // Ключ сессии, для PKT не используется и может быть заполнен как угодно (лучше нулями).
uint optionalHeader; // Размер опционального заголовка в байтах,
// который идет сразу после заголовка файла и содержит все, что угодно.
// Если optionalHeader == 0, тогда опциональный заголовок в файле отсутствует.
};
// sizeof(FileHeader) == 3 + 2 + 1 + 4 + 4 + 40 + 4 = 58 байт (align == 1)

RomanRom2
25.07.2010, 17:20
господа, поступило шикарное предложение по формату чанка:

(byte)Direction;
(uint)UnixTime
(uint)TickCount
(uint)Data.Length
(uint)DD.Length
(byte[])Data
(byte[])DD

как вам?
при этом хидер читается структурой, что удобно само по себе.
после хидера идут данные опкода.
после данных опкода идут DevelopersData, если DD.Length больше нуля.
в данном варианте сведены к минимуму все затраты и DD стал переменной длины, что тоже должно всех устроить.

правда в этом случае, к великому сожалению Константина, (uint)Data.Length будет содержать данные вместе с опкодом, а Data данные вместе с опкодом. ну в прочем это само по себе и вытекло бы, как ни крути.

хех. вон VDm предлагает ту же идею и с хидером снифа.

LordJZ
25.07.2010, 17:23
RomanRom2, только опкод все-равно форматируем до 32 бит, ага?

RomanRom2
25.07.2010, 17:27
RomanRom2, только опкод все-равно форматируем до 32 бит, ага?
да, пусть будет.

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

Йоха
25.07.2010, 17:43
коллеги, а для чего в снифе девелоперс дата ?

LordJZ
25.07.2010, 17:45
И так, на последний момент:


Заголовок файла:byte signature[3]; // 'PKT' | 'RAW'.
word version; // == 0x0003 - для версии 3.0.
byte snifferID; // Распределить уникальные номера. — это надо решить.
uint build; // Номер сборки клиента, обратите внимание, тип uint (4 байта). — зачем 4 байта?
byte language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40]; // Ключ сессии, для PKT не используется и может быть заполнен как угодно (лучше нулями).
byte OptionalHeaderLength;
byte optionalHeader[];Заголовок пакета:
(byte)Direction; // 0xFF — серверный, 0xCC — клиентский
(uint)UnixTime
(uint)TickCount
(uint)OptionalHeader.Length
(uint)Data.Length
(byte[])OptionalHeader
(byte[])Data — предлагаю именно такой порядок: длина DD, длина данных, DD, данные.
Данные включают в себя опкод, выравненный до 32 бит.




____________
коллеги, а для чего в снифе девелоперс дата ? Для данных создателей сниффа... я, например, там хочу хранить количество пакетов, а для каждого пакета — его флаги.

VDm
25.07.2010, 17:49
Предлагаю так же учесть доводы user456 насчет указания направления пакета, и расширить это поле с 1 до 4 байт, заодно, сделав размер заголовка чанка кратным 4:
struct ChunkHeader
{
char direction[4]; // 'RECV' и 'SEND', либо 'SMSG' и 'CMSG', либо то, что вы предложите.
uint unixTime;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
// sizeof(ChunkHeader) == 4 + 4 + 4 + 4 + 4 = 20 байт (align == 1)

Сразу после ChunkHeader следуют optional-данные, затем данные пакета.


P.S. Подстроился с учетом мнения LordJZ о порядке следования данных.

RomanRom2
25.07.2010, 17:52
еще одно из доводов user456:
цитирую:
я бы выкинул из каждого пакета и UnixTime
есть стартовый и тиккаунты

VDm
25.07.2010, 17:52
И так, на последний момент:
зачем 4 байта?

Конечно, сомнительно, что номера сборок превысят 65 535, но я увидел uint в описании у RomanRom2.

Йоха
25.07.2010, 17:53
по поводу byte SnifferID - иожет сделать не 1 байт, а немного длинней, и хранить там символьное представление, например "wcore"
Просто придумывать номера ID - это еще 1 стандарт, кто его будет поддерживать ? а так каждый сниферописатель придумает какое-нибудь символьное сокращение для своего детища

RomanRom2
25.07.2010, 18:08
Предлагаю так же учесть доводы user456 насчет указания направления пакета, и расширить это поле с 1 до 4 байт, заодно, сделав размер заголовка чанка кратным 4:
struct ChunkHeader
{
char direction[4]; // 'RECV' и 'SEND', либо 'SMSG' и 'CMSG', либо то, что вы предложите.

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

Конечно, сомнительно, что номера сборок превысят 65 535, но я увидел uint в описании у RomanRom2.
да, я тоже было подумал, что вдруг мы доживем до билда 65к. ну а пусть будет? для унификации и выравнивания, что ли. кто принципиально против?

по поводу byte SnifferID - иожет сделать не 1 байт, а немного длинней, и хранить там символьное представление
а это ничего не меняет. какая то сигнатура будет вместо 1 байта. а кто будет поддерживать эти сигнатуры? точно так же их надо будет описывать где то.

И так, на последний момент:
— предлагаю именно такой порядок: длина DD, длина данных, DD, данные.
Данные включают в себя опкод, выравненный до 32 бит.

в данном случае не принципиально в какой последовательности хранить. пусть так, логика парсеров ни сколько не меняется.
только хочу еще добавить, что длина данных содержит в себе 4 байта опкода (который выравнен до 4 байт).

user456
25.07.2010, 18:29
господа, поступило шикарное предложение по формату чанка:

(byte)Direction;
(uint)UnixTime
(uint)TickCount
(uint)Data.Length
(uint)DD.Length
(byte[])Data
(byte[])DD
Да, если слишком кратко излагать - не доходит. Развернуто:
struct main_hdr{
int sign;
uint pkt_hdr_offset;
uint pkt_hdr_len;
uint data_offset;
...
}

struct pkt_hdr_node{
int len;
char [50] name;
}

потом с адреса pkt_hdr_offset забиваеш массив и получаеш свои типы, можно по name разбор делать или добавить константы типа. Получится структура велосипеда, который давно изобрели в каком-нибудь DBase.
Один фиг через год станет понятно что UnixTime в каждом пакете это мусор (достаточно тиккаунтов на четверо суток в миллисекундах и даты создания файла или одного time в хедере)

VDm
25.07.2010, 18:43
Да, если слишком кратко излагать - не доходит.
Сложно, если это кому-то потребуется, пусть задает optionalData, а там - что угодно и сколько угодно.

VDm
25.07.2010, 19:19
По историческим соображениям, описанным здесь: http://www.gotwow.ic.cz/
Пытаемся составить список SnifferID (SnifferID получается так же при конвертации данных от команды, не имеющей совместимости с данным форматом):
0x00 - Wad // 2005 и ранее
0x01 - Nomad // 2005 и ранее
0x02 - WoWCore // 2005
0x03 - Mangos (TOM_RUS) // 2005, намеренно не отделяю по времени TOM_RUS от Mangos
0x04 - User456 // 2006
0x05 - Delfin // 2006
0x06 - Burlex // Хотя начинал он явно раньше, я точно не знаю, когда.
0x07 - WCell
0x08 - LordJZ
0x09 - Йоха // 2010
0x0A - abdula123 // 2010

Если кого-то забыл или не туда записал, отпишитесь.

user456
25.07.2010, 19:49
Если кого-то забыл или не туда записал, отпишитесь.
Да просто поле символов 25 оставь и все. А там уже WoWCore v 3.xx внутри или типа того.

P.S. бурлеха еще забыл.

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

LordJZ
25.07.2010, 20:08
По историческим соображениям, описанным здесь: http://www.gotwow.ic.cz/
Пытаемся составить список SnifferID (SnifferID получается так же при конвертации данных от команды, не имеющей совместимости с данным форматом):
0x00 - Wad // 2005 и ранее
0x01 - Nomad // 2005 и ранее
0x02 - WoWCore // 2005
0x03 - Mangos (TOM_RUS) // 2005, намеренно не отделяю по времени TOM_RUS от Mangos
0x04 - User456 // 2006
0x05 - Delfin // 2006
0x06 - Burlex // Хотя начинал он явно раньше, я точно не знаю, когда.
0x07 - WCell
0x08 - LordJZ
0x09 - Йоха // 2010
0x0A - abdula123 // 2010

Если кого-то забыл или не туда записал, отпишитесь.WowCore вроде-бы 6-ку и использует (со слов RomanRom2)

VDm
25.07.2010, 20:32
WowCore вроде-бы 6-ку и использует (со слов RomanRom2)
Мы посчитали, что использовать в качестве SnifferID - номер командры разработчиков, а не номер их программы (у одной команды может быть несколько разных программ), будет более правильно.

RomanRom2
25.07.2010, 20:33
WowCore вроде-бы 6-ку и использует (со слов RomanRom2)
нет. раньше мы этот SnifferID использовали как идентификатор снифера. у нас их тьма тараканья ведь :pardon:
а сейчас предлагается использовать как идетификатор команды, а то 255 значений для всех всевозможных сниферов может когда нибудь не хватить.

user456
25.07.2010, 21:00
Ну а признак что сниф не левый с эмулей? А то мы с ромкой в аське вроде со своими мыслями согласились...
И вопрос, обсуждаемый между собой, но не вошедший сюда:
1. снифами скорее всего делиться никто не будет, не только от жадности но и чтобы не получать баны
2. отсюда мы вроде как согласились что если что и шарить, то сразу пакеты респонсов и подобного
3. откуда следует что инфа должна быть заранее обработана и обсуждение формата пакетов raw вроде бури в стакане воды

Итого: смысл обсуждать? Только в случае одинаковых на всех обработчиков сниффов. У нас с ним по-любому будут разные. Он заряжает тулзу, которая буквами выводит "ну ты и крут, еще 500 айтемов". Я если тащу, так вытаскиваю всю нужную именно мне инфу (последовательно обрабатывая можно много чего еще вытащить). Даже не юзаю тиккаунты потому что в каждом пятом пакете они есть.

RomanRom2
25.07.2010, 21:32
вовк, на самом деле ситуация немного проще:

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

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

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

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

так что респонсы и всякие А9 (заселенку) можно легко и смело шарить. т.е. писать такой тул, которому скармливается снифф и который оставляет вот эти пакеты. т.е. пакеты, которые явно не спалят аккаунт, пакеты, в которых отсуствует гуид перса, его имя и т.п. в этом нам нужно соревноваться, я считаю. т.е. КАК СДЕЛАНО, а не СКОЛЬКО.

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

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

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

так что буря в стакане возможно и выглядет утопичной, но возьми например jpeg, или там mp3. все по своему и по разному их "обрабатывают". paint по проще, photoshop по круче. ну и что. так что я считаю все равно это создаст некоторое удобство. время покажет, какое именно.

Konctantin
25.07.2010, 22:23
сами снифы, не представляют никакой угрозы, так как они по сути являют собой бинарные файлы, а чтоб их читать, надо специальный "инструмент" и знания.

А так, он совершенно бесполезен (пример, wdb-cache, на данный момент мало кто его может прочитать).

RomanRom2
25.07.2010, 23:21
все верно, но уверен, у близзов эти инструменты найдутся, если им ну очень зачется узнать кто снифал тот снифф, который попал им в руки и забанить наглеца :declare:

Konctantin
25.07.2010, 23:23
а сейчас тему видно? отпишитесь кто нибудь...

Fmut
25.07.2010, 23:44
а смысл этого всего если не выкладывать снифы тоннами в паблик? да и желательно сам снифер давать в паблик, иначе тонн снифов небудет.

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

RomanRom2
25.07.2010, 23:58
а смысл этого всего если не выкладывать снифы тоннами в паблик? да и желательно сам снифер давать в паблик, иначе тонн снифов небудет.
я думаю это тоже вопрос времени. снифер давать в паблик я бы не стал, ибо его можно поиметь близзам и добавить в варден.
ну а в снифах, как я уже и говорил, куча инфы, связанной с твоим персом. при желании можно вычислить тебя и забанить. опять же повторюсь - при желании.
если помните может, мы выкладывали в паблик много снифов во времена 2.4.х, и даже сниферы выкладывали. никто что то не забанил...

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

Konctantin
25.07.2010, 23:59
смысл есть всегда, давайте простой пример:
идет обсуждение чего-то, надо пример сниффа с оффа, вы выкладываете этот снифф, и все, кому надо смогут прочитать его, и можно на основании конкретных данных вести конструктивную беседу.

Fmut
26.07.2010, 00:45
Как Ромка уже и сказал, в снифах самое ценное данные для респонзов и заселения.

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

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

munche
26.07.2010, 07:30
А как насчет англоязычного коммунити? До них эту идею донесли или они сами по себе как обычно?

Dereka
26.07.2010, 08:23
А как насчет англоязычного коммунити? До них эту идею донесли или они сами по себе как обычно?
сейчас из этого комьюнити только wcell и trinity
и если, как говорит Авен, "сделать единую базу с официальными данными без custom-полей и привязки к конкретному проекту" они всё равно узнают про эту базу, им будет выгодно делать такой же формат снифов.. правда нужно будет формат задокументировать на англицком

кстати забыли в этом списке про кобольд:yes3:
0x00 - Wad // 2005 и ранее
0x01 - Nomad // 2005 и ранее
0x02 - WoWCore // 2005
0x03 - Mangos (TOM_RUS) // 2005, намеренно не отделяю по времени TOM_RUS от Mangos
0x04 - User456 // 2006
0x05 - Delfin // 2006
0x06 - Burlex // Хотя начинал он явно раньше, я точно не знаю, когда.
0x07 - WCell
0x08 - LordJZ
0x09 - Йоха // 2010
0x0A - abdula123 // 2010

Nomad
26.07.2010, 09:36
у тебя есть CMSG_AUTH_SESSION с именем аккунта :secret:

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

RomanRom2
26.07.2010, 20:49
сейчас из этого комьюнити только wcell и trinity
они всё равно узнают про эту базу, им будет выгодно делать такой же формат снифов..
а разве мангос из буржуев никто не делает? это чисто русский проект? =)))
кажется в wcell один (или несколько) разработчиков русские, эмигранты. нет? разберуться, чай не :censored: шучу.

кстати забыли в этом списке про кобольд:yes3:
мы разве исторический список эмуляторов составляем? в таком случае, что мангос, что тринити, что кобольд, что вовд, что штормкрафт - одна фигня. а еще забыли какого нить wowwow, да много кого :pardon:

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

на самом деле это не важно, список чистая формальность. главное - формат разработали. и лично мне он очень даже нравится. и как прется с него WoWCore Team - тоже не пересказать :))) и самое главное - мы его ВМЕСТЕ сделали. и что ж - кажется можно считать, что обсуждение закончено, кажется добавить уже нечего. можно ускорить процесс - можно считать что документ разработан и начать его ревью. скажем до конца месяца, до 31 июля.

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

LordJZ
26.07.2010, 21:00
Они же другие форматы используют (sqlite, xml)


P.S. Может действительно использовать использовать не один байт на идентификатор сниффера, а несколько, или может вообще строку?

RomanRom2
26.07.2010, 21:07
ну понятно что другие. все мы каждый свои форматы используем. для чего ж мы тут тогда все собрались...
пусть переделывают :take_example:

P.S. Может действительно использовать использовать не один байт на идентификатор сниффера, а несколько, или может вообще строку?
строку, если хотите - пишите в DevelopersData. копирайты там вские, название снифера и его версию, билд, свн ревижн, точное время создания... вощем чо хотите :read:

Dereka
26.07.2010, 21:26
мы разве исторический список эмуляторов составляем? в таком случае, что мангос, что тринити, что кобольд, что вовд, что штормкрафт - одна фигня. а еще забыли какого нить wowwow, да много кого :pardon:

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


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

LordJZ
26.07.2010, 22:04
В таком случае дополнений/предложений не имею.

Konctantin
26.07.2010, 22:09
кеп, голос отдан вам - "ДА".

VDm
26.07.2010, 22:18
не так меня понял..
у кобольдов свой формат снифов это 100%.. и снифер вроде свой был.
Месяца полтора к ним не заходил, не знаю как у них сейчас обстоят дела:)))
В таком случае, ничто не мешает и им присвоить snifferID.
До тех пор, пока формат окончательно не утвержден, в списке могут быть подвижки (с поправкой на "давность" команды), после утверждения данный список может быть увеличен только путем добавления номера в конец.

zergtmn
26.07.2010, 22:21
struct MainHeader
{
char signature[3]; // 'RAW'.
word version; // 0x0003
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40];
uint optionalHeaderLength;
};
Зачем так экономить байты в хидере? Можно до dword'ов округлить все поля, вдруг захочется хранить версию или snifferID немного по другому, но не теряя совместимости? До 64 байт очень хорошо округляется :)

VDm
26.07.2010, 22:25
Зачем так экономить байты в хидере? Можно до dword'ов округлить все поля, вдруг захочется хранить версию или snifferID немного по другому, но не теряя совместимости? До 64 байт очень хорошо округляется :)
Это не совсем так, дело в том, что формат не просто так имеет версию 3, есть, например, версии 2.0, 2.1. В них первые пять байт - это сигнатура(3) + версия(2), эти поля менять точно нельзя, иначе существующие программные решения не смогут понять о какой версии идет речь.
На фоне этого, смысл расширять snifferID теряется. Мы уже говорили, что практическое значение snifferID крайне невелико, каждая команда разработчиков имеет полную свободу самовыражения в optionalHeader и optionalData.

Fall0ut
27.07.2010, 07:54
не так меня понял..
у кобольдов свой формат снифов это 100%.. и снифер вроде свой был.
Месяца полтора к ним не заходил, не знаю как у них сейчас обстоят дела:)))
Спасибо, Дерека. Я в тебе не сомневался )) Ты один из тех немногих, которых я уважаю как людей. Ну да ладно...
Тут в чем дело.. К нам именно по этому сабжу никаких предложений не поступало. Да и нужно ли это им? )
Эта тема для Мангос и Ко или же для всего эму коммунити? Я думаю все же первое..

Йоха
27.07.2010, 11:04
никаких замечаний/возражений не имею. По большому счету мне вообще все равно какой формат у файлов будет, переписать свой софт под поддержку формата 3.0 - не проблема.
Главное во всем этом то, что люди будут придерживаться некоего единого стандарта, а уж какой там сам стандарт - это не столь важно.

Konctantin
27.07.2010, 12:26
Эта тема для Мангос и Ко или же для всего эму коммунити? Я думаю все же первое..
нет, это не первое, это для всех...
Главное во всем этом то, что люди будут придерживаться некоего единого стандарта, а уж какой там сам стандарт - это не столь важно
придерживаться будут, если все будет устраивать, как раз в этом смысл всей этой дискуссии...

Перенес список ревьюверов в первый пост.

RomanRom2
27.07.2010, 12:31
Тут в чем дело.. К нам именно по этому сабжу никаких предложений не поступало. Да и нужно ли это им? )
Эта тема для Мангос и Ко или же для всего эму коммунити? Я думаю все же первое..
вы из кобольд тим? спасибо, что зашли.
предложение вывешено на этом форуме, потому что он, как мне кажется, самый популярный. нет? ваш популярней? :wink3: не вопрос, скажите ресурс, где это точно прочитают все - вывесим там.
все - я имею ввиду разработчиков :pleasantry:

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

Neverdie
27.07.2010, 12:56
Ромыч на даный момент у нас ваш
у нас просто 2-3 калеки раоботают и все сразу не можем
вот и пользуемся в даный случай (запозычеными технологиями) дамы не тратить время которого и так нету
раньше был свой
кстати за формат зачет
он даже меньше выходит по размеру (ну то сопли)

а на данном варианте мы просто мы не в силах поддреживать тему - не из лени или что-то там еще
а из на хватки уделять время опять же ((

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

гы сори за фала - наверно он сам не понял что ляпнул.

П.С, ничего личного

LordJZ
27.07.2010, 21:06
Написал обработчик PKT 3.0 Preview формата.
Как пример, вот лог промежуточной сессии. Присутствуют optional блоки — у некоторых пакетов и в основном заголовке. Для ознакомления.
http://dl.dropbox.com/u/9241118/PKT_3.0_Preview.pkt

VDm
27.07.2010, 21:37
Написал обработчик PKT 3.0 Preview формата.
Как пример, вот лог промежуточной сессии. Присутствуют optional блоки — у некоторых пакетов и в основном заголовке. Для ознакомления.
http://dl.dropbox.com/u/9241118/PKT_3.0_Preview.pkt
Проверил в HEX-редакторе, все корректно.
Прошу обратить внимание на одну важную деталь, второе поле в заголовке файла (поле version) записывается как word в big-endian формате, в то время, как остальные записи в little-endian.
LordJZ сделал это совершенно корректно, смотрим начало заголовка (в порядке: signature(3), version(2), snifferID(1), build(4)):
50 4B 54 | 00 03 | 09 | 34 30 00 00
На little-endian машинах архитектуры x86 и x64 взятие word для version выдаст число 768.
Выше я написал, что version == 0x0003, это некорректно, потому что такая константа будет записана на little-endian машине, как "03 00".

PS. Лучше поправить word version на byte version[2] с указанием, что оно равно: { 0x00, 0x03 }

LordJZ
27.07.2010, 21:50
Поправил, спасибо.

Blacksmither
29.07.2010, 08:25
и еще вопрос. действительно ли у вас есть собственный рабочий снифер? как называется и какого он типа? или вы используете опенсоурс?

Ну запишите:

name: kobold_px
date: 2009
type: proxy
author: Kosuha

RomanRom2
29.07.2010, 13:14
Ну запишите:
записал. присвоен код 8.

Konctantin
29.07.2010, 15:03
как бы теперь донести это на буржуйские форумы?

user456
30.07.2010, 00:12
Товарищ прав, какая разница в байтах главный хедер или в двордах? На 500Мбайтах зашедшего в рейд или на БГ сэкономить 5-10 байт? Тем более уже 30 лет процессорам проще читать 32-х битное и только ценой невероятных усилий почти с той же скоростью 8-ми битное.
Насчет локейла - если трудно тащить то на худой конец в wtf/config сидит типа SET locale "enUS"

Да, и будет все в интел-формате (не помню в какую сторону он endian) или кто-то еще гоняет моторолы?

user456
30.07.2010, 01:09
Вот продолжаем с ромкой по 2-3 байтных выяснять.

К примеру код на Delphi сравнения сигнатуры:

PHeader = ^THeader;
THeader = packed record
sign: dword;
ver: dword;
...
end;

const
SIGN_PKT = $00544B50;

var
buf: THeader;
begin
fread(f, buf, len);
if (buf.sign = SIGN_PKT) then
...

если делать 2-3-х байтными это уже выливается в сравнения массивов или всякие присвоения с масками и сдвигами. По-моему лучше и правда забить 32-х битными чем потом годами мучаться или разнобой получать.

VDm
30.07.2010, 01:34
если делать 2-3-х байтными это уже выливается в сравнения массивов или всякие присвоения с масками и сдвигами. По-моему лучше и правда забить 32-х битными чем потом годами мучаться или разнобой получать.
Так бы и сделали, если бы не желание оставить совместимость с прежними форматами. Да и стоит ли оно того ради 3 байт? Можно и memcmp сделать, один раз на файл-то.

user456
30.07.2010, 01:56
Так бы и сделали, если бы не желание оставить совместимость с прежними форматами. Да и стоит ли оно того ради 3 байт? Можно и memcmp сделать, один раз на файл-то.
А у кого кроме ромки такое же в старых форматах? По описанному уже всем придется переделывать. Потом как в дате биоса еще одного байта не хватит, потом еще...
Впрочем как сделаете так и делайте. Моё имхо: вместо того чтобы оставить ромкину "3" там где она и сидит я бы сделал 32-х битный тим типа MNGS и может по дворду на билд снифера LO и HI.

Konctantin
30.07.2010, 01:57
у меня хватает

RomanRom2
30.07.2010, 02:00
поддерживаю :yes3:
по моему не тот случай, где нужно так упираться за производительность.

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

шо мы не программисты шоле, трем байтам не сможем сделать:
var
signature: longint;
version: word;
begin
BlockRead(f, buf, 5);
move(buf[0], signature, 3);
move(buf[3], version, 2);
...

чего тут такого прям криминального то? ну, кроме подхода :pleasantry:

З.Ы. :heat::heat::heat:

Konctantin
30.07.2010, 03:02
Я получил локаль(индекс локали) читая память процесса по адресу 0x00C5DE9C, но это не выход, ведь с каждым билдом адрес будет менятся.
Или может есть более постоянный адрес?

TOM_RUS
30.07.2010, 06:13
Я получил локаль(индекс локали) читая память процесса по адресу 0x00C5DE9C, но это не выход, ведь с каждым билдом адрес будет менятся.
Или может есть более постоянный адрес?

0x00C5DE88 текущая локаль в виде строки

user456
30.07.2010, 06:17
не, я конечно понимаю, что подход там, все дела. но Вовка, в самом деле... :stop:

Впрочем как сделаете так и делайте


Я получил локаль(индекс локали) читая память процесса по адресу 0x00C5DE9C, но это не выход, ведь с каждым билдом адрес будет менятся.
Или может есть более постоянный адрес?
Разве что если найти структуру к которой оно привязано (как с ключом). Но тут проще или ловить логин или тупо читать из wtf/config. Или как Ромка когда-то делал - читать всю память процесса и не спеша искать в ней локаль чтобы запомнить адрес до следующего патча.

Konctantin
30.07.2010, 11:01
Но тут проще или ловить логин или тупо читать из wtf/config.
но если это первый запуск? тогда там будет пусто. пишется в wtf/* только после закрытия клиента.

LordJZ
30.07.2010, 11:46
Первый запуск — используем язык по-умолчанию из тех, что установлен в клиенте.

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

user456
30.07.2010, 19:43
но если это первый запуск?
Какова вероятность попасть на первый запуск клиента?
Попробовал у себя

const
LOCALE_SIGN = 'SET locale "';
...
//locale stuff
WowIni:= TRegistry.Create;
try
WowIni.RootKey:= HKEY_LOCAL_MACHINE;
if WowIni.OpenKey('\SOFTWARE\Blizzard Entertainment\World of Warcraft', false)then begin
fname:= WowIni.ReadString('InstallPath') + 'Wtf\Config.wtf';
fs:= TFileStream.Create(fname, fmOpenRead);
setlength(temp_arr, fs.Size);
fs.Read(temp_arr[0], fs.Size);
fs.Free;
temp_str:= PChar(temp_arr);
temp_arr:= nil;

locale_pos:= pos(LOCALE_SIGN, temp_str);
if (locale_pos > 0) and (locale_pos + length(LOCALE_SIGN) + sizeof(PktHdr.locale) <= length(temp_str)) then
move(temp_str[locale_pos + length(LOCALE_SIGN)], PktHdr.locale, sizeof(PktHdr.locale));
end
else PktHdr.locale:= UNK_SIGN;
finally
WowIni.Free;
end;

всё пашет

Konctantin
30.07.2010, 20:07
Ну это все, как говорится "у каждого свои методы", я ограничился таким кодом:
private byte[] GetLocales()
{
using (var mr = new ProcessMemoryReader("wow"))
{
return mr.Read(0x00C5DE88, 4);
}
}

TOM_RUS
31.07.2010, 10:48
Ну это все, как говорится "у каждого свои методы", я ограничился таким кодом:
private byte[] GetLocales()
{
using (var mr = new ProcessMemoryReader("wow"))
{
return mr.Read(0x00C5DE88, 4);
}
}

У меня почти так же :)


using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;

namespace Wlp
{
public class SessionInfoReader
{
private const string ProcessName = "Wow";

public static int ClientBuild
{
get
{
var p = ProcessMemoryReader.GetProcessByName(ProcessName);

if (File.Exists(p.MainModule.FileName))
{
var fi = FileVersionInfo.GetVersionInfo(p.MainModule.FileNa me);
return fi.FilePrivatePart;
}
else
{
Logger.Instance.ErrorFormat("{0} not found or missing required permissions!", ProcessName);
return -1;
}
}
}

public static byte[] GetSessionKey(uint offset)
{
using (var pmr = new ProcessMemoryReader(ProcessName))
{
return pmr.Read(pmr.ReadUInt(offset) + 0x508, 40);
}
}

public static byte[] GetWardenSeedKey(uint offset)
{
using (var pmr = new ProcessMemoryReader(ProcessName))
{
return pmr.Read(pmr.ReadUInt(offset) + 0x04, 16);
}
}

public static byte[] GetWardenRC4State(uint offset)
{
using (var pmr = new ProcessMemoryReader(ProcessName))
{
return pmr.Read(pmr.ReadUInt(offset) + 0x20, 0x204);
}
}

public static byte[] GetLocaleBytes(uint offset)
{
using (var pmr = new ProcessMemoryReader(ProcessName))
{
return pmr.Read(offset, 4);
}
}
}
}

Lordronn
01.08.2010, 18:27
А почему бы не узнавать локал клиента по названию под папки?
В папке Data есть под папка ruRU\enGB\enUS... Почему бы просто не брать локал клиента оттуда. Если поменять название папки, то вов не запустится(проверено)
Да и менять специально никто бы не стал

zergtmn
01.08.2010, 18:31
А если локалей несколько? enGB и ruRU отлично уживаются вместе. Для переключения локали мне достаточно сменить ее в конфиге.

Konctantin
01.08.2010, 18:41
А почему бы не узнавать локал клиента по названию под папки?
К примеру у меня 2 языковых пакета, и оба я использую...

Да и писалось выше, "у каждого свои методы", если есть желание, то можна и ручками писать, какая локаль используется.

Neverdie
01.08.2010, 18:50
Та це вы уже в крайности кидаетесь просто
как писаливые каждый меняет по своему
над этим лучше бы не мучались бы и все

RomanRom2
04.10.2010, 19:33
нууу... я так понимаю, формат утвержден.
с чем всех и поздравляю.

alien
04.10.2010, 19:58
Наверно в первом посте надо ***93; и ***91; надо поправить

NeatElves
04.10.2010, 20:08
Зачем ?? Нормально определяет
***91 - [
***93 - ]

alien
04.10.2010, 20:22
Хмм у показывается как ***91 и***93 а не как []

Konctantin
04.10.2010, 21:14
поправил, используя теги [code]

Lordronn
07.02.2011, 22:49
char signature[3]; // 'RAW'.

Почему не определять подпись сниффа по формату: .pkt .raw

char direction[4]; // 'SMSG', 'CMSG'

почему не использовать байт?

Direction direction = reader.ReadByte() == 1 ? Direction.SMSG : Direction.CMSG;

public enum Direction
{
CMSG = 0,
SMSG = 1
};

LordJZ
07.02.2011, 23:23
Почему не определять подпись сниффа по формату: .pkt .rawМожно еще по имени. Если начинается с цифры — это raw формат, в противном случае стандартный pkt. Или по дате, например, дамп, созданный в понедельник, — raw. А еще можно помечать raw дампы как системные файлы. А то мало-ли что наделают?почему не использовать байт?

Direction direction = reader.ReadByte() == 1 ? Direction.SMSG : Direction.CMSG;

public enum Direction
{
CMSG = 0,
SMSG = 1
};RomanRom2 объяснял почему. Ему хочется визуально смотреть PKTv3 в Far-е.

RomanRom2
08.02.2011, 00:43
Почему не определять подпись сниффа по формату: .pkt .raw

потому что никто так не делает. например zip, mp3, или даже (о боже!) mpq - имеют заголовок. не для того, что бы место на ваших дисках занять, а что бы быть уверенным в том, что читаем, хотя бы косьвенно. у тома, например, снифы на выходе имеют вообще расширение .bin, как понять чоо-там-чоо-там и каким методом парсить в этом случае? :pardon:

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

ЗЫ. кстати, сейчас хоть кто нибудь что нибудь снифает? :)

Konctantin
08.02.2011, 04:17
ЗЫ. кстати, сейчас хоть кто нибудь что нибудь снифает?
у меня есть гиг снифов

Fedia22
08.02.2011, 08:57
ЗЫ. кстати, сейчас хоть кто нибудь что нибудь снифает? :)

снифается потихоньку? если что то конкретно нада напиши в асю, освобожусь отснифаю

Йоха
08.02.2011, 16:12
А как сейчас пишется сниф ? с двух соединений в два файла ? или все в один файл как приходят данные на сокет так и скидываются ?

P.S. сейчас посмотрел, кроме 2-ух активных соединений на 195.12.246.210 и 195.12.246.213 болтается еще какое-то соединение на 213.248.127.130. Последнее это бнет ?

TOM_RUS
08.02.2011, 17:03
Последнее это бнет ?

Да. eu.logon.battle.net

LordJZ
08.02.2011, 17:21
А как сейчас пишется сниф ? с двух соединений в два файла ? или все в один файл как приходят данные на сокет так и скидываются ?
...Я пишу в 1 файл, а в заголовке пакета пишу номер соединения.

RomanRom2
21.04.2011, 21:27
у кого нить есть готовый конвертор PKT 2.1 -> PKT 3.0?

TOM_RUS
21.04.2011, 22:11
Я только сегодня добавил поддержку PKT 3.0 в свой WoWPacketViewer :)

HuntsMan
21.04.2011, 22:20
у кого нить есть готовый конвертор PKT 2.1 -> PKT 3.0?
А описание формата 2.1 где-нибудь глянуть можно?)

Йоха
21.04.2011, 22:31
на wowcore.ru

RomanRom2
21.04.2011, 23:09
не, ну если так сходу нет, то сам напишу :) лень просто...
я все свои снифы от классика сейчас перевел (почти) в PKT 2.1, да у меня в те времена было много разных форматов. вот думаю разом их в 3.0 конвертнуть и работать уже с ними. вот в бекграунде и пописываю...

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

HuntsMan
22.04.2011, 07:36
Да я какбэ просто хочет к себе в парсер добавить поддержку этого формата, авось попадется :)

PS: Кому не жалко покажите структуру optionalData хидера и чанка, хочется в свой парсер добавить поддержку как можно большего количества форматов :)

Йоха
22.04.2011, 08:52
PS: Кому не жалко покажите структуру optionalData хидера и чанка, хочется в свой парсер добавить поддержку как можно большего количества форматов :)

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

195.12.246.213:3724

HuntsMan
22.04.2011, 18:21
Спасибо :) Просто я у себя в хидере пишу описание, и количество пакетов в снифе. Естественно парсер использует эти данные. А то вдруг чей-нить сниф подвернется, и читатся не будет :)

RomanRom2
22.04.2011, 18:49
очень плохо. эти поля были сделаны не для хранения данных и последующего парсинга, а для как поля "для заметок". это не по феншую.

Lordronn
24.04.2011, 08:10
Не у кого не завалялось сниффа версии 2.1 и ранее. Хочу проверить как парсер будет их кушать

RomanRom2
24.04.2011, 12:13
http://wowcore.ru/downloads/HUMAN_priest[3.3.5]_PKT_v2.1.rar
там же и RAW и там же лог декодера, ну... какие опкоды там есть.

Lordronn
24.04.2011, 13:48
хедер:
ushort build
byte[40] sessionKey

чанк:
byte direction
uint unixTime
uint tickCount
uint size
uint opcode (direction == Direction.Client) ? uint : ushort;
byte[] data (size - (direction == Direction.Client) ? 4 : 2;

LordJZ
24.04.2011, 16:22
у кого нить есть готовый конвертор PKT 2.1 -> PKT 3.0?У меня в сниффере есть встроенный конвертор из любого в любой (почти) формат, если кому-то сильно надо, могу вырезать и выложить как отдельный .ехе.

RomanRom2
24.04.2011, 19:30
а конвертните мне примерчик плиз, что я выложил, что б было с чем сравнивать?

LordJZ
24.04.2011, 20:10
а конвертните мне примерчик плиз, что я выложил, что б было с чем сравнивать?Не понял, но все равно конвертнул в PKT 3.0 http://dl.dropbox.com/u/9241118/romanrompkt.rar

RomanRom2
24.04.2011, 20:24
все правильно сделал (с)
спасибо :)
я свой конвертор дописываю. когда есть пример - оно проще мне. я вообще люблю, знаете ли, по примерам обучаться.

Йоха
06.05.2011, 14:18
Вот и возник косячок, как я понял снифер или конвертер от LordJZ в поле версия пишет байты в другом порядке: 03 00
А в описании формата вроде как написано что надо писать 00 03.
Мой вьювер проверяет заголовок снифа и если что-то не совпадает, то файл не обрабатывается.
В частности проверяется сигнатура и версия.

RomanRom2
06.05.2011, 14:27
сначала должен быть записан младший байт, потом старший. в "3.0" 3 это старший, 0 - младший. при чтении word или (ushort или как там в си?) дожно быть число $0300 (0x0300).

LordJZ
06.05.2011, 14:28
Вот и возник косячок, как я понял снифер или конвертер от LordJZ в поле версия пишет байты в другом порядке: 03 00
А в описании формата вроде как написано что надо писать 00 03.
Мой вьювер проверяет заголовок снифа и если что-то не совпадает, то файл не обрабатывается.
В частности проверяется сигнатура и версия.Где это у меня такое? В выложенном выше архиве всё верно.

RomanRom2
06.05.2011, 14:29
http://ru-mangos.ru/showpost.php?p=11523&postcount=84

Йоха
06.05.2011, 14:34
сначала должен быть записан младший байт, потом старший. в "3.0" 3 это старший, 0 - младший. при чтении word или (ushort или как там в си?) дожно быть число $0300 (0x0300).

значит надо исправить тему, там явно написано:
// 0x00, 0x03

как это можно по другому понимать ? Для чего вообще это поле сделали byte[2], надо было сделать ushort и вопросов бы не возникало

RomanRom2
06.05.2011, 14:41
в теме все правильно написано. сначала младший, потом старший байты. соответственно 00, затем 03.

Йоха
06.05.2011, 14:42
ну так а почему в файле lich.pkt порядок байт другой
0000000000: 50 4B 54 03 00 0D 37 35 │ 00 00 72 75 52 55 00 00 PKT♥ ♪75 ruRU

Если это не конвертер от LordJZ, то сори, я лично обвинить тебя не хотел, просто подумал что это твоим конвертером сделан файл. Там в коментариях что-то мелькает насчет конвертера из izi в pkt.
Тогда претензии к автору этого снифа

http://ru-mangos.ru/showpost.php?p=21601&postcount=6

Вроде это Lordronn выкладывал, исправляй свой снифер или конвертер.

RomanRom2
06.05.2011, 14:57
не знаю почему Lordronn запутался в двух байтах =) в спецификации четко написано каков должен быть порядок байт.

Lordronn
06.05.2011, 15:49
Эм, я вообще не LordJZ-им конвертором конвертил. Я конвертировал с помощью IZI2PKT, только он у меня изменен.
С байтами не я запутался, а автор тулзы, а я проглядел)

RomanRom2
12.05.2011, 02:32
Не понял, но все равно конвертнул в PKT 3.0 http://dl.dropbox.com/u/9241118/romanrompkt.rar
наконец то написал свои конверторы pkt2-to-pkt3 и обратно, проверьте.
http://filebeam.com/dae73f8446073dada011b4120249b374

в приведенном выше LordJZ сниффе к каждому чанку добавлена optData длиной в два байта и содержащая два нуля. можно поинтересоваться зачем? =)

LordJZ
12.05.2011, 11:43
...
в приведенном выше LordJZ сниффе к каждому чанку добавлена optData длиной в два байта и содержащая два нуля. можно поинтересоваться зачем? =)Это «мои» данные, забыл поставить проверку на их запись при неправильном SnifferId. А данных в исходном дампе не было, поэтому писал нули. Поправлю у себя. :)

RomanRom2
19.05.2011, 12:41
прошу любить и жаловать, версия 3.1 - поддержка нескольких соединений в одном файле.

Редакция от 19 мая 2011, 14:00


1. RAW.

1.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'RAW'.
byte version[2]; // 0x01, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40];
uint unixTime;
uint tickCount;
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

1.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint connectionID;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;


2. PKT.

2.1. заголовок снифа.
struct MainHeader
{
char signature[3]; // 'PKT'
byte version[2]; // 0x01, 0x03
byte snifferID;
uint build;
char language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
byte sessionKey[40]; // может быть заполнено нулями
uint unixTime;
uint tickCount;
uint optionalHeaderLength;
};
byte[optionalHeaderLength] optionalData;

2.2. чанк
struct ChunkHeader
{
char direction[4]; // 'SMSG', 'CMSG'
uint connectionID;
uint tickCount;
uint optionalDataLength;
uint dataLength;
};
byte[optionalDataLength] optionalData;
byte[dataLength] data;
, где
- data включает в себя Opcode, выравненный до uint
- dataLength равен размеру data
- connectionID - любые числа на усмотрение разработчика, можно использовать socketID, можно автоинкремент. Важно что бы пакеты одной сессии можно было отличить от пакетов другой.


3. Имя файла.

3.1. имя файла
имя может быть произвольным и удобным каждому из разработчиков.

3.2. расширение файла
обязательно .raw или .pkt



Список ревьюверов тот же:
- Konctantin:
- LordJZ: accepted
- TOM_RUS:
- RomanRom2: accepted
- VDm:
- Deamon:
- Nomad:
- abdula123:
- user456:
- Aven:
- йоха:

ревью до 19 июня 2011г.

Йоха
19.05.2011, 13:39
я бы поле uint unixTime; перенес из хидера чанка в мейн хидер. Начальное время берется из хидера, а потом есть тиккаунт

И еще предлагаю opcode вынести из data в чанк хидер, а в data хранить чистые данные пакета

Lordronn
19.05.2011, 13:48
1.Я бы использовал 1 байт для connectionId, ибо ну не верю я, что будет более 255 соеденений, с которых можно будет получить интересное нам
2.tickCount - не понимаю зачем он вообще.
3.
Я бы изменил порядок на такой:

uint optionalDataLength;
uint dataLength;
byte[dataLength] data;
uint optionalDataLength;
byte[optionalDataLength] optionalData;

LordJZ
19.05.2011, 15:59
1.Я бы использовал 1 байт для connectionId, ибо ну не верю я, что будет более 255 соеденений, с которых можно будет получить интересное нам
...Это не индекс, это уникальный номер. Нулевое (которое закрывается сразу после открытия), первое (Home сервер), второе (World сервер 1 при входе в мир), третье (World сервер 2 при смене карты). Возможно, 4 байта под это много. Но где-то здесь (http://ru-mangos.ru/showthread.php?p=22657#post22657) проскакивала мысль про Socket Handle, в теории он может быть > 0xFFFF.Я бы изменил порядок на такой:Против.я бы поле uint unixTime; перенес из хидера чанка в мейн хидер. Начальное время берется из хидера, а потом есть тиккаунтУ меня тоже были мысли на эту тему, но в таком случае получается нелегким (точнее, небыстрым) вычисление времени для какого-то отдельного взятого пакета.[/quote]И еще предлагаю opcode вынести из data в чанк хидер, а в data хранить чистые данные пакета Вот здесь я «за». Еще можно сделать размер в 2 байта. ) Но не много ли изменений для 3.1 ?

RomanRom2
19.05.2011, 17:22
возможно вы правы, время для чанка может и не нужно, сейчас вспоминаю, когда и зачем оно было нужно... и не припоминаю. тем более в прошлый раз мы это тоже обсуждали. время чанка вычисляется одним сложением времени снифа и тиккаунта чанка. тиккаунт чанка - очень нужный параметр. можно сказать фундаментальная основа снифа. есть такие, кто этого не понимает?

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

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

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

в связи с вышесказанным есть предложение заменить unixDateTime на ConnectionID. вот и все изменения для 3.1

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

Йоха
19.05.2011, 18:07
против вынесения опкода из данных. опкод - это часть данных, это заголовок пакета. хидер чанка - это протольные поля, никакого отношения к данным не имеющие. не нужно их мешать, как например tcp с эзернетом. делать их 2 или 4 байта - без разницы, т.к. либо тот либо тот все равно придется выравнивать до выбранной размерности.


ну неудобно просто за опкодом лезть в данные ... Какой смысл хранить его там? кроме религиозных мотивов

меня бесит вот такое уродство в коде:

int opcode = *(int *)(m_Index[nIndex] + sizeof(PKT_CHUNK) + chunk->optionalDataLength);


а то как бы было красиво:

int opcode = chunk->opcode



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


это все фигня, выравнивание данных замечательно управляется из кода
у меня это структуры объявлены так:
#pragma pack(push, 1)

struct PKT_HEADER
{
BYTE signature[3]; // 'PKT'
BYTE version[2]; // 0x00, 0x03
BYTE snifferID;
DWORD build;
BYTE language[4]; // Язык клиента: 'ruRU', 'enGB' и т.д.
BYTE sessionKey[40]; // может быть заполнено нулями
DWORD optionalHeaderLength;
};

struct PKT_CHUNK
{
union
{
BYTE b[4]; // 'SMSG', 'CMSG'
DWORD d;
} direction;
DWORD unixTime;
DWORD tickCount;
DWORD optionalDataLength;
DWORD dataLength;
};

#pragma pack(pop)

Lordronn
19.05.2011, 18:11
Ну в разных языках\способах все выглядит по разному. У меня это вот так

byte[] optionalData = reader.ReadBytes(optionalDataLength);
byte[] data = reader.ReadBytes(dataLength);

using (BinaryReader binReader = new BinaryReader(new MemoryStream(data)))
{
uint opcode = binReader.ReadUInt32();
byte[] byteData = binReader.ReadBytes((int) (binReader.BaseStream.Length - 4));
packets.Add(new Packet(direction, (Opcode) opcode, byteData, unixTime, tickCount));
}

HuntsMan
19.05.2011, 18:30
Думаю для pkt все же удобнее было бы вынести опкод в отдельное поле, т.к. мы рассматриваем WoW Packet, а не TCP Packet. В остальном полностью согласен.

alien
19.05.2011, 18:45
это все фигня, выравнивание данных замечательно управляется из кода
у меня это структуры объявлены так:
#pragma pack(push, 1)
Угу только #pragma pack не стандарт а пошло из MS Studio и поддерживается не всеми компиляторами )

Йоха
19.05.2011, 19:37
Угу только #pragma pack не стандарт а пошло из MS Studio и поддерживается не всеми компиляторами )

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

alien
19.05.2011, 19:47
Есть но не все поддерживают прагму)

Йоха
19.05.2011, 20:16
при чем тут прагма ? речь идет о возможности как таковой, а не о том какие компиляторы как эту возможность реализуют

Я привел пример с прагмой потому что пишу на VC++, остальные могут почитать документацию к своему комплятору

LordJZ
19.05.2011, 20:21
возможно вы правы, время для чанка может и не нужно, сейчас вспоминаю, когда и зачем оно было нужно... и не припоминаю. тем более в прошлый раз мы это тоже обсуждали. время чанка вычисляется одним сложением времени снифа и тиккаунта чанка. тиккаунт чанка - очень нужный параметр. можно сказать фундаментальная основа снифа. есть такие, кто этого не понимает?Ага, понял свою ошибку....
в связи с вышесказанным есть предложение заменить unixDateTime на ConnectionID. вот и все изменения для 3.1
Вот это уже совсем хорошо. )

Добавлено через 2 минуты
...
меня бесит вот такое уродство в коде:

int opcode = *(int *)(m_Index[nIndex] + sizeof(PKT_CHUNK) + chunk->optionalDataLength);


а то как бы было красиво:

int opcode = chunk->opcode

...Дак создайте аксессор:int getOpcode()
{
return *(int *)(m_Index[nIndex] + sizeof(PKT_CHUNK) + this->optionalDataLength);
}И тогда:int opcode = chunk->getOpcode();

Добавлено:

Прошу прощения, не стерпел, сделал обработчик PKT 3.1, заодно переделал у себя алгоритм чтения.
PKT 3.1 превью номер 0, версия 19 мая, присутствуют Connection Id, Unix и Ticks в основном заголовке (файл был действительно создан 14 апреля), Opt Data во всех заголовках: http://dl.dropbox.com/u/9241118/PKT_3.1_Preview_0.pkt (файл «искусственный», т.е. конвертированный из PKT 3.0 в PKT 3.1)

LordJZ
13.07.2011, 10:30
Со времен 19 июня 2011 прошло уже почти 3 недели. Отзывов что-то не сильно видно. :/

RomanRom2
13.07.2011, 11:50
ну как не видно... вон сколько понаписали в коменты.
вот краткая выдержка:

1. размер connectionId 1 байт
2. убрать tickCount
3. изменить порядок
4. убрать unixTime из чанка
5. вынести opcode из данных в чанк

мои коменты по пунктам:
1. против. нужно оставить 4 байта.
2. категорически против. все понимают почему?
3. против. текущий порядок идеологически правильный. нужно подробно объяснять?
4. согласен. оставлен unixTime снифа.
5. категорически против. уже объяснял выше.

virusav
13.07.2011, 11:53
Последний пост 19.05.2011, 21:21, а это май.:)

RomanRom2
13.07.2011, 11:57
имелось ввиду, что месячное ревью закончилось.

LordJZ
13.07.2011, 13:49
ну как не видно... вон сколько понаписали в коменты.
вот краткая выдержка:

1. размер connectionId 1 байт
2. убрать tickCount
3. изменить порядок
4. убрать unixTime из чанка
5. вынести opcode из данных в чанк

мои коменты по пунктам:
1. против. нужно оставить 4 байта.
2. категорически против. все понимают почему?
3. против. текущий порядок идеологически правильный. нужно подробно объяснять?
4. согласен. оставлен unixTime снифа.
5. категорически против. уже объяснял выше.Поддерживаю это, структура в соответствии: http://ru-mangos.ru/showpost.php?p=22660&postcount=147

RomanRom2
31.07.2011, 12:14
итак, пора подводить итоги.
спецификация 3.1 принята, с чем всех и поздравляю.

что то нас на форматы к концу июля постоянно тянет =)

HuntsMan
06.08.2011, 19:19
В первом посте обновление будет?

RomanRom2
06.08.2011, 22:35
обновил.

LordJZ
06.08.2011, 23:17
обновил.Эм, кажется вы забыли в основном заголовке добавить новые поля.

RomanRom2
07.08.2011, 06:45
Эм, кажется вы забыли в основном заголовке добавить новые поля.
ммм, да да да... спасибо.

Chameleon
07.08.2011, 09:59
Эм, кажется вы забыли в основном заголовке добавить новые поля.
А так же версию с 0x00, 0x03 на 0x01, 0x03.

RomanRom2
07.08.2011, 21:25
что ж такое... еще не проснулся видать =)
поправил.