PDA

Просмотр полной версии : Пакеты клиент <-> сервер


Dubstep
22.06.2013, 16:35
Доброго времени суток, решил опять посидеть над мангосом, и глянул сразу на катаклизм. Раньше насколько я помню было простое считывание через поток данных из пакета, а сейчас вижу что то добавилось какие-то WriteGuidBytes, WriteGuidMask. Буду благодарен если кто то расскажет(может уже где то обсуждалось, но не нашёл) что это вообще такое и что за числа, например тут:
data.WriteGuidMask<0, 3, 6, 7, 2, 5, 1, 4>.

WorldPacket data(SMSG_MOVE_KNOCK_BACK, 9 + 4 + 4 + 4 + 4 + 4 + 1 + 8);
data.WriteGuidMask<0, 3, 6, 7, 2, 5, 1, 4>(guid);
data.WriteGuidBytes<1>(guid);
data << float(vsin); // y direction
data << uint32(0); // Sequence
data.WriteGuidBytes<6, 7>(guid);
data << float(horizontalSpeed); // Horizontal speed
data.WriteGuidBytes<4, 5, 3>(guid);
data << float(-verticalSpeed); // Z Movement speed (vertical)
data << float(vcos); // x direction
data.WriteGuidBytes<2, 0>(guid);
SendPacket(&data);

Заранее Спасибо!

Fabian
22.06.2013, 17:00
the numbers are for the indexes of the guid. the guid (uint64) is splitted to a byte array (length = 8).

if the value at the specific position is > 0, then True is written to the bit stream, else false.

The same for the guidbytes, if the value at the index is true the specific byte value is written to the buffer.

Dubstep
22.06.2013, 17:23
Thank you! Do not tell me how to find the indexes codes?

Amaru
22.06.2013, 22:47
Клиент дизассемблить и вытаскивать, больше никак. Ну или можно в тринях смотреть и их WPP, но там не все правильно.

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

Dubstep
23.06.2013, 00:55
Спасибо, буду разбираться!

открыл этот же пакет, но как можно довести индексы до понятного вида? guid[0] и так далее.
http://paste2.org/vHNvOHFH

Ещё интересует вопрос по поиску опкода, в ида про это возможно?
_ESI = (SMSG_MOVE_KNOCK_BACK_struct *)this;

Нужно найти один пакет, номер его есть, но структура кривая...

Lordronn
23.06.2013, 20:41
открыл этот же пакет, но как можно довести индексы до понятного вида? guid[0] и так далее.

Вот у тебя бит маска
v5 = v12;

_ESI->guid[0] = (unsigned int)v12 >> 7;

v5 *= 2;

_ESI->guid[3] = (unsigned int)(unsigned __int8)v5 >> 7;

v5 *= 2;

v6 = (unsigned int)(unsigned __int8)v5 >> 7;

v5 *= 2;

_ESI->guid[6] = v6;

v7 = (unsigned int)(unsigned __int8)v5 >> 7;

v5 *= 2;

_ESI->guid[7] = v7;

v8 = (unsigned int)(unsigned __int8)v5 >> 7;

v5 *= 2;

_ESI->guid[2] = v8;

v9 = (unsigned int)(unsigned __int8)v5 >> 7;

v5 *= 2;

_ESI->guid[5] = v9;

v10 = (unsigned int)(unsigned __int8)v5 >> 7;

_ESI->guid[1] = v10;

_ESI->guid[4] = (unsigned __int8)(2 * v5) >> 7;

а ниже уже идет чтение по битмаске

if ( _ESI->guid[7] )

{

BYTE3(a2) = 0;

CDataStore_GetInt8(v3, (int)((char *)&a2 + 3));

_ESI->guid[7] ^= BYTE3(a2);

}

Dubstep
23.06.2013, 21:19
Где бит маска и тп я вижу :)

Вопрос как найти индексы, т.е. довести

*((_BYTE *)v4 + 16) = (unsigned int)v12 >> 7;
До
_ESI->guid[0] = (unsigned int)v12 >> 7;

p.s. Сори за тупые вопросы, с ида не так сильно знаком :)

Lordronn
23.06.2013, 22:20
guid[0] - вот 0 твой индекс

Dubstep
23.06.2013, 22:55
Вы наверное не поняли.

Я про то что, у меня есть только
*((_BYTE *)v4 + 16) = (unsigned int)v12 >> 7; <- тут не понятно какой индекс

Вопрос со стоит как сделать так:
_ESI->guid[0] = (unsigned int)v12 >> 7; <- тут уже видно что индекс 0, но как дойти до этого(Это вариант Amaru)

Evgeniy
24.06.2013, 10:17
*((_BYTE *)v4 + 16) = (unsigned int)v12 >> 7; [0]
*((_BYTE *)v4 + 19) = (unsigned int)v5 >> 7; [3]
*((_BYTE *)v4 + 22) = (unsigned int)v5 >> 7; [6]
*((_BYTE *)v4 + 23) = (unsigned int)v5 >> 7; [7]
*((_BYTE *)v4 + 18) = (unsigned int)v5 >> 7; [2]
*((_BYTE *)v4 + 21) = (unsigned int)v5 >> 7; [5]
*((_BYTE *)v4 + 17) = (unsigned int)v5 >> 7; [1]
*((_BYTE *)v4 + 20) = (unsigned int)v5 >> 7; [4]
как то так наверное:pardon:

Amaru
24.06.2013, 11:56
v4 - адрес структуры, выражение в скобках - смещение по адресу.
ида имеет редактор структур + умеет предугадывать структуры
кликаешь правой кнопкой по переменной -> Create new struct type

00000000 SMSG_MOVE_KNOCK_BACK_struct struc ; (sizeof=0x20)
00000000 f0 db 16 dup(?)
00000010 guid db 8 dup(?) ; string(C)
00000018 f18 db 4 dup(?)
0000001C dword1C dd ?
00000020 SMSG_MOVE_KNOCK_BACK_struct endsструктура выглядит так, но может быть обобщена на многие другие опкоды

Dubstep
24.06.2013, 14:03
v4 - адрес структуры, выражение в скобках - смещение по адресу.
ида имеет редактор структур + умеет предугадывать структуры
кликаешь правой кнопкой по переменной -> Create new struct type

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

получилось, спасибо! :)

Есть ещё такой вопрос: как найти sub_* с нужным опкодом?

Amaru
25.06.2013, 10:29
Адреса нужно искать как написано здесь http://filebeam.com/80a86ab4f83b6f9e13a749e5646b257c, автор - Chameleon (http://ru-mangos.ru/member.php?u=4016).

Dubstep
26.06.2013, 19:49
Адреса нужно искать как написано здесь http://filebeam.com/80a86ab4f83b6f9e13a749e5646b257c, автор - Chameleon (http://ru-mangos.ru/member.php?u=4016).
Скомпилил указанную там тулзу, вписал в поле слева опкод 0x5CB4, в оффсете справа так ничего и не появилось :(

По вписывал разные, удалось ввести оффсет, кинул его в поиск ида, и ничего нужно не нашло, что делаю не так?

Amaru
27.06.2013, 11:50
Скомпилил указанную там тулзу, вписал в поле слева опкод 0x5CB4, в оффсете справа так ничего и не появилось :(

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

У меня нашло - special 0x16c
Это значит, что хендлер будет в NetClient__JAMClientDispatch в свиче с кейсом 0x16C, поэтому в коде дизассемблированном коде можно искать 0x16C


case 0x16Cu:
sub_6ADBE0((int)&v294, this, a2, a5, a3);
v175 = sub_6A7540(&v294);
sub_6A23E0(&v294);
result = v175;
break;

Dubstep
28.06.2013, 17:46
вводи десятичное число или копипасть, при вводе с клавиатуры тулза путает байты.

У меня нашло - special 0x16c
Это значит, что хендлер будет в NetClient__JAMClientDispatch в свиче с кейсом 0x16C, поэтому в коде дизассемблированном коде можно искать 0x16C


case 0x16Cu:
sub_6ADBE0((int)&v294, this, a2, a5, a3);
v175 = sub_6A7540(&v294);
sub_6A23E0(&v294);
result = v175;
break;

удалось найти. Спасибо, буду пробовать что ещё найти

Dubstep
08.07.2013, 19:06
Начал смотреть на CMSG опкоды, вот например тулза ничего не выдаёт по 0x0480, как быть?

Amaru
09.07.2013, 10:05
Тулза работает только с SMSG опкодами, для CMSG вычислять оффсеты смысла нет

Dubstep
09.07.2013, 16:09
Тулза работает только с SMSG опкодами, для CMSG вычислять оффсеты смысла нет
Не подскажите как найти структура пакетов для таких опкодов?

Amaru
09.07.2013, 16:26
Не подскажите как найти структура пакетов для таких опкодов?
Адреса нужно искать как написано здесь http://filebeam.com/80a86ab4f83b6f9e13a749e5646b257c, автор - Chameleon (http://ru-mangos.ru/member.php?u=4016).
Поиском CTRL+F по c-дампу
Будет что-то типа CDataStore__PutUInt32(xxx, 1152);

Fabian
09.07.2013, 16:34
and since a few patches, packet struct & opcode value are in different functions.
access by a off_xxxxxx

Dubstep
10.07.2013, 16:03
Спасибо. разобрался :)

Dubstep
11.07.2013, 17:52
Есть ещё не большой вопрос, заметил что с CMSG по особому читается, например
void WorldSession::HandleReorderCharactersOpcode(WorldP acket& recv_data)

recv_data.ReadGuidMask<1, 4, 5, 3, 0, 7, 6, 2>(guid);

Под этом надо тоже писать структуру по типу таких:
00000000 SMSG_MOVE_KNOCK_BACK_struct struc ; (sizeof=0x20)
00000000 f0 db 16 dup(?)
00000010 guid db 8 dup(?) ; string(C)
00000018 f18 db 4 dup(?)
0000001C dword1C dd ?
00000020 SMSG_MOVE_KNOCK_BACK_struct ends

?

Amaru
12.07.2013, 00:17
Там ничего особенного нет, также сначала считывается маска, потом байты
Посмотри опкод попроще, например CMSG_BATTLEMASTER_JOIN
char __thiscall PH_CMSG_BATTLEMASTER_JOIN(void *this, int a2)
{
char v2; // al@1
void *v3; // esi@1
char v4; // zf@1
char v5; // zf@1
char v6; // al@3
char v7; // al@5
char v8; // al@7
char v9; // al@9
char v10; // al@11
char v11; // al@13
char result; // al@15
int v13; // [sp+8h] [bp-8h]@1
int v14; // [sp+Ch] [bp-4h]@1

v3 = this;
CDataStore__PutInt32(30978);
CDataStore__PutInt32(*((_DWORD *)v3 + 4));
v4 = *((_BYTE *)v3 + 26) == 0;
v13 = a2;
LOBYTE(v14) = 2
* (2
* (*((_BYTE *)v3 + 20) | 2
* (2
* (2 * (2 * (2 * !v4 | *((_BYTE *)v3 + 24) != 0) | *((_BYTE *)v3 + 27) != 0) | *((_BYTE *)v3 + 25) != 0) | *((_BYTE *)v3 + 29) != 0)) | *((_BYTE *)v3 + 28) != 0) | *((_BYTE *)v3 + 30) != 0;
CDataStore__PutInt8(v14);
v5 = *((_BYTE *)v3 + 31) == 0;
BYTE1(v14) = 1;
LOBYTE(v14) = !v5;
sub_66ADB0(&v13);
v2 = *((_BYTE *)v3 + 26);
if ( v2 )
CDataStore__PutInt8(v2 ^ 1);
v6 = *((_BYTE *)v3 + 30);
if ( v6 )
CDataStore__PutInt8(v6 ^ 1);
v7 = *((_BYTE *)v3 + 28);
if ( v7 )
CDataStore__PutInt8(v7 ^ 1);
v8 = *((_BYTE *)v3 + 27);
if ( v8 )
CDataStore__PutInt8(v8 ^ 1);
v9 = *((_BYTE *)v3 + 31);
if ( v9 )
CDataStore__PutInt8(v9 ^ 1);
v10 = *((_BYTE *)v3 + 24);
if ( v10 )
CDataStore__PutInt8(v10 ^ 1);
v11 = *((_BYTE *)v3 + 29);
if ( v11 )
CDataStore__PutInt8(v11 ^ 1);
result = *((_BYTE *)v3 + 25);
if ( result )
result = CDataStore__PutInt8(result ^ 1);
return result;
}

00000000 CMSG_BATTLEMASTER_JOIN_struct struc ; (sizeof=0x20)
00000000 f0 db 16 dup(?)
00000010 instanceId dd ?
00000014 asGroup db ?
00000015 f15 db 3 dup(?)
00000018 guid db 8 dup(?) ; string(C)
00000020 CMSG_BATTLEMASTER_JOIN_struct ends


char __thiscall PH_CMSG_BATTLEMASTER_JOIN(void *this, int a2)
{
char v2; // al@1
CMSG_BATTLEMASTER_JOIN_struct *v3; // esi@1
char v4; // zf@1
char v5; // zf@1
char v6; // al@3
char v7; // al@5
char v8; // al@7
char v9; // al@9
char v10; // al@11
char v11; // al@13
char result; // al@15
int v13; // [sp+8h] [bp-8h]@1
int v14; // [sp+Ch] [bp-4h]@1

v3 = (CMSG_BATTLEMASTER_JOIN_struct *)this;
CDataStore__PutInt32(30978);
CDataStore__PutInt32(v3->instanceId);
v4 = v3->guid[2] == 0;
v13 = a2;
LOBYTE(v14) = 2
* (2
* (v3->asGroup | 2
* (2 * (2 * (2 * (2 * !v4 | v3->guid[0] != 0) | v3->guid[3] != 0) | v3->guid[1] != 0) | v3->guid[5] != 0)) | v3->guid[4] != 0) | v3->guid[6] != 0;
CDataStore__PutInt8(v14);
v5 = v3->guid[7] == 0;
BYTE1(v14) = 1;
LOBYTE(v14) = !v5;
sub_66ADB0(&v13);
v2 = v3->guid[2];
if ( v2 )
CDataStore__PutInt8(v2 ^ 1);
v6 = v3->guid[6];
if ( v6 )
CDataStore__PutInt8(v6 ^ 1);
v7 = v3->guid[4];
if ( v7 )
CDataStore__PutInt8(v7 ^ 1);
v8 = v3->guid[3];
if ( v8 )
CDataStore__PutInt8(v8 ^ 1);
v9 = v3->guid[7];
if ( v9 )
CDataStore__PutInt8(v9 ^ 1);
v10 = v3->guid[0];
if ( v10 )
CDataStore__PutInt8(v10 ^ 1);
v11 = v3->guid[5];
if ( v11 )
CDataStore__PutInt8(v11 ^ 1);
result = v3->guid[1];
if ( result )
result = CDataStore__PutInt8(result ^ 1);
return result;
}

Dubstep
13.07.2013, 22:22
спасибо!

blackmanos
08.08.2013, 08:03
а как найти адрес обработчика для такого типа пакетов?
SMSG_MAIL_LIST_RESULT = 0x4217, //15595
для простых выводит jam и по нему ищем, а тут выводит
Converted и Offset
что с ними делать чтоб найти обработчик?

Amaru
08.08.2013, 10:32
а как найти адрес обработчика для такого типа пакетов?
SMSG_MAIL_LIST_RESULT = 0x4217, //15595
для простых выводит jam и по нему ищем, а тут выводит
Converted и Offset
что с ними делать чтоб найти обработчик?
я писал инжектор, но возможно как-то проще можно сделать

blackmanos
09.08.2013, 03:48
похоже что можно, номер пакета встречается в коде так же как и клиентские номера пакетов.

Amaru
09.08.2013, 10:11
похоже что можно, номер пакета встречается в коде так же как и клиентские номера пакетов.
Как? Если обработчики лежат в массиве и индекс является функцией от опкода

blackmanos
09.08.2013, 10:32
поправка небольшая, так нашел пакет
SMSG_UPDATE_OBJECT
в мопе идет рекурсия и он сам себя по номеру вызывает.

Dubstep
29.08.2013, 18:23
В курсе кто нибудь что за опкод 0x1027, в тринити он идёт как CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, в мангосе похоже старое название.

Amaru
30.08.2013, 10:06
в мангосе его и нет.
определенно что-то связанное с гильдейскими ачивами

Dubstep
30.08.2013, 10:42
Он шлётся если открыть список ачив гильдии и нажать "Следить". И вот что там может отправляться не понятно О_о

Amaru
30.08.2013, 11:18
а снифы на что?)
http://paste2.org/Nag8AVFh
очевидно, айди ачив

Dubstep
31.08.2013, 12:04
ага, сначала количество потом сами ачивки.
Но что с ними делать? Может какие-то чудеса происходят при нажатии "Следить", кроме появления сбоку ачивок? :) На оффе не играл так что не знаю...

SeT
02.04.2014, 01:29
вводи десятичное число или копипасть, при вводе с клавиатуры тулза путает байты.

У меня нашло - special 0x16c
Это значит, что хендлер будет в NetClient__JAMClientDispatch в свиче с кейсом 0x16C, поэтому в коде дизассемблированном коде можно искать 0x16C


case 0x16Cu:
sub_6ADBE0((int)&v294, this, a2, a5, a3);
v175 = sub_6A7540(&v294);
sub_6A23E0(&v294);
result = v175;
break;

Попробывал сделать такую же магию, нашел case, только он другой... где в таком случае искать обработчик для smsg (билд 16048)?

case 0xFBu:
sub_7BE5C0(this, a2, a5, a3);
sub_751360(&v37);
sub_7B6C80(&v37);
result = 1;
break;

Amaru
02.04.2014, 14:56
Попробывал сделать такую же магию, нашел case, только он другой... где в таком случае искать обработчик для smsg (билд 16048)?

case 0xFBu:
sub_7BE5C0(this, a2, a5, a3);
sub_751360(&v37);
sub_7B6C80(&v37);
result = 1;
break;
Не понял, в чем проблема.
Вбиваем в OpcodeTools для 16048 опкод, получаем normal, special, либо auth
Вбиваем в поиск, получаем хендлер

SeT
02.04.2014, 15:25
Не понял, в чем проблема.
Вбиваем в OpcodeTools для 16048 опкод, получаем normal, special, либо auth
Вбиваем в поиск, получаем хендлер

Слона и не увидел =) Все нашлось, на своих местах. Спасибо.

SeT
28.07.2014, 08:58
Попался normal опокод - SMSG_AUCTION_BIDDER_LIST_RESULT (16135: hex - DB3, offset dec - 5148).
http://paste2.org/V75IIbKV

Дошёл до места - *(_DWORD *)(dword_11C95AC + 5148) = v6;

А вот куда дальше путь держать, не могу понять...

Amaru
29.07.2014, 14:48
Как уже говорили, сдампить можно хендлеры нормал опкодов, написав программу.
Либо прицепить дебаггер и посмотреть, какой обработчик вызывается

GriffonHeart
04.10.2014, 09:09
Использую http://www.privatepaste.com/7cc6a57a4d/SovakOpcodes
По второй колонке нахожу нужный мне sub_***
Но вот не могу найти у себя в ida опкоды, помеченные как LEGACY
Кто-нибудь знает, что это за опкоды и как их искать в ida?

Amaru
04.10.2014, 23:58
Использую http://www.privatepaste.com/7cc6a57a4d/SovakOpcodes
По второй колонке нахожу нужный мне sub_***
Но вот не могу найти у себя в ida опкоды, помеченные как LEGACY
Кто-нибудь знает, что это за опкоды и как их искать в ida?
Это "normal" опкоды в opcodetools

GriffonHeart
05.10.2014, 04:59
Это "normal" опкоды в opcodetools
И как для них найти читалку/писалку данных?

Amaru
06.10.2014, 21:58
И как для них найти читалку/писалку данных?
http://paste2.org/tA7HF34c

самый последний кусок вычислает обработчик нормал опкодов и вызывает его
(17538 билд)
там обычно в одной функции и читалка и обработка.
ну а писалки там нет, так как это серверные опкоды

Dubstep
26.11.2014, 00:16
всем привет. решил покапать 603, но вот наткнулся на проблемы.... что то не один из методов по поиску сабов не прокатывает :(
может кто подскажет как сейчас с этим обстоят дела и как найти их....

Amaru
27.11.2014, 01:59
клиентские как раньше ищутся, а серверные обработчики немного по другому
находим сначала NetClient::OneMessageReady
void __thiscall NetClient__OneMessageReady(void *this, int a2, int a3, int a4, signed int a5)
{
void *v5; // ebx@1
int v6; // edi@1
signed int v7; // eax@3
int v8; // eax@6
int v9; // eax@7
size_t v10; // esi@8
int v11; // eax@9
int v12; // ecx@13
signed int v13; // [sp-4h] [bp-12Ch]@19
char v14; // [sp+10h] [bp-118h]@8
void *v15; // [sp+10Ch] [bp-1Ch]@1
int (__stdcall **v16)(int, int, int); // [sp+110h] [bp-18h]@17
int v17; // [sp+114h] [bp-14h]@8
int v18; // [sp+118h] [bp-10h]@8
size_t v19; // [sp+11Ch] [bp-Ch]@8
int v20; // [sp+120h] [bp-8h]@8
int v21; // [sp+124h] [bp-4h]@8
int v22; // [sp+13Ch] [bp+14h]@9

v6 = a5;
v5 = this;
v15 = this;
if ( a5 < 4 || !a4 || (v7 = sub_653578(this, a2), v7 >= 4) )
goto LABEL_4;
v8 = (int)(v5 + v7 + 1650);
if ( *(_BYTE *)v8 )
{
v11 = *(_DWORD *)a4;
v22 = *(_DWORD *)a4;
if ( *(_DWORD *)a4 == 1882 )
{
v13 = 0;
}
else
{
if ( *(_DWORD *)a4 == 1994 )
{
NetClient__DecompressAndProcess(a2, a4 + 4, v6 - 4);
return;
}
if ( *(_DWORD *)a4 != 5962 )
{
if ( *(_DWORD *)a4 == 6105 )
{
NetClient__HandleMultiplePackets(a2, a3, a4 + 4, v6 - 4);
}
else
{
v12 = (v11 - 1) & 0xF6E;
if ( v12 == 1864 || v12 == 1896 )
{
v18 = 0;
v19 = -1;
v21 = 0;
v16 = &off_D62168;
v17 = a4 + 4;
v20 = v6 - 4;
NetClient__JAMClientConnectionDispatch(a2, a3, v11, &v16);
v16 = &off_D62168;
CDataStore__InternalDestroy(&v16);
}
else
{
if ( sub_6541A4(v5, a2) )
sub_6252E0(v22, (int)v5, a2, a4, v6);
}
}
return;
}
v13 = 1;
}
sub_653613(a2, a4 + 4, v6 - 4, v13);
return;
}
*(_BYTE *)v8 = 1;
v9 = strlen("WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT");
if ( sub_A3DE62(a4, "WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT", v9) )
{
LABEL_4:
sub_653F7D(a2, 3u);
sub_957D2F((LPCRITICAL_SECTION)a2);
return;
}
v10 = strlen("WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER") + 1;
memmove_0(&v14, "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER", v10);
v17 = (int)&v14;
v18 = 0;
v19 = v10;
v20 = 4;
v21 = 0;
WowConnection__Send(&v17, 1);
sub_53ACB3(
v18,
"d:\\buildserver\\wow\\4\\work\\wow-code\\branches\\wow-patch-6_0_3-branch-fastpatch-1\\wow\\source\\wowservices\\PacketPipe.h",
34,
0);
}
Эта штука проверяет айди коннекта, куда пришел опкод, определяет группу, к которой принадлежит опкод, и если все ок то ставит в очередь
if ( sub_6541A4(v5, a2) )
sub_6252E0(v22, (int)v5, a2, a4, v6);
вот этим, собственно, и ставит
if ( (unsigned __int8)(*(int (__cdecl **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)v7 + 0x18))(
a2,
a1,
a3,
a4,
a5) )массив собой представляет массив структур что-то вроде
[StructLayout(LayoutKind.Sequential)]
struct SMSGHandler
{
public IntPtr pName; // 0x0
public uint checker; // 0x4
public uint _2; // 0x8
public uint _3; // 0xC
public uint _4; // 0x10
public uint dataHandler; // 0x14
public uint connectionChecker; // 0x18
}я глубоко не вникал
pName - имя группы, checker - проверка принадлежности группы, dataHandler - адрес обработчика группы, connectionChecker - проверяет номер соединения (?)

вот так это выглядит в 19116
'ClientQuest'
Checker: 5F4D44
Connection Checker: 5F4D86
DataHandler: 5F4DD3
_2: 0
_3: 0
_4: 5F4D5C

'Client'
Checker: 5F8F77
Connection Checker: 5FF895
DataHandler: 5F90B3
_2: 0
_3: 0
_4: 5FF74D

'ClientGuild'
Checker: 61F2BD
Connection Checker: 61F2FF
DataHandler: 61F34C
_2: 0
_3: 0
_4: 61F2D5

'ClientSocial'
Checker: 62A9FD
Connection Checker: 62AA15
DataHandler: 62AA43
_2: 0
_3: 0
_4: 250000

'ClientSpell'
Checker: CAE449
Connection Checker: CAE52D
DataHandler: CAE5C8
_2: 0
_3: 0
_4: CAE4B5

'ClientMovement'
Checker: CB96EE
Connection Checker: CB9898
DataHandler: CB997B
_2: 0
_3: 0
_4: CB97BF

'ClientLFG'
Checker: CBC9E4
Connection Checker: CBCA26
DataHandler: CBCA54
_2: 0
_3: 0
_4: CBC9FC

'ClientChat'
Checker: CBFCED
Connection Checker: CBFD2F
DataHandler: CBFD5D
_2: 0
_3: 0
_4: CBFD05

'ClientGarrison'
Checker: CC1461
Connection Checker: CC1501
DataHandler: CC155D
_2: 0
_3: 0
_4: CC14AB

Собственно, в sub_6252E0 вызывается connectionChecker, например вот
char __cdecl sub_5FF895(int a1, int a2, int a3, int a4, int a5)
{
int v5; // eax@1
int v6; // ecx@3
int v7; // ecx@13
int v8; // ecx@16
int v9; // eax@18
char result; // al@22

v5 = a2 - 1;
if ( (((_WORD)a2 - 1) & 0x1F54) != 4608
&& (v5 & 0x1DDC) != 208
&& (v6 = v5 & 0xDDC, v6 != 256)
&& v6 != 2304
&& (v5 & 0x5D4) != 384
&& (v5 & 0x5D6) != 272
&& (v5 & 0x76C) != 832
&& (v5 & 0x5F4) != 480
&& (v5 & 0x15D4) != 4
&& (v5 & 0x15C4) != 260
&& (v5 & 0x15BE) != 5256
&& (v5 & 0x174E) != 1288
&& (v7 = v5 & 0x74E, v7 != 1292)
&& v7 != 1294
&& (v5 & 0x74A) != 1800
&& (v8 = v5 & 0xFCE, v8 != 1352)
&& v8 != 1480
&& (v9 = v5 & 0xDCE, v9 != 1354)
&& v9 != 1482
|| (unsigned __int8)sub_5FA1D7(a2) && sub_653578((void *)a1, a3) != 1 )
{
result = 0;
}
else
{
NETEVENTQUEUE__AddEvent_2(a1, 23, a3, a4, a5);
result = 1;
}
return result;
}

Сами обработчики вызываются в NetClient::ProcessMessage
char __thiscall NetClient__ProcessMessage(void *this, int a2, int a3, int a4, int a5)
{
char result; // al@1
int v6; // esi@1
void *v7; // edi@1

++dword_10B8FC4;
v6 = a4;
v7 = this;
CDataStore__GetInt32(&a4);
result = sub_625285(v7, a2, a3, a4, v6);
if ( !result )
result = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)v6 + 24))(v6);
return result;
}В sub_625285 идет та же итерация по структуре, и если опкод принадлежит к группе, то вызывается dataHandler этой группы

при желании для этого всего можно тоже сделать OpcodeTools

Dubstep
27.11.2014, 08:34
спасибо. Реально как нибудь написать тулзу которая достанет нужну инфу в формате типа: ипод - sub_xxxx

Amaru
27.11.2014, 13:08
спасибо. Реально как нибудь написать тулзу которая достанет нужну инфу в формате типа: ипод - sub_xxxx
не думаю, что это нужно
достаточно достать инфу опкод-тип-magic_value, а далее ручками найти в дереве if/else нужные обработчики

Dubstep
27.11.2014, 13:34
ясно. Но что то не могу найти OneMessageReady.... по си дампу надо искать? И можете показать на каком нибудь опкоде. пример поиска

Konctantin
27.11.2014, 13:51
вот адрес: 0x654910 - not rebased

Dubstep
28.11.2014, 01:57
вот адрес: 0x654910 - not rebased
это адрес OneMessageReady ? или что?

Fabian
28.11.2014, 04:18
это адрес OneMessageReady ? или что?

yes it is.

Dubstep
29.11.2014, 01:07
эм, по си дампу не нашёл ни одного GetInt32, CDataStore О_о как найти CMSG ?Оо

Konctantin
29.11.2014, 07:38
Это вручную переименованные функции, для удобного восприятия.
CDataStore - это структура (воссозданная вручную) :
typedef struct {
void* vTable;
BYTE* buffer;
DWORD base;
DWORD alloc;
DWORD size;
DWORD read;
} CDataStore;

О_о как найти CMSG ?Оо
что вас собственно удивляет? тут очень много тем по форуму, почитайте - поймете что да как.

Dubstep
29.11.2014, 13:48
Как я понял это так, есть DataHandler: 5F90B3, по нему ищу sub_5F90B3, нашёл. там получается большая функция с кучей кейзов, среди них получается есть нужный мне саб, который обрабатывает опкод?
Ну вот ещё вопросы:
1. Как из этих сабов найти нужный
2. И где взять 5F90B3, как я понимаю на каждую группу он свой. вот где взять список этот с адресами
Спасибо

Amaru
29.11.2014, 14:08
Как я понял это так, есть DataHandler: 5F90B3, по нему ищу sub_5F90B3, нашёл. там получается большая функция с кучей кейзов, среди них получается есть нужный мне саб, который обрабатывает опкод?
Ну вот ещё вопросы:
1. Как из этих сабов найти нужный
2. И где взять 5F90B3, как я понимаю на каждую группу он свой. вот где взять список этот с адресами
Спасибо
я же писал

Эта штука проверяет айди коннекта, куда пришел опкод, определяет группу, к которой принадлежит опкод, и если все ок то ставит в очередь
Код:

if ( sub_6541A4(v5, a2) )
sub_6252E0(v22, (int)v5, a2, a4, v6);

вот этим, собственно, и ставит
Код:

if ( (unsigned __int8)(*(int (__cdecl **)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD))(*(_DWORD *)v7 + 0x18))(
a2,
a1,
a3,
a4,
a5) )

массив собой представляет массив структур что-то вроде
Код:

[StructLayout(LayoutKind.Sequential)]
struct SMSGHandler
{
public IntPtr pName; // 0x0
public uint checker; // 0x4
public uint _2; // 0x8
public uint _3; // 0xC
public uint _4; // 0x10
public uint dataHandler; // 0x14
public uint connectionChecker; // 0x18
}

Dubstep
29.11.2014, 19:36
что то я всё равно не могу понять.... Покажите пожалуйста на каком нибудь примере как найти, например SMSG_TRAINER_LIST 0x0BA9

кстати, вот пытаюсь найти CMSG_ATTACKSWING = 0x1E9B(7835),
ctrl + f по дампу ", 7835)"

//----- (01412016) --------------------------------------------------------
int __thiscall sub_1412016(void *this, int a2)
{
void *v2; // esi@1

v2 = this;
sub_122FC66(a2, 7835);
return (*(int (__thiscall **)(_DWORD, _DWORD))(*(_DWORD *)v2 + 4))(v2, a2);
}

Всё что есть

Кстати ещё вопрос, раньше делал си дамп и там уже были созданы CDataStore структуры, а тут вообще пусто... всё надо самому дописывать

Konctantin
29.11.2014, 21:49
Кстати ещё вопрос, раньше делал си дамп и там уже были созданы CDataStore структуры, а тут вообще пусто... всё надо самому дописывать
скорее всего вы делали дамп с базы которую выкладывал TOM_RUS (с уже созданными структурами и переименованными функциями).

moJIto
01.12.2014, 05:53
как найти читалку клиента на пакеты типа варденовских, апдейт обджекта и подобных им ( там где просто putData ) и всё, а само читалки нету... всю голову уже сломал

Amaru
01.12.2014, 16:28
как найти читалку клиента на пакеты типа варденовских, апдейт обджекта и подобных им ( там где просто putData ) и всё, а само читалки нету... всю голову уже сломал
Как? По номеру пакета может?

moJIto
04.12.2014, 00:29
я про пакеты типа
```
{
int v2; // ebx@1
void *v3; // esi@1
int v4; // edi@1
int v5; // eax@1
int v6; // eax@1
int v8; // [sp+Ch] [bp-8h]@1
__int16 v9; // [sp+10h] [bp-4h]@1

v2 = a2;
v3 = this;
LOBYTE(a2) = 0;
v4 = (int)((char *)this + 20);
v8 = v2;
v9 = 0;
v5 = CDataStore::Strlen((int)((char *)this + 20));
CDataStore::Write6Bits((int)&v8, v5, a2);
CDataStore::FlushBits((int)&v8);
CDataStore::PutInt32(v2, *((_DWORD *)v3 + 4));
v6 = CDataStore::Strlen(v4);
return CDataStore::PutData(v2, v4, v6);
}
```

тут висит PutData - как найти функцию, которая это читает?

Amaru
07.12.2014, 05:37
я про пакеты типа
```
{
int v2; // ebx@1
void *v3; // esi@1
int v4; // edi@1
int v5; // eax@1
int v6; // eax@1
int v8; // [sp+Ch] [bp-8h]@1
__int16 v9; // [sp+10h] [bp-4h]@1

v2 = a2;
v3 = this;
LOBYTE(a2) = 0;
v4 = (int)((char *)this + 20);
v8 = v2;
v9 = 0;
v5 = CDataStore::Strlen((int)((char *)this + 20));
CDataStore::Write6Bits((int)&v8, v5, a2);
CDataStore::FlushBits((int)&v8);
CDataStore::PutInt32(v2, *((_DWORD *)v3 + 4));
v6 = CDataStore::Strlen(v4);
return CDataStore::PutData(v2, v4, v6);
}
```

тут висит PutData - как найти функцию, которая это читает?
xref по этой функции

moJIto
31.07.2015, 12:37
xref по этой функции


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

может кто подскажет как искать обработчики таких пакетов ? варден, апдейт_обджект

Amaru
31.07.2015, 14:43
они все в одном месте... в огромном джамптейбле в функции, которая обрабатывает Client опкоды

Dubstep
06.08.2015, 19:57
Доброго всем времени суток :) какова сейчас(WoD) структура пакета SMSG_WARDEN_DATA?

RomanRom2
06.08.2015, 23:56
я было прочитал "какого х.. сейчас ... блаблабла"
:pardon:

Dubstep
07.08.2015, 02:41
я было прочитал "какого х.. сейчас ... блаблабла"
:pardon:

Да счас сам прочитал, ужас :) исправил.

Konctantin
07.08.2015, 10:44
Ой, там все очень ...:
build 20338
int __thiscall sub_60F77E(int this, int a2)
{
int v2; // esi@1

v2 = this;
CDataStore::ReadInt32(a2, *(_DWORD *)(this + 32)); // data length
return sub_410B02(a2, *(_DWORD *)(v2 + 20), *(_DWORD *)(v2 + 32));
}
Можете посмотреть что там да и как.

Dubstep
07.08.2015, 13:27
спасибо, отличия не знает от лк или каты какой?

Konctantin
07.08.2015, 14:15
что значит отличия? структура пакетов? типы проверок?

Dubstep
07.08.2015, 14:33
Круто, PutData =\

Да структура, типы проверок, да бы запарсить это дело

moJIto
13.08.2015, 04:27
вооот.... я всё имел ввиду - как найти читалку к данным из PutData ?

Dubstep
15.08.2015, 16:45
вооот.... я всё имел ввиду - как найти читалку к данным из PutData ?
Похоже знающих людей тут не осталось или никто не хочет помочь :( это печально

RomanRom2
15.08.2015, 17:00
я например не понял вопрос. что за читалка к данным из PutData?

Amaru
15.08.2015, 22:18
Экстрасенс мод он
он имеет в виду как найти код, который генерит дату, которая потом суется putdata в пакет
Экстрасенс мод офф

Отвечу - все очень просто! открываем ида, и начинаем искать этот код. Отправная точка - адрес данных, которые суются в putdata

RomanRom2
16.08.2015, 14:22
ну это очевидно код, который в каждом опкоде свой, не? на передающей стороне это билдер какой то, на принимающей парсер структур, не?

Dubstep
19.08.2015, 17:59
RomanRom2, спасибо, я думаю тут все понимают как это работает.
Но вот подсказать как правильно по ида бегать, было бы хорошо, еще было бы лучше на примере вова.

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

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

Dubstep
21.08.2015, 15:35
Допустим, я от функции sub_60F77E, в ней лежит PutData, теоретически я могу просмотреть полное древо вызова ее?

ps TOM_RUS уже к сожалению свои базы не выкладывает (

Dubstep
21.11.2015, 18:37
доброго времени суток.

Такой вопрос есть функция JAMClientDispatch в ней дикий кейз http://pastebin.com/DDTYQyME (622)
Как я понимаю туда приходит опкод, мы его магически преобразуем до v8

далее v8 пускаем через ифы и получаем нужный хэндлер? JAM все smsg?

ps. Есть у кого нормальный IDA ? Текущий крашится при попытке диззамблить.