Показать сообщение отдельно
Старый 27.11.2014, 01:59   #46
Amaru
MaNGOS Dev
 
Регистрация: 16.01.2011
Сообщений: 262
Сказал(а) спасибо: 57
Поблагодарили 73 раз(а) в 59 сообщениях
Amaru На верном пути
По умолчанию

клиентские как раньше ищутся, а серверные обработчики немного по другому
находим сначала 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
Amaru вне форума   Ответить с цитированием