实例介绍
【实例简介】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) { } } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论