在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#网络编程 → C#网络抓包实例

C#网络抓包实例

C#网络编程

下载此实例
  • 开发语言:C#
  • 实例大小:0.16M
  • 下载次数:199
  • 浏览次数:1154
  • 发布时间:2017-05-11
  • 实例类别:C#网络编程
  • 发 布 人:ford2008
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 实例 C# 网络 c 抓包

实例介绍

【实例简介】C# 实现Http抓包工具,可预览图片,以及在Webbrowser中显示

【实例截图】

【核心代码】

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO.Compression;
using System.IO;

namespace 网络数据包分析工具
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitUiParms();
        }

        private Dictionary<string, List<byte>> dic_senddata = new Dictionary<string, List<byte>>();
        private Dictionary<string, httpsession> dic_ack_httpsession = new Dictionary<string, httpsession>();
        private Dictionary<string, string> dic_ack_seq = new Dictionary<string, string>();

        string localip = string.Empty;//监控IP
        int[] ports;//监控端口
        String filtedomain;//监控域名
        int rid;

        private Socket mainSocket;  //该容器 捕捉所有传入的数据包
        private bool bContinueCapturing = false; //检查数据包是否被捕获
        const int SIO_RCVALL = unchecked((int)0x98000001);
        private Queue<byte[]> pktcache = new Queue<byte[]>();
        private List<string> list_ack = new List<string>();
        private delegate void updatechart_del(string s);
        private delegate void updatemsg(string msg);
        private updatemsg myupdatemsg;
        private delegate void RecApacket(httpsession osession);
        private RecApacket Myrecvie;
        private delegate void updae_state_del(int id, int code, double times);
        private updae_state_del myupdatestatehandle;
        long pktcount;
        private int qpscount = 0;
        Thread main_raw;
        System.IO.StreamWriter sw = System.IO.File.AppendText(System.DateTime.Now.ToString("yyyyMMdd_")   "log.txt");
        System.IO.StreamWriter debugsw = System.IO.File.AppendText(System.DateTime.Now.ToString("yyyyMMdd")   "_debug_.txt");
        //记录日志
        private void log(string msg)
        {
            sw.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss\t")   msg);
            sw.Flush();
        }
        private void debugmsg(string msg)
        {
                this.txt_log.BeginInvoke(myupdatemsg, new object[] { msg });
                debugsw.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss\t")   msg);
                debugsw.Flush();
        }
        Regex rhost = new Regex(@"\bhost:.(\S*)", RegexOptions.IgnoreCase);
        private string Gethost(string http)
        {
            Match m = rhost.Match(http);
            return m.Groups[1].Value;
        }
        private bool isimage(string head)
        {
            if (head.ToLower().IndexOf("image") > 0)
                return true;
            return false;
        }
        private string getencompress(string head)
        {
            if (head.ToLower().IndexOf("gzip") > 0)
                return "gzip";
            if (head.ToLower().IndexOf("deflate") > 0)
                return "deflate";
            return "";
        }
        Regex regexencode = new Regex("charset=([\\w|-] )", RegexOptions.IgnoreCase);
        private string getencfromhead(string head)
        {
            Match mc = regexencode.Match(head);
            if (mc.Success)
            {
                return mc.Groups[1].Value;
            }
            return string.Empty;
        }
        private void updatemsginstance(string msg)
        {
            this.txt_log.AppendText(DateTime.Now.ToString()   "\t"   msg   "\r\n");
            Application.DoEvents();
        }

        private void UpdateRecPacket(httpsession osession)
        {
            if (rid > 40)
            {
                dataGridView1.VirtualMode = true;
                dataGridView1.RowCount = dic_ack_httpsession.Count;
            }
            else
            {
                dataGridView1.VirtualMode = false;
                dataGridView1.Rows.Add(osession.id, osession.ack, osession.method, osession.url, Encoding.ASCII.GetString(osession.sendraw.ToArray()), osession.statucode);
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void InitUiParms()
        {
            string strIP = null;
            IPHostEntry HosyEntry = Dns.GetHostEntry((Dns.GetHostName()));
            if (HosyEntry.AddressList.Length > 0)
            {
                foreach (IPAddress ip in HosyEntry.AddressList)
                {
                    if (ip.IsIPv6LinkLocal || ip.IsIPv6Multicast || ip.IsIPv6SiteLocal || ip.IsIPv6SiteLocal)
                        continue;
                    strIP = ip.ToString();
                    cbo_ipAddress.Items.Add(strIP);
                }
            }
            Myrecvie = new RecApacket(UpdateRecPacket);
            myupdatemsg = new updatemsg(updatemsginstance);
            myupdatestatehandle = new updae_state_del(update_statecode_instance);
        }

        /// 开始抓包
        private void btn_Start_Click(object sender, EventArgs e)
        {
            try
            {
                if (cbo_ipAddress.SelectedItem == null) return;
                filtedomain = txt_filteDomain.Text;
                rid = 0;
                pktcount = 0;

                if (btn_Start.Text == "开始抓包")
                {
                    dic_ack_seq.Clear();
                    dic_ack_httpsession.Clear();
                    string[] portstring = txt_port.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    ports = new int[portstring.Length];
                    for (int i = 0; i < portstring.Length; i  )
                    {
                        ports[i] = Convert.ToInt32(portstring[i]);
                    }
                    localip = cbo_ipAddress.Text;
                    if (txt_filteDomain.Text.Length > 0)
                        filtedomain = txt_filteDomain.Text;
                    bContinueCapturing = true;
                    mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
                    mainSocket.Bind(new IPEndPoint(IPAddress.Parse(localip), 0));
                    mainSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
                    byte[] IN = new byte[4] { 1, 0, 0, 0 };
                    byte[] OUT = new byte[4];
                    mainSocket.IOControl(SIO_RCVALL, IN, OUT);
                    main_raw = new Thread(new ThreadStart(MonitorData_raw));
                    main_raw.Priority = ThreadPriority.Highest;
                    main_raw.Start();

                    Thread ppcthread = new Thread(new ThreadStart(ParserCacheThread));
                    ppcthread.IsBackground = true;
                    ppcthread.Start();
                    btn_Start.Text = "停止抓包";
                }
                else
                {
                    while (this.pktcache.Count > 0)
                        Application.DoEvents();
                    bContinueCapturing = false;
                    Thread.Sleep(1100);
                    btn_Start.Text = "开始抓包";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 监控线程
        /// </summary>
        private void MonitorData_raw()
        {
            while (bContinueCapturing)
            {
                // byteData.Initialize();
                byte[] buf = new byte[4096];
                int size = mainSocket.Receive(buf, 0, buf.Length, SocketFlags.None);
                //   if (size <= 40) continue;
                if (buf[9] != 0x06) continue;
                int offset = 20;
                int srcport = PkFunction.Get2Bytes(buf, ref offset, 0);
                int desport = PkFunction.Get2Bytes(buf, ref offset, 0);
                bool isok = false;
                if (iswhiteport(desport))
                {
                    isok = true;
                    if (buf[33] == 0x18) qpscount  ;
                }
                else if (iswhiteport(srcport))
                {
                    isok = true;
                }
                if (!isok) continue;
                byte[] t = new byte[size];
                Array.Copy(buf, 0, t, 0, t.Length);
                pktcache.Enqueue(t);
            }
        }

        private void BuildPacket(bool isout, string ack, string seq, byte[] PacketData, int start, int reclen)
        {
            try
            {
                if (reclen <= start) return;
                byte[] dataArray = new byte[reclen - start];
                Array.Copy(PacketData, start, dataArray, 0, dataArray.Length);
                if (isout)//如果是请求包
                {
                    httpsession osesion = new httpsession();
                    osesion.id = rid;
                    osesion.senddtime = DateTime.Now;
                    osesion.ack = ack;
                    if (dic_senddata.ContainsKey(ack))
                    {
                        osesion.sendraw = dic_senddata[ack];
                    }
                    else
                    {
                        osesion.sendraw = new List<byte>();
                    }
                    osesion.sendraw.AddRange(dataArray);
                    string http_str = System.Text.Encoding.ASCII.GetString(osesion.sendraw.ToArray());
                    string host = Gethost(http_str);
                    if (filtedomain == "" || host.IndexOf(filtedomain) >= 0)
                    {
                        ////  this.dataGridView1.Rows.Add(vr.rid, vr.seq, vr.method, vr.url,http_str);
                        //else
                        int fltag = http_str.IndexOf("\r\n");
                        if (fltag > 0)
                        {
                            string fline = http_str.Substring(0, fltag);
                            int fblacktag = fline.IndexOf(" ");
                            if (fblacktag > 0)
                            {
                                osesion.method = fline.Substring(0, fline.IndexOf(" "));
                                int urllen = fline.LastIndexOf(" ") - fblacktag - 1;
                                if (urllen > 0)
                                    osesion.url = String.Format("http://{0}{1}", host, fline.Substring(fblacktag   1, urllen));
                            }
                        }
                        if (!this.dic_ack_httpsession.ContainsKey(osesion.ack))
                        {
                            this.dic_ack_httpsession.Add(osesion.ack, osesion);
                            //     this.dic_rid_ack.Add(osesion.id, ack);
                            this.list_ack.Add(ack);
                        }
                        rid  ;
                        this.dataGridView1.BeginInvoke(Myrecvie, new object[] { osesion });
                        debugmsg(string.Format("[{0}]  创建 {1}", seq, osesion.url));
                        //    }                     
                    }
                }
                else//如果是返回数据包
                {
                    if (dic_ack_httpsession.ContainsKey(seq))//如果第一次匹配
                    {
                        //    log(ack   ":"   seq   " 第一次返回匹配,添加映射");
                        debugmsg(string.Format("[{0}]  开始接受 {1}:{2}", seq, ack, seq));
                        httpsession osession = dic_ack_httpsession[seq];
                        if (osession.responseraw == null) osession.responseraw = new List<byte>();
                        osession.responseraw.AddRange(dataArray);
                        osession.responoversetime = DateTime.Now;
                        string headb = System.Text.Encoding.ASCII.GetString(dataArray);
                        int flinetag = headb.IndexOf("\r\n");
                        if (flinetag > 0)
                        {
                            headb = headb.Substring(0, flinetag);
                            string[] p3 = headb.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                            if (p3.Length >= 2)
                            {
                                osession.statucode = int.Parse(p3[1]);

                                this.dataGridView1.BeginInvoke(myupdatestatehandle, new object[] { osession.id, osession.statucode, (osession.responoversetime - osession.senddtime).TotalMilliseconds });
                                log(osession.method   "\t"   osession.url   "\t"   osession.statucode); ;
                            }
                        }
                        dic_ack_httpsession[seq] = osession;
                        if (!dic_ack_seq.ContainsKey(ack))
                        {
                            dic_ack_seq.Add(ack, seq);
                        }
                        //    if (osession.id<=40)
                    }//后面的数据包
                    else
                    {
                        if (dic_ack_seq.ContainsKey(ack))
                        {
                            httpsession osession = dic_ack_httpsession[dic_ack_seq[ack]];
                            osession.responseraw.AddRange(dataArray);
                            dic_ack_httpsession[dic_ack_seq[ack]] = osession;
                            debugmsg(string.Format("[{0}]  继续接受 {1}:{2}  总长度 {3} ", dic_ack_seq[ack], ack, seq, osession.responseraw.Count));
                        }
                        else
                        {
                            debugmsg(string.Format("[未识别]  接受 {1}:{2}", 0, ack, seq));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                debugmsg(string.Format("[异常]  {0}", ex.ToString()));
                log(ex.ToString());
            }
        }

        private void ParcePkt_Cache(byte[] byteData, int nReceived)
        {
            IPHeader ipHeader = new IPHeader(byteData, nReceived);
            switch (ipHeader.ProtocolType)
            {
                case Protocol.TCP:
                    TCPHeader tcpHeader = new TCPHeader(ipHeader.Data, ipHeader.MessageLength);//Length of the data field          
                    int headlen = ipHeader.HeaderLength   tcpHeader.HeaderLength;
                    if (iswhiteport(tcpHeader.DestinationPort))
                    {
                        pktcount  ;
                        if (headlen >= nReceived) return;
                        if (tcpHeader.Flags == 0x18)
                            BuildPacket(true, tcpHeader.AcknowledgementNumber, tcpHeader.SequenceNumber, byteData, headlen, nReceived);
                        else if (tcpHeader.Flags == 0x10)
                        {
                            byte[] dataArray = new byte[nReceived - headlen];
                            Array.Copy(byteData, headlen, dataArray, 0, dataArray.Length);
                            if (dic_senddata.ContainsKey(tcpHeader.AcknowledgementNumber))
                                dic_senddata[tcpHeader.AcknowledgementNumber].AddRange(dataArray);
                            else
                            {
                                List<byte> listtmp = new List<byte>();
                                listtmp.AddRange(dataArray);
                                dic_senddata.Add(tcpHeader.AcknowledgementNumber, listtmp);
                            }
                        }
                    }
                    else if (iswhiteport(tcpHeader.SourcePort))
                    {
                        pktcount  ;
                        if (headlen >= nReceived) return;
                        BuildPacket(false, tcpHeader.AcknowledgementNumber, tcpHeader.SequenceNumber, byteData, headlen, nReceived);
                    }
                    break;
            }
        }


        /// <summary>
        /// 查看是否是监控的端口
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        private bool iswhiteport(int port)
        {
            for (int i = 0; i < ports.Length; i  )
            {
                if (port == ports[i])
                    return true;
            }
            return false;
        }

        private void ParserCacheThread()
        {
            while (bContinueCapturing)
            {
                while (pktcache.Count > 0)
                {
                    byte[] t = pktcache.Dequeue();
                    ParcePkt_Cache(t, t.Length);
                    //Application.DoEvents();
                    //   Thread.Sleep(10);
                }
                System.Threading.Thread.Sleep(1000);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            bContinueCapturing = false;
        }

        private void update_statecode_instance(int id, int code, double times)
        {
            try
            {
                if (dataGridView1.Rows.Count > id && dataGridView1.Rows[id].Cells[0].Value.ToString() == id.ToString())
                {
                    dataGridView1.Rows[id].Cells[5].Value = code;
                    dataGridView1.Rows[id].Cells[6].Value = (int)times;
                }
            }
            catch (Exception e)
            {
            }
        }

        private void dataGridView1_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                string url = dataGridView1.SelectedRows[0].Cells["URL"].Value.ToString();
                System.Diagnostics.Process.Start(url);
            }
            catch (Exception ex)
            {

            }
            finally
            {

            }
        }

        private void dataGridView1_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
        {
            //if ((!dic_rid_ack.ContainsKey(e.RowIndex)) || (!dic_ack_httpsession.ContainsKey(dic_rid_ack[e.RowIndex]))) 
            //    return;

            if (list_ack.Count <= e.RowIndex || !dic_ack_httpsession.ContainsKey(list_ack[e.RowIndex]))
                return;
            // vrow vr= _dic_rid_virow[e.RowIndex];
            httpsession osession = dic_ack_httpsession[list_ack[e.RowIndex]];
            switch (e.ColumnIndex)
            {
                case 0:
                    e.Value = osession.id;
                    break;
                case 1:
                    e.Value = osession.ack;
                    break;
                case 2:
                    e.Value = osession.method;
                    break;
                case 3:
                    e.Value = osession.url;
                    break;

                case 4:
                    e.Value = System.Text.Encoding.ASCII.GetString(osession.sendraw.ToArray());
                    break;

                case 5:
                    e.Value = osession.statucode;
                    break;

                case 6:
                    e.Value = (int)((osession.responoversetime - osession.senddtime).TotalMilliseconds);
                    break;
            }
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            int tt = 0;
            try
            {
                if (dataGridView1.SelectedRows.Count > 0)
                {
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                        resetui();
                        string seq = dataGridView1.SelectedRows[0].Cells["seq"].Value.ToString();
                        if (dic_ack_httpsession.ContainsKey(seq))
                        {
                            httpsession osession = dic_ack_httpsession[seq];
                            this.txt_request.Text=dataGridView1.SelectedRows[0].Cells["RAW"].Value.ToString();

                            if (osession.responseraw == null)
                            {
                                debugmsg("没有数据");
                                return;
                            }
                            byte[] dataall = osession.responseraw.ToArray();
                            this.txt_response.Text =System.Text.Encoding.Default.GetString (dataall );
                            this.txt_request.Text = System.Text.Encoding.Default.GetString (osession.sendraw.ToArray());

                            int tag = 0;
                            for (int i = 0; i < dataall.Length - 3; i  )
                            {
                                if (dataall[i] == 0x0D && dataall[i   1] == 0x0A && dataall[i   2] == 0x0D && dataall[i   3] == 0x0A)
                                {
                                    tag = i;
                                    break;
                                }
                            }
                            byte[] headbyte = new byte[tag   4];
                            Array.Copy(dataall, 0, headbyte, 0, tag   4);
                            byte[] recbyte = new byte[dataall.Length - headbyte.Length];
                            Array.Copy(dataall, tag   4, recbyte, 0, recbyte.Length);
                            string headstring = Encoding.ASCII.GetString(headbyte).Trim(new char[] { '\0' });
                            if (headstring.IndexOf("chunk") >= 0)
                            {
                                recbyte = Chunk.doUnchunk(recbyte);
                            }
                            System.IO.Stream responseStream = new System.IO.MemoryStream(recbyte);
                            string compress = getencompress(headstring);
                            if (compress == "gzip")
                            {
                                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                            }
                            else if (compress == "deflate")// if (headstring.ToLower().Contains("deflate"))
                            {
                                responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                            }
                            if (isimage(headstring)) //图形
                            {
                                pictureBox1.Image = ConvertByteArrayToImage(recbyte);
                            }
                            else
                            {
                                string encstring = getencfromhead(headstring);
                                if (encstring == "")
                                {
                                    string prs = System.Text.Encoding.ASCII.GetString(recbyte);
                                    encstring = getencfromhead(prs);
                                }
                                if (encstring == "")
                                    encstring = "utf-8";
                                Encoding enc = Encoding.GetEncoding(encstring);
                                System.IO.StreamReader sr = new System.IO.StreamReader(responseStream, enc);
                                string html = sr.ReadToEnd();
                                this.txt_response.Text = headstring   html;
                                this.webBrowser1.DocumentText = html;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format("[异常]   {0}", ex.ToString()));
                debugmsg(string.Format("[异常]   {0}", ex.ToString()));
            }
        }

        private void resetui()
        {
            this.webBrowser1.DocumentText = "";
            txt_log.Text = "";
            txt_request.Text = "";
            txt_response.Text = "";
        }

        public static Image ConvertByteArrayToImage(byte[] myByteArray)
        {
            System.Drawing.Image newImage;
            using (MemoryStream ms = new MemoryStream(myByteArray, 0, myByteArray.Length))
            {
                ms.Write(myByteArray, 0, myByteArray.Length);
                newImage = Image.FromStream(ms, true);
                // work with image here. 
                // You'll need to keep the MemoryStream open for 
                // as long as you want to work with your new image. 
                return newImage;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }
}

标签: 实例 C# 网络 c 抓包

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警