当前位置: 代码迷 >> C# >> 及时修改TCP封包内容
  详细解决方案

及时修改TCP封包内容

热度:94   发布时间:2016-05-05 03:57:04.0
即时修改TCP封包内容
搜了好几天了,没找到合适的例子,NDIS  、HOOK SOCKET API、  WINPCAP都可以   谁有例子参考下
------解决思路----------------------
啥意思???不太明白?

是你玩网游的时候 你打开一个点卷 然后截取 然后包里的元宝+1W 然后停止截取 然后把这个重新无限发送给服务器?

还是 元宝+1 你修改成1000 之后 替换原来的数据 发给服务器?

以前是有三剑客的 eg+wpe+ccp 可以搞你想要的..

不过代码就不知道了...不是单纯的修改就可以吧 还需要代理什么什么的...
------解决思路----------------------

给你一个Sniffer的完整代码,基于winpcap抓包统计吞吐量的Demo;
如果涉及数据包加密,服务器验证,需要做的工作还很多。


using System;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using SharpPcap;
using SharpPcap.WinPcap;
using PacketDotNet;
using Demo.STP.Sniff.Packets;

namespace Demo.STP.Sniff
{
/// <summary>
/// 嗅探器,提供原始数据源
/// </summary>
public sealed class Sniffer
{
#region Instance
private static readonly Lazy<Sniffer> _lazy =
new Lazy<Sniffer>(() => new Sniffer());

public static Sniffer Instance
{
get { return _lazy.Value; }
}

private Sniffer() { }
#endregion Instance

#region Init
/// <summary>
/// 初始化嗅探器
/// </summary>
/// <param name="ipAddress">需拦截网卡所配IP</param>
/// <param name="filter">数据包过滤规则</param>
public void Init(string ipAddress, string filter = "")
{
var network = Demo.STP.Common.NetHelper.GetNetwork(ipAddress);
if (network == null)
throw new ArgumentException(string.Format("Invalid IPAddress {0}.", ipAddress));

this._currentDevice = WinPcapDeviceList.Instance.Where(deviceItem => 
string.Equals(network.Name, deviceItem.Interface.FriendlyName, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();

if (this._currentDevice == null)
throw new ArgumentException("无法从WinPcap找到对应网卡.");

this._currentDevice.OnPacketArrival += device_OnPacketArrival;
this._currentDevice.Open(DeviceMode.Normal);
this._currentDevice.Filter = filter;
}

private void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
this._packetQueue.Enqueue(e.Packet);
}
#endregion Init

#region Start Hook
/// <summary>
/// 启动嗅探器
/// </summary>
public void StartHook()
{
if (this._currentDevice == null)
throw new ArgumentException("请先初始化嗅探器.");

KeepHook = true;
this._currentDevice.StartCapture();

RawCapture rawCapture = null;

Task.Factory.StartNew(() =>
{
while (KeepHook)
{
if (this._packetQueue.IsEmpty)
{
//理论上能轻松应对所有终端
//如果吞吐量达不到要求,请删除Sleep,但会占用一个核心的全部时间
Thread.Sleep(10);
continue;
}
if (this._packetQueue.TryDequeue(out rawCapture))
{
var basePacket = this.AnalysisPacket(rawCapture);
if (basePacket.HasValue)
{
OnPacketArrival(new PacketArrivedEventArgs { BasePacket = basePacket.Value });
}
}
}
}, TaskCreationOptions.LongRunning);
}
#endregion Start Hook

#region Stop Hook
/// <summary>
/// 停止嗅探器
/// </summary>
public void StopHook()
{
if (this._currentDevice == null) return;

KeepHook = false;

if (this._currentDevice.Started)
this._currentDevice.StopCapture();

this._currentDevice.OnPacketArrival -= device_OnPacketArrival;
this._currentDevice.Close();
}
#endregion Stop Hook

#region 解析数据包
private Nullable<IPBasePacket> AnalysisPacket(RawCapture rawCapture)
{
            try
            {
                var rawPacket = rawCapture.ParseRawPacket();
                var ipPacket = rawPacket.ExtractTragetPacket<IpPacket>();
                if (ipPacket == null)
                    return null;

                EnumIPProtocol targetProtocol;
                var parseFlag = Enum.TryParse(ipPacket.Protocol.ToString(), true, out targetProtocol);
                if (!parseFlag)
                    return null;

                IPBasePacket basePacket = new IPBasePacket();
                basePacket.Protocol = targetProtocol;
                basePacket.IPVersion = ipPacket.Version.ToString();
                basePacket.SourceIP = ipPacket.SourceAddress.ToString();
                basePacket.TargetIP = ipPacket.DestinationAddress.ToString();

                dynamic tcp_udp_Packet = rawPacket.ExtractTragetPacket<TcpPacket>();
                if (tcp_udp_Packet == null)
                    tcp_udp_Packet = rawPacket.ExtractTragetPacket<UdpPacket>();

                if (tcp_udp_Packet != null)
                {
if (tcp_udp_Packet.PayloadData == null)
return null; 

                    basePacket.SourcePort = tcp_udp_Packet.SourcePort;
                    basePacket.TargetPort = tcp_udp_Packet.DestinationPort;

                    //basePacket.PacketLength = (uint)tcp_udp_Packet.Bytes.Length;
                    //basePacket.HeaderLength = (uint)tcp_udp_Packet.Header.Length;
                    //basePacket.MessageLength = (uint)tcp_udp_Packet.PayloadData.Length;

                    //basePacket.PacketBuffer = tcp_udp_Packet.Bytes;
                    //basePacket.HeaderBuffer = tcp_udp_Packet.Header;
                    //basePacket.MessageBuffer = tcp_udp_Packet.PayloadData;
                    
                    basePacket.MessageLength = (uint)tcp_udp_Packet.PayloadData.Length;
                    basePacket.MessageBuffer = tcp_udp_Packet.PayloadData;
                }

                return basePacket;
            }
            catch
            { 
                return null; 
            }
}
#endregion 解析数据包

#region PacketArrival Event
public event EventHandler<PacketArrivedEventArgs> PacketArrival;

internal void OnPacketArrival(PacketArrivedEventArgs e)
{
if (PacketArrival != null)
{
PacketArrival(this, e);
}
}

public bool IsMonitorEmpty
{
get { return PacketArrival == null; }
}
#endregion PacketArrival Event

#region Fields & Propertys
public bool KeepHook { get; private set; }
private WinPcapDevice _currentDevice;
private ConcurrentQueue<RawCapture> _packetQueue = new ConcurrentQueue<RawCapture>();
#endregion Fields & Propertys
}

public class PacketArrivedEventArgs : EventArgs
{
public IPBasePacket BasePacket { get; set; }
}
}


------解决思路----------------------

在wsasend下断,在内存处做修改就可以了。
技术上难度是很简单。但TM的分析包是蛋疼的事情。
  相关解决方案