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;
}
}
L2DecodeU("interface.u");
ТекстУ меня вопрос: как получить из текста "Lineage2Ver111" байты, которые будут такими же, как и из файла? Я не уверен, как это называется, но, по-моему, это связано с нулевыми байтами.
Например, в коде я получаю байты для текста "Lineage2Ver111": "4C 69 6E....". А в файле для этого же текста я получаю такие байты: "4C 00 69 00 6E....".
Я пробовал разные кодировки и много чего ещё, но не добавлять же после каждого байта нулевые байты. Я думаю, что в C# должна быть стандартная функция преобразования для этого.
Lineage2Ver111
закодирован как UTF-16LE - где на 1 символ отводится 2 байта.Я пробовал и так и так и в разных языках программирования но у меня все равно остаются нулевые байты(ТекстLineage2Ver111
закодирован как UTF-16LE - где на 1 символ отводится 2 байта.
Я пробовал и так и так и в разных языках программирования но у меня все равно остаются нулевые байты(
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;
}
Я изучу ваш код спасибо!Даже такой "жутко-код" выполнял свои функции.
да, так и есть.Я изучу ваш код спасибо!
И 121 как я понимаю по вашему коду берет ключ из имени файла?
Спасибо разобрался в C# нужно было выбрать кодировкуда, так и есть.
Encoding.Unicode.GetBytes("Lineage2Ver111")
private const int HeaderSize = 28;
private const byte XorKey = 0xAC;
private const string ExpectedHeader = "Lineage2Ver111";
private static void DecryptFile(string filePath)
{
using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
Span<byte> headerBytes = stackalloc byte[HeaderSize];
fileStream.Read(headerBytes);
string header = System.Text.Encoding.Unicode.GetString(headerBytes);
if (!header.StartsWith(ExpectedHeader))
{
//Console.WriteLine($"File '{filePath}' does not require decryption."); or display message or just skip
return;
}
string tempFilePath = $"{filePath}.tmp";
using var tempFileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write);
fileStream.Seek(HeaderSize, SeekOrigin.Begin);
var buffer = ArrayPool<byte>.Shared.Rent(8192);
int bytesRead;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
for (int i = 0; i < bytesRead; i++)
{
buffer[i] ^= XorKey;
}
tempFileStream.Write(buffer.AsSpan(0, bytesRead));
}
ArrayPool<byte>.Shared.Return(buffer);
fileStream.Close();
tempFileStream.Close();
File.Delete(filePath);
File.Move(tempFilePath, filePath);
}
вообще лучше будет декодировать файл по нужде наверное , Ане сразу весь грузить...@BIT_hack,
C#:private const int HeaderSize = 28; private const byte XorKey = 0xAC; private const string ExpectedHeader = "Lineage2Ver111"; private static void DecryptFile(string filePath) { using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); Span<byte> headerBytes = stackalloc byte[HeaderSize]; fileStream.Read(headerBytes); string header = System.Text.Encoding.Unicode.GetString(headerBytes); if (!header.StartsWith(ExpectedHeader)) { //Console.WriteLine($"File '{filePath}' does not require decryption."); or display message or just skip return; } string tempFilePath = $"{filePath}.tmp"; using var tempFileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write); fileStream.Seek(HeaderSize, SeekOrigin.Begin); var buffer = ArrayPool<byte>.Shared.Rent(8192); int bytesRead; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) { for (int i = 0; i < bytesRead; i++) { buffer[i] ^= XorKey; } tempFileStream.Write(buffer.AsSpan(0, bytesRead)); } ArrayPool<byte>.Shared.Return(buffer); fileStream.Close(); tempFileStream.Close(); File.Delete(filePath); File.Move(tempFilePath, filePath); }
хз, я баловался с .utx и .u файлами - причитав заголовок (узнав что за крипт) - после этого просто читал значения в разных местах без полного чтения файла
Ещё разхз, я баловался с .utx и .u файлами - причитав заголовок (узнав что за крипт) - после этого просто читал значения в разных местах без полного чтения файла
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?