diff options
Diffstat (limited to 'Impostor-dev/src/Impostor.Tools.Proxy')
3 files changed, 285 insertions, 0 deletions
diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs b/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs new file mode 100644 index 0000000..79517b4 --- /dev/null +++ b/Impostor-dev/src/Impostor.Tools.Proxy/HexUtils.cs @@ -0,0 +1,70 @@ +using System; +using System.Text; + +namespace Impostor.Tools.Proxy +{ + public static class HexUtils + { + public static string HexDump(byte[] bytes, int bytesPerLine = 16) + { + if (bytes == null) return "<null>"; + int bytesLength = bytes.Length; + + char[] HexChars = "0123456789ABCDEF".ToCharArray(); + + int firstHexColumn = + 8 // 8 characters for the address + + 3; // 3 spaces + + int firstCharColumn = firstHexColumn + + bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space + + (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th + + 2; // 2 spaces + + int lineLength = firstCharColumn + + bytesPerLine // - characters to show the ascii value + + Environment.NewLine.Length; // Carriage return and line feed (should normally be 2) + + char[] line = (new String(' ', lineLength - Environment.NewLine.Length) + Environment.NewLine).ToCharArray(); + int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine; + StringBuilder result = new StringBuilder(expectedLines * lineLength); + + for (int i = 0; i < bytesLength; i += bytesPerLine) + { + line[0] = HexChars[(i >> 28) & 0xF]; + line[1] = HexChars[(i >> 24) & 0xF]; + line[2] = HexChars[(i >> 20) & 0xF]; + line[3] = HexChars[(i >> 16) & 0xF]; + line[4] = HexChars[(i >> 12) & 0xF]; + line[5] = HexChars[(i >> 8) & 0xF]; + line[6] = HexChars[(i >> 4) & 0xF]; + line[7] = HexChars[(i >> 0) & 0xF]; + + int hexColumn = firstHexColumn; + int charColumn = firstCharColumn; + + for (int j = 0; j < bytesPerLine; j++) + { + if (j > 0 && (j & 7) == 0) hexColumn++; + if (i + j >= bytesLength) + { + line[hexColumn] = ' '; + line[hexColumn + 1] = ' '; + line[charColumn] = ' '; + } + else + { + byte b = bytes[i + j]; + line[hexColumn] = HexChars[(b >> 4) & 0xF]; + line[hexColumn + 1] = HexChars[b & 0xF]; + line[charColumn] = (b < 32 ? '·' : (char)b); + } + hexColumn += 3; + charColumn++; + } + result.Append(line); + } + return result.ToString(); + } + } +}
\ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj b/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj new file mode 100644 index 0000000..8f523dc --- /dev/null +++ b/Impostor-dev/src/Impostor.Tools.Proxy/Impostor.Tools.Proxy.csproj @@ -0,0 +1,17 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net5.0</TargetFramework> + </PropertyGroup> + + <ItemGroup> + <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" /> + <PackageReference Include="Pcap.Net.x64" Version="1.0.4.1" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\Impostor.Hazel\Impostor.Hazel.csproj" /> + </ItemGroup> + +</Project> diff --git a/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs b/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs new file mode 100644 index 0000000..9e765f0 --- /dev/null +++ b/Impostor-dev/src/Impostor.Tools.Proxy/Program.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Impostor.Api.Net.Messages; +using Impostor.Hazel; +using Impostor.Hazel.Extensions; +using Impostor.Hazel.Udp; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.ObjectPool; +using PcapDotNet.Core; +using PcapDotNet.Packets; + +namespace Impostor.Tools.Proxy +{ + internal static class Program + { + private const string DeviceName = "Intel(R) I211 Gigabit Network Connection"; + + private static readonly Dictionary<byte, string> TagMap = new Dictionary<byte, string> + { + {0, "HostGame"}, + {1, "JoinGame"}, + {2, "StartGame"}, + {3, "RemoveGame"}, + {4, "RemovePlayer"}, + {5, "GameData"}, + {6, "GameDataTo"}, + {7, "JoinedGame"}, + {8, "EndGame"}, + {9, "GetGameList"}, + {10, "AlterGame"}, + {11, "KickPlayer"}, + {12, "WaitForHost"}, + {13, "Redirect"}, + {14, "ReselectServer"}, + {16, "GetGameListV2"} + }; + + private static IServiceProvider _serviceProvider; + private static ObjectPool<MessageReader> _readerPool; + + //c 服务器入口 + private static void Main(string[] args) + { + var services = new ServiceCollection(); + services.AddHazel(); + + _serviceProvider = services.BuildServiceProvider(); + _readerPool = _serviceProvider.GetRequiredService<ObjectPool<MessageReader>>(); + + var devices = LivePacketDevice.AllLocalMachine; + if (devices.Count == 0) + { + Console.WriteLine("No interfaces found! Make sure WinPcap is installed."); + return; + } + + var device = devices.FirstOrDefault(x => x.Description.Contains(DeviceName)); + if (device == null) + { + Console.WriteLine("Unable to find configured device."); + return; + } + + using (var communicator = device.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000)) + { + using (var filter = communicator.CreateFilter("udp and port 22023")) + { + communicator.SetFilter(filter); + } + + communicator.ReceivePackets(0, PacketHandler); + } + } + + private static void PacketHandler(Packet packet) + { + var ip = packet.Ethernet.IpV4; + var ipSrc = ip.Source.ToString(); + var udp = ip.Udp; + + // True if this is our own packet. + using (var stream = udp.Payload.ToMemoryStream()) + { + using var reader = _readerPool.Get(); + + reader.Update(stream.ToArray()); + + var option = reader.Buffer[0]; + if (option == (byte) MessageType.Reliable) + { + reader.Seek(reader.Position + 3); + } + else if (option == (byte) UdpSendOption.Acknowledgement || + option == (byte) UdpSendOption.Ping || + option == (byte) UdpSendOption.Hello || + option == (byte) UdpSendOption.Disconnect) + { + return; + } + else + { + reader.Seek(reader.Position + 1); + } + + var isSent = ipSrc.StartsWith("192."); + + while (true) + { + if (reader.Position >= reader.Length) + { + break; + } + + //c 消息 + using var message = reader.ReadMessage(); + if (isSent) + { + HandleToServer(ipSrc, message); + } + else + { + HandleToClient(ipSrc, message); + } + + if (message.Position < message.Length) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("- Did not consume all bytes."); + } + } + } + } + + private static void HandleToClient(string source, IMessageReader packet) + { + var tagName = TagMap.ContainsKey(packet.Tag) ? TagMap[packet.Tag] : "Unknown"; + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine($"{source,-15} Client received: {packet.Tag,-2} {tagName}"); + + switch (packet.Tag) + { + case 14: + case 13: + // packet.Position = packet.Length; + break; + case 0: + Console.WriteLine("- GameCode " + packet.ReadInt32()); + break; + case 5: + case 6: + Console.WriteLine(HexUtils.HexDump(packet.Buffer.ToArray().Take(packet.Length).ToArray())); + // packet.Position = packet.Length; + break; + case 7: + Console.WriteLine("- GameCode " + packet.ReadInt32()); + Console.WriteLine("- PlayerId " + packet.ReadInt32()); + Console.WriteLine("- Host " + packet.ReadInt32()); + var playerCount = packet.ReadPackedInt32(); + Console.WriteLine("- PlayerCount " + playerCount); + for (var i = 0; i < playerCount; i++) + { + Console.WriteLine("- PlayerId " + packet.ReadPackedInt32()); + } + break; + case 10: + Console.WriteLine("- GameCode " + packet.ReadInt32()); + Console.WriteLine("- Flag " + packet.ReadSByte()); + Console.WriteLine("- Value " + packet.ReadBoolean()); + break; + } + } + + private static void HandleToServer(string source, IMessageReader packet) + { + var tagName = TagMap.ContainsKey(packet.Tag) ? TagMap[packet.Tag] : "Unknown"; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine($"{source,-15} Server received: {packet.Tag,-2} {tagName}"); + + switch (packet.Tag) + { + case 0: + Console.WriteLine("- GameInfo length " + packet.ReadBytesAndSize().Length); + break; + case 1: + Console.WriteLine("- GameCode " + packet.ReadInt32()); + Console.WriteLine("- Unknown " + packet.ReadByte()); + break; + case 5: + case 6: + Console.WriteLine("- GameCode " + packet.ReadInt32()); + Console.WriteLine(HexUtils.HexDump(packet.Buffer.ToArray().Take(packet.Length).ToArray())); + // packet.Position = packet.Length; + break; + } + } + } +} |