PDA

Просмотр полной версии : Сниффер


Страницы : [1] 2

xmolex
23.03.2010, 08:53
Кто знает сниффер под 3.3.2. Поискал по интернету, что-то не густо.

Deamon
23.03.2010, 10:43
А их никогда и не будет густо. Так уж сложилось традициями, что все сниферы под ВоВ всегда держатся в привате.

А после того, как близы перешли на RC4, снифить траффик можно только собрав session_key откуда либо. Прокси сейчас не работают из-за BN2 протокола, остались только инъекторы.

Dereka
23.03.2010, 10:47
http://github.com/arrai/tiawps смотри

Deamon
23.03.2010, 11:00
http://github.com/arrai/tiawps смотри

Хм... Интересный вариант, в принципе можно и так.

abdula123
29.03.2010, 16:56
прокси как работали, так и работают. просто приходится зарыться немного поглубже. :)

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

Konctantin
29.03.2010, 17:11
прокси как работали, так и работают. просто приходится зарыться немного поглубже.
А как же аутентификация?

Neverdie
29.03.2010, 18:09
прокси как работали, так и работают. просто приходится зарыться немного поглубже. :)

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

поделитесь тайной прохода аутентификации

abdula123
31.03.2010, 01:34
поделитесь тайной прохода аутентификации

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

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




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

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

Neverdie
31.03.2010, 10:24
а нету никакой тайны. клиент аутентифициуется на близовском сервере обычным порядком.

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




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

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

покамись юзаем tiawps

Neverdie
20.04.2010, 21:56
столкнулись с проблемой при использования метода tiawps
при попытки перевести дамп в читаемый вид
получаем файл с одним и темже размером

и рветца наче тут

CLIENT:
LENGTH: 10
OPCODE: 0510
DATA:
00 08 10 05 00 00 0A 00 00 00


SERVER:
LENGTH: 8
OPCODE: 050F
DATA:
00 06 0F 05 0A 00 00 00

неможем покамись определить

[13:00] <Kosuha> но мне кажеться чтото с
[13:00] <Kosuha> case 1293:
[13:00] <Kosuha> forwarding connection
[13:01] <Kosuha> какойто
[13:01] <Kosuha> попался

вопрос собетсвенно такой
кто нить юзает тивапс и работает ли нормально у вас ?
а то 1 в 1 струткура вот сидим думаем ктог лючит мы или тивапс

Konctantin
20.04.2010, 22:02
Я раз пробовал, еще когда была версия 332 - получилось.
Но он мне показался сильно геморным и я забил :(

Кстати, а никто не пробовал заюзать мелкософтовский net monitor, у них там даже API имеется?

Neverdie
20.04.2010, 22:07
да на 33,2 и у нас то работало
а вот с 3,3,3 фигня какая то
просто мало рук чтоб вникать

Konctantin
20.04.2010, 22:18
ну с портами там и хостами беда прыгают как зайчики, это раз
и 2 даже если поймаешь порт и хост, то иногда какого-то черта получает пакет 3 по счету после коннекта, который не декриптуется

LENGTH: 65536
OPCODE: 0000
DATA: 00 00 00 00

не стал пока разбираться, чего-то нету желания

Neverdie
20.04.2010, 22:21
да был такой
пакет
и еще могло почему-то выйти 2 дампа сразу
1 стандартно а 2 громадный

Konctantin
20.04.2010, 22:25
1 стандартно а 2 громадный
из-за смены портов

abdula123
21.04.2010, 17:47
да на 33,2 и у нас то работало
а вот с 3,3,3 фигня какая то
просто мало рук чтоб вникать

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

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

в 3.3.3(без а) был такой баг - первое соединение не закрывалось, хотя объекты, с ним связанные удалялись. в (а) уже исправили, вроде-бы.


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


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

RomanRom2
21.04.2010, 21:42
если взять и исключить из потока этот пакет (моя прокся такие издевательства позволяет) - то клиент так и будет работать в одно соединение (второе-то не согласовано). минуты 3 где-то, потом сервер кикнет.
прокся умеет вклиниваться в трафик с циклическим ключем? или прокся самостоятельно устанавливает соединение и с сервером со своим ключем и с клиентом со своим ключем? :acute:

Konctantin
21.04.2010, 21:48
Как вычислить этот пакет? я не могу его поймать. Сидел со сниффером пол часа так и не понял как его определить.

abdula123
22.04.2010, 15:17
прокся умеет вклиниваться в трафик с циклическим ключем? или прокся самостоятельно устанавливает соединение и с сервером со своим ключем и с клиентом со своим ключем? :acute:

размеры/заголовки пакетов XORятся потоком байт, генерируемых RC4. а этот поток назвать цикличным язык как-то не поворачивается :)

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


так что приходится поддерживать 4 rc4-состояния - на каждое направление с каждой стороны. инициализировать их из данных клиента и все до единого пакеты пропускать через них.

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



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


Как вычислить этот пакет? я не могу его поймать. Сидел со сниффером пол часа так и не понял как его определить.

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

опкод - 1293.


[S2C] SMSG_SECOND_CONNECTION (1293 = 0x050D) len: 30
ip : 62.67.45.65
port : 6112
unk1 : 6
digest : 11ae18435c2a504058d60ed647df65bc09d23248

...после того, как второе соединение будет установлено должным образом...

[S2C] SMSG_SWITCH_TO_SECOND (1295 = 0x050F) len: 4
seq : 10

[C2S] CMSG_SESSION_SWITCHED (1296 = 0x0510) len: 4
seq : 10

[S2C] SMSG_SWITCH_ENCRYPTION (1297 = 0x0511) len: 0


последний приходит уже во второе соединение.

RomanRom2
22.04.2010, 16:07
размеры/заголовки пакетов XORятся потоком байт, генерируемых RC4. а этот поток назвать цикличным язык как-то не поворачивается :)

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

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

да, кстати, у вардена свое шифрование со своими ключами, независимое от сессионного.
:yes3:

abdula123
23.04.2010, 07:50
только так и можно это организовать. плавали, знаем. именно по этому принципу работал наш сканер респонсов :secret:
:yes3:

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

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

а вот если хочется их редактировать на лету - таким способом это делать ну очерь извратно.

Neverdie
23.04.2010, 08:54
ну поняно
против лома нету приему если нет другого лома
менячто поражает больше
чем мудрее близы защиту делают тем сильнее их ломают

abdula123
23.04.2010, 09:35
ну поняно
против лома нету приему если нет другого лома
менячто поражает больше
чем мудрее близы защиту делают тем сильнее их ломают

близы в плане защиты очень ленивые. ОЧЕНЬ, ОЧЕНЬ ленивые.

к тому-же им пофиг на всё, кроме массового макро\ботоводства.

Neverdie
23.04.2010, 10:04
близы в плане защиты очень ленивые. ОЧЕНЬ, ОЧЕНЬ ленивые.

к тому-же им пофиг на всё, кроме массового макро\ботоводства.

черный пиар всегда был дешевой рекламой

Konctantin
23.04.2010, 19:05
а если б не сменили систему аутентификации, не так бы интересно было :)

Konctantin
31.05.2010, 21:26
Мы тут с LordJZ начали делать сниффер, но наткнулись на неприятность:
При логине и пока стоим на окне выбора персонажей пакеты декриптуются нормально
Вот лог сниффера:

World server address: 62.67.45.123:3724
Connected to 62.67.45.123:3724
SERVER: Header = 44 Packet = 44 OK Opcode: SMSG_AUTH_CHALLENGE
Session Key: 6250DC798DDEA48A01102CE9B7EA33060D425E42DC2145E047 7FBEC637F1287C00EAC7B10B54B3BB
CLIENT: Header = 278 Packet = 278 OK Opcode: CMSG_AUTH_SESSION
SERVER: Header = 15 Packet = 15 OK Opcode: SMSG_AUTH_RESPONSE
SERVER: Header = 192 Packet = 270 REUSE Opcode: SMSG_ADDON_INFO
SERVER: Header = 8 Packet = 78 REUSE Opcode: SMSG_CLIENTCACHE_VERSION
SERVER: Header = 36 Packet = 70 REUSE Opcode: SMSG_TUTORIAL_FLAGS
Redirect to 62.67.45.165:1119
SERVER: Header = 34 Packet = 34 OK Opcode: SMSG_REDIRECT_CLIENT
Connected to 62.67.45.165:1119
SERVER: Header = 44 Packet = 44 OK Opcode: SMSG_AUTH_CHALLENGE
Session Key: 6250DC798DDEA48A01102CE9B7EA33060D425E42DC2145E047 7FBEC637F1287C00EAC7B10B54B3BB
CLIENT: Header = 46 Packet = 46 OK Opcode: CMSG_REDIRECTION_AUTH_PROOF
SERVER: Header = 4 Packet = 4 OK Opcode: SMSG_FORCE_SEND_QUEUED_PACKETS
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_READY_FOR_ACCOUNT_DATA_TIMES
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_CHAR_ENUM
CLIENT: Header = 10 Packet = 10 OK Opcode: CMSG_REALM_SPLIT
SERVER: Header = 25 Packet = 25 OK Opcode: SMSG_ACCOUNT_DATA_TIMES
SERVER: Header = 291 Packet = 312 REUSE Opcode: SMSG_CHAR_ENUM
SERVER: Header = 21 Packet = 21 OK Opcode: SMSG_REALM_SPLIT
SERVER: Header = 41 Packet = 41 OK Opcode: SMSG_WARDEN_DATA

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

CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_PLAYER_LOGIN
SERVER: Header = 25 Packet = 25 OK Opcode: SMSG_ACCOUNT_DATA_TIMES
SERVER: Header = 36 Packet = 1460 REUSE Opcode: SMSG_TUTORIAL_FLAGS
SERVER: Header = 16 Packet = 1424 REUSE Opcode: MSG_SET_DUNGEON_DIFFICULTY
SERVER: Header = 24 Packet = 1408 REUSE Opcode: SMSG_LOGIN_VERIFY_WORLD
SERVER: Header = 29 Packet = 1384 REUSE Opcode: SMSG_ACCOUNT_DATA_TIMES
SERVER: Header = 6 Packet = 1355 REUSE Opcode: SMSG_FEATURE_SYSTEM_STATUS
SERVER: Header = 293 Packet = 1349 REUSE Opcode: SMSG_MOTD
SERVER: Header = 12 Packet = 1056 REUSE Opcode: SMSG_LEARNED_DANCE_MOVES
SERVER: Header = 12 Packet = 1044 REUSE Opcode: SMSG_CONTACT_LIST
SERVER: Header = 24 Packet = 1032 REUSE Opcode: SMSG_BINDPOINTUPDATE
SERVER: Header = 9 Packet = 1008 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 999 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 990 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 981 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 972 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 963 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 954 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 945 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 936 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 927 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 25 Packet = 918 REUSE Opcode: SMSG_TALENTS_INFO
SERVER: Header = 12 Packet = 893 REUSE Opcode: SMSG_INSTANCE_DIFFICULTY
SERVER: Header = 9 Packet = 881 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 9 Packet = 872 REUSE Opcode: SMSG_SET_PROFICIENCY
SERVER: Header = 285 Packet = 863 REUSE Opcode: SMSG_INITIAL_SPELLS
SERVER: Header = 8 Packet = 578 REUSE Opcode: SMSG_SEND_UNLEARN_SPELLS
ERROR: SERVER Size = 581 > packet.Length = 570
ERROR: SERVER Size = 27961 > packet.Length = 1460
ERROR: SERVER Size = 46186 > packet.Length = 1460
ERROR: SERVER Size = 27772 > packet.Length = 1355
CLIENT: Header = 7 Packet = 7 OK Opcode: CMSG_PLAYED_TIME
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_NAME_QUERY
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_SET_ACTIVE_MOVER
CLIENT: Header = 7 Packet = 7 OK Opcode: CMSG_SET_ACTIONBAR_TOGGLES
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_REQUEST_RAID_INFO
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_GMTICKET_GETTICKET
ERROR: SERVER Size = 34578 > packet.Length = 118
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_QUERY_TIME
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_QUEST_POI_QUERY
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_MEETINGSTONE_INFO
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_LFD_PLAYER_LOCK_INFO_REQUEST
CLIENT: Header = 6 Packet = 6 OK Opcode: MSG_GUILD_BANK_MONEY_WITHDRAWN
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_CALENDAR_GET_NUM_PENDING
CLIENT: Header = 8 Packet = 8 OK Opcode:
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_QUESTGIVER_STATUS_QUERY
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_NAME_QUERY
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_TIME_SYNC_RESP
CLIENT: Header = 42 Packet = 42 OK Opcode: MSG_MOVE_FALL_LAND
CLIENT: Header = 10 Packet = 10 OK Opcode: CMSG_ZONEUPDATE
CLIENT: Header = 43 Packet = 43 OK Opcode: CMSG_JOIN_CHANNEL
CLIENT: Header = 49 Packet = 49 OK Opcode: CMSG_JOIN_CHANNEL
CLIENT: Header = 47 Packet = 47 OK Opcode: CMSG_JOIN_CHANNEL
CLIENT: Header = 43 Packet = 43 OK Opcode: CMSG_JOIN_CHANNEL
CLIENT: Header = 47 Packet = 47 OK Opcode: CMSG_JOIN_CHANNEL
CLIENT: Header = 6 Packet = 6 OK Opcode: CMSG_WORLD_STATE_UI_TIMER_UPDATE
ERROR: SERVER Size = 44279 > packet.Length = 29
ERROR: SERVER Size = 7350 > packet.Length = 1460
ERROR: SERVER Size = 61367 > packet.Length = 649
ERROR: SERVER Size = 31772 > packet.Length = 62
ERROR: SERVER Size = 21770 > packet.Length = 388
ERROR: SERVER Size = 12076 > packet.Length = 54
ERROR: SERVER Size = 10025 > packet.Length = 108
ERROR: SERVER Size = 50091 > packet.Length = 62
ERROR: SERVER Size = 41905 > packet.Length = 61
ERROR: SERVER Size = 20541 > packet.Length = 66
ERROR: SERVER Size = 26947 > packet.Length = 54
ERROR: SERVER Size = 15250 > packet.Length = 66
ERROR: SERVER Size = 13283 > packet.Length = 147
ERROR: SERVER Size = 5655 > packet.Length = 170
ERROR: SERVER Size = 16965 > packet.Length = 54
ERROR: SERVER Size = 25301 > packet.Length = 62
ERROR: SERVER Size = 39797 > packet.Length = 62
ERROR: SERVER Size = 12419 > packet.Length = 54
CLIENT: Header = 32 Packet = 32 OK Opcode: CMSG_WARDEN_DATA
ERROR: SERVER Size = 18762 > packet.Length = 439
ERROR: SERVER Size = 9091 > packet.Length = 159
ERROR: SERVER Size = 32369 > packet.Length = 120
CLIENT: Header = 42 Packet = 42 OK Opcode: MSG_MOVE_SET_FACING
CLIENT: Header = 42 Packet = 42 OK Opcode: MSG_MOVE_START_FORWARD
ERROR: SERVER Size = 37437 > packet.Length = 5
CLIENT: Header = 42 Packet = 42 OK Opcode: MSG_MOVE_STOP
ERROR: SERVER Size = 11046 > packet.Length = 54
ERROR: SERVER Size = 59547 > packet.Length = 54
ERROR: SERVER Size = 32659 > packet.Length = 120
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_SET_SELECTION
CLIENT: Header = 14 Packet = 14 OK Opcode: CMSG_QUESTGIVER_HELLO
ERROR: SERVER Size = 23216 > packet.Length = 54
ERROR: SERVER Size = 12149 > packet.Length = 295
ERROR: SERVER Size = 25893 > packet.Length = 42


Сама функция которая обрабатывает пакеты:

private static void ProcessWorldPacket(byte[] data, Direction direction)
{
int i = 0, size = 0, opcode = 0;
int HEADER_LENGTH = 4;

bool isLarge = data.Length > 0x7FFF;
HEADER_LENGTH += (isLarge ? 1 : 0);

if (direction == Direction.SERVER)
{
Crypt.DecryptServer(data, HEADER_LENGTH);
}
else
{
HEADER_LENGTH += 2;
Crypt.DecryptClient(data, HEADER_LENGTH);
}

if (isLarge)
size = data[i++] & 0x7F;

size = (size << 8) | data[i++];
size = (size << 8) | data[i++];

for (int j = 0; j < HEADER_LENGTH - 2; j++)
opcode |= ((0xFF & data[i++]) << (8 * j));

size += 2;

if (size > data.Length)
{
Console.WriteLine("ERROR: {0} Size = {1} \t>\t packet.Length = {2}", direction, size, data.Length);
return;
}

using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))
{
reader.BaseStream.Position += HEADER_LENGTH;
byte[] newData = reader.ReadBytes(size - HEADER_LENGTH);

HandleWorldPacket((WorldOpcodes)opcode, newData);

Console.WriteLine("{0}:\tHeader = {1}\tPacket = {2}\t{3}\tOpcode: {4}", direction, size, data.Length, data.Length == size ? "OK" : "REUSE", (WorldOpcodes)opcode);

if (size < data.Length)
{
ProcessWorldPacket(reader.ReadBytes(data.Length - size), direction);
}
}
}


Подскажите, в чем загвоздка, или есть какой-то нюанс?

RomanRom2
31.05.2010, 22:38
похвально. pcap?
потерялась синхронизация на серверных опкодах. индексы уехали.

Konctantin
31.05.2010, 23:07
Да, pcap? а потом "поверху" SharpPcap.

потерялась синхронизация на серверных опкодах. индексы уехали.
А можно по подробнее, как за ними уследить?

TOM_RUS
31.05.2010, 23:34
А помоему некорректно определяются large пакеты...

// check for large packet
if ((m_buffer[index] & 0x80) != 0)
{
...
}

RomanRom2
01.06.2010, 01:53
а очень просто. я даже сейчас объясню где багу ловите.

итак, вы входите в мир. попёрло много пакетов. и больших пакетов. что это означает?

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

тут то все и происходит :) в следующей пачке данных вы считаете, что пришел новый пакет и начинаете декриптовать, тут индексы и съезжают.

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

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

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

ну и если вам вдруг будет все равно в каком формате записывать, хотел бы предложить разработанный нами формат raw (http://wowcore.ru/?ID=5&forum=1&mpage=1&theme=2cc20a5f46510cf19fac97a75f71f94e) - как раз для случая сбора трафика через pcap. если соберетесь - примеры снифов, утилит для декриптовки в pkt с исходниками и pktViewer (http://wowcore.ru/images/zPktViewer.png) - подарю.

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

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

abdula123
01.06.2010, 04:00
лишнее подтвердждение того, что прокси удобнее будет :)

Konctantin
01.06.2010, 09:58
Спасибо всем за советы и подсказки:
А помоему некорректно определяются large пакеты...
Да так и есть, щас переделаю:
http://github.com/arrai/tiawps/blob/master/src/decrypter/decrypt.c
Если я правильно понял с примера, то нужно дополнительно декриптовать еще 1 байт, или же сразу нужный размер.
private static void ProcessWorldPacket(byte[] data, Direction direction)
{
int i = 0, size = 0, opcode = 0;
bool isLarge = (data[i] & 0x80) != 0;
int HEADER_LENGTH = isLarge ? 4 : 5;

if (direction == Direction.SERVER)
{
Crypt.DecryptServer(data, 0, HEADER_LENGTH);
}
else
{
HEADER_LENGTH += 2;
Crypt.DecryptClient(data, 0, HEADER_LENGTH);
}

if (isLarge)
size = data[i++] & 0x7F;

size = (size << 8) | data[i++];
size = (size << 8) | data[i++];

for (int j = 0; j < HEADER_LENGTH - 2; j++)
opcode |= ((0xFF & data[i++]) << (8 * j));

size += (2 + (isLarge ? 1 : 0));

if (size > data.Length)
{
Console.WriteLine("ERROR: {0} Size = {1} > packet.Length = {2}", direction, size, data.Length);
return;
}

using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))
{
reader.BaseStream.Position += HEADER_LENGTH;
byte[] newData = reader.ReadBytes(size - HEADER_LENGTH);
HandleWorldPacket((WorldOpcodes)opcode, newData);

Console.WriteLine("{0}:\tHeader = {1}\tPacket = {2}\t{3}\tOpcode: {4}",
direction, size, data.Length, data.Length == size ? "OK" : "REUSE", (WorldOpcodes)opcode);

if (size < data.Length)
{
ProcessWorldPacket(reader.ReadBytes(data.Length - size), direction);
}
}
}
Но надо проверить, а это уже вечером.

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

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

ну и если вам вдруг будет все равно в каком формате записывать,
не все равно, формат ваш (pkt)

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

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

TOM_RUS
01.06.2010, 10:05
Сначала надо расшифровать, потом проверить на флаг 0x80, если он выставлен, расшифровать еще 1 байт... А вы сначала проверяете, а потом расшифровываете.

abdula123
01.06.2010, 15:30
А это как нож в горло, как видите пока не в силах сделать сниффер, а до прокси еще как до неба...

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


на самом деле всё гораздо проще.

в самом простейшем случае - использовать готовый LSP-редиректор (proxycap, например) для переброса всех соединений wow на свой сервер. всё.

никаких подмен в памяти, никаких собственных аутентификаций.

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

Сначала надо расшифровать, потом проверить на флаг 0x80, если он выставлен, расшифровать еще 1 байт... А вы сначала проверяете, а потом расшифровываете.

это баг нескоро бы всплыл.

единственное место где мне встречались large пакеты - это SMSG_COMPRESSED_UPDATE_OBJECT при телепорте (или логине, что по сути одно и то-же) в даларан, в час пик, когда там бегают толпы народа.
все данные по этим разодетым и сверкающим "объектам" близы почему-то отсылают одним большим пакетом.

пока кроме этого места я больше ни одного large пакета не видел.

Konctantin
01.06.2010, 16:06
единственная заморочка, которая там есть - это обработка второго соединения и ключей для него.
я так и не осилил ее - все эти новые сиды\хэши, осн.\доп. ключи и т.п. и

Ну на сколько я понимаю до редиректа используются статические сиды, потом, после редиректа, они приходят в пакете SMSG_AUTH_CHALLENGE и уже надо декриптовать пакеты используя эти сиды.

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

Или я чего-то недопонимаю!?

Я пробовал сначала написать прокси, сделал наброски, но потом все заглохло за неимением данных и неумением.

TOM_RUS
01.06.2010, 16:37
кроме этого места я больше ни одного large пакета не видел.


Список достижений тоже не маленький и приходит при каждом логине/телепорте.

abdula123
01.06.2010, 17:18
Список достижений тоже не маленький и приходит при каждом логине/телепорте.

у меня SMSG_ALL_ACHIEVEMENT_DATA - обычный пакет с 2хбайтовым размером.
наверное ачивок мало :)


[S2C] normal pkt, sz:27329, opcode:1149 (SMSG_ALL_ACHIEVEMENT_DATA)
...
[S2C] large pkt, sz:42257, opcode:502 (SMSG_COMPRESSED_UPDATE_OBJECT)



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

Или я чего-то недопонимаю!?

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

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

YuruY
01.06.2010, 17:21
Давно пора собраться и сделать один сниффер, всем вместе, и польза будет всем (хотябы делиться мыслями и помогать друг другу), сколько с Konctantin-ом работаю, он всегда старался для всех, от остальных этого не видел (но всем подряд его раздавать не стоит, чтобы не ...).
... просто мысль вслух. ;)

Neverdie
01.06.2010, 17:53
у меня SMSG_ALL_ACHIEVEMENT_DATA - обычный пакет с 2хбайтовым размером.
наверное ачивок мало :)






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

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

но теперь опять в ОПе -)

надежда опять на прокси

вот что нам не удалось просто после батлы

[11:18] <Kosuha> мне нужно всеголишь реалм лист
[11:18] <Kosuha> перекинуть
[11:18] <Kosuha> т.е. это стадия логин сервера

[12:55] <Kosuha> будет работать в области логгера и прокси
[12:55] <Kosuha> там с прокси я бы щас бился
[12:55] <Kosuha> а выяснил
[12:55] <Kosuha> что изза ИП клиент полюбому рвёт коннект
[12:56] <Kosuha> и реалм лист подменяют как что прослушивая Winsock
[12:56] <Kosuha> я в эти дебри ещё никогда не лазил даже

рук не хватате уна спросто -)) остлись просто " у самовара я и моя бабка"

YuruY
01.06.2010, 18:20
рук не хватате уна спросто
Я и предложил вам объедениться, а не вариться в собственном соку. ;)

RomanRom2
01.06.2010, 18:25
прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.

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

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

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

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

.....
но всем подряд его раздавать не стоит, чтобы не ...
;)

Neverdie
01.06.2010, 18:41
Я и предложил вам объедениться, а не вариться в собственном соку. ;)

мыы уже с константином обсудили все и каг
авось из нас всех выйдет толк
а не сразу "баны" =))) не там написал и читай правила :censored: шучу -)

и с колидой тоже отписали всеровно в одной каше варимся:sorry:

Neverdie
01.06.2010, 18:43
прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.


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

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

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

наслышаны сами -)

"прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще."

хз хз против лома нету приема если нету другого лома

abdula123
01.06.2010, 19:04
прокси не будет работать с батлнетом, сколько не старайтесь. не тратьте время.
надо либо pcap, либо инжектор, либо lsp. pcap по проще.


pcap никогда проще не был. и не будет.

а под прокси мы наверное имеем в виду разные вещи.

если речь идет об L7 (http://en.wiktionary.org/wiki/OSI_layer_7)-прокси, который изображает для клиента близардовский сервер - то тут действительно ой. перспектив никаких не видно.

а если о жутком кадавре, который для LSP-редиректора выглядит как L4 (http://en.wiktionary.org/wiki/OSI_layer_4)-прокси (socks4/5), а по сути - реализует MITM-атаку. - то тут всё очень даже перспективно.

+ не нужно заморачиваться с реализацией LSP
+ не нужно заморачиваться с косяками сборки потока из пакетов. (4х потоков, точнее)
+ есть возмножность активно влиять на передаваемые данные. в том числе и данные, передаваемые варденом внутри дополнительного крипто-потока.
+ существенно меньший объем работ по реализации, в сравнении с pcap и своим lsp (насчет хуков - не уверен).
+ гораздо более легкая миграция на новые версии, по сравнению с хуками.

Konctantin
03.06.2010, 11:30
хм... заставить трафик ходить через указанный адрес. Читал про это в интернете...
есть возмножность активно влиять на передаваемые данные.
вот это уже очень интересно, получается:
декриптовать -> внести свою лепту -> обратно зашифровать и пускай идет дальше.

а если о жутком кадавре, который для LSP-редиректора выглядит как L4-прокси (socks4/5), а по сути - реализует MITM-атаку. - то тут всё очень даже перспективно.
Но очень смущает то, что нужно работать с WinAPI, тобиш мне как человеку незнающему толком С++ будет тяжело приаттачить необходимые либы и заставить их работать на себя, но это все решается с помощью гугда и танца с бубном.

Неясным осталось только то,
L4-прокси (socks4/5)
Не нашел внятного описания всему этому делу, и вообще-то хотелось узнать реализуемо ли это средствами С# (без написания отдельных длл-ок)?

Что-то чем дальше тем сложнее все становится.

abdula123
03.06.2010, 14:56
вот это уже очень интересно, получается:
декриптовать -> внести свою лепту -> обратно зашифровать и пускай идет дальше.


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


никуда не нужно зарываться.

1. идем на http://www.proxycap.com/download.html , скачиваем и устанавливаем этот "proxifier". (ну или любой другой по вкусу, они все практически одинаковые). ВСЁ!!! про LSP и связанные с ним заморочки можно забыть - эта программа занимается ими сама.

2. добавляем socks4 прокси с адресом 127.0.0.1:наш_порт.
добавляем правила "wow.exe перекидывать на этот прокси, остальное не трогать".

3. идем на http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol , читаем описание протокола. проще не придумать.
реализуем сервер этого счастья хоть на C#, хоть на чём угодно другом.

4. добавляем логику типа такой:


принять соединение
соединиться с запрашиваемым адресом
ответить ок
принять первые 4 байта данных от клиента
если 3-4 байты равны "\xed\x01"(SMSG_AUTH_SESSION) или "\x12\x05" (SMSG_AUTH_SECOND_SESSION):
значит в этом соединении идут интересующие нас данные и его нада обрабатывать
иначе:
просто и тупо прокидывать данные между клиентом и сервером (battle.net / запрос новостей и т.п.)


5. думаем на тему "а как обрабатывать параллельно 2 и более соединения". select или треды - в помощь.

6. прикидываем (ida в помощь) когда и где в памяти wow.exe образуются интересующие нас ключи и читаем их оттуда.



Неясным осталось только то,

Не нашел внятного описания всему этому делу, и вообще-то хотелось узнать реализуемо ли это средствами С# (без написания отдельных длл-ок)?


у меня весь прокси полностью написан на питоне, так что на C# тоже можно.


Что-то чем дальше тем сложнее все становится.

это только в начале, потом легче пойдет. :)

Konctantin
03.06.2010, 20:17
Спасибо, я вашем посте я получил почти все что меня интересовало.
Теперь, как немного освобожусь от роботы, попытаюсь все это дело реализовать.

Еще раз спасибо.

ЗЫ. Не вы случайно автор адской трупожерки?

zhenya
04.06.2010, 09:18
ЗЫ. Не вы случайно автор адской трупожерки?
именно он...

Neverdie
04.06.2010, 09:35
именно он...

гыы
тогда ему респект и уважуха :friends:

Konctantin
04.06.2010, 10:55
Вчера посидел немного, и сделал "прозрачный" прокси сервер,
С помощью проксификатора заставил клиент ходить через свой прокси.

Теперь вот как будет время, перенесу все наработки по снифферу в прокси.

Но, у меня такой вопрос:
пакеты будут приходить ферментированные?
ну скажем так: размер в заголовке 20 а длинна пакета 15, значить записать этот пакет в буффер и принять следующий пакет, объединить и обработать

abdula123
04.06.2010, 11:20
Но, у меня такой вопрос:
пакеты будут приходить ферментированные?
ну скажем так: размер в заголовке 20 а длинна пакета 15, значить записать этот пакет в буффер и принять следующий пакет, объединить и обработать

таки фрагментированные. ферментированное - пиво (и не только). :)

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

так что разбиение потока на пакеты делать обязательно.

Konctantin
04.06.2010, 12:07
несколько пакетов - вполне себе нормальное явление.
Ну это я уже почувствовал на своей шкуре.

Konctantin
12.06.2010, 21:14
Мдя, как не везет, так не везет, при логине клиентом говорит что готово, и ничего (доступен только список миров)

GriffonHeart
13.06.2010, 06:04
А я скучаю по временам адской трупожорки :(
Там всё так просто было и можно было снифить много-много чего. Сейчас, увы, такого удобного снифера нет :(

Konctantin
13.06.2010, 08:40
Ностальгия...
Мне вот интересно, кто-то уже реализовал проксю или сниффер, или все сделано только в теории?

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

Бывает такое, что загвоздка в том самом "да" или "нет", и требуется мизерная подсказка, но увы...

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

Максимум что у меня получилось, так это получения списка миров, дальше ничего не выходит :(

Выше я писал:

Вчера посидел немного, и сделал "прозрачный" прокси сервер,
С помощью проксификатора заставил клиент ходить через свой прокси.

А заходило потому, что перенаправил enUS клиент, а заходил enGB клиентом.
Так был рад, а оно оказалось лажа...

И все таки, надо по чуть чуть по изучать все это и сделать то, что задумал.

Konctantin
14.06.2010, 17:10
Давайте вернемся к нашим баранам и продолжим тему

ЗЫ. Естественно америку я не открою, но просто опишу суть.

В даном случае использован проксификатор, с правилами следуещего содержания:

Если приложение wow.exe соединяется с конечной точкой 213.248.127.130:1119,
тогда перенаправить его на 127.0.0.1:9998 (Login - сервер)
иначе если приложение wow.exe соеденяется (адресс не указан, тобиш 0.0.0.0:0),
тогда перенаправляем его на 127.0.0.1:9999 (World - сервер)

Значит, нам надо создать прокси, который бы создал 2 соединения, это соединение с клиентом и соединение с сервером:
* Соединение с клиентом, прокси выступает в качестве сервера и общается с клиентом
* Соединение с сервером, прокси выступает в качестве клиента и общается с сервером (Login - сервером)

но это все у нас пока процесс общения сервером авторизации. (213.248.127.130:1119)

Мы просто выступаем посредником и пересылаем пакеты при этом слушая их.

Но, клиент же должен подключится к World - серверу.
По этому, когда приходит пакет AUTH_REALM в котором приходит IPAdress:port сервера к которому надо подключится,
запоминаем этот IPAdress:port.

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

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

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

Далее, по скольку ввели новую систему распределения нагрузки World - сервер может прислать пакет, который указывает,
что нужно переподключится на новый World - сервер, и присылает данные:
1) SMSG_REDIRECT_CLIENT он присылает адрес нового сервера
2) SMSG_AUTH_CHALLENGE приходят новые сиды

Не знаю, может я что-то упустил, если так, то поправьте пожалуйста.

abdula123
15.06.2010, 17:32
Ностальгия...
Мне вот интересно, кто-то уже реализовал проксю или сниффер, или все сделано только в теории?


ну, как минимум, мой реализован и работает.

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



В даном случае использован проксификатор, с правилами следуещего содержания:

Если приложение wow.exe соединяется с конечной точкой 213.248.127.130:1119,
тогда перенаправить его на 127.0.0.1:9998 (Login - сервер)
иначе если приложение wow.exe соеденяется (адресс не указан, тобиш 0.0.0.0:0),
тогда перенаправляем его на 127.0.0.1:9999 (World - сервер)



лишние сложности.
у меня, например, нет разделения на login/world.
всё, что не начинается с нужного пакета - просто и тупо перекидывается без обработки. ну или можно на диск писать, если желание есть.


Значит, нам надо создать прокси, который бы создал 2 соединения, это соединение с клиентом и соединение с сервером:
* Соединение с клиентом, прокси выступает в качестве сервера и общается с клиентом
* Соединение с сервером, прокси выступает в качестве клиента и общается с сервером (Login - сервером)

но это все у нас пока процесс общения сервером авторизации. (213.248.127.130:1119)

Мы просто выступаем посредником и пересылаем пакеты при этом слушая их.

Но, клиент же должен подключится к World - серверу.
По этому, когда приходит пакет AUTH_REALM в котором приходит IPAdress:port сервера к которому надо подключится,
запоминаем этот IPAdress:port.



повторяю - лишние сложности!
для упрощения начать с такой конфигурации:

1. клиент у нас ровно одна штука, в начальный момент времени загружен, но не залогинен.

2. прокси запускается строго перед логином


в таком случае - какая разница, какой там адрес отдал клиенту сервер авторизации???
интересующее нас соединение, один черт, начнется с SMSG_AUTH_CHALLENGE
больше оно в нашем раскладе ни с чего начаться не может!

значит:
0. открываем (bind) сокет на нужном порту и ждем подключений (listen) от проксификатора

1. принимаем (accept) соединение от проксификатора

2. разбираем socks4 запрос, подключаемся (connect) к указанному адресу, отдаем проксификатору socks4-ответ "ОК"

3. тут я прошлый раз неправильно написал.
нужно делать так:
ждем, пока клиент что-нибудь пошлет, проверяем у этого "чего-нибудь" 3й+4й байты - и если они не равны опкоду CMSG_AUTH_SESSION (а не SMSG_AUTH_SESSION - такого опкода вообще нету) - забиваем на это соединение. ничего интересного тут не предвидится.
естественно продолжая прокидывать через него данные в обе стороны

5. если таки интересующие нас байты найдены - то ВЫВОДИМ НА КОНСОЛЬ МНОГО РАЗНОЦВЕТНЫХ БУКВ И РАДУЕМСЯ, ЧТО НАКОНЕЦ ЧТО-ТО ПОЛУЧИЛОСЬ.
пишем поток на диск (естественно каждое направление в свой файл. разделять на отдельные пакеты не нужно.)

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

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





вот так выглядит функция, занимающаяся пересылкой данных: http://paste2.org/p/878723 (шаги 2-3)

это, конечно, не C#, но представление дает :)

на yield не смотреть, они для реализации со-процедур (самопальной и весьма корявой, но "и так работает").

на read_session_key() и вытаскивания сидов из SMSG_AUTH_CHALLENGE не смотреть, она осталась со времен, когда по этим сидам я генерил крипто-состояния сам, а не читал их готовыми из памяти. не судьба убрать, "и так работает".

разбиение на пакеты, расшифровка пакетов, расшифровка вардена, логика, шифровка вардена, шифровка пакетов, сборка пакетов в поток - они все в WorldFilter

код коряв и страшен, как моя жизнь. однако "и так работает" :)))

Konctantin
15.06.2010, 22:21
меня просто в большей сложности смущает то, что нужно из одного потока разделять на на 2 потока, тобиш приходят пакеты которые должны идти на LoginServer и WorldServer но как их потом разделять, чтоб определить куда какой перенаправлять???

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

Просто я понимаю такую реализацию:
получаем соединение от клиента, и соединяемся с сервером: но, чтобы соединится с сервером, надо знать конечную точку. Тобиш работать в так званом клиент серверном режиме.

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

Черт, я еще больше запутался, или может это так пиво повлияло...

abdula123
16.06.2010, 05:47
меня просто в большей сложности смущает то, что нужно из одного потока разделять на на 2 потока, тобиш приходят пакеты которые должны идти на LoginServer и WorldServer но как их потом разделять, чтоб определить куда какой перенаправлять???


для начала - просто и тупо реализуй socks4-proxy, способный прокидывать через себя произвольное кол-во произвольных соединений параллельно.

просто прокси, без всякой специфики wow.


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

Konctantin
16.06.2010, 12:38
вот тут я и застрял, я не могу понять как прокси будет знать куда перебрасывать соединение, если в сокете, конечный адресс уже выглядит как localhost:port

abdula123
16.06.2010, 15:06
вот тут я и застрял, я не могу понять как прокси будет знать куда перебрасывать соединение, если в сокете, конечный адресс уже выглядит как localhost:port

http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol

читать до просветления.

Konctantin
16.06.2010, 18:40
Черт, биг сенкую. Наконец то мне дошло, в самом пакете все есть

+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
# of bytes: 1 1 2 4 variable 1


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

abdula123
16.06.2010, 20:21
А я скучаю по временам адской трупожорки :(
Там всё так просто было и можно было снифить много-много чего. Сейчас, увы, такого удобного снифера нет :(

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

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

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


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

RomanRom2
16.06.2010, 21:58
бот наверное имеется ввиду тот, который на запущенном и залогиненном клиенте кнопки нажимает и мышкой шевелит?

abdula123
17.06.2010, 04:13
бот наверное имеется ввиду тот, который на запущенном и залогиненном клиенте кнопки нажимает и мышкой шевелит?

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

тем самым имеющий практически полную информацию об окружении и действующий в соответствии с ней. :)

GriffonHeart
17.06.2010, 06:49
адская трупожорка переделывается (без потери функциональности) под нынешние реалии заменой 2х модулей и добавлением еще 2х - чтение из памяти и arc4. + почти без "бесплатно" по затратам времени добавляетя поддержка чтения\изменения вардена.

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

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


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

abdula123
17.06.2010, 16:26
Было бы не плохо увидеть нововведения в старой svn-ке... или завести новую :)


я пролюбил пароль от старого svn-репозитория. :)



кстати, а что случилось с Trac'ом проекта? почему он пускает незалогиненых, дает им доступ к коду. и не дает логиниться.

кагбе паблика не очень хочется.

UPD:
а, понятно, проклятые китайцы забили на opensvn


As the site is complety full, the code is very antiquated and buggy, and we just don't have the time to keep maintaining it, we have decided to shutdown this site on 2010/5/15.
Open source projects can consider migrating to SourceForge, Google Code, or any of the other free hosting services.

Update
We will provide read-only access until 2010/5/1. (As of 4/23 our disks are full.)
From 2010/5/1 till 2010/5/15, we will provide the ability to download your repository, either as a dump file, or as a tarball.

RomanRom2
19.06.2010, 02:12
решил тряхнуть стариной - переписал старый zLogger (который работает на pcap) на новый лад. следующую сессию видит и начинает новый снифф. пишет в raw, потом в оффлайне уже декриптую утилиткой. спасибо том_рус что подсказал где брать сиды для нового соединения.

Neverdie
19.06.2010, 22:17
Хех -)) запахло порохом ? ))
решили все тряхнуть стариной ? -)

RomanRom2
20.06.2010, 00:44
не. просто после затянувшегося перерыва я вернулся :)
пока вот в роли догоняющего.

user456
22.06.2010, 19:48
ну, как минимум, мой реализован и работает.

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

Ну просто мангосы живут какой-то своей жизнью и до сих пор вроде ни о чем не спрашивали. Я вот месяц без оффа, решил глянуть сервер в локалке (точнее задолбался с тем что инфа в UI клиента разбросана, а у меня не 8 глаз чтобы смотреть за кулдауном на кнопке внизу экрана, мобом в центре и аггро с дотами наверху, короче переделывал один аддон и учил Lua заодно). Так вот: я так понимаю везде стоит Мангос в локалках. Был страшно удивлен что мобы не тапятся (от tap). В то время как я уже делал это, нормальные gameobjects квестовые (те что видел все были активны, даже если некоторые собрал полностью, и оставались активны после квеста) и госсипы гардов табличные в summit (после того как ascent закрылся) еще пару лет назад под 2.4.

Так вот к нашим баранам: можно вообще делать под raw сокетами. Пакеты и правда могут приходить "всё в одном", с повторами, порезаные. Но логика сборки там простая. Я и такой сделал и он куда проще даже проксевого (с проксевым головняк лично у меня с критическими секциями, пока не отправлено надо ж что-то делать с новыми пакетами). У Ромки под PCap принцип тот-же, разве что ему влом пакеты собирать (какая-то у него либа проприетарно-тыреная этим занимается).

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

user456
23.06.2010, 00:24
Вот собсно raw сокеты в 2-х словах. Код на Дельфи, но винапи он и в Африке винапи. PChar соответственно в си char*. Элементарного типа WSAStartup не касаюсь.
Инициализация
//декларация обработки ивента
const
WM_ListenSocketEvent = WM_User+1;
....
procedure WMListenSocketEventHandler(var Msg:TMessage);message WM_ListenSocketEvent;

....

function TfrmMain.InitSocket: Boolean;
var
PromiscuousMode: dword;
temp: integer;
BufSize: dword;
begin
result:=false;
// создаем сокет
hSocket := socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if hSocket = INVALID_SOCKET then begin
DeInitSocket(WSAGetLastError);
AddToLog('Raw sockets not supported');
Exit;
end;
FillChar(Addr_in, SizeOf(sockaddr_in), 0);
Addr_in.sin_family:= AF_INET;
// указываем за каким интерфейсом будем следить
Addr_in.sin_addr.s_addr := inet_addr(PChar(Host));
// связываем сокет с локальным адресом
if ScktErrorCheck(bind(hSocket, @Addr_in, SizeOf(sockaddr_in))) = SOCKET_ERROR then exit;
BufSize:=MAX_PACKET_SIZE;
if ScktErrorCheck(SetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), sizeof(BufSize))) = SOCKET_ERROR then exit;
temp:=sizeof(integer);
if ScktErrorCheck(GetSockOpt(hSocket, SOL_SOCKET, SO_RCVBUF, PChar(@BufSize), temp)) = SOCKET_ERROR then exit
else AddToLog('Buffer size = '+IntToHex(BufSize,4));
if ScktErrorCheck(WSAAsyncSelect(hSocket,frmMain.Hand le,WM_ListenSocketEvent,FD_READ or FD_CLOSE)) = SOCKET_ERROR then exit;

// Переключаем интерфейс на прием всех пакетов проходящих через интерфейс - promiscuous mode.
PromiscuousMode := 1;
if ScktErrorCheck(ioctlsocket(hSocket, SIO_RCVALL, PromiscuousMode)) = SOCKET_ERROR then exit;
Result := True;
end;

обработчик ивента
procedure TfrmMain.WMListenSocketEventHandler(var Msg:TMessage);
var
Sock: TSocket;
SockError,PacketSize: integer;
begin
Sock:=TSocket(Msg.WParam);
SockError:=WSAGetSelectError(Msg.lParam);
if SockError <> 0 then begin
CloseSocket(Sock);
Exit;
end;
case WSAGetSelectEvent(Msg.lParam) of
FD_Read: begin
CS.Enter;
PacketSize := recv(hSocket, Packet, MAX_PACKET_SIZE, 0);
// Если есть данные - производим их разбор
ParcePacket(PacketSize);
CS.Leave;
end;
FD_Close: begin
AddToLog('FD_CLOSE');
end;
end;
end;

далее разбор пакета if PacketSize <= SizeOf(TIPHeader) then exit;

pIpHdr:=PIPHeader(@Packet[0]);
ipHdrLen:=GetIPHeaderLen(pIpHdr);
pTcpHdr:=PTCPHeader(@Packet[ipHdrLen]);
// определяем тип протокола
if pIpHdr.iph_protocol = IPPROTO_TCP then begin
PacketType := 'TCP';
// Смотрим порт отправителя и получателя
SrcPort := pTcpHdr.sourcePort;
DestPort := pTcpHdr.destinationPort;
end
else exit;

SrcPort := htons(SrcPort);
DestPort := htons(DestPort);
if (SrcPort <> frmMain.FListenPort)and(DestPort <> frmMain.FListenPort) then exit;

// Пишем IP адрес отправителя с портом
AddrSrc.S_addr := pIpHdr.iph_src;
// Пишем IP адрес получателя с портом
AddrDst.S_addr := pIpHdr.iph_dest;

tcpHdrDataOffs:=ipHdrLen + GetTCPDataOffset(@Packet[ipHdrLen]);

PacketFlags:=ntohs(pTcpHdr.flags);
...
в общем на основе структур ip и tcp хедеров разбираем, если что читаем доку "RFC793 - Transmission Control Protocol".

продолжение ниже...

user456
23.06.2010, 00:27
сама сборка пакетов (для пикапа тоже пригодится)constructor TTcpBuffer.Create;
begin
FCS:=TCriticalSection.Create;
setlength(FSeqArr, SIZE64);
FSeqCount:=0;
FCurrSeq:=0;
//FNextSeq:=0;
FDupCount:=0;
FOorCount:=0;
end;

destructor TTcpBuffer.Destroy;
var
i: integer;
begin
FCS.Enter;
// |--[ack|array] count,first
// | |--[seq|wsabuf]
// | |--[seq|wsabuf]
// | |--[seq|wsabuf]
for i:=0 to FSeqCount - 1 do
FreeMem(FSeqArr[i].wsa_buf.buf);
FSeqArr:=nil;
FCS.Leave;
FCS.Free;
inherited;
end;

procedure TTcpBuffer.ASwap(Lo, Hi: integer);
var
temp: TSeqRec;
begin
move(FSeqArr[Lo],temp,sizeof(TSeqRec));
move(FSeqArr[Hi],FSeqArr[Lo],sizeof(TSeqRec));
move(temp,FSeqArr[Hi],sizeof(TSeqRec));
end;

procedure TTcpBuffer.QuickSort(iLo, iHi: integer);
var
Lo, Hi: integer;
pivot: dword;
begin
Lo := iLo;
Hi := iHi;
pivot:=FSeqArr[(Lo + Hi) div 2].swappedSeq;
repeat
while FSeqArr[Lo].swappedSeq < pivot do Inc(Lo);
while FSeqArr[Hi].swappedSeq > pivot do Dec(Hi);
if Lo <= Hi then begin
if Lo <> Hi then ASwap(Lo,Hi);
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then QuickSort(iLo, Hi);
if Lo < iHi then QuickSort(Lo, iHi);
end;

{function TTcpBuffer.QuickFind(const looking_for: dword; iLo, iHi: integer):dword;
var
Mid: dword;
pivot: dword;
begin
if (iHi-iLo-1) > 0 then begin
Mid:=(iLo+iHi) div 2;
pivot:=FSeqArr[Mid].swappedSeq;
if pivot < looking_for then result:=QuickFind(looking_for,Mid,iHi)
else result:=QuickFind(looking_for,iLo,Mid);
end
else if looking_for > FSeqArr[iLo].swappedSeq then result:=iHi
else result:=iLo;
end;}

function TTcpBuffer.Match(Value: dword; ItemIndex: integer): integer;
begin
result:=0;
if Value < FSeqArr[ItemIndex].swappedSeq then result:=-1
else if Value > FSeqArr[ItemIndex].swappedSeq then result:=1;
end;

function TTcpBuffer.QuickSearch(Value: dword; Count: integer; MatchFunction: TMatchFunction): integer;
var
L, M, C: integer;
begin
if Count > 0 then
begin
L := 0;
Dec(Count);
while L <= Count do
begin
M := (L + Count) shr 1;
C := MatchFunction(Value, M);
if C > 0 then
L := M + 1
else if C <> 0 then
Count := M - 1
else
begin
Result := M;
Exit;
end;
end;
end;
Result := -1;
end;

{ Add any match cap sequence to array }
procedure TTcpBuffer.Add2Buffer(data: pointer; swappedSeq,len,dataOffs: dword; isFromServer: boolean);
var
prev: dword;
dataLen: dword;
i: integer;
begin
prev:=FSeqCount;
inc(FSeqCount);
if FSeqCount > length(FSeqArr) then
setlength(FSeqArr, ((length(FSeqArr) shr 6) + 1) shl 6); //by 64
GetMem(FSeqArr[prev].wsa_buf.buf, len);
move(data^, FSeqArr[prev].wsa_buf.buf^, len);
FSeqArr[prev].wsa_buf.len:=len;
FSeqArr[prev].swappedSeq:=swappedSeq;
FSeqArr[prev].dataOffs:=dataOffs;
dataLen:=len - dataOffs;
FSeqArr[prev].dataLen:=dataLen;
//if swappedSeq = FNextSeq then
// FNextSeq:=FCurrSeq + dataLen;
if FSeqCount > 1 then
QuickSort(0, FSeqCount - 1);
if FSeqCount = 10 then begin
if isFromServer then AddToLog('SMSG')
else AddToLog('CMSG');
AddToLog('current '+IntToHex(FCurrSeq,8)+' datalen '+IntToHex(dataLen,4));
AddToLog('expecting '+IntToHex(FCurrSeq + dataLen,8));
for i := 0 to 9 do AddToLog('seq['+IntToStr(i)+']='+IntToHex(FSeqArr[i].swappedSeq,8));
end;
end;

{ Add any packet from current to current+MAX_DELTA_BROWSE_SEQUENCE }
procedure TTcpBuffer.AddData(data: pointer; len: dword; isFromServer: boolean);
var
packetFlags: word;
ipHdrLen,tcpHdrDataOffs,dataOffs: dword;
pIpHdr: PIPHeader;
pTcpHdr: PTCPHeader;
pseudoHdr: TTCPPseudoHeader;
pseudohdrCS,cs: word;
swappedSeq,maxPossibleSeq: dword;
label fin;
begin
FCS.Enter;
pIpHdr:=PIPHeader(data);
ipHdrLen:=GetIPHeaderLen(pIpHdr);
pTcpHdr:=PTCPHeader(@TBytes(data)[ipHdrLen]);

//check already in array
swappedSeq:=ntohl(pTcpHdr.sequenceNumber);
if FSeqCount > 1 then begin
if QuickSearch(swappedSeq, FSeqCount, Match) >= 0 then begin
//AddToLog(Format('skip duplicated seq: %.8x swseq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq]));
inc(FDupCount); goto fin;
end;
end
else if FSeqCount > 0 then begin
if FSeqArr[0].swappedSeq = swappedSeq then begin
//AddToLog(Format('skip duplicated seq: %.8x swseq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq]));
inc(FDupCount); goto fin;
end;
end;
//check CS
cs:=GetChecksum(pIpHdr, ipHdrLen);
if cs <> 0 then begin
if isFromServer then AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=server')
else AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=client');
if (checkCS)and(isFromServer) then goto fin;
end;
if isFromServer then begin
pseudoHdr.iph_src:=pIpHdr.iph_src;
pseudoHdr.iph_dest:=pIpHdr.iph_dest;
pseudoHdr.reserved:=0;
pseudoHdr.iph_protocol:=pIpHdr.iph_protocol;
pseudoHdr.tcp_length:=ntohs(len - ipHdrLen); //ntohl shr 16;
pseudohdrCS:=not(GetChecksum(@pseudoHdr, sizeof(pseudoHdr)));
cs:=GetChecksum(pTcpHdr, len - ipHdrLen, pseudohdrCS);
if cs <> 0 then begin
if isFromServer then AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=server')
else AddToLog('wrong iphdr cs='+IntToHex(cs,4)+' src=client');
if (checkCS) then goto fin;
end;
end;

packetFlags:=ntohs(pTcpHdr.flags);
//initial sequences
if (packetFlags and TCP_FLAG_SYN) <> 0 then begin
//FNextSeq:=
FCurrSeq:=swappedSeq + 1; //FNextSeq;
goto fin;
end;
//if (packetFlags and TCP_FLAG_ACK) <> 0 then goto fin;
maxPossibleSeq:=FCurrSeq + MAX_DELTA_BROWSE_SEQUENCE;
if ((FCurrSeq < maxPossibleSeq)and((swappedSeq < FCurrSeq)or(swappedSeq > maxPossibleSeq))) //linear
or ((FCurrSeq > maxPossibleSeq)and((swappedSeq < FCurrSeq)and(swappedSeq > maxPossibleSeq))) then begin
//AddToLog(Format('skip out of range seq: %.8x swseq: %.8x FCurrSeq: %.8x',[pTcpHdr.sequenceNumber,swappedSeq,FCurrSeq]));
inc(FOorCount); goto fin;
end;
tcpHdrDataOffs:=GetTCPDataOffset(@TBytes(data)[ipHdrLen]);
dataOffs:=ipHdrLen+tcpHdrDataOffs;
if len > dataOffs then
Add2Buffer(data, swappedSeq, len, dataOffs, isFromServer);
fin:
FCS.Leave;
end;

procedure TTcpBuffer.RemoveAt(seqArrPos: integer);
begin
Assert(seqArrPos < FSeqCount);
FreeMem(FSeqArr[seqArrPos].wsa_buf.buf);
if seqArrPos < (FSeqCount - 1) then
move(FSeqArr[seqArrPos+1], FSeqArr[seqArrPos], sizeof(TSeqRec)*(FSeqCount - seqArrPos - 1));
dec(FSeqCount);
end;

procedure TTcpBuffer.Release(swappedSeq: dword);
var
maxPossibleSeq: dword;
i,spos: integer;
begin
FCS.Enter;
if FSeqCount > 1 then begin
//AddToLog(Format('TTcpBuffer.Release seq: %.8x swseq: %.8x FSeqCount: %d',[bswap(swappedSeq),swappedSeq,FSeqCount]));
//for i := 0 to FSeqCount - 1 do
// AddToLog(Format('FSeqArr[%d] swseq: %.8x wsa_buf.buf: %.8x wsa_buf.len: %d',[i,FSeqArr[i].swappedSeq,dword(FSeqArr[i].wsa_buf.buf),FSeqArr[i].wsa_buf.len]));

spos:=QuickSearch(swappedSeq, FSeqCount, Match);
if spos >= 0 then begin
//AddToLog(Format('swseq found at %d',[spos]));
FCurrSeq:=FCurrSeq + FSeqArr[spos].dataLen;
RemoveAt(spos);
end;
//remove trash
i:=0;
while i < FSeqCount do begin
maxPossibleSeq:=FCurrSeq + MAX_DELTA_BROWSE_SEQUENCE;
if maxPossibleSeq > FCurrSeq then begin
if (FSeqArr[i].swappedSeq < FCurrSeq)or(FSeqArr[i].swappedSeq > maxPossibleSeq) then begin
//AddToLog(Format('FSeqCount: %d removing at: %d FCurrSeq: %.8x maxPossibleSeq: %.8x swseq: %.8x',[FSeqCount,i,FCurrSeq,maxPossibleSeq,FSeqArr[i].swappedSeq]));
RemoveAt(i);
end
else inc(i);
end
else if (FSeqArr[i].swappedSeq < FCurrSeq)and(FSeqArr[i].swappedSeq > maxPossibleSeq) then begin
//AddToLog(Format('FSeqCount: %d removing at: %d FCurrSeq: %.8x maxPossibleSeq: %.8x swseq: %.8x',[FSeqCount,i,FCurrSeq,maxPossibleSeq,FSeqArr[i].swappedSeq]));
RemoveAt(i);
end
else inc(i);
end;
end
else if FSeqCount > 0 then begin
if FSeqArr[0].swappedSeq = swappedSeq then begin
FCurrSeq:=FCurrSeq + FSeqArr[0].dataLen;
RemoveAt(0);
end;
end;
FCS.Leave;
end;

{ Get next matched sequence }
function TTcpBuffer.GetSequence: PSeqRec;
var
spos: integer;
begin
result:=nil;
FCS.Enter;
if FSeqCount > 1 then begin
spos:=QuickSearch(FCurrSeq, FSeqCount, Match);
if spos >= 0 then result:=@FSeqArr[spos];
end
else if FSeqCount > 0 then begin
if FSeqArr[0].swappedSeq = FCurrSeq then
result:=@FSeqArr[0];
end;
FCS.Leave;
end;

и вот тут были вопросы по самой организации обработки (если какой-то пакет не пришел то сколько надо хранить? не гигабайты же. Если потом пришел, но с него другие sequence пошли, то что? А приходили такие порой при глючной сети и жутких лагах). Потом описанная в никсах проверка контрольных сумм шла под ХР и нивкакую под вин7. Пришлось отказаться от проверки КС.

user456
23.06.2010, 00:31
да, сама структура "номер пакета" - "пакет"
PSeqRec = ^TSeqRec;
TSeqRec = packed record
swappedSeq: dword;
dataOffs,dataLen: dword;
wsa_buf: WSABUF;
end;

TSeqArr = array of TSeqRec;


и вспомогательные функцииfunction GetDWordDiff(aLo,aHi: dword):dword;
begin
if aHi >= aLo then result:=aHi - aLo
else result:= maxdword - aLo + aHi;
end;

function GetIPHeaderLen(ih: PIPHeader): Word; // IP header length
begin
// multiply the low nibble by 4
// and return the length in bytes
Result := (ih.iph_verlen and $F) shl 2;
end;

function GetTCPDataOffset(th: PTCPHeader): Word;
begin
// doff (data offset) stored in 32 bit words,
// multiply the value by 4 to get byte offset
Result := ((th.flags and $F0) shr 4) shl 2;
end;

function GetFlags(flags: word): string;
begin
result := '' ;
if (flags AND TCP_FLAG_FIN) = TCP_FLAG_FIN then result := result + 'FIN ';
if (flags AND TCP_FLAG_SYN) = TCP_FLAG_SYN then result := result + 'SYN ';
if (flags AND TCP_FLAG_RST) = TCP_FLAG_RST then result := result + 'RST ';
if (flags AND TCP_FLAG_PSH) = TCP_FLAG_PSH then result := result + 'PSH ';
if (flags AND TCP_FLAG_ACK) = TCP_FLAG_ACK then result := result + 'ACK ';
if (flags AND TCP_FLAG_URG) = TCP_FLAG_URG then result := result + 'URG ';
if (flags AND TCP_FLAG_ECH) = TCP_FLAG_ECH then result := result + 'ECH ';
if (flags AND TCP_FLAG_CWR) = TCP_FLAG_CWR then result := result + 'CWR ';
result := trim (result);
end;

function GetChecksum(lpBuf: pointer; count: integer; initial_value: word = 0):word;
var
temp: integer;
begin
//http://www.faqs.org/rfcs/rfc1071.html
temp:=initial_value;
while count > 1 do begin
temp:=temp + PWord(lpBuf)^;
inc(integer(lpBuf),sizeof(word));
dec(count,sizeof(word));
end;
if count > 0 then
temp:=temp + PByte(lpBuf)^;

while (temp shr 16) <> 0 do
temp:=(temp and $ffff) + (temp shr 16);

result:= not(temp);
end;

abdula123
23.06.2010, 08:55
Так вот к нашим баранам: можно вообще делать под raw сокетами. Пакеты и правда могут приходить "всё в одном", с повторами, порезаные. Но логика сборки там простая. Я и такой сделал и он куда проще даже проксевого (с проксевым головняк лично у меня с критическими секциями, пока не отправлено надо ж что-то делать с новыми пакетами).


и вся та простыня кода называется "проще"???
ё-маё. как-же всё-таки любят некоторые усложнять себе жизнь.

у меня ВСЯ обработка соединений \ расшифровка \ лог \ зашифровка в разы меньше и проще, чем одно только это чтение и сборка tcp-пакетов.

user456
23.06.2010, 11:24
и вся та простыня кода называется "проще"???
Это не "проще", это другой вариант. Другой уровень выхода на данные. В вашем такой код никуда не исчезает, просто им ось занимается.

abdula123
24.06.2010, 17:31
Это не "проще", это другой вариант. Другой уровень выхода на данные. В вашем такой код никуда не исчезает, просто им ось занимается.

код - имеется в виду код написанный для этой задачи.

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


так что в данном случае, это не только другой вариант, но еще и проще :)

Йоха
02.07.2010, 12:41
Приветствую,
решил написать свой сниффер, больше из спортивного интереса. В ВоВ играю на офе с 2006 года.
По образованию программист, но уже достаточно давно не кодил ничего

Долого выбирал каким способом перехватывать трафик, сперва была идея сделать свой TDI фильтр драйвер и перенаправлять весь трафик идущий от приложения wow.exe в пользовательское приложение. Почитав DDK на тему создания TDI фильтров - понял что такой подход это как из пушки по воробьям. Слишком сложно.

использовать pcap мне почему-то не понравилось ... И с первого взгляда я не нашел как фильтровать трафик от конкретного приложения.

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

Больше всего понравился вариант предложеный abdula123. По сути это и есть первый вариант с TDI фильтром, только фильтр уже написан и отлажен хорошими людьми :thank_you:. Я использую proxifier (www.proxifier.com)
Плюсом такого подхода так же является платформонезависимость, посколько этот проксификатор работает на всех версиях виндовс. К тому же у этого проксификатора есть portable версия, не требующая установки.

Настраиваем правило, для приложения wow весь трафик перенаправлять на localhost, наш порт. И все, весь поток данных от wow.exe у нас.
SOCKS4 - примитивнешйи протокол, имеющий всего две команды CONNECT и BIND.
CONNECT - это запрос на установку соединения с удаленным хостом.
BIND - запрос на открытие порта в режиме прослушивания (для принятия соединений)

В нашем случае реализация поддержки BIND не требуется, вов ничего не слушает.

В общем скачав VisualStudio2010, со скрипом вспоминал програмирование с использованием сокетов. Вчера много тупил, сегодня мой прокси отлично работает. Во всяком случае все приложения с использованием SOCKS4 прокси, и вов через проксифиер - работает без проблем.
Если есть желание, могу показать код, всего 290 строк -)

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

Deamon
02.07.2010, 13:32
В связи с этим вопрос по поводу получения ключа. Его можно считать на лету ? или только выдергивать из памяти роцесса ?

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

RomanRom2
02.07.2010, 16:59
Приветствую,
решил написать свой сниффер, больше из спортивного интереса.
похвально. спрашивайте, поможем. какой формат снифов используете? =)))

использовать pcap мне почему-то не понравилось ... И с первого взгляда я не нашел как фильтровать трафик от конкретного приложения.
я вам в прошлый раз наврал, у меня не pcap, а pssdk. но роли особой не меняет. фильтры тут настраиваются очень и очень просто, пример по этой ссылке: http://www.microolap.com/products/network/pssdk/helpdll/BPF/TCP_UDP_level_BPF_example.htm

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

Настраиваем правило, для приложения wow весь трафик перенаправлять на localhost, наш порт. И все, весь поток данных от wow.exe у нас. Вчера много тупил, сегодня мой прокси отлично работает.
имейте ввиду, что близзы проксификаторы палят, но не банят пока.

Двигаемся дальше, вставляем теперь непосредственно разбор трафика вов.
В связи с этим вопрос по поводу получения ключа. Его можно считать на лету ? или только выдергивать из памяти роцесса ?
так собственно он получается на лету из памяти процесса :) существует два принципиально разных способа, один требует так называемой точки входа для поиска ключа, другой эту точку входа самостоятельно ищет и поиск адреса тут проще. в первом случае конечно тоже существуют методы автоматического поиска точки входа по wow.exe, этот адрес просто меняется от билда к билду. а адрес, по которому находится ключ может меняться каждый раз при загрузке игры. одну из реализаций первого метода вы можете посмотреть в исходниках tiawps.

Йоха
02.07.2010, 17:34
похвально. спрашивайте, поможем. какой формат снифов используете? =)))

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

я вам в прошлый раз наврал, у меня не pcap, а pssdk. но роли особой не меняет. фильтры тут настраиваются очень и очень просто, пример по этой ссылке: http://www.microolap.com/products/network/pssdk/helpdll/BPF/TCP_UDP_level_BPF_example.htm

Да это практически тоже самое , в общем все равно, не хочется связываться с разбором пакетов :-)


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


инфа 100% ?

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

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

угу, запасся исходниками tiawps ... но учитывая что моему проекту всего 2 дня, пока до всего еще руки не дошли :-)
тем более на работе не всегда бывает время полностью посвятить себя програмированию, иногда приходится работать ;-)

Deamon
02.07.2010, 17:46
инфа 100% ?

Вохе привет.

Konctantin
02.07.2010, 18:05
С проксей сейчас туговато, раньше нужный коннект определялся исходя из того какой адресс приходит в пакете с опкодом 4, а сейчас ввели криптовку и стало плохо.
приходится извращатся

if (!Regex.IsMatch(search.ToString(), @"213.248.127.\d{3}:1119") && first && search.Port != 80)
{
first = false;
return new WowReactor(Conn);
}

Йоха
02.07.2010, 18:54
Вохе привет.

какому такому Вохе ?

RomanRom2
02.07.2010, 22:30
Пока до записи снифов на диск дело не дошло, разбираюсь пока с самим протоколом вов и как там что шифруется ...
Планирую использовать Ваш формат, почитал описание, на мой взгляд весьма удачный.
спасибо :yes3:
спрашивайте, все расскажем покажем.

Да это практически тоже самое , в общем все равно, не хочется связываться с разбором пакетов :-)
а не нужно с этим связываться, либа сама всё делает. я же только пишу обработчики, связанные с событиями. вот, перечислю:
procedure OnSessionCreate(Sender: TObject; hTcpSession : Pointer; var Need : LongBool);
procedure OnSessionDelete(Sender: TObject; hTcpSession : Pointer);
procedure OnSessionConnect(Sender: TObject; hTcpSession : Pointer);
procedure OnClientData(Sender: TObject; hTcpSession : Pointer; pData : Pointer; DataSize : Integer);
procedure OnServerData(Sender: TObject; hTcpSession : Pointer; pData : Pointer; DataSize : Integer);
procedure OnSessionClose(Sender: TObject; hTcpSession : Pointer; var Need : LongBool);
это всё что я делаю по делу :yes3:

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

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

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

но с точки зрения реализации прокся - самый простой вариант. начните с нее, я тоже с нее начинал :secret:

у меня лично нет цели вклиниваться в трафик, мне интересен контент. поэтому меня устраивают pcap-о подобные схемы :pardon:

RomanRom2
02.07.2010, 22:46
С проксей сейчас туговато, раньше нужный коннект определялся исходя из того какой адресс приходит в пакете с опкодом 4, а сейчас ввели криптовку и стало плохо.
Константин :punish:, нужжный коннект определяется по dst ip addr. у меня два критерия:
1. коннект на 213.248.127.130:1119 - это однозначно коннект на BattleNet2
2. коннект на любой порт на подсеть адресов 62.67.*.* - это коннект на реалм.

первая проверка уже потеряла актуальность - раньше в этом трафике я выдирал реалм лист, из него айпишники и названия реалмов. а так же билд клиента. по этим данным строилось имя файла. сейчас с битстримом лень делать разбор реалмлиста (тем более вон шифрование добавили), названия файлов у меня сейчас выглядят так:
11723_[01ED]_62.67.45.88.3724_4C2139F3.raw
11723_[0512]_62.67.45.85.6112_4C2139F4.raw
11723_[01ED]_62.67.45.88.3724_4C213BB5.raw
11723_[0512]_62.67.45.85.1119_4C213BB6.raw

как видите, видно "вторую сессию" :censored:
кстати, про вторую сессию. любой новый коннект на 62.67.*.* я считаю новой сессией и открываю новый снифф. вот и всё. всё просто. и не важно сколько "переконнектов" еще сделает клиент (я пробовал менять несколько раз реалм), откроется новая сессия (как понятно - 512ая :declare:) и все будет чики-пуки :dance2:

ЗЫ. насчет :punish: сорри, не удержался. смачный смайлик :friends:

LordJZ
02.07.2010, 23:02
У нас с Konctantin получилась универсальная прокся, но даже сам WoW (в частности BN2) лезет куда-то по http, плюс скачивает себе модули. Я подумал определять по первому пакету (как раз ваши 1EDh и 512h), и в противном случае отключаться от соединения (наша реализация это позволяет).

Konctantin
03.07.2010, 08:40
62.67.*.*
Это актуально лишь в том случае, если вы используете русские игровые миры

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

Йоха
03.07.2010, 09:39
У меня получился вот такой расклад по коннектам:
Это запуск клиента, логин и вход и игровой мир, потом выход

CONNECT 213.248.127.130:1119
CONNECT 213.248.127.132:1119
CONNECT 62.67.45.98:3724
CONNECT 213.248.127.132:1119
CONNECT 213.248.127.132:1119
CONNECT 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CONNECT 62.67.45.157:3724
CLOSE 62.67.45.98:3724
CONNECT 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CONNECT 213.248.127.132:1119
CLOSE 213.248.127.132:1119
CLOSE 62.67.45.157:3724
CLOSE 213.248.127.130:1119

если говорите что 213.248.127.132:1119 это BNET, то что такое 213.248.127.130:1119 ? то же самое ?

62.67.45.98:3724 и 62.67.45.157:3724 это явно игровые миры

Konctantin
03.07.2010, 10:43
213.248.127.132:1119
скорее всего, это какой-то вспомогательный сервер, или сервер для общения, хз... чего они там наворотили.

ЗЫ. Надо снифонуть этот трафик по этому коннекту, и посмотреть что за пакеты в нем ходят

RomanRom2
03.07.2010, 11:44
Это актуально лишь в том случае, если вы используете русские игровые миры

И у вас и у нас на данном этапе корявое определение, ибо кто знает что они за коннект еще добавят, и постоянно надо это дело мониторить.
верно, это для русских реалмов. но у меня евро аккаунт :)
сейчас проверил. итак:
213.248.127.130:1119 - это БН2.
62.67.45.174:6114 - это мой реалм.
и большинство "наших" - все на русских аккаунтах играет, не так ли?

ну да ладно.
меняю реалм - 195.12.236.164, однако.
80.239.233.88
внимание! - 213.248.123.52

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

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

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

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

Konctantin
03.07.2010, 12:01
в идеальном случае надо сделать как у меня было раньше - читать из БН трафика реалм лист и коннекты фильтровать в соответствии с этим листом. и всё. вот схема "на всю жизнь". а сейчас мы просто упрощаем.
В идеале:
раньше нужный коннект определялся исходя из того какой адресс приходит в пакете с опкодом 4,
а перебор и сравнение, это немножко не то, да конешно, таким образом можно взять имя рилма, и еще чего-то, "вклеить" в дамп, но... это пока не то что надо...

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

Йоха
03.07.2010, 12:44
Коннект на адрес 213.248.127.132_1119
GET /b03a85262f8f83f767da530c046dd36315e503887bf4bc3665 6f62b5335209f3.pfty HTTP/1.1
User-Agent: Battle.net Web Client
Host: EU.depot.battle.net:1119
Accept: */*

ответ:
HTTP/1.1 404 Not Found
Server: Apache
Content-Type: text/html; charset=iso-8859-1
Content-Length: 338
Date: Sat, 03 Jul 2010 09:35:38 GMT
X-Varnish: 2119243220 2086117285
Age: 241637
Via: 1.1 varnish
Connection: keep-alive

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /b03a85262f8f83f767da530c046dd36315e503887bf4bc3665 6f62b5335209f3.pfty was not found on this server.</p>
<hr>
<address>Apache Server at eu.depot.battle.net Port 1119</address>
</body></html>


в общем на этот адрес идут обычные HTTP запросы на получение каких-то файлов:
*.pfty

потом запрос каких-то *.xml

Но на все запросы, ответ был один: HTTP/1.1 404 Not Found

Konctantin
03.07.2010, 14:46
какие-то модули, или хз... Но в процессе разработки

LordJZ
03.07.2010, 15:05
О чем я и говорил...

Shadez
03.07.2010, 15:22
какому такому Вохе ?
Вох.ру =) Тамошние эксперты любят уточнять достоверность данных подобным выражением :)

http://lurkmore.ru/%D0%98%D0%BD%D1%84%D0%B0_100%25 - прим. модератора

Йоха
03.07.2010, 15:42
коллеги подскажите где взять полный перечень опкодов ?

LordJZ
03.07.2010, 15:45
коллеги подскажите где взять полный перечень опкодов ?http://github.com/mangos/mangos/raw/master/src/game/Opcodes.h

Йоха
04.07.2010, 11:09
простите за глупые вопросы, просто раньше никогда не разбирал вов-трафик.
Я получаю в своем приложении поток данных, в котором начало "\xed\x01" или "\x12\x05".
Как дальше разбирать пакеты, подскажите описание формата пакетов вов

Konctantin
04.07.2010, 11:29
Первые 2 пакета идут не зашифрованные, после начинается поток уже шифрованных пакетов.
Но шифруются пакеты не полностью, а только их заголовки.
Алгоритм шифрования ARC4 http://github.com/mangos/mangos/tree/master/src/shared/Auth/.

описание пакета:

Заголовок:
2 байта - размер пакета
Если Пакет идет от клиента к серверу тогда
4 байта Опкод
иначе
2 байта опкод

далее идут данные

Ps. В одном ТСР пакете может стразу прийти несколько игровых пакетов, поэтому и определяется размер, дабы вычислить столько надо обработать данных

Йоха
04.07.2010, 12:08
Первые 2 пакета идут не зашифрованные, после начинается поток уже шифрованных пакетов.
Но шифруются пакеты не полностью, а только их заголовки.
Алгоритм шифрования ARC4 http://github.com/mangos/mangos/tree/master/src/shared/Auth/.

описание пакета:

Заголовок:
2 байта - размер пакета
Если Пакет идет от клиента к серверу тогда
4 байта Опкод
иначе
2 байта опкод

далее идут данные


благодарю.


Ps. В одном ТСР пакете может стразу прийти несколько игровых пакетов, поэтому и определяется размер, дабы вычислить столько надо обработать данных

это понятно.

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

Konctantin
04.07.2010, 12:39
вот так у нас в прокси:

Header.AddRange(pkt, 0, SizeLength + OpcodeLength);
AuthCrypt.Process(d, pkt, 0, SizeLength + OpcodeLength);

bool large = (pkt[0] & 0x80) != 0;
if (large)
{
Header.Add(pkt[SizeLength + OpcodeLength]);
AuthCrypt.Process(d, pkt, SizeLength + OpcodeLength, 1);
SizeLength += 1;
}

int i = 0;

/// Size includes OpcodeLength, but doesn't include SizeLength.
int Size = 0;
for (int j = 0; j < SizeLength; ++j)
Size = (Size << 8) | (pkt[i++] & (j == 0 ? 0x7F : 0xFF));

int Opcode = 0;
for (int j = 0; j < OpcodeLength; ++j)
Opcode |= (pkt[i++] & 0xFF) << (j * 8);

user456
05.07.2010, 20:19
Да это практически тоже самое , в общем все равно, не хочется связываться с разбором пакетов :-)

А кто говорит что надо самому долбаться (разве что на Дельфи)? Во-первых если поставить Comodo Firewall то он сам собирает фрагментированные ip-пакеты и raw-сокеты получают от него клиентские пакеты с просчитанными контрольными суммами (пришлось вспоминать отчего кривые кс под вин7 были). Во-вторых если на си писать, то есть либы типа libnids в которых это все уже сделано (даже демка снифера прилагается, правда оно похоже pcap-овое, но никто не мешает юзать сборщики пакетов по-своему).

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

Йоха
07.07.2010, 15:55
Подскажите я правильно понял суть алгоритма расшифровки ?

- создаем экземпляр класса AuthCrypt
- вызываем функцию Init(BigNumber), в качестве параметра передается выдраный из памяти вов session key
- для расшифровки заголовка пакета вызываем функцию DecryptRecv

LordJZ
07.07.2010, 17:27
Эти функции вам предстоит написать.

Йоха
07.07.2010, 19:15
в смысле ? реализация же есть в мангосе
или это не то ?

Йоха
07.07.2010, 19:25
просто я уже сделал прокси который сохраняет на диск так сказать raw поток обмена между клиентом и сервером. Как объяснили первые два пакета идут нормальные, а потом начинается шифрованный обмен. Вот собственно и вопрос возник. В исходниках мангоса есть реализация класса AuthCrypt. Я спрашивал как раз касательно его применения.

YuruY
07.07.2010, 19:35
Эти функции вам предстоит написать.
Читать умеем?

LordJZ
07.07.2010, 19:45
просто я уже сделал прокси который сохраняет на диск так сказать raw поток обмена между клиентом и сервером. Как объяснили первые два пакета идут нормальные, а потом начинается шифрованный обмен. Вот собственно и вопрос возник. В исходниках мангоса есть реализация класса AuthCrypt. Я спрашивал как раз касательно его применения.Дак если вы берете реализацию из мангоса, почему-бы и не использовать ее так же, как в мангосе?..

RomanRom2
07.07.2010, 20:41
просто я уже сделал прокси который сохраняет на диск так сказать raw поток обмена между клиентом и сервером. Как объяснили первые два пакета идут нормальные, а потом начинается шифрованный обмен. Вот собственно и вопрос возник. В исходниках мангоса есть реализация класса AuthCrypt. Я спрашивал как раз касательно его применения.
если у вас уже существует запись raw в файл, и ключ пишется, то этого достаточно. потом в оффлайне расшифруете утилиткой.
утилитку вам подарю с исходниками.
ну и можно попробовать прислать ваш raw, за одно и проверим.

Йоха
08.07.2010, 09:44
Большое спасибо RomanRom2 за бесценные советы

Сделал запись снифа в raw формат, но что-то с ключом не то у меня, вроде читается нечто из памяти, но утилитка конвертирующая raw файлы в pkt зависает на моих файлах -(

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

Йоха
08.07.2010, 14:04
Итак, снифер готов. с ключом оказалось все в порядке.
Косяк оказался с форматом raw снифа.
Вроде на сайте написано что формат такой:
заголовок серверных данных:
1 байт: 0xFF
4 байта: DateTimeToUnix(Now)
4 байта: GetTickCount, тики, полученные с машины, где работал снифер (обычно - клиентская машина)
4 байта: длина пакета
?? байт: пакет

Однако порывшись в снифах выяснилось что поле "длина пакета" должно идти сразу после сигнатуры (0xff), а не последним.

В общем все работает, спасибо всем кто помогал, и отдельное спасибо RomanRom2!


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

RomanRom2
08.07.2010, 21:54
Однако порывшись в снифах выяснилось что поле "длина пакета" должно идти сразу после сигнатуры (0xff), а не последним.
спасибо. исправил на сайте описание.

alien
08.07.2010, 23:40
хмммм... двойные стандарты?
На логах снифера которые лежали недавно на фтп size был последним как и в описании.
Кому верить?

RomanRom2
09.07.2010, 01:51
все верно. мой фолт.

итак, в raw-файлах длина лежит в начале, в pkt-файлах - в конце. вот такой косяк, уж не знаю как так вышло, простите христа ради :)
опять исправил на сайте, спасибо alien за наблюдательность.

Йоха
17.07.2010, 19:25
Что-то я запутался немного с расшифровкой заголовков пакетов
за основу взял код из tiawps

Инициализация выглядит так:

BYTE digest[SHA_DIGEST_LENGTH];
ZeroMemory(&digest, SHA_DIGEST_LENGTH);

HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, seed, SEED_KEY_SIZE, EVP_sha1(), NULL);
HMAC_Update(&ctx, m_sessionkey, SESSION_KEY_LENGTH);

uint32_t length = 0;
HMAC_Final(&ctx, digest, &length);
HMAC_CTX_cleanup(&ctx);

EVP_CIPHER_CTX_init(&m_key);
EVP_EncryptInit_ex(&m_key, EVP_rc4(), NULL, NULL, NULL);
EVP_CIPHER_CTX_set_key_length(&m_key, SHA_DIGEST_LENGTH);
EVP_EncryptInit_ex(&m_key, NULL, NULL, digest, NULL);

// drop first 1024 bytes
BYTE trash;
for(int i = 0; i < 1024; ++i)
{
DecryptData(&trash, 1);
}


Сама функция расшифровки так

void CCrypt::DecryptData(BYTE *data, int len)
{
int outlen = 0;
EVP_EncryptUpdate(&m_key, data, &outlen, data, len);
EVP_EncryptFinal_ex(&m_key, data, &outlen);
}


Расшифровываются нормально только первый серверный и первый клиентский пакет. Потом ерунда какая-то получается.
В самом tiawps разобраться по человечески не получается, там такой дикий код что можно его выставлять как пример к лозунгу "как не нужно писать программы на С"

Подскажите что я упустил ?

LordJZ
17.07.2010, 19:48
Первые 2 пакета — не зашифрованы вообще, следовательно, у вас расшифровка не работает вообще. По этому куску кода нельзя судить о правильности...

P.S. tiawps просто написан на Function C

Йоха
17.07.2010, 20:11
Первые 2 пакета — не зашифрованы вообще, следовательно, у вас расшифровка не работает вообще. По этому куску кода нельзя судить о правильности...


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

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

Йоха
18.07.2010, 12:43
разобрался вроде, мелкие ошибки были везде и в декодировании и в основной программе...
Сейчас расшифровывается нормально второе соединение, после SMSG_AUTH_CHALLENGE.
А первый поток - нет. Видимо сиды в tiawps нерабочие. Там такие:
const uint8_t serverSeed[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
const uint8_t clientSeed[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };

а на данный момент другие ?

LordJZ
18.07.2010, 13:01
Именно такие, может вы перепутали server/client?

Йоха
18.07.2010, 13:39
Разобрался. В первом соединении тоже приходит SMSG_AUTH_CHALLENGE, но там сиды какие-то левые.
Фэйк что ли какой-то близы придумали ... или просто эти сиды для первого соединения зашифрованые каким-то образом.
А вот во втором уже приходит SMSG_AUTH_CHALLENGE с верными сидами.

LordJZ
18.07.2010, 13:44
Сиды из первого SMSG_AUTH_CHALLENGE не используются

Йоха
18.07.2010, 13:45
значит фэйк =)))

Вроде все как будто работает, расшифровку пакетов на лету отладил...
Я учел в своем снифере возможность того что в одном куске данных от сервера или клиента может быть либо несколько маленьких пакетов, либо один большой пакет доходит кусками ... с этим проблем нет
А вот остался такой вопрос, возможна ли такая ситуация что в данных с сервера или клиента может оказаться не полный заголовок пакета?
Ну примерно так:
Предыдущая обработка завершилась нормально, ожидаем следующий пакет, тут приходит порция данных с сервера, а длина ну скажем 3.
Ясное дело что минимальный пакет от сервера может быть длиной 4. И если все делать правильно, если обнаружена такая ситуация, то надо дождаться недостающих данных. Или не стоит заморачиваться, и такого не бывет ?

LordJZ
18.07.2010, 14:00
Бывает, я на это напарывался.

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

Йоха
18.07.2010, 14:10
ясно, значит нужно учесть еще что заголовок может прийти не полностью

zergtmn
28.08.2010, 20:25
Как-то уныло через виртуальную машину снифать... Есть способ заставить работать pcap с VPN подключением?

Konctantin
28.08.2010, 20:51
он просто его не понимает.

Йоха
03.09.2010, 21:03
Кто-нибудь знает библиотеку для работы с raw сокетам на с++ под винду ?

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


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

Konctantin
03.09.2010, 21:17
раньше нужный коннект определялся исходя из того какой адресс приходит в пакете с опкодом 4
я имел в виду не
Кстати насчет поиска адреса второй сессии
а поиск первой сессии, раньше мы брали ИП:порт с батлнет траффика.

Йоха
03.09.2010, 21:18
ясно, значит я неправильно понял пост -)

Йоха
04.09.2010, 22:35
В продолжение темы (http://ru-mangos.ru/showthread.php?p=13613#post13613), если я хочу вставить свой пакет в поток, мне придется следующие пакеты от клиента все перешифровывать, в связи с этим вопрос, как зашифровать заголовок ?

Расшифровкой занимается такая функция
void CCrypt::DecryptData(BYTE *data, int len)
{
int outlen = 0;
EVP_EncryptUpdate(&m_key, data, &outlen, data, len);
EVP_EncryptFinal_ex(&m_key, data, &outlen);
}

а как зашифровать заголовок ? В криптографии не силен к сожалению

84ivan
05.10.2010, 11:54
пропусти его через DecryptData и он зашифруется. в рц4 нет специального алгоритма для зашифровывания, он в оба конца работает.

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

alien
20.10.2010, 19:17
От нечего делать решил найти где лежит sessionkey в 4.0.1
вот правка для tiawps
tiawps_reader.exe 13261876 1288

Konctantin
21.10.2010, 00:26
локаль 0x00C8155C

acteros
24.10.2010, 20:54
От нечего делать решил найти где лежит sessionkey в 4.0.1
вот правка для tiawps
tiawps_reader.exe 13261876 1288

Можно узнать как вы получили это "13261876" значение ?

Deamon
24.10.2010, 21:55
Можно узнать как вы получили это "13261876" значение ?

Это секретное искусство ниндзюцу, о котором обычно не пишут на форумах. Передается оно из рук в руки. И таких мелочей загадок в кухне ВоВ ой как много.

А конкретно по этому вопросу - ищется определенная строка в wow.exe и по ней находится определенный программный код. Вот вот из этого кода адресок и берется.

Konctantin
24.10.2010, 21:56
Найти эту функцию, можно по строке ACCOUNT_MESSAGE_BODY_NO_READ_URL, она такая одна
signed int __thiscall sub_92B460(int this, int a2)
{
int v2; // edi@1
int v3; // edx@3
char *v4; // ecx@3
signed int v5; // esi@3
int v6; // eax@3
char v7; // al@4
int v8; // eax@9
signed int v9; // esi@9
int v10; // esi@9
int v11; // eax@9
char v13; // [sp+4h] @3
char v14; // [sp+504h] [bp-7Ch]@9
char v15[20]; // [sp+560h] [bp-20h]@9
char v16; // [sp+574h] [bp-Ch]@9
int v17; // [sp+57Ch] [bp-4h]@11

v2 = this;
if ( *(_DWORD *)(this + 4) == 1 || *(_DWORD *)(this + 60) )
return 0;
v13 = 0;
v6 = sub_4D3320();
v4 = &v13;
v5 = 1279;
v3 = v6 - (_DWORD)&v13;
while ( 1 )
{
v7 = v4[v3];
*v4++ = v7;
if ( !v7 )
break;
--v5;
if ( !v5 )
goto LABEL_8;
}
if ( v5 )
goto LABEL_9;
LABEL_8:
*v4 = 0;
LABEL_9:
v8 = [B]ClientServices__GetCurrentConnection();
v10 = ClientServices__GetSessionKey(v8);
SHA1__Init(&v14);
SHA1__Update(&v14, v10, 40);
SHA1__Update(&v14, "\vz", 2);
SHA1__Final(v15, &v14);
DynamicString__DynamicString(&v16);
DynamicString__Resize(1024);
v11 = FrameScript__GetText("ACCOUNT_MESSAGE_BODY_NO_READ_URL", -1, 0);
sub_7CB5A0(v11);
DynamicString__Append("?accountName=");
DynamicString__Append(&v13);
DynamicString__Append("&sessionKeyHash=");
v9 = 0;
do
DynamicString__Unknown1((unsigned __int8)v15[v9++]);
while ( v9 < 20 );
DynamicString__Append("&messageId=");
DynamicString__Unknown1(a2);
if ( !(unsigned __int8)sub_7D4F60(v17, sub_92C010, v2) )
{
*(_DWORD *)(v2 + 4) = 3;
DynamicString__Free(&v16);
return 0;
}
*(_DWORD *)(v2 + 64) = 0;
sub_92BFF0(v2);
DynamicString__Free(&v16);
return 1;
}

int __cdecl ClientServices__GetCurrentConnection()
{
return dword_CA5C34;// в десятичной системе исчисления это и будет искомое значение
}


int __thiscall ClientServices__GetSessionKey(void *this)
{
return (int)((char *)this + 1288);
}


Когда-то показывал все это TOM_RUS еще на старом форуме

acteros
25.10.2010, 01:08
Разобрался но tiawps выдаёт
версия 4.0.1
tiawps_reader.exe 13261876 1288

couldn't read pointer, just read 0 bytes instead of 4
reading sessionkey failed - will try again in 1 second

Konctantin
25.10.2010, 01:36
какая у вас ОС ? Если виндовс 7, тогда примените это
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Session Manager\Memory Management]
"MoveImages"=dword:00000000
источник (http://ru-mangos.ru/showthread.php?t=2088)

TOM_RUS
25.10.2010, 05:03
Еще можно вместо отключения ASLR использовать:

address = Process.MainModule.BaseAddress + relativeOffset;


Relative offset можно получить, выполнив в IDA следующие операции:
edit -> segments -> rebase, 0x1000

Йоха
25.10.2010, 09:27
когда я разбирался с этой фигней, то выяснил что функция API - AdjustTokenPrivileges под вин7 не работает без прав администратора. Собственно просто запускаешь программу с правами администратора и все работает.

TOM_RUS
25.10.2010, 11:41
когда я разбирался с этой фигней, то выяснил что функция API - AdjustTokenPrivileges под вин7 не работает без прав администратора. Собственно просто запускаешь программу с правами администратора и все работает.

Это никак не поможет, если процесс использует ASLR.

Йоха
25.10.2010, 18:40
Странно, но у меня все работает, без правки реестра и прочих ухищрений
Хватает запуска программы с правами администратора

Вин7 домашняя расширенная (64 бит)

З.Ы. возможно мы о разных вещах говорим ...

alien
25.10.2010, 23:38
Я так понял близы не мешали опкоды, а просто применяю некоторые выражения для получения из старых опкодов новые.
к примеру
a1 & 1 | ((a1 & 0xC | ((a1 & 0x1E0 | ((a1 & 0x800 | (a1 >> 1) & 0x7000) >> 2)) >> 1)) >> 1)
где а1 это старый опкод а на выходе новый.
.....
это просто мои мысли поправте если я неправ.

TOM_RUS
26.10.2010, 00:31
Я так понял близы не мешали опкоды, а просто применяю некоторые выражения для получения из старых опкодов новые.
к примеру
a1 & 1 | ((a1 & 0xC | ((a1 & 0x1E0 | ((a1 & 0x800 | (a1 >> 1) & 0x7000) >> 2)) >> 1)) >> 1)
где а1 это старый опкод а на выходе новый.
.....
это просто мои мысли поправте если я неправ.

Это получение индекса для массива указателей на обработчики пакетов aka condensed Id.

Deamon
26.10.2010, 00:44
Это получение индекса для массива указателей на обработчики пакетов aka condensed Id.

Который к тому же менялся несколько раз за время бета теста клизмы.

Fabian
28.10.2010, 20:33
I don't understand it. I try to find a few opcode values for a little test, but I don't understand the new things in the beta wow.exe.

can anyone give me a sample to find out some opcode values?

alien
07.11.2010, 18:32
Тут был бред ))

Konctantin
07.11.2010, 19:06
там нету под 4.0.1, и гляньте на дату последнего обновления...

alien
07.11.2010, 19:33
Да точно что-то я опростоволосился )))

abdula123
13.11.2010, 17:41
начал обновлять свой сниффер до 4.0.1...


близзи - долбоящеры.


если я правильно понял в 4.0.1.13205 у объекта ClientConnection есть массив на 4 ServerConnection'а.

они что, собираются поднимать до 4х соединений одновременно?

virusav
13.11.2010, 18:58
http://ru-mangos.ru/showpost.php?p=16121&postcount=15
http://ru-mangos.ru/showpost.php?p=16123&postcount=17

abdula123
13.11.2010, 19:41
http://ru-mangos.ru/showpost.php?p=16121&postcount=15
http://ru-mangos.ru/showpost.php?p=16123&postcount=17

... еще при смене карты редирект должен быть.

все эти редиректы я отслеживаю и обрабатываю. они были еще в 3.3.3.

просто раньше в коде клиента была работа с 2мя соединениями - основным и дополнительным.

после согласования дополнительного приходила команда SMSG_SWITCH_TO_SECOND и основное закрывалось, а дополнительное становилось основным.


а сейчас там, если я правильно понимаю - 4 полноправных соединения, из которых 2 используются в параллель.

и ничего не мешает клиенту использовать параллельно все 4 :)



основной обмен данными идет через второе активное соединение (3е после логина)

а вот что сыпется в первое непонятно:
вижу SMSG_ZONE_UNDER_ATTACK, SMSG\CMSG_WARDEN_DATA, что-то про ГМские тикеты, GAMEUI.

похоже, всякая фоновая ересь.

Йоха
14.11.2010, 17:02
видимо разделили поток на 2 типа, 1 -всякие второстепенные вещи, которые обрабатываются когда есть время, и 2 - все что касается игры непосредственно, перемещения, создание/удаление объектов, касты и т.д. сообщения из этого потока обрабатываются в приоритете. Борются так сказать с лагами.

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

valsha
18.12.2010, 16:25
кто то мог бы поделится снифами от 3.3.5 стартовой локации DK?
заранее спасибо.

Fedia22
20.12.2010, 14:59
при перенаправлении ВоВа на ProxyCap чтоб начать снифать у меня усердно не хочет запускаться ВоВ :( падает с ошибкой
This application has encountered a critical error:

ERROR #134 (0x85100086) Fatal Condition
Program: D:\Fedia22\WoW\Wow.exe

Failed to open archive Data/wow-update-13164.MPQ. Missing or corrupted data.
Unable to recover using data from the network. Please check your Internet connection and try again.

Debug Details:

[0] err=4 text=Win32 Open - Data\wow-update-13164.MPQ.writeCacheBackup
[7] err=0 text=Manifests::ReadDirectFile - ReadDirectFileFromBuffer failed
[6] err=0 text=ManifestInfo::ReadDirectFileFromBuffer - manifest_partial tag failed
[5] err=8 text=FileManifest::ReadIndirectFile - DownloadURL failed - http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
[4] err=0 text=Blizzard::Streaming::ManifestInfo::ReadIndire ctFile - MD5 validation failed for http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
[3] err=0 text=Blizzard::Streaming::ManifestInfo::ReadIndire ctFile - MD5 validation failed for http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
[2] err=0 text=Blizzard::Streaming::ManifestInfo::ReadIndire ctFile - MD5 validation failed for http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
[1] err=0 text=Blizzard::Streaming::ManifestInfo::ReadIndire ctFile - MD5 validation failed for http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
[0] err=0 text=Blizzard::Streaming::ManifestInfo::ReadIndire ctFile - MD5 validation failed for http://ak.worldofwarcraft.com.edgesuite.net/wow-pod-retail/EU/12911.streaming/wow-13329-0658AFCDDF4D212A872B108F25947FA4.mfil
Storm Error Msg:Попытка поместить указатель на файл перед началом файла. :( подскажите что может быть :( у Константина всё нормально, настройки 1 в 1 :(

Йоха
03.03.2011, 10:09
переписал снифер с нуля для поддержки нового клиента и нового формата 3.0, в raw формат пишет нормально, но ввиду отсутствия конвертера в pkt решил приделать возможность записи сразу в пкт. И тут возникли грабли, первые два пакета такие:

S->C opcode 0x6019, len 37, connectionindex 0
C->S opcode 0x0E0E, len 314, connectionindex 0

что это за опкоды ?

HuntsMan
03.03.2011, 10:40
1. SMSG_AUTH_CHALLEGE
2. CMSG_AUTH_SESSION

Lordronn
03.03.2011, 10:40
SMSG_AUTH_CHALLENGE
CMSG_AUTH_SESSION

HuntsMan
03.03.2011, 10:59
Такой вопрос: сколько соединений сейчас открывает клиент - 2 или больше?

Йоха
03.03.2011, 11:43
Во время игры используется 3 соединения, одно на бнет и два на рилм
а так в любое время клиент может ломануться еще куда-нибудь

Йоха
03.03.2011, 12:16
а есть где-нибудь список актуальных опкодов ?

Lordronn
03.03.2011, 13:35
а есть где-нибудь список актуальных опкодов ?

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

RomanRom2
03.03.2011, 13:44
кстати, а кто нибудь точно знает, каким опкодом они заканчивались в 1.12.1, 2.4.3 и 3.3.5?
у меня кроме как взять снифы и собрать все что в них встречалось других мыслей нет, как это собрать.

Lordronn
03.03.2011, 14:09
каким опкодом они заканчивались

Ласт опкод в листе?

Раньше опкоды были в клиенте(до катаклизма). Если есть экзешники и экстрактор, то можно извлеч листы опкодов и посмотреть. А вообще листы опкодов для этих версий есть в ветке 1.12, 2.4.3 и мастер

RomanRom2
03.03.2011, 18:03
да не, опкоды в клиенте - это косяк близзов, большая редкость. такое было по моему раза 4 за всю историю. но то были промежуточные билды.

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

я просто к чему... если делать БК, то 2.4.3, если ВЛК, то 3.3.5, если классик, то 1.12.1, другие билды уже нафиг не нужны и смысла в них ноль.

Йоха
03.03.2011, 19:44
Подскажите какой сейчас опкод на смену сидов ? раньше было CMSG_AUTH_NEW_SESSION, но сейчас что-то не найду его в списке

EDIT:

разобрался, это опкод 0x0E4C

srv38
20.04.2011, 17:37
У меня пока получилось снифать весь трафик между клиентом и сервером и получать ключ сессии, теперь надо трафик расшифровать, по какому алгоритму он шифруется?:dntknw:

Йоха
20.04.2011, 17:44
У меня пока получилось снифать весь трафик между клиентом и сервером и получать ключ сессии, теперь надо трафик расшифровать, по какому алгоритму он шифруется?:dntknw:

Функция расшифровки есть в tiawps, я брал оттуда.
Лично для меня самое сложное было написать алгоритм сборки целых пакетов из кусков raw-потока. На отладку убил пол дня.

HuntsMan
29.04.2011, 15:11
Можете подсказать адрес ключа для 4.1.0?

Йоха
29.04.2011, 15:40
все есть на форуме. Базу иды выкладывает TOM_RUS, в этой же теме есть сообщение как найти адрес ключа в базе.

HuntsMan
29.04.2011, 17:12
все есть на форуме. Базу иды выкладывает TOM_RUS, в этой же теме есть сообщение как найти адрес ключа в базе.
Я видел эти сообщения. Проблема заключается в том, что я до сих пор не пойму как в IDA увидеть адрес того или иного элемента :sorry:

Йоха
30.04.2011, 08:53
Я видел эти сообщения. Проблема заключается в том, что я до сих пор не пойму как в IDA увидеть адрес того или иного элемента

Смотри, как описано на предыдущей странице ищем функцию по уникальной строке. Внутри нее есть такой кусок :
http://мангос.рф/attachment.php?attachmentid=888&stc=1&d=1304141916

Этот момент понятен ?
Тогда заходим в функцию ClientServices__GetCurrent, там видим:
http://мангос.рф/attachment.php?attachmentid=889&stc=1&d=1304142383

На этот раз переменная переименована в g_clientConnection, что бы увидеть ее адрес нажимаем на нее 2 раза мышью:
http://мангос.рф/attachment.php?attachmentid=890&stc=1&d=1304142561

Слева ее адрес - .data:00D03F14, он то нам и нужен. .data: - означает что переменная находится в сегменте с именем .data. нас это мало интересует, нам важно смещение внутри сегмента, это число после двоеточия.

Аналогично с функцией ClientServices__GetSessionKey.
Только там мы видим следующее:
http://мангос.рф/attachment.php?attachmentid=891&stc=1&d=1304142981
Здесь нужное нам число окрашено в зеленый цвет.

Еще вопросы остались ?

HuntsMan
30.04.2011, 11:29
Спасибо :) Все понял, все замечательно :) Просто навигация в IDA по-моему малость неудобная. Кстати, если вдруг кому пригодится, то вот хорошенькая книженция (http://fox3264.narod.ru/literatura/Obraz_myshleniya_-_dizassembler_IDA.pdf)

Йоха
12.05.2011, 14:58
Подгонял снифер под 14007 билд, обнаружил любопытную вещь: клиент теперь умудряется открывать 2 соединения на одинаковый адрес:порт. В моей реализации это вызывало сбой, поскольку делалось предположение что пара адрес:ип уникальна.

Lordronn
12.05.2011, 15:20
Хм, вот уже 3 дня пишу свой прокси для 4.1.0а. Ниразу не замечал, чтобы был 1 адресс и порт по несколько раз

Йоха
12.05.2011, 15:22
Я вчера офигел, сегодня ситуация повторялась. сперва я подумал что это у меня глюк. Открыл окно проксифиера, долго пялился на адреса, действительно было 2 коннекта на одинаковый адрес и порт, даже скрин сделал

HuntsMan
12.05.2011, 17:53
Мммм близзы знают толк в извращеньях. Я просто новый класс соединения создаю, и запихиваю его в контейнерный класс.

RomanRom2
12.05.2011, 18:10
да почему в извращеньях то? почему вы озадачены подключениями на один и тот же target? раньше ведь все коннектились на какой нибудь localhost:3724 тремя клиентами одновременно и ничего...

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

HuntsMan
12.05.2011, 18:11
Если я правильно понял Йоху, то клиент открыл 2 соединения на один и тот же хост и порт, это помоему извращение.

ЗЫ: А у меня сейчас впервые в жизни клиент открыл соединения только с 3724 и 1119 :D обычно ещё на 80 порты соединений 5 откроет :)

alien
12.05.2011, 18:32
А в чем извращение то? Я вот тоже не понимаю. Ну подумаешь клиент открывает соединения на один и тотже хост, порт что в этом такого то?

Йоха
12.05.2011, 18:50
Если я правильно понял Йоху, то клиент открыл 2 соединения на один и тот же хост и порт, это помоему извращение.

Правильно понял, я тоже так думаю -)

Роман смотри как это получается (например):
клиент открывает коннект на адрес 195.12.246.210:3724
потом там с десяток пакетов пробегает, он открывает новое соединение на адрес 195.12.246.213:3724 (или 211 или 212) и закрывает первое.
И в это одно соединение бегают редкие пакетики (наверно варден).
В это время клиент находится в окне выбора персонажей. При входе в мир он открывает еще одно соединение ну там опять же допустим на адрес 195.12.246.212:3724. И получается что у клиента два активных соединения:
195.12.246.212:3724
195.12.246.213:3724

А бывает что после входа в мир остаются два соединения абсолютно одинаковых:
195.12.246.211:3724
195.12.246.211:3724

Хотя бывали случаи что клиент открывает одно соединение и до входа в мир в это одно соединение и работает

Lordronn
12.05.2011, 18:52
И получается что у клиента два активных соединения:
195.12.246.212:3724
195.12.246.213:3724

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

HuntsMan
12.05.2011, 19:09
Подтверждаю слова Йохи:
http://filebeam.com/c1248889bf4b97f686b1d78049de9656.jpg

Непонимаю только зачем так делать...

Lordronn
12.05.2011, 19:14
Глянь в лог проксикапа. Мб он закрыл коннект и потом появился такой-же новый.

HuntsMan
12.05.2011, 19:20
Да не закрывает он ничего... Держутся 2 активных соединения на один и тот же хост и порт

Йоха
12.05.2011, 19:23
Уверен что они активны? Может он их закрывает, а ты просто не пишешь информацию о закрытии соединения?(у тебя ведь консольный сниффер?)

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

У меня в снифере корректно отслеживаются октрытия/закрытия соединений.

[Добавлено]
Вот сейчас клиент открыл всего 1 соединение до входа в мир, а при входе еще одно, точно такое же, и все прекрасно работает

http://мангос.рф/attachment.php?attachmentid=945&stc=1&d=1305218185

http://мангос.рф/attachment.php?attachmentid=946&stc=1&d=1305218185

RomanRom2
12.05.2011, 21:02
я не понимаю, чего вы паритесь... честно, не понимаю. я же объяснил, так ведет себя близовский лоадбалансер. ну выбирает он тот же хост, в чем проблема?

вы должны понимать, что это ВТОРОЕ соединение и работает оно соответствующе, сервер с клиентом это вот понимают. а вы чего? =)

HuntsMan
12.05.2011, 21:14
вы должны понимать, что это ВТОРОЕ соединение и работает оно соответствующе, сервер с клиентом это вот понимают. а вы чего? =)
Пытаемся понять а на*** все это :) Думаю что теперь по умолчанию подымается 2 соединения на одном хосте, а потом в зависимости от нагрузки одно из соединений закрывается, и открывается на другом хосте.

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

не спрашивайте на*** это все, не знаю =) это нужно принять как свершившийся факт и жить с этим.

Lordronn
12.05.2011, 21:28
Йоха, я думал ты имеешь ввиду 2 абсолютно одинаковых коннекта.
Тут же порт клиента разный. адресс 127.0.0.1, а порт то меняется

Йоха
12.05.2011, 21:43
Йоха, я думал ты имеешь ввиду 2 абсолютно одинаковых коннекта.
Тут же порт клиента разный. адресс 127.0.0.1, а порт то меняется

да это все понятно. Раньше такого не было, я сколько снифал всегда коннекты были на разные адреса или порт. Это только с 14007 билда пошла такая фигня что коннекты оказываются на один и тот же адрес порт.
В этом ясное дело нет ничего сверхъестественного, просто именно на 14007 билде мой снифер стал падать, до этого все работало, и это меня и удивило. Я уже исправил недочет, сейчас тоже все снифается без проблем.

HuntsMan
12.05.2011, 21:50
странные вы...
второе соединение устанавливается со времен 3.3.5, ну правда тогда оно просто переключалось. не помню с какого момента связь клиента с миром поддерживается двумя соединениями. они даже в клиенте по разному обозначаются и показывают каждый свое latency.

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

RomanRom2
12.05.2011, 22:14
ну судя по предыдущему сообщению не совсем наизусть =)

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

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

после установки второго коннекта лоадбалансер уже ничего не указывает. он уже указал.

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

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

Grinder
22.05.2011, 13:57
Разщбираюсь со снифером! Как образец взял tiawps.
Добился получения процесса!
Но блин упорно не хочет читать SessionKey :(

В tiawps делают вот так:


DWORD number_of_read_bytes=0;

char pointer[4] = {'\0'};
ReadProcessMemory(wow_process_handle, (LPCVOID)CONNECTION_PTR_OFFSET, pointer, 4, &number_of_read_bytes);

if(number_of_read_bytes != 4)
{
printf("couldn't read pointer, just read %u bytes instead of 4\n", number_of_read_bytes);
CloseHandle(wow_process_handle);
return FALSE;
}
// convert bytes to pointer
unsigned int sessionKeyPosition = 0;
memcpy(&sessionKeyPosition, pointer, 4);
printf("Got pointer: %#X\n", sessionKeyPosition);

number_of_read_bytes = 0;
ReadProcessMemory(wow_process_handle, (LPCVOID)(SESSIONKEY_OFFSET+sessionKeyPosition), sessionKey, SESSIONKEY_LENGTH, &number_of_read_bytes);
CloseHandle(wow_process_handle);
if(number_of_read_bytes != SESSIONKEY_LENGTH)
{
printf("couldn't read sessionkey, read %u bytes instaed of %u\n", number_of_read_bytes, SESSIONKEY_LENGTH);
return FALSE;
}


Это забил в enum'е чтобы не передавать параметры

SESSIONKEY_LENGTH = 40
SESSIONKEY_OFFSET = 0x508
CONNECTION_PTR_OFFSET = 0x00D03F14

Для проверки делал вывод в консоль на равенство
if(number_of_read_bytes != SESSIONKEY_LENGTH)

В итоге плучил что number_of_read_bytes = 0!!!!! Где косяк?

zergtmn
22.05.2011, 14:30
Win7? ASLR?

TOM_RUS
22.05.2011, 14:31
Разщбираюсь со снифером! Как образец взял tiawps.
Добился получения процесса!
Но блин упорно не хочет читать SessionKey :(

В tiawps делают вот так:


DWORD number_of_read_bytes=0;

char pointer[4] = {'\0'};
ReadProcessMemory(wow_process_handle, (LPCVOID)CONNECTION_PTR_OFFSET, pointer, 4, &number_of_read_bytes);

if(number_of_read_bytes != 4)
{
printf("couldn't read pointer, just read %u bytes instead of 4\n", number_of_read_bytes);
CloseHandle(wow_process_handle);
return FALSE;
}
// convert bytes to pointer
unsigned int sessionKeyPosition = 0;
memcpy(&sessionKeyPosition, pointer, 4);
printf("Got pointer: %#X\n", sessionKeyPosition);

number_of_read_bytes = 0;
ReadProcessMemory(wow_process_handle, (LPCVOID)(SESSIONKEY_OFFSET+sessionKeyPosition), sessionKey, SESSIONKEY_LENGTH, &number_of_read_bytes);
CloseHandle(wow_process_handle);
if(number_of_read_bytes != SESSIONKEY_LENGTH)
{
printf("couldn't read sessionkey, read %u bytes instaed of %u\n", number_of_read_bytes, SESSIONKEY_LENGTH);
return FALSE;
}


Это забил в enum'е чтобы не передавать параметры

SESSIONKEY_LENGTH = 40
SESSIONKEY_OFFSET = 0x508
CONNECTION_PTR_OFFSET = 0x00D03F14

Для проверки делал вывод в консоль на равенство
if(number_of_read_bytes != SESSIONKEY_LENGTH)

В итоге плучил что number_of_read_bytes = 0!!!!! Где косяк?

GetLastError() и смотрите код ошибки...

Grinder
22.05.2011, 14:33
Win7? ASLR?

Да, Win7

Konctantin
22.05.2011, 14:54
попробуйте так:
http://ru-mangos.ru/showpost.php?p=12460&postcount=4

Lordronn
27.05.2011, 08:52
Я правильно понимаю принцип декриптации:

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

Konctantin
27.05.2011, 09:30
Сначала используются сиды по умолчанию, а потом по уже вытягиваются из пакета...

Lordronn
27.05.2011, 09:57
А, т.е первые 4 все же зашифрованы, но default сидами

Konctantin
27.05.2011, 09:59
нет, они не зашифрованы, просто после них надо декриптовать с default сидами, а уже после установки новых коннектов - вытаскивать из пакетов.

Lordronn
27.05.2011, 14:14
Так пакет с сидами идет почти с сразу. Он то ли третий, то ли четвертый. или мы его пропускаем и ждем такой же следующий? А до него все расшифровываем default сидами

LordJZ
27.05.2011, 16:38
Так пакет с сидами идет почти с сразу. Он то ли третий, то ли четвертый. или мы его пропускаем и ждем такой же следующий? А до него все расшифровываем default сидамиВот я написал примерный код для расшифровки RAW 3.1, только не тестил: https://gist.github.com/995263

Йоха
27.05.2011, 16:54
Так пакет с сидами идет почти с сразу. Он то ли третий, то ли четвертый. или мы его пропускаем и ждем такой же следующий? А до него все расшифровываем default сидами

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

Lordronn
28.05.2011, 16:59
1.Хм, если я решу сменить реалм не входя в игру, то у меня откроется новое соединение. Получается для пакетов с этого соединения надо будет использовать сиды из пакета? Или только для игровых пакетов, которые идут при входе на персонажа????

2.Как отследить время, когда надо закрывать соединение? Единственное что приходит в голову, там это смотреть когда придет реконект пакет и закрывать соединение, с которого оно пришло

Йоха
29.05.2011, 12:23
1.Хм, если я решу сменить реалм не входя в игру, то у меня откроется новое соединение. Получается для пакетов с этого соединения надо будет использовать сиды из пакета? Или только для игровых пакетов, которые идут при входе на персонажа????

неважно куда соединение, первое - сиды по умолчанию, все остальные из пакета


2.Как отследить время, когда надо закрывать соединение? Единственное что приходит в голову, там это смотреть когда придет реконект пакет и закрывать соединение, с которого оно пришло


ничего не нужно отслеживать, клиент сам все закрывает

Йоха
07.07.2011, 09:00
Наконец-то на работе смог зайти в ВоВ после патча 4.2.
Близы что-то накосячили с поддержкой uPnP, получилось зайти в мир только после того как отключил в ADSL модеме поддержку uPnP. Хотя может это DLINK криво этот протокол реализовал в модеме...

Поправил снифер до 14333 билда, собственно все как обычно: новые опкоды, новый адрес ключа, новый порядок сборки сидов

Lordronn
07.07.2011, 12:16
Везет, а я с 4.1.0 совокуплялся дня 3 без перерыва. Так и не собрал нормальный декриптор.

Йоха
07.07.2011, 15:04
пиши сюда в чем затык, буду подсказывать

Lordronn
07.07.2011, 16:35
Решил переписать его почти с 0. Оставлю только саму прокси часть и мемори ридер. Начал с обнаружения сессион кея. Надеюсь я все верно нашел

public long SessionKey = 0x00D7DA5C;

Lordronn
07.07.2011, 18:45
Пошаманил я с декриптором, но оценить работу не могу ввиду отсутствия многих данных. Я пока смог найти только 2 пакета:

SMSG_AUTH_CHALLENGE = 35856,
CMSG_AUTH_SESSION = 10656,

Со второго соединения поймал пакет. Опкод = 416, длина 36 байт. Это случайно не CMSG_AUTH_CONTINUED_SESSION ?

Дальше он ничего не уловил, что и не странно.

В 4.2.0 SMSG_AUTH_CHALLENGE порядок чтения сидов тотже? Я пытался выяснить это сам с помощью ИДЫ, но ничего толком не понял в этом обработчике

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

Йоха
07.07.2011, 20:44
Адрес ключа верный.

Сборка сидов совершенно ясно описана в функции
.:: Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 50 сообщение(ий)) ::.

С опкодами еще проще, в первом соединении после дурацких безопкодных пакетов идут подряд
SMSG_AUTH_CHALLENGE
CMSG_AUTH_SESSION
А во втором
SMSG_AUTH_CHALLENGE
CMSG_AUTH_NEW_SESSION (или как у тебя называется CMSG_AUTH_CONTINUED_SESSION )

Lordronn
07.07.2011, 21:30
Ясно, а я пытался разобраться в PH_SMSG_AUTH_CHALLENGE)


А как быть с ASLR? Читаю и получаю одни нули. Читаю после AUTH_NEW_SESSION

Сделать как говорит Константин

да, это она противная и была,
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Session Manager\Memory Management]
"MoveImages"=dword:00000000
Оффеты верны, ключ получил и локаль тоже

не получается, из-за отсутствия в реестре MoveImages на Win7 x64 Ultimate. Использовал глаза и поиск - нету. Дебаг привилегия присутствует

Йоха
07.07.2011, 21:38
Ну правильно, его там нет по умолчанию, создай этот параметр

Или используй метод чтения памяти процесса с учетом ASLR, тут на форуме где-то была тема, там я и ТОМ_РУС выкладывали решение, вот тема (http://мангос.рф/showthread.php?t=4394&highlight=aslr)

Lordronn
08.07.2011, 13:34
А может быть такое, что пакет разбило не на 2 части, а на 21? Я тут сделал вывод информации дабы посмотреть. Увидел что 1 пакет разбили на 22 части.

Йоха
08.07.2011, 13:45
Конечно может.
Данные приходят в программу по протоколу TCP, а уж пакеты ВоВ собирай сам.
Нет никакого правила какими кусками данные будут поступать в твою программу, это зависит от типа подключения, загруженности канала, сетевого оборудования, настроек сети, провайдера и еще фиг знает от чего.

Например у меня проверяется в таком порядке:
0. Получаем данные с сокета, копируем в буфер.
1. Ожидаем недостающие данные или ждем начало нового пакета?
2. Хватает данных для обработки заголовка пакета ? (размер данных минимум 4 байта (сервер) или 6 (клиент), если нет то переходим к 0.
3. Проверка на "большой" пакет
4. Хватат ли данных для большого пакета ? (плюс 1 байт), если нет то переходим к 0.
5. В этом месте уже ясно что за опкод и размер пакета. Следовательно ждем данные равные размеру пакета
6. Пакет есть в буфере целиком - обрабатываем его, если нет то переходим к 0.
7. Повторяем с пункта 2 пока данные в буфере не закончились, иначе переходим к 0.

Lordronn
08.07.2011, 14:22
У меня почти также. Осталось побороть ASLR. Не очень понял зачем нужен BaseAddress в C#. Для чтения я прибегнул к функции ReadProcessMemory из библиотеки kernel32.

В ХР я читал так

public byte[] ReadSessionKey()
{
using (ProcessMemoryReader reader = new ProcessMemoryReader("wow"))
{
return reader.Read(reader.ReadInt(_wow.SessionKey) + _wow.Offset, 40L);
}
}


public long SessionKey = 0x00D7DA5C;
public long Offset = 0x508;

Йоха
08.07.2011, 15:39
По умолчанию в виндах до версии 7 процесс загружается в память по виртуальному адресу 0x00400000, и этот адрес не меняется для всех программ (если не предпринимать специальных действий для этого).
В семерке поменяли механизм загрузки процессов в память и теперь (при включеном ASLR, а он по умолчанию включен) базовый адрес выбирает неким случайным образом винда.
И адрес 0x00D7DA5C который мы берем из IDA (которая тоже предполагает что процесс грузится по адресу 0x00400000) будет неверным если винда выберет любой другой базовый адрес.
Что бы исправить это недоразумение вычисляем смещение адреса ключа относительно базового адреса 0x00400000 (0x00D7DA5C - 0x00400000 = 0x0097DA5C).
В снифере получаем BaseAdress процесса wow.exe, прибавляем к нему полученный 0x0097DA5C и получаем валидный адрес по которому находится ключ в памяти с учетом ASLR.

Lordronn
08.07.2011, 16:51
Собственно с ключем вроде разобрался благодаря Косте! Хотяя вроде все ровно не тот ключ, ибо после разбора пакетов получаю большой размер.Йоха, можешь кинуть лог я посмотрю правильно ли декриптую или нет по номерам опкодов

Sid
08.07.2011, 18:58
Йоха, на шарпе пишешь сниффер? Хотелось бы начать подробней изучать принципы и механизм работы подобных программ :)

Йоха
08.07.2011, 19:47
Йоха, можешь кинуть лог я посмотрю правильно ли декриптую или нет по номерам опкодов

лог чего ? Работы снифера ?
ну вот, включил вывод отладочной информации в консоль (это логин до состояние окна выбора персонажа):
ready
connect 195.12.234.53:80
close 195.12.234.53:80
connect 213.248.127.130:1119
connect 195.12.246.220:3724
* StartSession
S opcode=0x0000 len= 48 , ip = 195.12.246.220:3724 (009C)
C opcode=0x0000 len= 48 , ip = 195.12.246.220:3724 (009C)
S opcode=0x8C10 len= 39 , ip = 195.12.246.220:3724 (009C)
C opcode=0x29A0 len= 360 , ip = 195.12.246.220:3724 (009C)
got key
S opcode=0xBEFB len= 14 , ip = 195.12.246.220:3724 (009C)
S opcode=0x0B27 len= 882 , ip = 195.12.246.220:3724 (009C)
S opcode=0x6AAE len= 262 , ip = 195.12.246.220:3724 (009C)
S opcode=0xA237 len= 6 , ip = 195.12.246.220:3724 (009C)
S opcode=0x7E72 len= 34 , ip = 195.12.246.220:3724 (009C)
S opcode=0x0410 len= 271 , ip = 195.12.246.220:3724 (009C)
connect 195.12.246.219:3724
S opcode=0x0000 len= 48 , ip = 195.12.246.219:3724 (0104)
C opcode=0x0000 len= 48 , ip = 195.12.246.219:3724 (0104)
S opcode=0x8C10 len= 39 , ip = 195.12.246.219:3724 (0104)
C opcode=0x01A0 len= 40 , ip = 195.12.246.219:3724 (0104)
C opcode=0xF226 len= 4 , ip = 195.12.246.220:3724 (009C)
C opcode=0x1091 len= 4 , ip = 195.12.246.220:3724 (009C)
C opcode=0xB6E2 len= 8 , ip = 195.12.246.220:3724 (009C)
S opcode=0x8490 len= 6 , ip = 195.12.246.220:3724 (009C)
C opcode=0x09A0 len= 8 , ip = 195.12.246.220:3724 (009C)
S opcode=0x0C10 len= 2 , ip = 195.12.246.219:3724 (0104)
C opcode=0x0920 len= 8 , ip = 195.12.246.220:3724 (009C)
close 195.12.246.220:3724
S opcode=0x3C02 len= 331 , ip = 195.12.246.219:3724 (0104)
C opcode=0x7E3B len= 8 , ip = 195.12.246.219:3724 (0104)
C opcode=0x7E3B len= 8 , ip = 195.12.246.219:3724 (0104)
C opcode=0x7E3B len= 8 , ip = 195.12.246.219:3724 (0104)
S opcode=0xAA66 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0xAA66 len= 146 , ip = 195.12.246.219:3724 (0104)
S opcode=0xAA66 len= 611 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 39 , ip = 195.12.246.219:3724 (0104)
C opcode=0xE2FB len= 5 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)
S opcode=0x7A36 len= 505 , ip = 195.12.246.219:3724 (0104)

Добавлено через 2 минуты
Йоха, на шарпе пишешь сниффер? Хотелось бы начать подробней изучать принципы и механизм работы подобных программ :)

Я c# не знаю вообще, пишу на с++.
Ну а механизмы они от языка не зависят -) Почитай эту тему с начала, тут очень много полезной информации, я сам начал писать снифер с нуля читая эту тема и задавая вопросы про непонятные места. Если что неясно, спрашивай, всегда готов ответить на вопросы.

Lordronn
08.07.2011, 22:57
Те, которые не зашифрованны идут нормально, что и не странно, а вот дальше идет бред. Размер самого пакета 16 байт, а после декриптовки получаю 17кб, при том что это пакет целый, а не частичный.

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

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

RomanRom2
08.07.2011, 22:59
значит ключ неправильный.

Lordronn
08.07.2011, 23:03
Я пропатчил реестр дабы вырубить ASLR, Йоха подтвердил что адрес верный. Чтение ключа идет верно

Йоха
09.07.2011, 08:33
Я пропатчил реестр дабы вырубить ASLR, Йоха подтвердил что адрес верный. Чтение ключа идет верно

Сиды правильно собираются ?

Покажи свой кусок кода где идет расшифровка заголовка пакета.

Lordronn
09.07.2011, 13:30
.:: Скрытый текст (вы должны войти под своим логином или зарегистрироваться и иметь 120 сообщение(ий)) ::.

LordJZ
09.07.2011, 14:23
Костя видимо вам скинул мой старый код от 4.0.6. Он не предназначен для работы с 4.1.0+.

Lordronn
09.07.2011, 16:59
Простите, а вы рабочем не поделитесь?

LordJZ
09.07.2011, 23:12
Напишите самостоятельно.

Йоха
12.07.2011, 09:59
Посетила мысль сделать очередной вариант снифера -) На этот раз он самодостаточен.
Тип - перехват функций WIN32 API. Перехватываются соответственно winsock функции: bind, connect, recv, send. Возможно что-то еще надо будет перехватывать ... там разберемся.
Преимущества такого подхода в том что не нужно городить огород из проксификаторов или подобных программ, ну и конечно то что можно влиять на происходящее - подменять данные, адреса и т.д. на лету. К тому же разбор данных не усложняется, а остается такой же как в прокси варианте снифера. Мы так же получаем готовые данные с сокета. И еще немаловажный момент - с точки зрения API все делается легально, никаких "грязных хаков" -). Память процесса wow.exe не меняется, warden спокойно курит.

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

RomanRom2
12.07.2011, 10:35
четвертое (http://wowcore.ru/history/sniffer4/) поколение? =)

Йоха
12.07.2011, 10:56
четвертое (http://wowcore.ru/history/sniffer4/) поколение? =)

Мне кажется у тебя другой принцип используется

В моем варианте просто перехват функций API, с сетевой моделью никак не связано, перехват осуществляется так же как и для любой другой функции.
Кстати посмотрел wow.exe импортирует функции из wininet.dll, видимо загружает файлы с веб сервера при помощи InternetreadFileExA, надо проверить что он там загружает и если что, то можно сделать сохранялку этих файлов себе куда-нибудь.

RomanRom2
12.07.2011, 15:37
винапишный хук по моему близзами палится.
все таки на данный момент безопасным способом является либо прокси/проксификатор, либо pcap/pssdk. самым скрытым и неспалеваемым способом по прежнему остается "четвертое поколение" (LSP), т.к. работает на уровне ос, куда приложению не добраться.

Йоха
12.07.2011, 15:52
У меня не хук, это раз
Перехват API можно делать разными способами это два
Первый - правка таблицы импорта - палево, ибо изменяется память процесса
Второй - splicing - не все антивирусы даже палят такое дело. меняется код самой API функции

Ну и как показывает практика, вов нормально работает.

Насчет бесплалевности LSP весьма сомнительно...
Ничто не мешает близам запустить во время работы вов драйвер и спалить все потроха ОС и все что хочешь...

RomanRom2
12.07.2011, 22:33
сплайсинг сам по себе тоже по сути хук. причем при кажущейся перспективности - один хрен в чужой процесс лезть надо. то есть инжект. а дальше пошло поехало: ридПроцессМемори, РайтПроцессМемори, проблемы ASLR и тд и тп. насчет антивирусов - они это палят только в путь, особенно если реализация сделана баяном с прологом в 5 байт, антивирусы (все) проверяют прологи на джамп за пределы модуля.

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

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

GriffonHeart
13.07.2011, 07:18
очень и очень много параноиков, трясущихся за свою ******у на винте и пароли от одноклассников.
Последнее улыбнуло :D

Йоха
13.07.2011, 07:24
ASLR - проблема это только проблема если атакуется комп через сеть, когда нет доступа к компьютеру.
Если атака делается уже с этого компьютера то базовый адрес приложения вычисляется тремя строчками кода. Так что никакой проблемы на самом деле нет.

Все остальное верно, но не существенно. Так сказать на летные характеристики не влияет.

Я уже реализовал подход с перехватом как ты говоришь "баянистым" -) путем джампа на месте стандартного пролога. и все чудесно, антивирь молчит, вов играет, я получаю данные.
Кстати есть такая штука: detours - автор сама MS, сейчас это монстрило стоит 10к зелени, но первый ее простой вариант в виде одного .h и 1 .cpp файла прекрасно справляется с поставленой задачей

RomanRom2
13.07.2011, 10:36
ну это реально новый тип снифера, давайте назовем это пятым поколением чтоли :)
причем я думаю без разницы как именно, либо слайсинг, либо через таблицу импорта - технология одна, через перехват winapi.

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

Йоха
13.07.2011, 15:35
причем я думаю без разницы как именно, либо слайсинг, либо через таблицу импорта - технология одна, через перехват winapi.

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


каким образом различаются второй и последующие коннекты клиента?

точно так же как и в прокси варианте. Обрабатывается вызов функции connect


возможно ли разные коннекты хендлить в разных обработчиках?

да без проблем, в функции recv и send первым параметром идет SOCKET, для разных SOCKET вызываем разные обработчики если есть такая нужда.

P.S. внедрение в процесс производится тремя вариантами:
1) глобальный хук
2) CreateRemoteThread
3) использование раздела реестра KnownDLLs

У меня сейчас используется 2 вариант

LordJZ
13.07.2011, 17:01
...
P.S. внедрение в процесс производится тремя вариантами:
1) глобальный хук
2) CreateRemoteThread
3) использование раздела реестра KnownDLLs
...Кстати, я сегодня написал сниффер, напрямую пишущий бинарный код в память клиента. Работает отлично.

Йоха
13.07.2011, 19:23
Кстати, я сегодня написал сниффер, напрямую пишущий бинарный код в память клиента. Работает отлично.

а что пишется ?

LordJZ
13.07.2011, 19:46
а что пишется ?Предварительно и «налету» собираемый х86 исполняемый код.

Йоха
13.07.2011, 19:58
Предварительно и «налету» собираемый х86 исполняемый код.

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

RomanRom2
13.07.2011, 22:38
вы про инжектор? да, инжектор - самый бронебойный вариант. только там надо много писать - изменить то что тебе надо, плюс подхачить проверки клиента. а их там несколько насколько я помню.

Ven
05.11.2011, 08:43
может кто подскажет? что случилось с опкодами в 4.2.2 или ранее, я уж не знаю (последний раз этим занимался в 3.2.0)? Чет цифры там уж нереально большие после дешифровки.

Konctantin
05.11.2011, 08:46
они рандомные, и имеют значение в 0x0000-0хFFFF

Deamon
07.11.2011, 15:42
может кто подскажет? что случилось с опкодами в 4.2.2 или ранее, я уж не знаю (последний раз этим занимался в 3.2.0)? Чет цифры там уж нереально большие после дешифровки.

Привет :pleasantry:.
Опкоды меняются с каждым билдом начиная с релиза катаклизма. Близзы своим алгоритмом каждый раз генгерят рандомный набор опкодов.