Где в клиенте хранятся структуры пакетов?

  • Автор темы Автор темы stiller
  • Дата начала Дата начала

stiller

Путник
Пользователь
Сообщения
4
Розыгрыши
0
Репутация
0
Реакции
0
Баллы
3
1) вопрос простой где клиент хранит структры пакетов, тоесть клиент должен ведь знать сколько байт читать например:
writeC(type.getId());
writeD(itemsCount);
writeC(0);
writeH(startPage);
writeH(brokerItems.length);
for (BrokerItem item : brokerItems) {
writeItemInfo(item);
}
клиент точно понимает какие врайты за что отвечают где найти просто структуру что бы понять сколько байт требуется для пакета там будет и порядок их, и то что он ждет впринципе так хоть методом тыка можно хоть что то узнать.
спасибо!
 
Аргументом в Disassemble вероятно. Айон на движке л2 построен ведь
 
Ну если на базе л2...

В IDA (Interactive Disassembler) открываем Engine.dll (если чистый, если под темидой - дампаем в мире игры (через PE Tools) и открываем его).
После чего ждем пока IDA изучает DLL...
Когда закончили - переходим в View - Open Subviews - Strings.
В окшке тыкаем ПКМ и там нужно выбрать "Setup" ну и включить строки "C-Style (32 bits)".


Дальше можно или по этой теме:

* Дополнительно можно попробовать пройтись вот этим по DLL в IDA, но это на свой вкус:

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

Вот у меня условно такое было:
sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22);
И IDA разобрала функцию как - int sub_205E13D0(va_list a1, int a2, int a3, ...)
Там нужно тыкнуть ПКМ на "int a3", после чего нажать на "Set Ivar Type..."
1785052212466.webp
Указываем там char* format, после чего переходим по таким местам &dword_20C5F290 (2 раза мышкой) и тыкаем "А" (английскую разуемеется).
После этого наш условный sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22); превращается на sub_205E13D0(*(_DWORD *)(a1 + 72), a2, "h", v22);
 
спасибо всем огромное хоть видно куда капать работы конечно жесть, буду разбираться как снять защиту) а то данные не читаются там)
 
спасибо всем огромное хоть видно куда капать работы конечно жесть, буду разбираться как снять защиту) а то данные не читаются там)
\bin64 Game.dll - все пакеты там
Напиши, что конкретно интересует
 
структура всех пакетов как писал выше( хочу все пакеты увидеть что клиент хочет получать. 5,8 версии
На 5.8 всё есть в сети, даже VM ка pts в паблике(это если желание поснифать появится), но и сборок java с разобранными пакетами хватает.
 
Ну если на базе л2...

В IDA (Interactive Disassembler) открываем Engine.dll (если чистый, если под темидой - дампаем в мире игры (через PE Tools) и открываем его).
После чего ждем пока IDA изучает DLL...
Когда закончили - переходим в View - Open Subviews - Strings.
В окшке тыкаем ПКМ и там нужно выбрать "Setup" ну и включить строки "C-Style (32 bits)".


Дальше можно или по этой теме:

* Дополнительно можно попробовать пройтись вот этим по DLL в IDA, но это на свой вкус:

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

Вот у меня условно такое было:
sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22);
И IDA разобрала функцию как - int sub_205E13D0(va_list a1, int a2, int a3, ...)
Там нужно тыкнуть ПКМ на "int a3", после чего нажать на "Set Ivar Type..."
Посмотреть вложение 96780
Указываем там char* format, после чего переходим по таким местам &dword_20C5F290 (2 раза мышкой) и тыкаем "А" (английскую разуемеется).
После этого наш условный sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22); превращается на sub_205E13D0(*(_DWORD *)(a1 + 72), a2, "h", v22);

Доброго времени стуок, были проведены следующие операции:
1)Был снят дамп клиента(game.dll) с помощью x64dbg
2)Обошли Themida с помощью плагина Scylla
3)И этот дамп был проанализирован в IDA

Собственно получил вот это:
(в данном конкретном случае рассмотрим пакет SM_BROKER_SERVICE)
Objective-C:
__int64 __fastcall sub_59CEB320(__int64 a1, __int64 a2)
{
  signed __int64 v2; // r8
  __int64 result; // rax
  char v4; // cl
  int v5; // er11
  char v6; // dl
  __int64 v7; // r10
  __int64 v8; // r9
  __int64 v9; // r8

  v2 = *(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64;
  result = *(unsigned __int8 *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32));
  switch ( (_DWORD)result )
  {
    case 0:
      result = sub_59CEB440(a1, (int *)v2);
      break;
    case 1:
      result = sub_59CEB780(a1, v2);
      break;
    case 2:
      result = sub_5965BA80(
                 a1,
                 (unsigned int)*(char *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64),
                 *(unsigned int *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64),
                 *(_QWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 6i64));
      break;
    case 3:
      result = sub_59CEBAC0(a1, v2);
      break;
    case 4:
      result = sub_59CEBD50(a1, v2);
      break;
    case 5:
      result = sub_59CEBEF0(a1, v2);
      break;
    case 6:
      if ( !*(_BYTE *)v2 )
        result = sub_59B761E0(a1);
      break;
    case 7:
      v4 = *(_BYTE *)v2;
      v5 = *(_DWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64);
      v6 = *(_BYTE *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 14i64);
      v7 = *(_QWORD *)(v2 + 22);
      v8 = *(_QWORD *)(v2 + 14);
      v9 = *(_QWORD *)(v2 + 5);
      result = sub_59AECD00(1145446400i64);
      break;
    default:
      return result;
  }
  return result;
}


(рассмотрим 0 кейс)
C-подобный:
__int64 __fastcall sub_59CEB440(__int64 a1, int *a2)
{
  __int16 v2; // bx
  int v3; // edi
  char v4; // r14
  __int16 v5; // r15
  char *v6; // rsi
  __int64 v7; // r14
  __int128 v8; // xmm0
  __int128 v9; // xmm1
  int v10; // er15
  unsigned int v11; // er12
  __int64 v12; // r9
  __int64 v13; // r13
  __int128 v14; // xmm0
  __int128 v15; // xmm1
  __int128 v16; // xmm0
  __int128 v17; // xmm1
  __int128 v18; // xmm0
  __int128 v19; // xmm1
  __int64 v20; // rax
  signed int v21; // er8
  __int128 v22; // xmm0
  __int128 v23; // xmm1
  __int128 v24; // xmm0
  signed __int64 v25; // rcx
  __int16 v26; // dx
  __int16 *i; // rax
  signed __int64 v28; // rcx
  __int16 *v29; // rdx
  __int16 v30; // ax
  signed int j; // er8
  char v32; // r8
  char v33; // di
  __int16 v34; // bx
  int v35; // er11
  __int16 v36; // r10
  __int64 v37; // rax
  __int16 v39; // [rsp+70h] [rbp-88h]
  __int64 v40; // [rsp+72h] [rbp-86h]
  __int64 v41; // [rsp+7Ah] [rbp-7Eh]
  __int64 v42; // [rsp+82h] [rbp-76h]
  __int64 v43; // [rsp+8Ah] [rbp-6Eh]
  __int64 v44; // [rsp+92h] [rbp-66h]
  __int16 v45; // [rsp+9Ah] [rbp-5Eh]
  __int16 v46; // [rsp+A0h] [rbp-58h]
  __int64 v47; // [rsp+A2h] [rbp-56h]
  __int64 v48; // [rsp+AAh] [rbp-4Eh]
  __int64 v49; // [rsp+B2h] [rbp-46h]
  __int64 v50; // [rsp+BAh] [rbp-3Eh]
  __int64 v51; // [rsp+C2h] [rbp-36h]
  __int64 v52; // [rsp+CAh] [rbp-2Eh]
  __int16 v53; // [rsp+D2h] [rbp-26h]
  __int128 v54; // [rsp+D8h] [rbp-20h]
  __int128 v55; // [rsp+E8h] [rbp-10h]
  __int128 v56; // [rsp+F8h] [rbp+0h]
  __int128 v57; // [rsp+108h] [rbp+10h]
  __int128 v58; // [rsp+118h] [rbp+20h]
  __int128 v59; // [rsp+128h] [rbp+30h]
  __int128 v60; // [rsp+138h] [rbp+40h]
  __int128 v61; // [rsp+148h] [rbp+50h]
  __int128 v62; // [rsp+158h] [rbp+60h]
  __int128 v63; // [rsp+168h] [rbp+70h]
  __int128 v64; // [rsp+178h] [rbp+80h]
  __int64 v65; // [rsp+188h] [rbp+90h]
  __int16 v66; // [rsp+190h] [rbp+98h]
  char v67; // [rsp+192h] [rbp+9Ah]
  __int128 v68; // [rsp+198h] [rbp+A0h]
  __int128 v69; // [rsp+1A8h] [rbp+B0h]
  __int128 v70; // [rsp+1B8h] [rbp+C0h]
  __int128 v71; // [rsp+1C8h] [rbp+D0h]
  __int128 v72; // [rsp+1D8h] [rbp+E0h]
  __int128 v73; // [rsp+1E8h] [rbp+F0h]
  __int128 v74; // [rsp+1F8h] [rbp+100h]
  __int128 v75; // [rsp+208h] [rbp+110h]
  __int128 v76; // [rsp+218h] [rbp+120h]
  __int128 v77; // [rsp+228h] [rbp+130h]
  __int128 v78; // [rsp+238h] [rbp+140h]
  __int64 v79; // [rsp+248h] [rbp+150h]
  __int16 v80; // [rsp+250h] [rbp+158h]
  char v81; // [rsp+252h] [rbp+15Ah]

  v2 = *(_WORD *)((char *)a2 + 7);
  v3 = *a2;
  v4 = *((_BYTE *)a2 + 4);
  v5 = *(_WORD *)((char *)a2 + 5);
  v6 = (char *)a2 + 9;
  sub_59C45F30(a1);
  sub_59AE7AE0(1145446400i64, v5, v3, v4);
  if ( v2 > 0 )
  {
    v7 = (unsigned int)v2;
    do
    {
      v8 = *((_OWORD *)v6 + 2);
      v9 = *((_OWORD *)v6 + 3);
      v10 = *(_DWORD *)v6;
      v11 = *((_DWORD *)v6 + 1);
      v12 = *((_QWORD *)v6 + 1);
      v13 = *((_QWORD *)v6 + 3);
      v40 = 0i64;
      v41 = 0i64;
      v54 = v8;
      v14 = *((_OWORD *)v6 + 4);
      v55 = v9;
      v41 = 0i64;
      v42 = 0i64;
      v43 = 0i64;
      v15 = *((_OWORD *)v6 + 5);
      v56 = v14;
      v16 = *((_OWORD *)v6 + 6);
      v44 = 0i64;
      v45 = 0;
      v47 = 0i64;
      v48 = 0i64;
      v49 = 0i64;
      v50 = 0i64;
      v57 = v15;
      v17 = *((_OWORD *)v6 + 7);
      v58 = v16;
      v51 = 0i64;
      v52 = 0i64;
      v53 = 0;
      v18 = *((_OWORD *)v6 + 8);
      v59 = v17;
      v19 = *((_OWORD *)v6 + 9);
      v20 = *((_QWORD *)v6 + 26);
      v39 = 0;
      v46 = 0;
      v21 = 26;
      v60 = v18;
      v22 = *((_OWORD *)v6 + 10);
      v61 = v19;
      v23 = *((_OWORD *)v6 + 11);
      v62 = v22;
      v24 = *((_OWORD *)v6 + 12);
      v63 = v23;
      v64 = v24;
      v65 = v20;
      v66 = *((_WORD *)v6 + 108);
      v25 = (signed __int64)(v6 + 219);
      v67 = v6[218];
      v26 = *(_WORD *)(v6 + 219);
      for ( i = &v46; v26; v25 += 2i64 )
      {
        if ( --v21 > 0 )
        {
          *i = v26;
          ++i;
        }
        v26 = *(_WORD *)(v25 + 2);
      }
      v28 = v25 + 2;
      *i = 0;
      v29 = &v39;
      v30 = *(_WORD *)v28;
      for ( j = 26; v30; v28 += 2i64 )
      {
        if ( --j > 0 )
        {
          *v29 = v30;
          ++v29;
        }
        v30 = *(_WORD *)(v28 + 2);
      }
      v32 = *(_BYTE *)(v28 + 10);
      v33 = *(_BYTE *)(v28 + 2);
      v34 = *(_WORD *)(v28 + 3);
      v35 = *(_DWORD *)(v28 + 5);
      *v29 = 0;
      v36 = *(unsigned __int8 *)(v28 + 9);
      v68 = v54;
      v69 = v55;
      v6 = (char *)(v28 + 11);
      v70 = v56;
      v71 = v57;
      v72 = v58;
      v73 = v59;
      v74 = v60;
      v75 = v61;
      v76 = v62;
      v77 = v63;
      v78 = v64;
      v79 = v65;
      v80 = v66;
      v81 = v67;
      v37 = sub_59C45BA0(
              (__int64)&v62,
              v10,
              v11,
              v12,
              v13,
              (unsigned __int64)&v68,
              (unsigned __int64)&v39,
              (unsigned __int64)&v46,
              v33,
              v34,
              v35,
              v36,
              v32 != 0);
      if ( v37 )
        sub_59AE7C40(1145446400i64, v37);
      --v7;
    }
    while ( v7 );
  }
  return sub_59AE8060(1145446400i64);
}


1785140867531.webp
1785140979770.webp
1785141042034.webp
структура пакета на эмуляторе:
(0 кейс)

Java:
package com.aionemu.gameserver.network.aion.serverpackets;

import java.sql.Timestamp;
import java.util.Calendar;

import com.aionemu.gameserver.model.gameobjects.BrokerItem;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.network.aion.AionConnection;
import com.aionemu.gameserver.network.aion.AionServerPacket;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob.ItemBlobType;

public class SM_BROKER_SERVICE extends AionServerPacket {
    private enum BrokerPacketType {
        SEARCHED_ITEMS(0), REGISTERED_ITEMS(1), REGISTER_ITEM(3), SHOW_SETTLED_ICON(5), SETTLED_ITEMS(5),
        REMOVE_SETTLED_ICON(6), AVE_LOW_HIGH_ITEM(7);

        private int id;

        private BrokerPacketType(int id) {
            this.id = id;
        }

        private int getId() {
            return id;
        }
    }

    private BrokerPacketType type;
    private BrokerItem[] brokerItems;
    private int itemsCount;
    private int startPage;
    private int message;
    private long settled_kinah;
    private int itemUniqueId;
    private long Ave7day;
    private long CurrentLow;
    private long CurrentHigh;
    private boolean IsLowHighSame;

    public SM_BROKER_SERVICE(BrokerItem brokerItem, int message, int itemsCount) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.brokerItems = new BrokerItem[] { brokerItem };
        this.message = message;
        this.itemsCount = itemsCount;
    }

    public SM_BROKER_SERVICE(int message) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.message = message;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems) {
        this.type = BrokerPacketType.REGISTERED_ITEMS;
        this.brokerItems = brokerItems;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, long settled_kinah) {
        this.type = BrokerPacketType.SETTLED_ITEMS;
        this.brokerItems = brokerItems;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, int itemsCount, int startPage) {
        this.type = BrokerPacketType.SEARCHED_ITEMS;
        this.brokerItems = brokerItems;
        this.itemsCount = itemsCount;
        this.startPage = startPage;
    }

    public SM_BROKER_SERVICE(boolean showSettledIcon, long settled_kinah) {
        this.type = showSettledIcon ? BrokerPacketType.SHOW_SETTLED_ICON : BrokerPacketType.REMOVE_SETTLED_ICON;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(int itemUniqueId, long Ave7day, long CurrentLow, long CurrentHigh, boolean IsLowHighSame) {
        this.type = BrokerPacketType.AVE_LOW_HIGH_ITEM;
        this.itemUniqueId = itemUniqueId;
        this.Ave7day = Ave7day;
        this.CurrentLow = CurrentLow;
        this.CurrentHigh = CurrentHigh;
        this.IsLowHighSame = IsLowHighSame;
    }

    @Override
    protected void writeImpl(AionConnection con) {
        switch (type) {
        case SEARCHED_ITEMS:
            writeSearchedItems();
            break;
        case REGISTERED_ITEMS:
            writeRegisteredItems();
            break;
        case REGISTER_ITEM:
            writeRegisterItem();
            break;
        case SHOW_SETTLED_ICON:
            writeShowSettledIcon();
            break;
        case REMOVE_SETTLED_ICON:
            writeRemoveSettledIcon();
            break;
        case SETTLED_ITEMS:
            writeShowSettledItems();
            break;
        case AVE_LOW_HIGH_ITEM:
            writeItemAveLowHigh();
            break;
        }
    }

    private void writeItemAveLowHigh() {
        writeC(type.getId());
        writeC(0x00);
        writeD(itemUniqueId);
        writeQ(Ave7day);
        writeC(IsLowHighSame ? 0x02 : 0x00);
        writeQ(CurrentLow);
        writeQ(CurrentHigh);
    }

    private void writeSearchedItems() {
        writeC(type.getId());
        writeD(itemsCount);
        writeC(0);
        writeH(startPage);
        writeH(brokerItems.length);
        for (BrokerItem item : brokerItems) {
            writeItemInfo(item);
        }
    }

    private void writeRegisteredItems() {
        writeC(type.getId());
        writeD(0x00);
        writeH(brokerItems.length);
        for (BrokerItem brokerItem : brokerItems) {
            writeRegisteredItemInfo(brokerItem);
        }
    }

    private void writeRegisterItem() {
        writeC(type.getId());
        writeC(message);
        if (message == 0) {
            writeC(itemsCount + 1);
            BrokerItem itemForRegistration = brokerItems[0];
            writeRegisteredItemInfo(itemForRegistration);
        } else {
            writeB(new byte[107]);
        }
    }

    private void writeShowSettledIcon() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeD(0x00);
        writeH(0x00);
        writeH(0x01);
        writeC(0x00);
    }

    private void writeRemoveSettledIcon() {
        writeH(type.getId());
    }

    private void writeShowSettledItems() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeH(brokerItems.length);
        writeD(0x00);
        writeC(0x00);
        writeH(brokerItems.length);
        for (BrokerItem settledItem : brokerItems) {
            writeD(settledItem.getItemId());
            if (settledItem.isSold()) {
                writeQ(settledItem.getPrice());
            } else {
                writeQ(0);
            }
            writeQ(settledItem.getItemCount());
            writeQ(settledItem.getItemCount());
            writeD((int) ((settledItem.getSettleTime().getTime() / 60000) & 0xffffffffl));
            Item item = settledItem.getItem();
            if (item != null) {
                ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
            } else {
                writeB(new byte[187]);
            }
            writeS(settledItem.getItemCreator());

            writeB(new byte[8]);// 5.5
        }
    }

    private void writeRegisteredItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(brokerItem.getItemUniqueId());
        writeD(brokerItem.getItemId());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        writeQ(item.getItemCount());
        Timestamp currentTime = new Timestamp(Calendar.getInstance().getTimeInMillis());
        int daysLeft = (int) ((brokerItem.getExpireTime().getTime() - currentTime.getTime()) / 86400000);
        writeC(daysLeft);
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
        int commission = brokerItem.getSellCommission();
        writeD(commission); // unk 5.5
        writeD(0x00); // unk 5.5
    }

    private void writeItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(item.getObjectId());
        writeD(item.getItemTemplate().getTemplateId());
        writeQ(brokerItem.getPrice());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getSeller());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
    }
}

казалось бы структура похожа на то что ожидает клиент, но есть некоторые проблемы с поиском предметов(в некоторых вкладках) в брокере и не показывает иконку упаковки на предмете в окне поиска, казалось бы что проблема в структуре
ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
но последние поля как имя продавца и сплитселл читаются адекватно,а при попытках поменять струкутуру блоба натыкаешься на вылет игры либо некорректное отображение предметов в брокере

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

сравнение сниффов было буквально проверено по байтам с нашей структурой
собственно разницы там не было

Вопросы:
Где ошибка? В стратегии починки пакета( не тот инструментарий либо иду не достаточно глубоко )?
Насколько Scylla вообще способна обходить защиту которую имеет клиент Aion?
Допустим я знаю размер и примерную структуру пакета у меня вообще есть возможно узнать какие данные ожидает клиент?
Если есть некоторые рекомендации по извлечению информации из клиента касательно структуры пакетов, то я буду очень благодарен.
 
но есть некоторые проблемы с поиском предметов(в некоторых вкладках) в брокере и не показывает иконку упаковки на предмете в окне поиска, казалось бы что проблема в структуре
Возможно у вас дело не в пакете даже, думаю стоит посмотреть BrokerItemMask - существует ли вообще данная маска в вашей сборке для упаковки (если нет то добавить). Так же в статиках (item_templates.xml) посмотреть как была спарсена упаковка.

Вопросы:
Где ошибка? В стратегии починки пакета( не тот инструментарий либо иду не достаточно глубоко )?
Насколько Scylla вообще способна обходить защиту которую имеет клиент Aion?
Допустим я знаю размер и примерную структуру пакета у меня вообще есть возможно узнать какие данные ожидает клиент?
Если есть некоторые рекомендации по извлечению информации из клиента касательно структуры пакетов, то я буду очень благодарен.
Самый лучший способ всё таки сниф, а сейчас при наличии оф сборки 5.8 есть хорошая возможность отснифать все желаемые пакеты.
Но не забывайте, что и снифер придется переделать протоколы под 5.8 (поменять внутри структуру).
Ставьте сборку на отдельной машине, а другим компом собирайте инфу (в локалке может не получится).
 
Доброго времени стуок, были проведены следующие операции:
1)Был снят дамп клиента(game.dll) с помощью x64dbg
2)Обошли Themida с помощью плагина Scylla
3)И этот дамп был проанализирован в IDA

Собственно получил вот это:
(в данном конкретном случае рассмотрим пакет SM_BROKER_SERVICE)
Objective-C:
__int64 __fastcall sub_59CEB320(__int64 a1, __int64 a2)
{
  signed __int64 v2; // r8
  __int64 result; // rax
  char v4; // cl
  int v5; // er11
  char v6; // dl
  __int64 v7; // r10
  __int64 v8; // r9
  __int64 v9; // r8

  v2 = *(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64;
  result = *(unsigned __int8 *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32));
  switch ( (_DWORD)result )
  {
    case 0:
      result = sub_59CEB440(a1, (int *)v2);
      break;
    case 1:
      result = sub_59CEB780(a1, v2);
      break;
    case 2:
      result = sub_5965BA80(
                 a1,
                 (unsigned int)*(char *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64),
                 *(unsigned int *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64),
                 *(_QWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 6i64));
      break;
    case 3:
      result = sub_59CEBAC0(a1, v2);
      break;
    case 4:
      result = sub_59CEBD50(a1, v2);
      break;
    case 5:
      result = sub_59CEBEF0(a1, v2);
      break;
    case 6:
      if ( !*(_BYTE *)v2 )
        result = sub_59B761E0(a1);
      break;
    case 7:
      v4 = *(_BYTE *)v2;
      v5 = *(_DWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64);
      v6 = *(_BYTE *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 14i64);
      v7 = *(_QWORD *)(v2 + 22);
      v8 = *(_QWORD *)(v2 + 14);
      v9 = *(_QWORD *)(v2 + 5);
      result = sub_59AECD00(1145446400i64);
      break;
    default:
      return result;
  }
  return result;
}


(рассмотрим 0 кейс)
C-подобный:
__int64 __fastcall sub_59CEB440(__int64 a1, int *a2)
{
  __int16 v2; // bx
  int v3; // edi
  char v4; // r14
  __int16 v5; // r15
  char *v6; // rsi
  __int64 v7; // r14
  __int128 v8; // xmm0
  __int128 v9; // xmm1
  int v10; // er15
  unsigned int v11; // er12
  __int64 v12; // r9
  __int64 v13; // r13
  __int128 v14; // xmm0
  __int128 v15; // xmm1
  __int128 v16; // xmm0
  __int128 v17; // xmm1
  __int128 v18; // xmm0
  __int128 v19; // xmm1
  __int64 v20; // rax
  signed int v21; // er8
  __int128 v22; // xmm0
  __int128 v23; // xmm1
  __int128 v24; // xmm0
  signed __int64 v25; // rcx
  __int16 v26; // dx
  __int16 *i; // rax
  signed __int64 v28; // rcx
  __int16 *v29; // rdx
  __int16 v30; // ax
  signed int j; // er8
  char v32; // r8
  char v33; // di
  __int16 v34; // bx
  int v35; // er11
  __int16 v36; // r10
  __int64 v37; // rax
  __int16 v39; // [rsp+70h] [rbp-88h]
  __int64 v40; // [rsp+72h] [rbp-86h]
  __int64 v41; // [rsp+7Ah] [rbp-7Eh]
  __int64 v42; // [rsp+82h] [rbp-76h]
  __int64 v43; // [rsp+8Ah] [rbp-6Eh]
  __int64 v44; // [rsp+92h] [rbp-66h]
  __int16 v45; // [rsp+9Ah] [rbp-5Eh]
  __int16 v46; // [rsp+A0h] [rbp-58h]
  __int64 v47; // [rsp+A2h] [rbp-56h]
  __int64 v48; // [rsp+AAh] [rbp-4Eh]
  __int64 v49; // [rsp+B2h] [rbp-46h]
  __int64 v50; // [rsp+BAh] [rbp-3Eh]
  __int64 v51; // [rsp+C2h] [rbp-36h]
  __int64 v52; // [rsp+CAh] [rbp-2Eh]
  __int16 v53; // [rsp+D2h] [rbp-26h]
  __int128 v54; // [rsp+D8h] [rbp-20h]
  __int128 v55; // [rsp+E8h] [rbp-10h]
  __int128 v56; // [rsp+F8h] [rbp+0h]
  __int128 v57; // [rsp+108h] [rbp+10h]
  __int128 v58; // [rsp+118h] [rbp+20h]
  __int128 v59; // [rsp+128h] [rbp+30h]
  __int128 v60; // [rsp+138h] [rbp+40h]
  __int128 v61; // [rsp+148h] [rbp+50h]
  __int128 v62; // [rsp+158h] [rbp+60h]
  __int128 v63; // [rsp+168h] [rbp+70h]
  __int128 v64; // [rsp+178h] [rbp+80h]
  __int64 v65; // [rsp+188h] [rbp+90h]
  __int16 v66; // [rsp+190h] [rbp+98h]
  char v67; // [rsp+192h] [rbp+9Ah]
  __int128 v68; // [rsp+198h] [rbp+A0h]
  __int128 v69; // [rsp+1A8h] [rbp+B0h]
  __int128 v70; // [rsp+1B8h] [rbp+C0h]
  __int128 v71; // [rsp+1C8h] [rbp+D0h]
  __int128 v72; // [rsp+1D8h] [rbp+E0h]
  __int128 v73; // [rsp+1E8h] [rbp+F0h]
  __int128 v74; // [rsp+1F8h] [rbp+100h]
  __int128 v75; // [rsp+208h] [rbp+110h]
  __int128 v76; // [rsp+218h] [rbp+120h]
  __int128 v77; // [rsp+228h] [rbp+130h]
  __int128 v78; // [rsp+238h] [rbp+140h]
  __int64 v79; // [rsp+248h] [rbp+150h]
  __int16 v80; // [rsp+250h] [rbp+158h]
  char v81; // [rsp+252h] [rbp+15Ah]

  v2 = *(_WORD *)((char *)a2 + 7);
  v3 = *a2;
  v4 = *((_BYTE *)a2 + 4);
  v5 = *(_WORD *)((char *)a2 + 5);
  v6 = (char *)a2 + 9;
  sub_59C45F30(a1);
  sub_59AE7AE0(1145446400i64, v5, v3, v4);
  if ( v2 > 0 )
  {
    v7 = (unsigned int)v2;
    do
    {
      v8 = *((_OWORD *)v6 + 2);
      v9 = *((_OWORD *)v6 + 3);
      v10 = *(_DWORD *)v6;
      v11 = *((_DWORD *)v6 + 1);
      v12 = *((_QWORD *)v6 + 1);
      v13 = *((_QWORD *)v6 + 3);
      v40 = 0i64;
      v41 = 0i64;
      v54 = v8;
      v14 = *((_OWORD *)v6 + 4);
      v55 = v9;
      v41 = 0i64;
      v42 = 0i64;
      v43 = 0i64;
      v15 = *((_OWORD *)v6 + 5);
      v56 = v14;
      v16 = *((_OWORD *)v6 + 6);
      v44 = 0i64;
      v45 = 0;
      v47 = 0i64;
      v48 = 0i64;
      v49 = 0i64;
      v50 = 0i64;
      v57 = v15;
      v17 = *((_OWORD *)v6 + 7);
      v58 = v16;
      v51 = 0i64;
      v52 = 0i64;
      v53 = 0;
      v18 = *((_OWORD *)v6 + 8);
      v59 = v17;
      v19 = *((_OWORD *)v6 + 9);
      v20 = *((_QWORD *)v6 + 26);
      v39 = 0;
      v46 = 0;
      v21 = 26;
      v60 = v18;
      v22 = *((_OWORD *)v6 + 10);
      v61 = v19;
      v23 = *((_OWORD *)v6 + 11);
      v62 = v22;
      v24 = *((_OWORD *)v6 + 12);
      v63 = v23;
      v64 = v24;
      v65 = v20;
      v66 = *((_WORD *)v6 + 108);
      v25 = (signed __int64)(v6 + 219);
      v67 = v6[218];
      v26 = *(_WORD *)(v6 + 219);
      for ( i = &v46; v26; v25 += 2i64 )
      {
        if ( --v21 > 0 )
        {
          *i = v26;
          ++i;
        }
        v26 = *(_WORD *)(v25 + 2);
      }
      v28 = v25 + 2;
      *i = 0;
      v29 = &v39;
      v30 = *(_WORD *)v28;
      for ( j = 26; v30; v28 += 2i64 )
      {
        if ( --j > 0 )
        {
          *v29 = v30;
          ++v29;
        }
        v30 = *(_WORD *)(v28 + 2);
      }
      v32 = *(_BYTE *)(v28 + 10);
      v33 = *(_BYTE *)(v28 + 2);
      v34 = *(_WORD *)(v28 + 3);
      v35 = *(_DWORD *)(v28 + 5);
      *v29 = 0;
      v36 = *(unsigned __int8 *)(v28 + 9);
      v68 = v54;
      v69 = v55;
      v6 = (char *)(v28 + 11);
      v70 = v56;
      v71 = v57;
      v72 = v58;
      v73 = v59;
      v74 = v60;
      v75 = v61;
      v76 = v62;
      v77 = v63;
      v78 = v64;
      v79 = v65;
      v80 = v66;
      v81 = v67;
      v37 = sub_59C45BA0(
              (__int64)&v62,
              v10,
              v11,
              v12,
              v13,
              (unsigned __int64)&v68,
              (unsigned __int64)&v39,
              (unsigned __int64)&v46,
              v33,
              v34,
              v35,
              v36,
              v32 != 0);
      if ( v37 )
        sub_59AE7C40(1145446400i64, v37);
      --v7;
    }
    while ( v7 );
  }
  return sub_59AE8060(1145446400i64);
}


Посмотреть вложение 96795
Посмотреть вложение 96796
Посмотреть вложение 96797
структура пакета на эмуляторе:
(0 кейс)

Java:
package com.aionemu.gameserver.network.aion.serverpackets;

import java.sql.Timestamp;
import java.util.Calendar;

import com.aionemu.gameserver.model.gameobjects.BrokerItem;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.network.aion.AionConnection;
import com.aionemu.gameserver.network.aion.AionServerPacket;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob.ItemBlobType;

public class SM_BROKER_SERVICE extends AionServerPacket {
    private enum BrokerPacketType {
        SEARCHED_ITEMS(0), REGISTERED_ITEMS(1), REGISTER_ITEM(3), SHOW_SETTLED_ICON(5), SETTLED_ITEMS(5),
        REMOVE_SETTLED_ICON(6), AVE_LOW_HIGH_ITEM(7);

        private int id;

        private BrokerPacketType(int id) {
            this.id = id;
        }

        private int getId() {
            return id;
        }
    }

    private BrokerPacketType type;
    private BrokerItem[] brokerItems;
    private int itemsCount;
    private int startPage;
    private int message;
    private long settled_kinah;
    private int itemUniqueId;
    private long Ave7day;
    private long CurrentLow;
    private long CurrentHigh;
    private boolean IsLowHighSame;

    public SM_BROKER_SERVICE(BrokerItem brokerItem, int message, int itemsCount) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.brokerItems = new BrokerItem[] { brokerItem };
        this.message = message;
        this.itemsCount = itemsCount;
    }

    public SM_BROKER_SERVICE(int message) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.message = message;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems) {
        this.type = BrokerPacketType.REGISTERED_ITEMS;
        this.brokerItems = brokerItems;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, long settled_kinah) {
        this.type = BrokerPacketType.SETTLED_ITEMS;
        this.brokerItems = brokerItems;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, int itemsCount, int startPage) {
        this.type = BrokerPacketType.SEARCHED_ITEMS;
        this.brokerItems = brokerItems;
        this.itemsCount = itemsCount;
        this.startPage = startPage;
    }

    public SM_BROKER_SERVICE(boolean showSettledIcon, long settled_kinah) {
        this.type = showSettledIcon ? BrokerPacketType.SHOW_SETTLED_ICON : BrokerPacketType.REMOVE_SETTLED_ICON;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(int itemUniqueId, long Ave7day, long CurrentLow, long CurrentHigh, boolean IsLowHighSame) {
        this.type = BrokerPacketType.AVE_LOW_HIGH_ITEM;
        this.itemUniqueId = itemUniqueId;
        this.Ave7day = Ave7day;
        this.CurrentLow = CurrentLow;
        this.CurrentHigh = CurrentHigh;
        this.IsLowHighSame = IsLowHighSame;
    }

    @Override
    protected void writeImpl(AionConnection con) {
        switch (type) {
        case SEARCHED_ITEMS:
            writeSearchedItems();
            break;
        case REGISTERED_ITEMS:
            writeRegisteredItems();
            break;
        case REGISTER_ITEM:
            writeRegisterItem();
            break;
        case SHOW_SETTLED_ICON:
            writeShowSettledIcon();
            break;
        case REMOVE_SETTLED_ICON:
            writeRemoveSettledIcon();
            break;
        case SETTLED_ITEMS:
            writeShowSettledItems();
            break;
        case AVE_LOW_HIGH_ITEM:
            writeItemAveLowHigh();
            break;
        }
    }

    private void writeItemAveLowHigh() {
        writeC(type.getId());
        writeC(0x00);
        writeD(itemUniqueId);
        writeQ(Ave7day);
        writeC(IsLowHighSame ? 0x02 : 0x00);
        writeQ(CurrentLow);
        writeQ(CurrentHigh);
    }

    private void writeSearchedItems() {
        writeC(type.getId());
        writeD(itemsCount);
        writeC(0);
        writeH(startPage);
        writeH(brokerItems.length);
        for (BrokerItem item : brokerItems) {
            writeItemInfo(item);
        }
    }

    private void writeRegisteredItems() {
        writeC(type.getId());
        writeD(0x00);
        writeH(brokerItems.length);
        for (BrokerItem brokerItem : brokerItems) {
            writeRegisteredItemInfo(brokerItem);
        }
    }

    private void writeRegisterItem() {
        writeC(type.getId());
        writeC(message);
        if (message == 0) {
            writeC(itemsCount + 1);
            BrokerItem itemForRegistration = brokerItems[0];
            writeRegisteredItemInfo(itemForRegistration);
        } else {
            writeB(new byte[107]);
        }
    }

    private void writeShowSettledIcon() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeD(0x00);
        writeH(0x00);
        writeH(0x01);
        writeC(0x00);
    }

    private void writeRemoveSettledIcon() {
        writeH(type.getId());
    }

    private void writeShowSettledItems() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeH(brokerItems.length);
        writeD(0x00);
        writeC(0x00);
        writeH(brokerItems.length);
        for (BrokerItem settledItem : brokerItems) {
            writeD(settledItem.getItemId());
            if (settledItem.isSold()) {
                writeQ(settledItem.getPrice());
            } else {
                writeQ(0);
            }
            writeQ(settledItem.getItemCount());
            writeQ(settledItem.getItemCount());
            writeD((int) ((settledItem.getSettleTime().getTime() / 60000) & 0xffffffffl));
            Item item = settledItem.getItem();
            if (item != null) {
                ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
            } else {
                writeB(new byte[187]);
            }
            writeS(settledItem.getItemCreator());

            writeB(new byte[8]);// 5.5
        }
    }

    private void writeRegisteredItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(brokerItem.getItemUniqueId());
        writeD(brokerItem.getItemId());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        writeQ(item.getItemCount());
        Timestamp currentTime = new Timestamp(Calendar.getInstance().getTimeInMillis());
        int daysLeft = (int) ((brokerItem.getExpireTime().getTime() - currentTime.getTime()) / 86400000);
        writeC(daysLeft);
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
        int commission = brokerItem.getSellCommission();
        writeD(commission); // unk 5.5
        writeD(0x00); // unk 5.5
    }

    private void writeItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(item.getObjectId());
        writeD(item.getItemTemplate().getTemplateId());
        writeQ(brokerItem.getPrice());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getSeller());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
    }
}

казалось бы структура похожа на то что ожидает клиент, но есть некоторые проблемы с поиском предметов(в некоторых вкладках) в брокере и не показывает иконку упаковки на предмете в окне поиска, казалось бы что проблема в структуре
ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
но последние поля как имя продавца и сплитселл читаются адекватно,а при попытках поменять струкутуру блоба натыкаешься на вылет игры либо некорректное отображение предметов в брокере

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

сравнение сниффов было буквально проверено по байтам с нашей структурой
собственно разницы там не было

Вопросы:
Где ошибка? В стратегии починки пакета( не тот инструментарий либо иду не достаточно глубоко )?
Насколько Scylla вообще способна обходить защиту которую имеет клиент Aion?
Допустим я знаю размер и примерную структуру пакета у меня вообще есть возможно узнать какие данные ожидает клиент?
Если есть некоторые рекомендации по извлечению информации из клиента касательно структуры пакетов, то я буду очень благодарен.
жеееесть, у меня просто по тупому. Идет строка и циферки / буфферы которые в него записываются :)
 
Доброго времени стуок, были проведены следующие операции:
1)Был снят дамп клиента(game.dll) с помощью x64dbg
2)Обошли Themida с помощью плагина Scylla
3)И этот дамп был проанализирован в IDA
Вроде как с 7.7 оф сборкой были где то и pdb в комплекте, можно ещё и их покопать раз уж решился в IDA смотреть.
 
Последнее редактирование:
Доброго времени стуок, были проведены следующие операции:
1)Был снят дамп клиента(game.dll) с помощью x64dbg
2)Обошли Themida с помощью плагина Scylla
3)И этот дамп был проанализирован в IDA

Собственно получил вот это:
(в данном конкретном случае рассмотрим пакет SM_BROKER_SERVICE)
Objective-C:
__int64 __fastcall sub_59CEB320(__int64 a1, __int64 a2)
{
  signed __int64 v2; // r8
  __int64 result; // rax
  char v4; // cl
  int v5; // er11
  char v6; // dl
  __int64 v7; // r10
  __int64 v8; // r9
  __int64 v9; // r8

  v2 = *(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64;
  result = *(unsigned __int8 *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32));
  switch ( (_DWORD)result )
  {
    case 0:
      result = sub_59CEB440(a1, (int *)v2);
      break;
    case 1:
      result = sub_59CEB780(a1, v2);
      break;
    case 2:
      result = sub_5965BA80(
                 a1,
                 (unsigned int)*(char *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 1i64),
                 *(unsigned int *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64),
                 *(_QWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 6i64));
      break;
    case 3:
      result = sub_59CEBAC0(a1, v2);
      break;
    case 4:
      result = sub_59CEBD50(a1, v2);
      break;
    case 5:
      result = sub_59CEBEF0(a1, v2);
      break;
    case 6:
      if ( !*(_BYTE *)v2 )
        result = sub_59B761E0(a1);
      break;
    case 7:
      v4 = *(_BYTE *)v2;
      v5 = *(_DWORD *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 2i64);
      v6 = *(_BYTE *)(*(_QWORD *)(a2 + 24) + *(signed int *)(a2 + 32) + 14i64);
      v7 = *(_QWORD *)(v2 + 22);
      v8 = *(_QWORD *)(v2 + 14);
      v9 = *(_QWORD *)(v2 + 5);
      result = sub_59AECD00(1145446400i64);
      break;
    default:
      return result;
  }
  return result;
}


(рассмотрим 0 кейс)
C-подобный:
__int64 __fastcall sub_59CEB440(__int64 a1, int *a2)
{
  __int16 v2; // bx
  int v3; // edi
  char v4; // r14
  __int16 v5; // r15
  char *v6; // rsi
  __int64 v7; // r14
  __int128 v8; // xmm0
  __int128 v9; // xmm1
  int v10; // er15
  unsigned int v11; // er12
  __int64 v12; // r9
  __int64 v13; // r13
  __int128 v14; // xmm0
  __int128 v15; // xmm1
  __int128 v16; // xmm0
  __int128 v17; // xmm1
  __int128 v18; // xmm0
  __int128 v19; // xmm1
  __int64 v20; // rax
  signed int v21; // er8
  __int128 v22; // xmm0
  __int128 v23; // xmm1
  __int128 v24; // xmm0
  signed __int64 v25; // rcx
  __int16 v26; // dx
  __int16 *i; // rax
  signed __int64 v28; // rcx
  __int16 *v29; // rdx
  __int16 v30; // ax
  signed int j; // er8
  char v32; // r8
  char v33; // di
  __int16 v34; // bx
  int v35; // er11
  __int16 v36; // r10
  __int64 v37; // rax
  __int16 v39; // [rsp+70h] [rbp-88h]
  __int64 v40; // [rsp+72h] [rbp-86h]
  __int64 v41; // [rsp+7Ah] [rbp-7Eh]
  __int64 v42; // [rsp+82h] [rbp-76h]
  __int64 v43; // [rsp+8Ah] [rbp-6Eh]
  __int64 v44; // [rsp+92h] [rbp-66h]
  __int16 v45; // [rsp+9Ah] [rbp-5Eh]
  __int16 v46; // [rsp+A0h] [rbp-58h]
  __int64 v47; // [rsp+A2h] [rbp-56h]
  __int64 v48; // [rsp+AAh] [rbp-4Eh]
  __int64 v49; // [rsp+B2h] [rbp-46h]
  __int64 v50; // [rsp+BAh] [rbp-3Eh]
  __int64 v51; // [rsp+C2h] [rbp-36h]
  __int64 v52; // [rsp+CAh] [rbp-2Eh]
  __int16 v53; // [rsp+D2h] [rbp-26h]
  __int128 v54; // [rsp+D8h] [rbp-20h]
  __int128 v55; // [rsp+E8h] [rbp-10h]
  __int128 v56; // [rsp+F8h] [rbp+0h]
  __int128 v57; // [rsp+108h] [rbp+10h]
  __int128 v58; // [rsp+118h] [rbp+20h]
  __int128 v59; // [rsp+128h] [rbp+30h]
  __int128 v60; // [rsp+138h] [rbp+40h]
  __int128 v61; // [rsp+148h] [rbp+50h]
  __int128 v62; // [rsp+158h] [rbp+60h]
  __int128 v63; // [rsp+168h] [rbp+70h]
  __int128 v64; // [rsp+178h] [rbp+80h]
  __int64 v65; // [rsp+188h] [rbp+90h]
  __int16 v66; // [rsp+190h] [rbp+98h]
  char v67; // [rsp+192h] [rbp+9Ah]
  __int128 v68; // [rsp+198h] [rbp+A0h]
  __int128 v69; // [rsp+1A8h] [rbp+B0h]
  __int128 v70; // [rsp+1B8h] [rbp+C0h]
  __int128 v71; // [rsp+1C8h] [rbp+D0h]
  __int128 v72; // [rsp+1D8h] [rbp+E0h]
  __int128 v73; // [rsp+1E8h] [rbp+F0h]
  __int128 v74; // [rsp+1F8h] [rbp+100h]
  __int128 v75; // [rsp+208h] [rbp+110h]
  __int128 v76; // [rsp+218h] [rbp+120h]
  __int128 v77; // [rsp+228h] [rbp+130h]
  __int128 v78; // [rsp+238h] [rbp+140h]
  __int64 v79; // [rsp+248h] [rbp+150h]
  __int16 v80; // [rsp+250h] [rbp+158h]
  char v81; // [rsp+252h] [rbp+15Ah]

  v2 = *(_WORD *)((char *)a2 + 7);
  v3 = *a2;
  v4 = *((_BYTE *)a2 + 4);
  v5 = *(_WORD *)((char *)a2 + 5);
  v6 = (char *)a2 + 9;
  sub_59C45F30(a1);
  sub_59AE7AE0(1145446400i64, v5, v3, v4);
  if ( v2 > 0 )
  {
    v7 = (unsigned int)v2;
    do
    {
      v8 = *((_OWORD *)v6 + 2);
      v9 = *((_OWORD *)v6 + 3);
      v10 = *(_DWORD *)v6;
      v11 = *((_DWORD *)v6 + 1);
      v12 = *((_QWORD *)v6 + 1);
      v13 = *((_QWORD *)v6 + 3);
      v40 = 0i64;
      v41 = 0i64;
      v54 = v8;
      v14 = *((_OWORD *)v6 + 4);
      v55 = v9;
      v41 = 0i64;
      v42 = 0i64;
      v43 = 0i64;
      v15 = *((_OWORD *)v6 + 5);
      v56 = v14;
      v16 = *((_OWORD *)v6 + 6);
      v44 = 0i64;
      v45 = 0;
      v47 = 0i64;
      v48 = 0i64;
      v49 = 0i64;
      v50 = 0i64;
      v57 = v15;
      v17 = *((_OWORD *)v6 + 7);
      v58 = v16;
      v51 = 0i64;
      v52 = 0i64;
      v53 = 0;
      v18 = *((_OWORD *)v6 + 8);
      v59 = v17;
      v19 = *((_OWORD *)v6 + 9);
      v20 = *((_QWORD *)v6 + 26);
      v39 = 0;
      v46 = 0;
      v21 = 26;
      v60 = v18;
      v22 = *((_OWORD *)v6 + 10);
      v61 = v19;
      v23 = *((_OWORD *)v6 + 11);
      v62 = v22;
      v24 = *((_OWORD *)v6 + 12);
      v63 = v23;
      v64 = v24;
      v65 = v20;
      v66 = *((_WORD *)v6 + 108);
      v25 = (signed __int64)(v6 + 219);
      v67 = v6[218];
      v26 = *(_WORD *)(v6 + 219);
      for ( i = &v46; v26; v25 += 2i64 )
      {
        if ( --v21 > 0 )
        {
          *i = v26;
          ++i;
        }
        v26 = *(_WORD *)(v25 + 2);
      }
      v28 = v25 + 2;
      *i = 0;
      v29 = &v39;
      v30 = *(_WORD *)v28;
      for ( j = 26; v30; v28 += 2i64 )
      {
        if ( --j > 0 )
        {
          *v29 = v30;
          ++v29;
        }
        v30 = *(_WORD *)(v28 + 2);
      }
      v32 = *(_BYTE *)(v28 + 10);
      v33 = *(_BYTE *)(v28 + 2);
      v34 = *(_WORD *)(v28 + 3);
      v35 = *(_DWORD *)(v28 + 5);
      *v29 = 0;
      v36 = *(unsigned __int8 *)(v28 + 9);
      v68 = v54;
      v69 = v55;
      v6 = (char *)(v28 + 11);
      v70 = v56;
      v71 = v57;
      v72 = v58;
      v73 = v59;
      v74 = v60;
      v75 = v61;
      v76 = v62;
      v77 = v63;
      v78 = v64;
      v79 = v65;
      v80 = v66;
      v81 = v67;
      v37 = sub_59C45BA0(
              (__int64)&v62,
              v10,
              v11,
              v12,
              v13,
              (unsigned __int64)&v68,
              (unsigned __int64)&v39,
              (unsigned __int64)&v46,
              v33,
              v34,
              v35,
              v36,
              v32 != 0);
      if ( v37 )
        sub_59AE7C40(1145446400i64, v37);
      --v7;
    }
    while ( v7 );
  }
  return sub_59AE8060(1145446400i64);
}


Посмотреть вложение 96795
Посмотреть вложение 96796
Посмотреть вложение 96797
структура пакета на эмуляторе:
(0 кейс)

Java:
package com.aionemu.gameserver.network.aion.serverpackets;

import java.sql.Timestamp;
import java.util.Calendar;

import com.aionemu.gameserver.model.gameobjects.BrokerItem;
import com.aionemu.gameserver.model.gameobjects.Item;
import com.aionemu.gameserver.network.aion.AionConnection;
import com.aionemu.gameserver.network.aion.AionServerPacket;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob;
import com.aionemu.gameserver.network.aion.iteminfo.ItemInfoBlob.ItemBlobType;

public class SM_BROKER_SERVICE extends AionServerPacket {
    private enum BrokerPacketType {
        SEARCHED_ITEMS(0), REGISTERED_ITEMS(1), REGISTER_ITEM(3), SHOW_SETTLED_ICON(5), SETTLED_ITEMS(5),
        REMOVE_SETTLED_ICON(6), AVE_LOW_HIGH_ITEM(7);

        private int id;

        private BrokerPacketType(int id) {
            this.id = id;
        }

        private int getId() {
            return id;
        }
    }

    private BrokerPacketType type;
    private BrokerItem[] brokerItems;
    private int itemsCount;
    private int startPage;
    private int message;
    private long settled_kinah;
    private int itemUniqueId;
    private long Ave7day;
    private long CurrentLow;
    private long CurrentHigh;
    private boolean IsLowHighSame;

    public SM_BROKER_SERVICE(BrokerItem brokerItem, int message, int itemsCount) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.brokerItems = new BrokerItem[] { brokerItem };
        this.message = message;
        this.itemsCount = itemsCount;
    }

    public SM_BROKER_SERVICE(int message) {
        this.type = BrokerPacketType.REGISTER_ITEM;
        this.message = message;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems) {
        this.type = BrokerPacketType.REGISTERED_ITEMS;
        this.brokerItems = brokerItems;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, long settled_kinah) {
        this.type = BrokerPacketType.SETTLED_ITEMS;
        this.brokerItems = brokerItems;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(BrokerItem[] brokerItems, int itemsCount, int startPage) {
        this.type = BrokerPacketType.SEARCHED_ITEMS;
        this.brokerItems = brokerItems;
        this.itemsCount = itemsCount;
        this.startPage = startPage;
    }

    public SM_BROKER_SERVICE(boolean showSettledIcon, long settled_kinah) {
        this.type = showSettledIcon ? BrokerPacketType.SHOW_SETTLED_ICON : BrokerPacketType.REMOVE_SETTLED_ICON;
        this.settled_kinah = settled_kinah;
    }

    public SM_BROKER_SERVICE(int itemUniqueId, long Ave7day, long CurrentLow, long CurrentHigh, boolean IsLowHighSame) {
        this.type = BrokerPacketType.AVE_LOW_HIGH_ITEM;
        this.itemUniqueId = itemUniqueId;
        this.Ave7day = Ave7day;
        this.CurrentLow = CurrentLow;
        this.CurrentHigh = CurrentHigh;
        this.IsLowHighSame = IsLowHighSame;
    }

    @Override
    protected void writeImpl(AionConnection con) {
        switch (type) {
        case SEARCHED_ITEMS:
            writeSearchedItems();
            break;
        case REGISTERED_ITEMS:
            writeRegisteredItems();
            break;
        case REGISTER_ITEM:
            writeRegisterItem();
            break;
        case SHOW_SETTLED_ICON:
            writeShowSettledIcon();
            break;
        case REMOVE_SETTLED_ICON:
            writeRemoveSettledIcon();
            break;
        case SETTLED_ITEMS:
            writeShowSettledItems();
            break;
        case AVE_LOW_HIGH_ITEM:
            writeItemAveLowHigh();
            break;
        }
    }

    private void writeItemAveLowHigh() {
        writeC(type.getId());
        writeC(0x00);
        writeD(itemUniqueId);
        writeQ(Ave7day);
        writeC(IsLowHighSame ? 0x02 : 0x00);
        writeQ(CurrentLow);
        writeQ(CurrentHigh);
    }

    private void writeSearchedItems() {
        writeC(type.getId());
        writeD(itemsCount);
        writeC(0);
        writeH(startPage);
        writeH(brokerItems.length);
        for (BrokerItem item : brokerItems) {
            writeItemInfo(item);
        }
    }

    private void writeRegisteredItems() {
        writeC(type.getId());
        writeD(0x00);
        writeH(brokerItems.length);
        for (BrokerItem brokerItem : brokerItems) {
            writeRegisteredItemInfo(brokerItem);
        }
    }

    private void writeRegisterItem() {
        writeC(type.getId());
        writeC(message);
        if (message == 0) {
            writeC(itemsCount + 1);
            BrokerItem itemForRegistration = brokerItems[0];
            writeRegisteredItemInfo(itemForRegistration);
        } else {
            writeB(new byte[107]);
        }
    }

    private void writeShowSettledIcon() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeD(0x00);
        writeH(0x00);
        writeH(0x01);
        writeC(0x00);
    }

    private void writeRemoveSettledIcon() {
        writeH(type.getId());
    }

    private void writeShowSettledItems() {
        writeC(type.getId());
        writeQ(settled_kinah);
        writeH(brokerItems.length);
        writeD(0x00);
        writeC(0x00);
        writeH(brokerItems.length);
        for (BrokerItem settledItem : brokerItems) {
            writeD(settledItem.getItemId());
            if (settledItem.isSold()) {
                writeQ(settledItem.getPrice());
            } else {
                writeQ(0);
            }
            writeQ(settledItem.getItemCount());
            writeQ(settledItem.getItemCount());
            writeD((int) ((settledItem.getSettleTime().getTime() / 60000) & 0xffffffffl));
            Item item = settledItem.getItem();
            if (item != null) {
                ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
            } else {
                writeB(new byte[187]);
            }
            writeS(settledItem.getItemCreator());

            writeB(new byte[8]);// 5.5
        }
    }

    private void writeRegisteredItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(brokerItem.getItemUniqueId());
        writeD(brokerItem.getItemId());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        writeQ(item.getItemCount());
        Timestamp currentTime = new Timestamp(Calendar.getInstance().getTimeInMillis());
        int daysLeft = (int) ((brokerItem.getExpireTime().getTime() - currentTime.getTime()) / 86400000);
        writeC(daysLeft);
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
        int commission = brokerItem.getSellCommission();
        writeD(commission); // unk 5.5
        writeD(0x00); // unk 5.5
    }

    private void writeItemInfo(BrokerItem brokerItem) {
        Item item = brokerItem.getItem();
        writeD(item.getObjectId());
        writeD(item.getItemTemplate().getTemplateId());
        writeQ(brokerItem.getPrice());
        writeQ(brokerItem.getPrice());
        writeQ(item.getItemCount());
        ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
        writeS(brokerItem.getSeller());
        writeS(brokerItem.getItemCreator());
        ItemInfoBlob.newBlobEntry(ItemBlobType.PREMIUM_OPTION, null, item).writeThisBlob(getBuf());
        ItemInfoBlob.newBlobEntry(ItemBlobType.IDIAN_INFO, null, item).writeThisBlob(getBuf());
        //ItemInfoBlob.newBlobEntry(ItemBlobType.WRAPP_INFO, null, item).writeThisBlob(getBuf());
        writeC(0x00);
        writeC(brokerItem.isSplitSell() ? 0x01 : 0x00);
    }
}

казалось бы структура похожа на то что ожидает клиент, но есть некоторые проблемы с поиском предметов(в некоторых вкладках) в брокере и не показывает иконку упаковки на предмете в окне поиска, казалось бы что проблема в структуре
ItemInfoBlob.newBlobEntry(ItemBlobType.MANA_SOCKETS, null, item).writeThisBlob(getBuf());
но последние поля как имя продавца и сплитселл читаются адекватно,а при попытках поменять струкутуру блоба натыкаешься на вылет игры либо некорректное отображение предметов в брокере

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

сравнение сниффов было буквально проверено по байтам с нашей структурой
собственно разницы там не было

Вопросы:
Где ошибка? В стратегии починки пакета( не тот инструментарий либо иду не достаточно глубоко )?
Насколько Scylla вообще способна обходить защиту которую имеет клиент Aion?
Допустим я знаю размер и примерную структуру пакета у меня вообще есть возможно узнать какие данные ожидает клиент?
Если есть некоторые рекомендации по извлечению информации из клиента касательно структуры пакетов, то я буду очень благодарен.
А ты не пробовал запустить IDA Pro 9 подключить AI и поставить точку останова на эту функцию? А дальше скриптом полный дамп всех переменных которые тебе нужны. Ну и вообще чего она тебе скажет, если ты снял "Был снят дамп клиента(game.dll) с помощью x64dbg" то все должно заработать
 
Ну если на базе л2...

В IDA (Interactive Disassembler) открываем Engine.dll (если чистый, если под темидой - дампаем в мире игры (через PE Tools) и открываем его).
После чего ждем пока IDA изучает DLL...
Когда закончили - переходим в View - Open Subviews - Strings.
В окшке тыкаем ПКМ и там нужно выбрать "Setup" ну и включить строки "C-Style (32 bits)".


Дальше можно или по этой теме:

* Дополнительно можно попробовать пройтись вот этим по DLL в IDA, но это на свой вкус:

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

Вот у меня условно такое было:
sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22);
И IDA разобрала функцию как - int sub_205E13D0(va_list a1, int a2, int a3, ...)
Там нужно тыкнуть ПКМ на "int a3", после чего нажать на "Set Ivar Type..."
Посмотреть вложение 96780
Указываем там char* format, после чего переходим по таким местам &dword_20C5F290 (2 раза мышкой) и тыкаем "А" (английскую разуемеется).
После этого наш условный sub_205E13D0(*(_DWORD *)(a1 + 72), a2, &dword_20C5F290, v22); превращается на sub_205E13D0(*(_DWORD *)(a1 + 72), a2, "h", v22);
темиду снять можно только на виндовс хп? если нет можешь дать инструменты?
 
Назад
Сверху Снизу