Add experimental decompression support.

This commit is contained in:
KimLS 2024-10-17 22:53:33 -07:00
parent d3cd037fa7
commit 999ccdcb19
3 changed files with 89 additions and 13 deletions

View File

@ -13,6 +13,7 @@ using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Ionic.Zlib;
namespace StreamParser namespace StreamParser
{ {
@ -72,7 +73,7 @@ namespace StreamParser
{ {
if(o.Dump) if(o.Dump)
{ {
DumpConnectionToTextFile(c.Value, o.Output, o.Decrypt); DumpConnectionToTextFile(c.Value, o.Output, o.Decrypt, o.DecompressOpcodes);
} }
if(o.Csv) if(o.Csv)
@ -153,7 +154,7 @@ namespace StreamParser
}); });
} }
private void DumpConnectionToTextFile(ParsedConnection c, string output, bool decrypt) private void DumpConnectionToTextFile(ParsedConnection c, string output, bool decrypt, IEnumerable<int> decompressOpcodes)
{ {
try try
{ {
@ -213,12 +214,58 @@ namespace StreamParser
break; break;
default: default:
{ {
bool reported_decompressed = false;
int opcode = BitConverter.ToUInt16(data.Slice(0, 2)); int opcode = BitConverter.ToUInt16(data.Slice(0, 2));
File.AppendAllText(path, foreach (var decompressOpcode in decompressOpcodes)
string.Format("{0} [Opcode: 0x{1}, Size: {2}] ({3})\n", dir, opcode.ToString("X4"), data.Length - 2, p.Time.ToString("s"))); {
if (opcode == decompressOpcode && data.Length > 12)
{
if (data[10] == 0x78 && data[11] == 0xDA)
{
var totalLen = BitConverter.ToInt32(data.Slice(6, 4));
if (totalLen > 0)
{
var decompressed = Inflate(data.Slice(10));
if(decompressed != null)
{
var decompressed_gp = new GamePacket(decompressed);
File.AppendAllText(path,
string.Format("{0} [Opcode: 0x{1}, Size (decompressed): {2}] ({3})\n", dir, opcode.ToString("X4"), totalLen, p.Time.ToString("s")));
var gp = new GamePacket(data.Slice(2)); File.AppendAllText(path, string.Format("{0}\n", decompressed_gp.ToString()));
File.AppendAllText(path, string.Format("{0}\n", gp.ToString())); reported_decompressed = true;
break;
}
}
}
else if (data[6] == 0x78 && data[7] == 0xDA)
{
var totalLen = BitConverter.ToInt32(data.Slice(2, 4));
if (totalLen > 0)
{
var decompressed = Inflate(data.Slice(6));
if (decompressed != null)
{
File.AppendAllText(path,
string.Format("{0} [Opcode: 0x{1}, Size (decompressed): {2}] ({3})\n", dir, opcode.ToString("X4"), totalLen, p.Time.ToString("s")));
var decompressed_gp = new GamePacket(decompressed);
File.AppendAllText(path, string.Format("{0}\n", decompressed_gp.ToString()));
reported_decompressed = true;
break;
}
}
}
}
}
if (!reported_decompressed)
{
File.AppendAllText(path,
string.Format("{0} [Opcode: 0x{1}, Size: {2}] ({3})\n", dir, opcode.ToString("X4"), data.Length - 2, p.Time.ToString("s")));
var gp = new GamePacket(data.Slice(2));
File.AppendAllText(path, string.Format("{0}\n", gp.ToString()));
}
} }
break; break;
} }
@ -230,6 +277,36 @@ namespace StreamParser
} }
} }
private byte[] Inflate(ReadOnlySpan<byte> data)
{
try
{
using (var out_stream = new MemoryStream())
using (var in_stream = new MemoryStream(data.ToArray()))
{
const int bufferLen = 4096;
var buffer = new byte[bufferLen];
using (var zs = new ZlibStream(in_stream, CompressionMode.Decompress))
{
int r = 0;
do
{
r = zs.Read(buffer, 0, bufferLen);
out_stream.Write(buffer, 0, r);
} while (r == bufferLen);
}
var ret = out_stream.ToArray();
return ret;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error inflating data");
return null;
}
}
private class CsvRow private class CsvRow
{ {
public int Index { get; set; } public int Index { get; set; }

View File

@ -1,8 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommandLine; using CommandLine;
namespace StreamParser namespace StreamParser
@ -23,5 +19,8 @@ namespace StreamParser
[Option("decrypt", Default = false, HelpText = "Decrypt the \"Encrypted\" packets.")] [Option("decrypt", Default = false, HelpText = "Decrypt the \"Encrypted\" packets.")]
public bool Decrypt { get; set; } public bool Decrypt { get; set; }
[Option("decompress", Default = false, HelpText = "Which opcodes to attempt to decompress")]
public IEnumerable<int> DecompressOpcodes { get; set; }
} }
} }

View File

@ -2,8 +2,8 @@
"profiles": { "profiles": {
"stream_parser": { "stream_parser": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "--input input/cap_login_to_zone_10_16_2024.pcap --output output_test/ --text --decrypt", "commandLineArgs": "--input input/cap_login_to_zone_10_16_2024.pcap --output output_test/ --text --decrypt --decompress 16742 168 30346",
"workingDirectory": "E:\\Projects\\stream_parser\\stream_parser\\bin\\Debug\\net6.0\\" "workingDirectory": "E:\\Projects\\stream_parser\\stream_parser\\bin\\Debug\\net6.0\\"
} }
} }
} }