private static void Main(string[] args) { var devices = CaptureDeviceList.Instance; if (devices.Count < 1) { Console.WriteLine("No device found on this machine"); return; } Console.WriteLine("The following devices are available on this machine:"); Console.WriteLine("----------------------------------------------------"); Console.WriteLine(); var i = 0; foreach (var dev in devices) { Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description); i++; } Console.WriteLine(); Console.Write("-- Please choose a device to capture: "); i = int.Parse(Console.ReadLine()); var device = devices[i]; device.OnPacketArrival += device_OnPacketArrival; var readTimeoutMilliseconds = 1000; device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds); var filter = "ip and tcp"; device.Filter = filter; Console.WriteLine(); Console.WriteLine("-- The following tcpdump filter will be applied: \"{0}\"", filter); if (LoginServerIP == null) { Console.Write("-- Please input target LoginServer IP: "); LoginServerIP = IPAddress.Parse(Console.ReadLine()); Console.WriteLine(); } if (LoginServerPort == 0) { Console.Write("-- Please input target LoginServer Port: "); LoginServerPort = int.Parse(Console.ReadLine()); Console.WriteLine(); } BreakIpAddresses.Add(LoginServerIP); ServerPorts.Add(LoginServerPort); Console.WriteLine ("-- Listening on {0}, hit 'Ctrl-C' to exit...", device.Description); var filePath = Path.Combine(LaunchTime.ToString("s").Replace(':', '_'), "PacketFlow.txt"); var flowFile = new FileInfo(filePath); flowFile.Directory?.Create(); using var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write); using (packerFlowStream = new StreamWriter(fs)) { packerFlowStream.AutoFlush = true; device.Capture(); device.Close(); packerFlowStream.Flush(); fs.Flush(true); } }
private static void HandleTcpPacket(TcpPacket tcpPacket) { var ipPacket = (IPPacket)tcpPacket.ParentPacket; var srcIp = ipPacket.SourceAddress; var dstIp = ipPacket.DestinationAddress; int srcPort = tcpPacket.SourcePort; int dstPort = tcpPacket.DestinationPort; if (!BreakIpAddresses.Contains(srcIp) && !BreakIpAddresses.Contains(dstIp)) { return; } if (!tcpPacket.PayloadData.Any() || tcpPacket.PayloadData.Length < 2) { return; } if (tcpPacket.SequenceNumber.Equals(BeforePacket?.SequenceNumber)) // なんか二回来るので { return; } BeforePacket = tcpPacket; var fromServer = ServerPorts.Contains(srcPort); var server = ServerTypeEnum.Unknown; var key = LoginKeyIndex; var checkHeader = tcpPacket.PayloadData.Take(6).ToArray(); if ((srcIp.Equals(LoginServerIP) || dstIp.Equals(LoginServerIP)) && (!fromServer || srcPort == LoginServerPort) && (fromServer || dstPort == LoginServerPort)) { var loginHelloHeader = new byte[] { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00 }; server = ServerTypeEnum.Login; if (checkHeader.SequenceEqual(loginHelloHeader)) { Console.WriteLine($"---{server} Server Packet(from:{srcIp})---"); Console.WriteLine($"---Hello Message(Size:{tcpPacket.PayloadData.Length})---"); HandleMessage(new PangServerMessage(tcpPacket.PayloadData, server)); RecordPacketFlow(fromServer, fromServer ? srcIp : dstIp, fromServer ? srcPort : dstPort, 0, server); LoginKeyIndex = tcpPacket.PayloadData[6]; return; } if (!GotLoginKey) { Console.WriteLine("???LoginKey Unknown Skipped???"); return; } } else if (fromServer && GameServers.Select(g => (g.IP, g.Port)).Contains((srcIp, srcPort)) || !fromServer && GameServers.Select(g => (g.IP, g.Port)).Contains((dstIp, dstPort))) { var gameHelloHeader = new byte[] { 0x00, 0x3F, 0x00, 0x01, 0x01 }; server = ServerTypeEnum.Game; if (tcpPacket.PayloadData[0] == 0x00 && tcpPacket.PayloadData.Skip(3).Take(5).ToArray().SequenceEqual(gameHelloHeader)) { Console.WriteLine($"---{server} Server Packet(from:{srcIp})---"); Console.WriteLine($"---Hello Message(Size:{tcpPacket.PayloadData.Length})---"); HandleMessage(new PangServerMessage(tcpPacket.PayloadData, server)); RecordPacketFlow(fromServer, fromServer ? srcIp : dstIp, fromServer ? srcPort : dstPort, 0, server); GameKeyIndex = tcpPacket.PayloadData[8]; ConnectingGameServer = GameServers.First(g => Equals(g.IP, srcIp) && g.Port == srcPort); return; } if (fromServer && !CheckCapture(ConnectingGameServer, srcIp, srcPort) || !fromServer && !CheckCapture(ConnectingGameServer, dstIp, dstPort)) { return; } key = GameKeyIndex; if (!GotGameKey) { Console.WriteLine("???GameKey Unknown Skipped???"); return; } }