Дешифратор файлов Lineage2 версии 111. С#

BIT_hack

Знающий
Участник
Сообщения
154
Розыгрыши
0
Решения
2
Репутация
45
Реакции
94
Баллы
420
Это мой первый опыт использования XOR и C#. Возможно, профессионалу мой код покажется не самым оптимальным, но он выполняет свою задачу.

У меня вопрос: как получить из текста "Lineage2Ver111" байты, которые будут такими же, как и из файла? Я не уверен, как это называется, но, по-моему, это связано с нулевыми байтами.
Например, в коде я получаю байты для текста "Lineage2Ver111": "4C 69 6E....". А в файле для этого же текста я получаю такие байты: "4C 00 69 00 6E....".
Я пробовал разные кодировки и много чего ещё, но не добавлять же после каждого байта нулевые байты. Я думаю, что в C# должна быть стандартная функция преобразования для этого.

Этот код представляет собой дешифратор файлов Lineage2 версии 111. на C#
Чтобы не тратить ваше время, сразу скажу, что этот код работает.
У меня только один вопрос, который я описал выше.
C#:
using System.IO;

public static class Lineage2Decrypter
{
    // Ключ XOR для Lineage2Ver111
    private const byte KeyXOR = 0xAC;

    // Шаблон байтов для поиска начала зашифрованных данных Lineage2Ver111
    private static readonly byte[] ByteVersion111 = { 76, 0, 105, 0, 110, 0, 101, 0, 97, 0, 103, 0, 101, 0, 50, 0, 86, 0, 101, 0, 114, 0, 49, 0, 49, 0, 49, 0 };

    // Дешифрование файла Lineage2
    public static string L2DecodeU(string fileName)
    {
        if (!File.Exists(fileName)) return fileName;
        byte[] fileData = File.ReadAllBytes(fileName);
        int startIndex = FindStringIndex(fileData, ByteVersion111);
        if (startIndex >= 0)
        {
            startIndex += ByteVersion111.Length;
            byte[] decryptedData = DecryptData(fileData, startIndex, KeyXOR);
            string outputFilePath = "temp/dec-" + Path.GetFileName(fileName);
            Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath));
            using (FileStream outputFile = File.OpenWrite(outputFilePath))
            {
                outputFile.Write(decryptedData, 0, decryptedData.Length);
            }
            return outputFilePath;
        }
        return fileName;
    }

    // Поиск начала зашифрованных данных в массиве байт
    private static int FindStringIndex(byte[] data, byte[] pattern)
    {
        for (int i = 0; i <= data.Length - pattern.Length; i++)
        {
            bool match = true;
            for (int j = 0; j < pattern.Length; j++)
            {
                if (data[i + j] != pattern[j])
                {
                    match = false;
                    break;
                }
            }
            if (match) return i;
        }
        return -1;
    }

    // Дешифрование данных с помощью XOR
    private static byte[] DecryptData(byte[] data, int startIndex, byte key)
    {
        byte[] decryptedData = new byte[data.Length - startIndex];
        for (int i = startIndex; i < data.Length; i++)
        {
            decryptedData[i - startIndex] = (byte)(data[i] ^ key);
        }
        return decryptedData;
    }
}
 

Если вам понадобится использовать этот код, вы можете сделать это следующим образом:
C#:
L2DecodeU("interface.u");
После выполнения этой команды в текущей папке с программой появится папка temp, а в ней — файл dec-interface.u.
 
У меня вопрос: как получить из текста "Lineage2Ver111" байты, которые будут такими же, как и из файла? Я не уверен, как это называется, но, по-моему, это связано с нулевыми байтами.
Например, в коде я получаю байты для текста "Lineage2Ver111": "4C 69 6E....". А в файле для этого же текста я получаю такие байты: "4C 00 69 00 6E....".
Я пробовал разные кодировки и много чего ещё, но не добавлять же после каждого байта нулевые байты. Я думаю, что в C# должна быть стандартная функция преобразования для этого.
Текст Lineage2Ver111 закодирован как UTF-16LE - где на 1 символ отводится 2 байта.
 
Текст Lineage2Ver111 закодирован как UTF-16LE - где на 1 символ отводится 2 байта.
Я пробовал и так и так и в разных языках программирования но у меня все равно остаются нулевые байты(
Если есть возможно приведите свой код.
 
Я пробовал и так и так и в разных языках программирования но у меня все равно остаются нулевые байты(
Java:
    public final static String LINEAGE_2_HEADER    = "Lineage2Ver";
    public final static int LINEAGE_2_HEADER_SIZE  = (LINEAGE_2_HEADER.length() * 2) + (3 * 2);
   
    private CommonPair<Integer, Integer> getCryptVersion(File inputFile)
    {
        byte[] headerAsBytes = readHeader(inputFile);
        if (headerAsBytes.length == 0)
        {
            return null;
        }
        final String headerAsString = new String(headerAsBytes, StandardCharsets.UTF_16LE);
        if (headerAsString.startsWith(LINEAGE_2_HEADER))
        {
            int cryptVersion = Integer.parseInt(headerAsString.substring(LINEAGE_2_HEADER.length()));
            if (!(cryptVersion == 111 || cryptVersion == 121))
            {
                return null;
            }
            switch (cryptVersion)
            {
                case 111:
                {
                    return new CommonPair<>(cryptVersion, -1397969748);
                }
                case 121:
                {
                    String filename = getFileName().toLowerCase(Locale.ROOT); //_fileName.split("\\.")[_fileName.split("\\.").length - 1];
                    int xor = 0;
                    for (int index = 0; index < filename.length(); ++index)
                    {
                        xor += filename.charAt(index);
                    }
                    xor = xor & 0xff;
                    xor = xor | xor << 8 | xor << 16 | xor << 24;
                    return new CommonPair<>(cryptVersion, xor);
                }
            }
        }
        return null;
    }
Даже такой "жутко-код" выполнял свои функции.
 
Назад
Сверху Снизу