实例介绍
【实例简介】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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论