Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Копаем клиент (http://mangos.ytdb.ru/forumdisplay.php?f=35)
-   -   NetClient__ProcessMessage (http://mangos.ytdb.ru/showthread.php?t=7764)

Konctantin 12.12.2013 14:05

NetClient__ProcessMessage
 
Копаясь дальше в клиенте, наткнулся на такое:
Код:

char __userpurge NetClient::ProcessMessage<al>(void *this<ecx>, int edi0<edi>, int a2, int a3, int a4)
{
  int v5; // esi@1
  unsigned int v6; // ebx@1
  int v7; // edx@2
  int v8; // ecx@6
  char result; // al@11
  int v10; // ecx@12
  int v11; // ecx@19
  unsigned int v12; // eax@31
  int v13; // ecx@32
  unsigned int dwOpcode; // [sp+Ch] [bp-18h]@1
  unsigned int v15; // [sp+10h] [bp-14h]@1
  unsigned int v16; // [sp+14h] [bp-10h]@17
  unsigned int v17; // [sp+18h] [bp-Ch]@10
  unsigned int v18; // [sp+1Ch] [bp-8h]@9
  unsigned int v19; // [sp+20h] [bp-4h]@8

  ++dword_10A775C;
  v5 = (int)this;
  CDataStore__GetInt32(&dwOpcode);
  v15 = dwOpcode & 0x1EF0;
  v6 = dwOpcode;
  if ( dwOpcode & 0x1EF0
    && (v7 = dwOpcode & 0x1F54, v7 != 768)
    && (dwOpcode & 0x1C52) != 3072
    && (dwOpcode & 0x15D8) != 64
    && (dwOpcode & 0x11D8) != 72
    && (v8 = dwOpcode & 0x1D90, v8 != 2064)
    && v8 != 2192
    && (v19 = dwOpcode & 0x1472, (dwOpcode & 0x1472) != 4162)
    && (v18 = dwOpcode & 0x1492, edi0 = 4114, (dwOpcode & 0x1492) != 4114) )
  {
    v17 = dwOpcode & 0x1D50;
    if ( (dwOpcode & 0x1D50) == 1280 )
    {
      result = sub_68DE64(v5, 0, a2, dwOpcode, a3);
    }
    else
    {
      v10 = dwOpcode & 0x1ED2;
      if ( v10 == 128
        || v10 == 130
        || v7 == 516
        || (dwOpcode & 0x11D0) == 192
        || (dwOpcode & 0x1F94) == 528
        || (v16 = dwOpcode & 0x1D34, (dwOpcode & 0x1D34) == 20)
        || (dwOpcode & 0x1450) == 1104
        || (v11 = dwOpcode & 0x117A, v11 == 4362) )
      {
        result = sub_C7EDD4(v5, 0, a2, dwOpcode, a3);
      }
      else
      {
        if ( v15 == 32
          || (dwOpcode & 0x1FD4) == 640
          || (dwOpcode & 0x1D94) == 144
          || (dwOpcode & 0x157E) == 272
          || v19 == 4194
          || v18 == 5138 )
        {
          result = sub_68EA8F(0, a2, dwOpcode, a3);
        }
        else
        {
          if ( v17 == 1024 || v16 == 52 || v19 == 1040 || v19 == 1042 || v11 == 4394 )
          {
            result = sub_C653F2(0, a2, dwOpcode, a3);
          }
          else
          {
            (*(void (__thiscall **)(int, unsigned int))(*(_DWORD *)v5 + 68))(v5, dwOpcode);
            v12 = v6 & 1 | ((v6 & 0xC | ((v6 & 0xFE0 | (v6 >> 1) & 0x7000) >> 1)) >> 1);
            if ( (v6 & 0x1012) == 4096 && (v13 = *(_DWORD *)(v5 + 4 * v12 + 1360)) != 0 )
              result = ((int (__cdecl *)(_DWORD, unsigned int, int, int))(v13 - ((v6 | (v6 << 16)) ^ 0x62A3A31D)))(
                        *(_DWORD *)(v5 + 4 * v12 + 9552),
                        v6,
                        a2,
                        a3);
            else
              result = (*(int (**)(void))(*(_DWORD *)a3 + 24))();
          }
        }
      }
    }
  }
  else
  {
    result = sub_658438(edi0, v5, v5, 0, a2, dwOpcode, a3);
  }
  return result;
}

а дальше еще хуже:
Код:

char __userpurge sub_658438<al>(int a1<edi>, int a2<esi>, int ecx0<ecx>, int a3, int a4, unsigned __int16 a5, int a6)
{
 ..........................
  sub_A6EED0(0x466Cu, ecx0);
  v92 = a2;
  if ( !(a5 & 0x1EF0) )
  {
    v8 = a5 & 0xF | ((a5 & 0x100 | ((unsigned int)a5 >> 4) & 0xE00) >> 4);
    goto LABEL_19;
  }
  v9 = 768;
  v91 = a1;
  if ( (a5 & 0x1F54) == 768 )
  {
    v8 = (a5 & 3 | ((a5 & 8 | ((a5 & 0x20 | (((unsigned __int8)(a5 & 0x80) | ((unsigned int)a5 >> 5) & 0x700) >> 1)) >> 1)) >> 1))
      + 32;
    goto LABEL_19;
  }
  if ( (a5 & 0x1C52) == 3072 )
  {
    v8 = (a5 & 1 | ((a5 & 0xC | ((a5 & 0x20 | ((a5 & 0x380 | ((unsigned int)a5 >> 3) & 0x1C00) >> 1)) >> 1)) >> 1)) + 64;
    goto LABEL_19;
  }
  if ( (a5 & 0x15D8) == 64 )
  {
    v8 = (a5 & 7 | ((a5 & 0x20 | ((a5 & 0x200 | ((a5 & 0x800 | ((unsigned int)a5 >> 1) & 0x7000) >> 1)) >> 3)) >> 2))
      + 192;
    goto LABEL_19;
  }
  if ( (a5 & 0x11D8) == 72 )
  {
    v8 = (a5 & 7 | ((a5 & 0x20 | ((a5 & 0xE00 | ((unsigned int)a5 >> 1) & 0x7000) >> 3)) >> 2)) + 256;
    goto LABEL_19;
  }
  if ( (a5 & 0x1D90) == 2064 )
  {
    v8 = (a5 & 0xF | ((a5 & 0x60 | ((a5 & 0x200 | ((unsigned int)a5 >> 3) & 0x1C00) >> 2)) >> 1)) + 384;
    goto LABEL_19;
  }
  if ( (a5 & 0x1D90) == 2192 )
  {
    v9 = 512;
    v10 = (a5 & 0x200 | ((unsigned int)a5 >> 3) & 0x1C00) >> 2;
    v11 = a5 & 0x60;
    v12 = a5 & 0xF;
  }
  else
  {
    if ( (a5 & 0x1472) == 4162 )
    {
      v8 = (a5 & 1 | ((a5 & 0xC | ((a5 & 0x380 | ((a5 & 0x800 | ((unsigned int)a5 >> 1) & 0x7000) >> 1)) >> 3)) >> 1))
        + 640;
      goto LABEL_19;
    }
    v10 = (a5 & 0x60 | ((a5 & 0x300 | ((a5 & 0x800 | ((unsigned int)a5 >> 1) & 0x7000) >> 1)) >> 1)) >> 1;
    v11 = a5 & 0xC;
    v12 = a5 & 1;
  }
  v8 = v9 + (v12 | ((v11 | v10) >> 1));
LABEL_19:
  switch ( v8 )
  {
    case 0x50u:

интересно, они как-то классифицируют разбивку или просто так от фонаря цифр наставили?
Интересуюсь потому что непонятно как функции обзывать.

Amaru 12.12.2013 14:35

какой клиент?
первое это, в принципе, все что нам надо, там как раз идет классификация опкодов, идут проверки на spell, quest, guild, movement и обычные jam опкоды. все остальные хендлеры по-старому лежат в массиве, но с хитрой индексацией

HuntsMan 21.01.2014 21:34

Цитата:

но с хитрой индексацией
Насколько хитрой?

Fabian 22.01.2014 01:21

The old handlers will be removed step by step.
I guess only round about 35?! are left and they will be replaced with the jam opcode functions.

The same for client messages. They are replaced step by step with the jam opcode functions which is just another handler definition.

Код:

        public static uint JAMClientDispatch(uint value)
        {
            if ((value & 0x1EF0) == 0)
                return value & 0xF | ((value & 0x100 | (value >> 4) & 0xE00) >> 4);

            if ((value & 0x1F54) == 768)
                return (value & 3 | ((value & 8 | ((value & 0x20 | (((value & 0x80) | (value >> 5) & 0x700) >> 1)) >> 1)) >> 1)) + 32;

            if ((value & 0x1C52) == 3072)
                return (value & 1 | ((value & 0xC | ((value & 0x20 | ((value & 0x380 | (value >> 3) & 0x1C00) >> 1)) >> 1)) >> 1)) + 64;

            if ((value & 0x15D8) == 64)
                return (value & 7 | ((value & 0x20 | ((value & 0x200 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 3)) >> 2)) + 192;

            if ((value & 0x11D8) == 72)
                return (value & 7 | ((value & 0x20 | ((value & 0xE00 | (value >> 1) & 0x7000) >> 3)) >> 2)) + 256;

            if ((value & 0x1D90) == 2064)
                return (value & 0xF | ((value & 0x60 | ((value & 0x200 | (value >> 3) & 0x1C00) >> 2)) >> 1)) + 384;

            if ((value & 0x1D90) == 2192)
                return 512 + (value & 0xF | ((value & 0x60 | (value & 0x200 | (value >> 3) & 0x1C00) >> 2) >> 1));
            else
            {
                if ((value & 0x1472) == 4162)
                    return (value & 1 | ((value & 0xC | ((value & 0x380 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 3)) >> 1)) + 640;

                return 768 + (value & 1 | ((value & 0xC | (value & 0x60 | ((value & 0x300 | ((value & 0x800 | (value >> 1) & 0x7000) >> 1)) >> 1)) >> 1) >> 1));
        }

        public static bool JamClientDispatchConditions(uint value)
        {
            if ((value & 0x1EF0) != 0 && (value & 0x1C52) != 3072 && (value & 0x15D8) != 64
                && (value & 0x11D8) != 72 && (value & 0x1F54) != 768 && (value & 0x1D90) != 2064
                && (value & 0x1D90) != 2192 && (value & 0x1472) != 4162 && (value & 0x1492) != 4114)
                return false;

            return true;
        }

Calculate a JamClientdispatch opcode to the case value:

Код:

var caseVal = JAMClientDispatch(opcode);
The other way calculating from case value to opcode:

Код:

            for (uint i = 0; i <= 0x1FFF; ++i)
                if (JamClientDispatchConditions(i) && JAMClientDispatch(i) == caseValue)
                    Console.WriteLine("NetMessage: {0}", i);

Then the legacy opcodes (the old way over index things...):

Код:

        public static uint ServerMessageCalc(uint value)
        {
            uint offset = value & 3 | ((value & 8 | ((value & 0x1E0 | (value >> 1) & 0x7E00) >> 1)) >> 1);
            return (offset * 4) + 0x550;
        }

And then the conditions from NetClient::ProcessMessage for it to get unique opcode values.

Here a little snippet for legacy opcode handlers:

Код:

            Memory.Initialize("WoW");

            var connectionPtr = Memory.Read<uint>(0xEA239C);
            var handlerPtr = 0u;
            var offset = 0u;

            List<uint> possibleOffsets = new List<uint>();
            List<uint> opcodeList = new List<uint>();
            List<uint> offsetList = new List<uint>();
            List<uint> handlerList = new List<uint>();

            for (uint i = 0; i <= 0x1FFF; ++i)
                if (IsLegacyMessage(i, offset) && (offset = LegacyMessageOffset(i)) != 0)
                    possibleOffsets.Add(offset);

            foreach (uint o in possibleOffsets)
            {
                if ((handlerPtr = Memory.Read<uint>((connectionPtr + o), false)) != 0)
                {
                    for (uint i = 0; i <= 0x1FFF; ++i)
                    {
                        if (IsLegacyMessage(i, o) && LegacyMessageOffset(i) == o)
                        {
                            offsetList.Add(o);
                            opcodeList.Add(i);

                            var handler = handlerPtr - ((i | (i << 16)) ^ 0x62A3A31D);
                            handler = (uint)(handler - Memory.BaseAddress + 0x400000);

                            handlerList.Add(handler);
                        }
                    }
                }
            }

            Memory.Dispose();

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < handlerList.Count; i++)
            {
                sb.AppendLine(String.Format("Offset:  {0}", offsetList[i]));
                sb.AppendLine(String.Format("Message{0} = 0x{1:X4},", i, opcodeList[i]));
                sb.AppendLine(String.Format("Handler: 0x{0:X}", handlerList[i]));
                sb.AppendLine();
            }

            using (StreamWriter sw = new StreamWriter("finished.txt"))
            {
                sw.WriteLine(sb.ToString());
                sw.Close();
            }

            Console.WriteLine("Legacy opcode dump finished");
            Console.ReadLine();
        }


Konctantin 12.10.2014 23:09

В аддоне 6.х.х нас ждет небольшое изменение:
похоже уже нету разбивки на тип пакетов.
Код:

char __thiscall NetClient::ProcessMessage(void *this, int a2, int a3, int buffer, int a5)
{
  int v5; // esi@1
  void *v6; // edi@1
  char result; // al@1

  ++dword_10B5C24;
  v5 = buffer;
  v6 = this;
  CDataStore::GetInt32(buffer, (int)&buffer);
  result = sub_623A4A(v6, a2, a3, buffer, v5);
  if ( !result )
    result = (*(int (__thiscall **)(_DWORD))(*(_DWORD *)v5 + 24))(v5);
  return result;
}

Код:

char __thiscall sub_623A4A(void *this, int a2, int a3, int a4, int a5)
{
  int *v5; // eax@1
  int *v6; // edi@1
  int v7; // esi@1
  int i; // eax@1
  int v9; // ebx@2
  void *v11; // [sp+Ch] [bp-4h]@1

  v11 = this;
  v5 = sub_6239BC();
  v6 = v5;
  v7 = *v5;
  for ( i = *v5 + 4 * v5[1]; ; i = *v6 + 4 * v6[1] )
  {
    if ( v7 == i )
      return 0;
    v9 = *(_DWORD *)v7;
    if ( (unsigned __int8)(*(int (__cdecl **)(int))(*(_DWORD *)v7 + 4))(a4) )
      break;
    v7 += 4;
  }
  (*(void (__cdecl **)(void *, _DWORD, int, int, int, int))(v9 + 20))(v11, 0, a2, a3, a4, a5);
  return 1;
}


Fabian 13.10.2014 12:24

addresses from build 19027 wod beta

0x6724E8 'registers' the vtables for the different jam groups, client and server.

Код:

int __cdecl sub_6724E8(char a1)
{
  int v1; // eax@1

  v1 = (int)sub_6724B6();
  return sub_672436(v1, (int)&a1);
}

They can be found by strings too (Client for JAMClientDispatch):

Код:

.data:010AFEC4 off_10AFEC4    dd offset aClient      ; DATA XREF: sub_E1BCDDo
.data:010AFEC4                                        ; "Client"
.data:010AFEC8                dd offset sub_642C77
.data:010AFECC                db    0
.data:010AFECD                db    0
.data:010AFECE                db    0
.data:010AFECF                db    0
.data:010AFED0                db    0
.data:010AFED1                db    0
.data:010AFED2                db    0
.data:010AFED3                db    0
.data:010AFED4                dd offset sub_648FD9
.data:010AFED8                dd offset sub_642CA0
.data:010AFEDC                dd offset sub_64900E

but in general I see no big change in the function processmessage

Konctantin 13.02.2016 19:55

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

RomanRom2 13.02.2016 23:01

а батлнет протокол стал позипованным json.
близзы опять делают послабления? соскучились по эмуляторам и сандбоксам? :)

Amaru 15.02.2016 15:08

Цитата:

Сообщение от RomanRom2 (Сообщение 34488)
а батлнет протокол стал позипованным json.
близзы опять делают послабления? соскучились по эмуляторам и сандбоксам? :)

больше похоже на бинарный protobuf

Konctantin 24.03.2016 07:42

Обновил сегодня сниффер под build 21348, серверные опкоды теперь по 2 байта, но "внезапно" обнаружил пакеты с нулевыми опкодами. :mda:

Нормально ли это, что такие приходят пакеты с такими опкодами?

Использовал вот такой хук:
Код:

// x32
DWORD __fastcall RecvHook_WOD(LPVOID self, LPVOID dummy, LPVOID param1, LPVOID param2, CDataStore* ds, LPVOID param4)
{
    if (wowInfo.build >= 21336)
        DumpPacket(SMSG, 0, *(WORD*)ds->buffer, 2, ds->size, ds->buffer);
    else
        DumpPacket(SMSG, 0, *(DWORD*)ds->buffer, 4, ds->size, ds->buffer);

    CHECK(hookInfo.recvHookGood, "Recv hook is working.\n");
    typedef DWORD(__thiscall *proto)(LPVOID, LPVOID, LPVOID, CDataStore*, LPVOID);
    return reinterpret_cast<proto>(hookInfo.recvDetour)(self, param1, param2, ds, param4);
}

//x64
DWORD_PTR __fastcall RecvHook_WOD(LPVOID a1, LPVOID a2, LPVOID a3, PBYTE buff, DWORD size)
{
    if (wowInfo.build >= 21336)
        DumpPacket(SMSG, 0, *(WORD*)buff, 2, size, buff);
    else
        DumpPacket(SMSG, 0, *(DWORD*)buff, 4, size, buff);

    CHECK(hookInfo.recvHookGood, "Recv hook is working.\n");
    return reinterpret_cast<decltype(&RecvHook_WOD)>(hookInfo.recvDetour)(a1, a2, a3, buff, size);
}

адреса:
Код:

# x86
[21348]
send=0x295950
recv=0x293DA3
lang=0xE97C90

# x64
[21348]
send=0x04767C0
recv=0x0474350
lang=0x1616958

вот часть лога работы сниффера
Код:

ExePath: E:\wow\World of Warcraft\Wow-64.exe
Detected build number: 21348 expansion: 6
Detected client locale: ruRU
Found 'WOD' hooks!
>> All 'WOD' hooks is installed.
Sniff dump: wowsniff_ruRU_6_21348_2016-03-24_07-37-16.pkt

CMSG Opcode: 0x0000 Size: 1278
Send hook is working.
SMSG Opcode: 0x279D Size: 245
Recv hook is working.
SMSG Opcode: 0x279E Size: 264
SMSG Opcode: 0x24EA Size: 142
CMSG Opcode: 0x0000 Size: 6
CMSG Opcode: 0x0000 Size: 6
CMSG Opcode: 0x0000 Size: 6
CMSG Opcode: 0x0000 Size: 6
CMSG Opcode: 0x0000 Size: 6
CMSG Opcode: 0x0000 Size: 6
SMSG Opcode: 0x2620 Size: 28
SMSG Opcode: 0x277E Size: 10
SMSG Opcode: 0x2558 Size: 11
SMSG Opcode: 0x26FC Size: 353
SMSG Opcode: 0x26C4 Size: 6
SMSG Opcode: 0x279F Size: 3
CMSG Opcode: 0x0000 Size: 45
SMSG Opcode: 0x279E Size: 299
SMSG Opcode: 0x2732 Size: 8
SMSG Opcode: 0x2770 Size: 34
SMSG Opcode: 0x25E9 Size: 6
CMSG Opcode: 0x0000 Size: 45
CMSG Opcode: 0x0000 Size: 18
SMSG Opcode: 0x2500 Size: 2412
SMSG Opcode: 0x279D Size: 1151
SMSG Opcode: 0x279E Size: 348
SMSG Opcode: 0x279E Size: 178
SMSG Opcode: 0x279E Size: 216


Konctantin 24.03.2016 07:55

А не, туплю как говорится смотрю в книгу и вижу [censored].
Прошу прощения, но оказывается изменился обработчик клиентских сообщений.

Сначала идут 4 байта, которые пропускаются:
Код:

void __fastcall sub_140476990(__int64 a1, __int64 a2, unsigned int a3)
{
  __int64 v3; // rsi@1
  __int64 v4; // rbx@1
  int v5; // edi@1
  __int64 v6; // [sp+20h] [bp-28h]@1
  __int64 v7; // [sp+28h] [bp-20h]@1
  __int64 v8; // [sp+30h] [bp-18h]@1
  int v9; // [sp+38h] [bp-10h]@1
  int v10; // [sp+3Ch] [bp-Ch]@1

  v3 = a1;
  v4 = a2;
  v7 = 0i64;
  v8 = 0i64;
  v6 = (__int64)off_140F06120;
  v9 = 0;
  v10 = -1;
  v5 = a3;
  CDataStore::GetInt32((__int64)&v6, 0); // вот тут пропускается 4 байта
  (*(void (__fastcall **)(__int64, __int64 *))(*(_QWORD *)v4 + 16i64))(v4, &v6);
  v10 = 4;
  sub_1404767C0(v3, (__int64)&v6, v5);
  v6 = (__int64)off_140F06120;
  if ( HIDWORD(v8) != -1 )
    sub_140019BC0((__int64)&v6, (__int64)&v7, (__int64)&v8, (__int64)((char *)&v8 + 4));
}

а сам опкод теперь 2 байта:
Код:

void __fastcall sub_1404767C0(__int64 a1, __int64 a2, int a3)
{
  __int64 v3; // rbx@1
  int v4; // er13@1
  __int64 v5; // rdi@1
  int v6; // ebp@2
  int v7; // er12@2
  int v8; // ebp@4
  unsigned int v9; // eax@5
  int v10; // er15@14
  unsigned int v11; // er14@14
  __int64 v12; // rdi@14
  __int64 v13; // rax@14
  __int64 v14; // rax@15
  __int64 v15; // rdi@15
  __int64 v16; // rbp@17
  unsigned __int16 v17; // [sp+70h] [bp+8h]@5
  __int64 v18; // [sp+88h] [bp+20h]@14

  v3 = a1;
  v4 = a3;
  v5 = a2;
  EnterCriticalSection((LPCRITICAL_SECTION)(a1 + 144));
  if ( *(_DWORD *)(v3 + 184) == 5 )
  {
    v6 = *(_DWORD *)(v5 + 28);
    v7 = *(_DWORD *)(v5 + 24) - v6;
    if ( *(_DWORD *)(v5 + 24) != v6 )
    {
      if ( v4 == 2 )
      {
        v17 = 0;
        CDataStore::GetInt16(v5, (__int64)&v17);// opcode
        v9 = v17;
        *(_DWORD *)(v5 + 28) = v6;
        v8 = v17 >= 0x30D4u && v9 < 0x327D
          || v9 >= 0x33F4 && v9 < 0x34B0
          || v9 >= 0x3912 && v9 < 0x391E
          || v9 - 14690 <= 0x54;
      }


Amaru 02.04.2016 17:50

Даа, есть такое. Непонятные 4 байта, на легионе и теперь на лайве. Насколько я видел, там всегда 0

Konctantin 03.04.2016 10:24

угу, может зарезервировали для чего-то.

Dubstep 25.04.2016 12:00

Доброго времени суток, какие есть варианты получить vTable, а именно переименовать функции CDataStore

Konctantin 26.04.2016 11:29

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

# Wow.exe 21463
MakeNameEx(0x009EF14E, "CDataStore__ReadString2", SN_NOWARN);
MakeNameEx(0x009EA64A, "CDataStore__PutPackedGuid128", SN_NOWARN);
MakeNameEx(0x009EA26A, "CDataStore__ReadPackedGuid128", SN_NOWARN);
MakeNameEx(0x0065E1B7, "CDataStore__Read21Bits", SN_NOWARN);
MakeNameEx(0x0065E16C, "CDataStore__Read20Bits", SN_NOWARN);
MakeNameEx(0x0065B3B0, "CDataStore__Read30Bits", SN_NOWARN);
MakeNameEx(0x0065B365, "CDataStore__Read28Bits", SN_NOWARN);
MakeNameEx(0x00659E30, "CDataStore__Read16Bits", SN_NOWARN);
MakeNameEx(0x0063A1CE, "CDataStore__ReadPascalString9", SN_NOWARN);
MakeNameEx(0x00639EF6, "CDataStore__Read14Bits", SN_NOWARN);
MakeNameEx(0x00638353, "CDataStore__ReadPascalString8", SN_NOWARN);
MakeNameEx(0x00637502, "CDataStore__ReadPascalString7", SN_NOWARN);
MakeNameEx(0x006142BC, "CDataStore__Read13Bits", SN_NOWARN);
MakeNameEx(0x00614287, "CDataStore__Read12Bits", SN_NOWARN);
MakeNameEx(0x00614252, "CDataStore__Read11Bits", SN_NOWARN);
MakeNameEx(0x0061421D, "CDataStore__Read10Bits", SN_NOWARN);
MakeNameEx(0x00611EDB, "CDataStore__Read7Bits", SN_NOWARN);
MakeNameEx(0x00611E54, "CDataStore__Read6Bits", SN_NOWARN);
MakeNameEx(0x00611DCD, "CDataStore__Read5Bits", SN_NOWARN);
MakeNameEx(0x00611D46, "CDataStore__Read4Bits", SN_NOWARN);
MakeNameEx(0x00611CBF, "CDataStore__Read3Bits", SN_NOWARN);
MakeNameEx(0x00611C38, "CDataStore__Read2Bits", SN_NOWARN);
MakeNameEx(0x0060F1F0, "CDataStore__Read8Bits", SN_NOWARN);
MakeNameEx(0x0060F1B6, "CDataStore__Read1Bit", SN_NOWARN);
MakeNameEx(0x0041160F, "CDataStore__ReadString3", SN_NOWARN);
MakeNameEx(0x004113C6, "CDataStore__ReadString", SN_NOWARN);
MakeNameEx(0x00411396, "CDataStore__ReadFloat", SN_NOWARN);
MakeNameEx(0x0041135D, "CDataStore__ReadInt64", SN_NOWARN);
MakeNameEx(0x0041132D, "CDataStore__ReadInt32", SN_NOWARN);
MakeNameEx(0x004112FB, "CDataStore__ReadInt16", SN_NOWARN);
MakeNameEx(0x004112CC, "CDataStore__ReadInt8", SN_NOWARN);
MakeNameEx(0x00411251, "CDataStore__FetchRead", SN_NOWARN);
MakeNameEx(0x004110B6, "CDataStore__PutInt64", SN_NOWARN);
MakeNameEx(0x00411083, "CDataStore__PutInt32", SN_NOWARN);
MakeNameEx(0x0041104E, "CDataStore__PutInt16", SN_NOWARN);
MakeNameEx(0x0041101C, "CDataStore__PutInt8", SN_NOWARN);
MakeNameEx(0x00407350, "CDataStore__FetchWrite", SN_NOWARN);


Dubstep 27.04.2016 20:36

А как вы их получаете? чисто интуитивно?
Еще такой вопрос, пакеты делятся на группы, есть функция проверки принадлежность к группе, есть сама которая дергает нужный хэндлер. Вопрос вот в чём: как можно сдампить их(адрес обработчика, номер пакета)? Может хотя бы идея какие нибудь

moJIto 27.04.2016 21:57

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

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

Konctantin 28.04.2016 13:55

Цитата:

А как вы их получаете? чисто интуитивно?
Ну когда-то сидел разбирал пакеты и давал имена, а потом дифф базы делал.

Dubstep 17.05.2016 16:38

Цитата:

Сообщение от moJIto (Сообщение 34623)
ну сделать список обработчиков CData изи для половины банально по последовательности и размеру данных, а остальные типа PutBits - уже изучать нужно.

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

про дамп по подробнее можете? Может какой пример есть. Спасибо

Konctantin 22.05.2016 01:23

Это что имена обработчиков включили в клиент?
Код:

.?AV?$TSGrowableArray@UJamAvailableCharacterTemplateClass@@@@
.?AV?$TSGrowableArray@UJamVirtualRealmInfo@@@@
.?AV?$TSGrowableArray@UJamRaceClassAvailability@@@@


Konctantin 22.05.2016 16:17

Цитата:

про дамп по подробнее можете? Может какой пример есть. Спасибо
Вот накалякал скрипт для ИДА, он собирает опкоды:обработчики для сообщений.
https://gist.github.com/Konctantin/1...b8aa5759e215fc

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

PS. Надо будет попробовать подтянуть имена обработчиков еще, но пока не пойму как.

Konctantin 23.05.2016 14:59

задампил обработчики build 21742
https://gist.github.com/Konctantin/2...89ff19bfbeded0

Dubstep 23.05.2016 17:04

Цитата:

Сообщение от Konctantin (Сообщение 34692)
Вот накалякал скрипт для ИДА, он собирает опкоды:обработчики для сообщений.
https://gist.github.com/Konctantin/1...b8aa5759e215fc

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

PS. Надо будет попробовать подтянуть имена обработчиков еще, но пока не пойму как.

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

Konctantin 23.05.2016 19:03

Есть утилита BinDiff, для сравнивания баз IDA.

Amaru 24.05.2016 10:02

Цитата:

Сообщение от Konctantin (Сообщение 34691)
Это что имена обработчиков включили в клиент?
Код:

.?AV?$TSGrowableArray@UJamAvailableCharacterTemplateClass@@@@
.?AV?$TSGrowableArray@UJamVirtualRealmInfo@@@@
.?AV?$TSGrowableArray@UJamRaceClassAvailability@@@@


это метаданные внутриопкодных структур

Konctantin 24.05.2016 13:09

Интересно, а их можно как-то связать с самими обработчиками, что-то потом легче было делать opcode reseach

Amaru 24.05.2016 13:42

Цитата:

Сообщение от Konctantin (Сообщение 34698)
Интересно, а их можно как-то связать с самими обработчиками, что-то потом легче было делать opcode reseach

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

moJIto 25.05.2016 12:25

Цитата:

Сообщение от Konctantin (Сообщение 34691)
Это что имена обработчиков включили в клиент?
Код:

.?AV?$TSGrowableArray@UJamAvailableCharacterTemplateClass@@@@
.?AV?$TSGrowableArray@UJamVirtualRealmInfo@@@@
.?AV?$TSGrowableArray@UJamRaceClassAvailability@@@@


это есть только для пакетов, внутри которых есть контейнеры

Konctantin 25.05.2016 14:08

Ну это я уже понял, и частично подтянул к обработчикам.

Dubstep 16.06.2016 21:17

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

Konctantin 18.06.2016 10:20

Чего читаю?
Я на руби не пишу, это питон-скрипт для ИДА

Dubstep 22.06.2016 02:45

Цитата:

Сообщение от Konctantin (Сообщение 34734)
Чего читаю?
Я на руби не пишу, это питон-скрипт для ИДА

Значит питон :) не знаком не, но уже просмотрел по вашему коду более менее разобрался. Такой вопрос, у вас адреса вписаны под билды, по какому принципу вы их находите? Какая там цепочка есть вызовов от NetClient?

Konctantin 22.06.2016 06:51

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

Dubstep 23.06.2016 14:36

Цитата:

Сообщение от Konctantin (Сообщение 34761)
это адреса функций которые регистрируют обработчики (и для серверных сообщений групп обработчиков). посмотрите в ИДА где они находятся и попробуйте посмотреть на последовательность вызовов и вам должно все стать понятно.

да, всё ок, находится отлично, такой вопрос еще по поводу известных CDataStore, мб есть какие варианты проще чем сравнить базы?:) Хотя бы для основных функций(read/write16, 32) заметил что у вас скрипт ищит uint16 по шаблону, мб так же сделать для всех?

Konctantin 23.06.2016 15:59

каждый делать в праве так, как ему удобней.

Konctantin 23.06.2016 16:28

вот мои имена для CDataStore, за неточности ответственности не несу
Код:

CDataStore__FetchWrite      0x00407350
CDataStore__Free            0x0040B1EE
CDataStore__GetBufferParams  0x00410E95
CDataStore__PutInt8          0x0041101C
CDataStore__PutInt16        0x0041104E
CDataStore__PutInt32        0x00411083
CDataStore__PutInt64        0x004110B6
CDataStore__PutInt32_2      0x004110F0
CDataStore__PutWowString    0x00411214
CDataStore__FetchRead        0x00411251
CDataStore__GetInt8          0x004112CC
CDataStore__GetInt16        0x004112FB
CDataStore__GetInt32        0x0041132D
CDataStore__GetInt64        0x0041135D
CDataStore__GetFloat        0x00411396
CDataStore__GetString        0x004113C6
CDataStore__GetWowString    0x0041160F
CDataStore__GetDataInSitu    0x00411618
CDataStore__PutBit          0x0060F138
CDataStore__Put8Bits        0x0060F166
CDataStore__Get1Bit          0x0060F1B6
CDataStore__Get8Bits        0x0060F1F0
CDataStore__PutAlign6Bits    0x0060F4E4
CDataStore__PutAlign5Bits    0x0060F562
CDataStore__PutAlign4Bits    0x0060F5E0
CDataStore__PutAlign3Bits    0x0060F65E
CDataStore__PutAlign2Bits    0x0060F6DC
CDataStore__PutAlign1Bits    0x0060F75A
CDataStore__PutAlignBits    0x0060F851
CDataStore__Get2Bits        0x00611C38
CDataStore__Get3Bits        0x00611CBF
CDataStore__Get4Bits        0x00611D46
CDataStore__Get5Bits        0x00611DCD
CDataStore__Get6Bits        0x00611E54
CDataStore__Get7Bits        0x00611EDB
CDataStore__Put10Bits        0x00614131
CDataStore__Put11Bits        0x0061416C
CDataStore__Put12Bits        0x006141A7
CDataStore__Get10Bits        0x0061421D
CDataStore__Get11Bits        0x00614252
CDataStore__Get12Bits        0x00614287
CDataStore__Get13Bits        0x006142BC
CDataStore__GetPascalString7 0x00637502
CDataStore__GetPascalString8 0x00638353
CDataStore__Get14Bits        0x00639EF6
CDataStore__GetPascalString9 0x0063A1CE
CDataStore__Get16Bits        0x00659E30
CDataStore__Get28Bits        0x0065B365
CDataStore__Get30Bits        0x0065B3B0
CDataStore__Get20Bits        0x0065E16C
CDataStore__Get21Bits        0x0065E1B7
CDataStore__GetPackedInt64  0x009EA21D
CDataStore__GetPackedGuid128 0x009EA26A
CDataStore__PutPackedInt64  0x009EA5E5
CDataStore__PutPackedGuid128 0x009EA64A
CDataStore__GetString2      0x009EF14E


Dubstep 24.06.2016 13:44

Спасибо за адреса, сделал поиск по шаблону и переименование

Dubstep 09.08.2016 12:50

Может кто нибудь объяснить, возможно ли накатить дифф между старой idb и новой, интересуют имена функций, например те же CDataStore. Спасибо

Konctantin 10.08.2016 10:38

возможно, но делать надо осторожно, диффу доверять нельзя на 100%.

Dubstep 10.08.2016 20:36

Цитата:

Сообщение от Konctantin (Сообщение 34858)
возможно, но делать надо осторожно, диффу доверять нельзя на 100%.

ну это понятно, не подскажите как это можно сделать?


Текущее время: 17:50. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS