• Новые темы в этом разделе публикуются автоматически при добавлении файла в менеджер ресурсов.
    Ручное создание новых тем невозможно.
Иконка ресурса

Packet Shuffler for L2jMobius Salvation/Arena

òbi добавил(а) новый ресурс:

Packet Shuffler for L2jMobius Salvation/Arena - Шафлер опкодов

  • Что это? - Шафлер опкодов. Тот самый алгоритм перемешивания опкодов пакетов, который был когда-то разработан компанией эНСиСофт (предположительно с хроник Gracia final).
  • Как это работает? - Клиент игры, получив пакет KeyPacket/CryptInit/VersionCheck со значением поля obfuscation Key/shuffle seed отличным от 0, начанает с этого момента запутывать опкоды пакетов при отправки на сервер.


Как это выглядит в логах:
Код:
// после отправки пакета KeyPacket...

Узнать больше об этом ресурсе...
 
Ну я бы использовал вместо ИДшников (статических), динамический вариант (для более наглядного варианта):

Java:
    private static final int[] MAINTAIN_IDS = {0x11, 0x12, 0xB1, 0xD0};
    private static final int[] MAINTAIN_EX_IDS = {0x70, 0x71};

Java:
    private static final int[] MAINTAIN_IDS =
    {
            ClientPacketsOpCodes.C_ENTER_WORLD.ordinal(),
            ClientPacketsOpCodes.C_CHARACTER_SELECT.ordinal(),
            ClientPacketsOpCodes.C_NET_PING.ordinal(),
            ClientPacketsOpCodes.EX_PACKET.ordinal(),
    };

    private static final int[] MAINTAIN_EX_IDS =
    {
            ExClientPacketsOpCodes.C_EX_CONNECT_TO_RAID_SERVER.ordinal(),
            ExClientPacketsOpCodes.C_EX_RETURN_FROM_RAID.ordinal(),
    };

Но для мобиуса нужно бы использовать "getPacketId" :)


Посидел, поколдовал и даже на 542 смог запустить :)

// Скрипты, не мобиус
 
Последнее редактирование модератором:
Но для мобиуса нужно бы использовать "getPacketId" :)
ничего не понимаю в этих ваших мобиусах :LOL: делал себе на шарпе, а эти исходы на жабе просто были под рукой. Вот и портонул в шару
// Скрипты, не мобиус
стало быть перебежчик? :ROFLMAO: чет аж вспомнился ролик из медиа
1767300527462.webp


Посидел, поколдовал и даже на 542 смог запустить :)
так а что по итогу правилось? только кол-во пакетов? Может кому-то пригодится для этих хроник
 
У меня вопросик зачем и для чего, можно включить network log в клиенте и получать актуальные данные. Видимо автор про это не знал
 
У меня вопросик зачем и для чего, можно включить network log в клиенте и получать актуальные данные. Видимо автор про это не знал
актуальные данные чего ты собрался там получать с тех логов, просвети?
Код:
(05:42:12) Log: Log file open, 01/02/26 05:42:12
(05:42:12) Log: (Send)[NONE] RequestAuthLogin
(05:42:12) Log: (Receive)[NONE] ProtocolVersionPacket
(05:42:12) Log: (Send)[NONE] ResponseAuthGameGuard
(05:42:12) Log: (Receive)[NONE] AuthGameGuardPacket
(05:42:13) Log: (Send)[NONE] RL
(05:42:27) Log: (Send)[NONE] RequestServerListsessionId_1:1075046362, sesstionId_2:0, cListKind:5
(05:42:27) Log: (Receive)[NONE] ServerListPacketAll ServerNum:3
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:49, ServerType:1, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:51, ServerType:1099, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:30, ServerType:2609, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServerNum:3
(05:42:35) Log: (Send)[NONE] RequestServerLogin
(05:42:35) Log: (Receive)[NONE] PlayOkPacket
(05:42:35) Log:     (Send)Send Protocol Version:140
(05:42:35) Log: (Receive)[S_VERSION_CHECK] VersionCheckPacket
(05:42:37) Log:     (Send)C_LOGIN Packet
(05:42:37) Log: (Receive)[S_LOGIN_RESULT] LoginResultPacketClient Not Use NP
(05:42:37) Log: (Receive)[S_CHARACTER_SELECTION_INFO] CharacterSelectionInfoPacketcount:0
 
так а что по итогу правилось? только кол-во пакетов? Может кому-то пригодится для этих хроник
Для мобиуса - вот так вот универсальный вариант.
Java:
package org.l2jmobius.gameserver.network;

public class PacketShuffler
{
    private final int[] _state = new int[16];
    private int _stateIndex;

    private final int[] _idsMap;
    private final int[] _exIdsMap;

    private static final int[] MAINTAIN_IDS;
    static
    {
        MAINTAIN_IDS = new int[]
                {
                        ClientPackets.ENTER_WORLD.getPacketId(),
                        ClientPackets.CHARACTER_SELECT.getPacketId(),
                        ClientPackets.NET_PING.getPacketId(),
                        ClientPackets.EX_PACKET.getPacketId(),
                };
    }
    private static final int[] MAINTAIN_EX_IDS;
    static
    {
        MAINTAIN_EX_IDS = new int[]
                {
                        ExClientPackets.EX_CONNECT_TO_RAID_SERVER.getPacketId(),
                        ExClientPackets.EX_RETURN_FROM_RAID_SERVER.getPacketId(),
                };
    }

    private boolean enabled;

    public PacketShuffler()
    {
        _idsMap = new int[ClientPackets.PACKET_ARRAY.length];
        _exIdsMap = new int[ExClientPackets.PACKET_ARRAY.length];
    }

    public boolean isEnabled()
    {
        return enabled;
    }

    public void makeShuffledPacket(int seed)
    {
        for (int i = 0; i < _idsMap.length; i++) _idsMap[i] = i;
        for (int i = 0; i < _exIdsMap.length; i++) _exIdsMap[i] = i;

        _stateIndex = 0;
        int currentSeed = seed;
        for (int i = 0; i < 16; i++)
        {
            _state[i] = currentSeed;
            currentSeed = 2 * currentSeed + 51;
        }

        doShuffle(_idsMap);
        doShuffle(_exIdsMap);

        for (int id : MAINTAIN_IDS) maintainPacket(_idsMap, id);
        for (int id : MAINTAIN_EX_IDS) maintainPacket(_exIdsMap, id);

        enabled = true;
    }

    private void doShuffle(int[] list)
    {
        int nLength = list.length;
        for (int i = 2; i <= nLength; i++)
        {
            int mIdx = _stateIndex;

            int s0 = _state[mIdx];
            int s3 = _state[(mIdx - 3) & 0xF];
            int s7 = _state[(mIdx - 7) & 0xF];

            int v8 = s0 ^ s3 ^ ((s3 ^ (s0 << 1)) << 15);
            int v9 = (s7 >>> 11) ^ s7;

            _state[mIdx] = v8 ^ v9;

            _stateIndex = (_stateIndex - 1) & 0xF;
            int nextIdx = _stateIndex;

            int magic = (v8 ^ v9) & 0xFED22169;
            _state[nextIdx] ^= v9 ^ (magic << 5) ^ (4 * (_state[nextIdx] ^ ((v8 ^ (v9 << 10)) << 16)));

            long unsignedStateValue = Integer.toUnsignedLong(_state[_stateIndex]);
            int swapIdx = (int) (unsignedStateValue % i);
            int currIdx = i - 1;

            int temp = list[currIdx];
            list[currIdx] = list[swapIdx];
            list[swapIdx] = temp;
        }
    }

    private void maintainPacket(int[] map, int targetId)
    {
        if (targetId >= map.length) return;

        for (int i = 0; i < map.length; i++)
        {
            if (map[i] == targetId) {
                int temp = map[i];
                map[i] = map[targetId];
                map[targetId] = temp;
                break;
            }
        }
    }

    public int getOriginalId(int shuffledId)
    {
        return _idsMap[shuffledId];
    }

    public int getOriginalExId(int shuffledId)
    {
        return _exIdsMap[shuffledId];
    }
}
 
У меня вопросик зачем и для чего, можно включить network log в клиенте и получать актуальные данные. Видимо автор про это не знал
та отвкой ты уже тайну того что написал, ибо как то волшебно написал.
 
Я как понял не дружит это с АА? Поставил, АА критует.
 
Я как понял не дружит это с АА? Поставил, АА критует.
значит не дружет :)



У АА есть ритуал обязательный
// Часть моего коментария к этой реализации
Код:
     * Будем надеятся что корейцы не будут добавлять C_EX пакеты в последовательность входа
     * // Вообще он уже есть, просто packetWriter.writeC(0); // 1 - queue / можно не слать, а отправлять инфомрацию об очереди после пакета "C_AUTH_LOGIN", не отправляя "S_AUTH_LOGIN".
     * Так же, если есть AA (Актив Античит) - отправка данного байта поломает вообще всю последовательность входа, к сожалению (АА нужно обязательно выполнить последовательность C_VERSION_CHECK -> S_VERSION_CHECK (seed) -> C_AUTH_LOGIN) :)

Без этого - у меня вот такое (хотя при не выполнении последовательности (включение очереди) писало 110 ошибку).
1767383254583.webp

Сейчас попробую еще одну вещь...



Ну вообщем видимо не поддерживает и причина скорее всего таже, что я описал выше.
В документации АА я увидел параметр для мобиусов:
&lt;ingamecrypt value="False"/&gt;
Но ни его включение, ни выключение оного не помогает :)
 
Последнее редактирование:
В документации АА я увидел параметр для мобиусов:
&lt;ingamecrypt value="False"/&gt;
Но ни его включение, ни выключение оного не помогает
Есть предположение, что этот конфиг относится к шифрованию на основе алгоритма blowfish, который по умолчанию выключен у мобиуса.

1767430778873.webp

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

Посмотреть вложение 92655

Посмотреть вложение 92656
одному разрабу АА известно, за что этот конфиг отвечает
Укажука и себе...
Markdown (GitHub flavored):
# Packet encryption.
# ==========================================================================================================
# By default packets sent or received are encrypted using the Blowfish algorithm.
# Disabling this reduces the resources needed to process any packets transfered,
# also broadcasted packets do not need to be re-encrypted for each client sent.
# ==========================================================================================================
# По умолчанию отправляемые и получаемые пакеты шифруются с использованием алгоритма Blowfish.
# Отключение этого параметра снижает потребление ресурсов, необходимых для обработки передаваемых пакетов,
# а также избавляет от необходимости повторного шифрования широковещательных пакетов для каждого клиента.
# ==========================================================================================================
# Offlike = true
# Active Anticheat = должно быть представлено таким же значением, что и в l2.xml в значении '<ingamecrypt value="*значение*" />' (default - true)
# Active Anticheat = should be the same value, as in l2.xml by value '<ingamecrypt value="*value*" />' (default - true)
ENABLE_PACKET_ENCRYPTION = true
 
актуальные данные чего ты собрался там получать с тех логов, просвети?
Код:
(05:42:12) Log: Log file open, 01/02/26 05:42:12
(05:42:12) Log: (Send)[NONE] RequestAuthLogin
(05:42:12) Log: (Receive)[NONE] ProtocolVersionPacket
(05:42:12) Log: (Send)[NONE] ResponseAuthGameGuard
(05:42:12) Log: (Receive)[NONE] AuthGameGuardPacket
(05:42:13) Log: (Send)[NONE] RL
(05:42:27) Log: (Send)[NONE] RequestServerListsessionId_1:1075046362, sesstionId_2:0, cListKind:5
(05:42:27) Log: (Receive)[NONE] ServerListPacketAll ServerNum:3
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:49, ServerType:1, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:51, ServerType:1099, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServer ID:30, ServerType:2609, RegionCode:0
(05:42:27) Log: (Receive)[NONE] ServerListPacketServerNum:3
(05:42:35) Log: (Send)[NONE] RequestServerLogin
(05:42:35) Log: (Receive)[NONE] PlayOkPacket
(05:42:35) Log:     (Send)Send Protocol Version:140
(05:42:35) Log: (Receive)[S_VERSION_CHECK] VersionCheckPacket
(05:42:37) Log:     (Send)C_LOGIN Packet
(05:42:37) Log: (Receive)[S_LOGIN_RESULT] LoginResultPacketClient Not Use NP
(05:42:37) Log: (Receive)[S_CHARACTER_SELECTION_INFO] CharacterSelectionInfoPacketcount:0
Постой, т.е. по твоему если клиент получает это, он не получает тело ?
Боюсь спросить, а что именно в этой очереди не верно ? Вот которую ты предоставил - выглядит валидно.
Соотвественно вопрос - зачем и для чего и для какой цели этот шафл ?

там есть поддержка.
но там важно знать конечный пакет

Как пример...

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

Как пример...

Я пока совсем не могу уловить мысль твоего решения - зачем и для чего
Это вроде дефолтный функционал клиента. Скорее всего, корейцы рассчитывали дополнительно шафлить опкоды для клиента на каждую сессию, чтобы усложнить жизнь чувакам со снифферами на офе, но потом поняли, что их темиду снимают просто в один клик и забили. Либо это точечно включается ботоводам для проверки))
 
Это вроде дефолтный функционал клиента. Скорее всего, корейцы рассчитывали дополнительно шафлить опкоды для клиента на каждую сессию, чтобы усложнить жизнь чувакам со снифферами на офе
аааа, ну это известная тема и все юзают как бы. Но это отсекает аутгеймы и прочие лоу рейт секюр методы входа. У меня недавно была бойня с этими моментами когда чексам отваливался из-за того что на 306 протоколе при входе в игру летел дважды ServerList если нажимать именно Enter, а не мышкой. Полезно, но окей.
Пришлось чисто первый входящий чекать, потом игнорить если влетает этот же пакет с другим чексамом

1767558084389.webp
 
там есть поддержка.
очень даже похоже
Я пока совсем не могу уловить мысль твоего решения - зачем и для чего
Да в принципе не зачем и не для чего, поскольку как я уже написал еще в первом посту, что это в большинстве случаев не защитит от ботов. Вот просто заняться не чем было :ROFLMAO:
У меня недавно была бойня с этими моментами когда чексам отваливался из-за того что на 306 протоколе при входе в игру летел дважды ServerList если нажимать именно Enter, а не мышкой.
На 140 подобное не смог воспроизвести, не в логах клиента, не в логах сервера повторных запросов/отправок ServerList не заметил. По нажатию enter приходят/уходят те же самые пакеты. Интересный баг конечно, но это не относится шафлу, который работает исключительно на гейм-сервере и по сути не участвует в основном шифровании полезной нагрузки пакетов
 
Назад
Сверху Снизу