關於c#實現影音嗅探的問題
這幾天參考網上的RawSocket初步些了個,但發現丟包現象嚴重,效果很不理想很多時候都嗅探不出來
後來藉助httpwatch的API介面頁很理想,大家有什麼關於.net上的實現思慮麼? vb.net或c#都行
下面這個基類是我仿照網上些的
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;
namespace v.sniffer
{
/**
* IP資料包結構,解釋完畢的包存放到這裡,最終用它來組成總的資料
*/
[StructLayout(LayoutKind.Explicit)]
public struct IPHeader
{
[FieldOffset(0)]
public byte ip_verlen; //I4位首部長度+4位IP版本號
[FieldOffset(1)]
public byte ip_tos; //8位服務型別TOS
[FieldOffset(2)]
public ushort ip_totallength; //16位資料包總長度(位元組)
[FieldOffset(4)]
public ushort ip_id; //16位標識
[FieldOffset(6)]
public ushort ip_offset; //3位標誌位
[FieldOffset(8)]
public byte ip_ttl; //8位生存時間 TTL
[FieldOffset(9)]
public byte ip_protocol; //8位協議(TCP, UDP, ICMP, Etc.)
[FieldOffset(10)]
public ushort ip_checksum; //16位IP首部校驗和
[FieldOffset(12)]
public uint ip_srcaddr; //32位源IP地址
[FieldOffset(16)]
public uint ip_destaddr; //32位目的IP地址
}
public class RawSocket
{
private bool error_occurred; //套接字在接收包時是否產生錯誤
public bool KeepRunning; //是否繼續進行
private int len_receive_buf; //得到的資料流的長度
byte[] receive_buf_bytes; //收到的位元組
private Socket socket = null; //宣告套接字
const int SIO_RCVALL = unchecked((int)0x98000001);//監聽所有的資料包
/**
* 建構函式
*/
public RawSocket()
{
error_occurred = false;//沒有產生錯誤
len_receive_buf = 4096;//接收的資料流的長度
receive_buf_bytes = new byte[len_receive_buf];//接收的內容
}
/**
* 建立並繫結套接字
*
* @param 要監聽的IP地址,單網路卡的可以直接通過Dns.GetHostByName(Dns.GetHostEntry()).AddressList[0].ToString()方式來指定監聽本地
*/
public void CreateAndBindSocket(string IP)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Blocking = false; //設定socket非阻塞狀態
socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0)); //繫結套接字
if (SetSocketOption() == false) error_occurred = true;//開始偵聽資料
}
/**
* 偵聽資料包的引數
*/
private bool SetSocketOption() //設定raw socket
{
bool ret_value = true;
try
{
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
byte[] IN = new byte[4] { 1, 0, 0, 0 };
byte[] OUT = new byte[4];
//低階別操作模式,接受所有的資料包,這一步是關鍵,必須把socket設成raw和IP Level才可用SIO_RCVALL
int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4個8位位元組合成一個32位整數
if (ret_code != 0) ret_value = false;
}
catch (SocketException)
{
ret_value = false;
}
return ret_value;
}
public bool ErrorOccurred
{
get
{
return error_occurred;
}
}
//解析接收的資料包,形成PacketArrivedEventArgs事件資料類物件,並引發PacketArrival事件
unsafe private void Receive(byte[] buf, int len)
{
byte temp_protocol = 0;//協議
uint temp_version = 0;//版本
uint temp_ip_srcaddr = 0;//源地址
uint temp_ip_destaddr = 0;//目的地址
short temp_srcport = 0;//源埠
short temp_dstport = 0;//目標埠
IPAddress temp_ip;//IP地址
PacketArrivedEventArgs e = new PacketArrivedEventArgs();//新網路資料包資訊事件
fixed (byte* fixed_buf = buf)
{
IPHeader* head = (IPHeader*)fixed_buf;//把資料流整和為IPHeader結構
e.HeaderLength = (uint)(head->ip_verlen & 0x0F) << 2;
e.IPHeaderBuffer = new byte[e.HeaderLength];
temp_protocol = head->ip_protocol;
switch (temp_protocol)//提取協議型別
{
case 1: e.Protocol = "ICMP"; break;
case 2: e.Protocol = "IGMP"; break;
case 6: e.Protocol = "TCP"; break;
case 17: e.Protocol = "UDP"; break;
default: e.Protocol = "UNKNOWN"; break;
}
temp_version = (uint)(head->ip_verlen & 0xF0) >> 4;//提取IP協議版本
e.IPVersion = temp_version.ToString();
//以下語句提取出了PacketArrivedEventArgs物件中的其他引數
temp_ip_srcaddr = head->ip_srcaddr;
temp_ip_destaddr = head->ip_destaddr;
temp_ip = new IPAddress(temp_ip_srcaddr);
e.OriginationAddress = temp_ip.ToString();
temp_ip = new IPAddress(temp_ip_destaddr);
e.DestinationAddress = temp_ip.ToString();
temp_srcport = *(short*)&fixed_buf[e.HeaderLength];
temp_dstport = *(short*)&fixed_buf[e.HeaderLength + 2];
e.OriginationPort = IPAddress.NetworkToHostOrder(temp_srcport).ToString();
e.DestinationPort = IPAddress.NetworkToHostOrder(temp_dstport).ToString();
e.PacketLength = (uint)len;
e.MessageLength = (uint)len - e.HeaderLength;
e.MessageBuffer = new byte[e.MessageLength];
e.ReceiveBuffer = buf;
//把buf中的IP頭賦給PacketArrivedEventArgs中的IPHeaderBuffer
Array.Copy(buf, 0, e.IPHeaderBuffer, 0, (int)e.HeaderLength);
//把buf中的包中內容賦給PacketArrivedEventArgs中的MessageBuffer
Array.Copy(buf, (int)e.HeaderLength, e.MessageBuffer, 0, (int)e.MessageLength);
}
//引發PacketArrival事件
OnPacketArrival(e);
}
public void Run() //開始監聽
{
if (socket != null)
{
IAsyncResult ar = socket.BeginReceive(receive_buf_bytes, 0, len_receive_buf, SocketFlags.None, new AsyncCallback(CallReceive), this);
}
}
private void CallReceive(IAsyncResult ar)//非同步回撥
{
if (socket != null)
{
try
{
int received_bytes;
received_bytes = socket.EndReceive(ar);
Receive(receive_buf_bytes, received_bytes);
if (KeepRunning) Run();
}catch (Exception e) { }
}
}
public void Shutdown() //關閉raw socket
{
if (socket != null)
{
try
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}catch (Exception e) { }
}
}
public delegate void PacketArrivedEventHandler(Object sender, PacketArrivedEventArgs args);
//事件控制程式碼:包到達時引發事件
public event PacketArrivedEventHandler PacketArrival;//宣告時間控制程式碼函式
private void OnPacketArrival(PacketArrivedEventArgs e)
{
PacketArrivedEventHandler temp = PacketArrival;
if (temp != null)
temp(this, e);
}
public class PacketArrivedEventArgs : EventArgs
{
public uint HeaderLength;
public string Protocol;
public string IPVersion;
public string OriginationAddress;
public string DestinationAddress;
public string OriginationPort;
public string DestinationPort;
public uint PacketLength;
public uint MessageLength;
public byte[] ReceiveBuffer;
public byte[] IPHeaderBuffer;
public byte[] MessageBuffer;
public PacketArrivedEventArgs()
{
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("/r/n----------------/r/n");
sb.AppendFormat("src = {0}:{1}, dst= {2}:{3}/r/n", OriginationAddress, OriginationPort,
DestinationAddress, DestinationPort);
sb.AppendFormat("protocol = {0}, ipVersion={1}/r/n", Protocol, IPVersion);
sb.AppendFormat("PacketLength={0},MessageLength={1}", PacketLength, MessageLength);
sb.Append("/r/n----------------/r/n");
return sb.ToString();
}
}
}
}
這個是我的主視窗呼叫
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using v.sniffer;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;
namespace v.winForms
{
public partial class listen : Form
{
private Hashtable ht = new Hashtable();
private System.Data.DataTable httpTable =new DataTable("httpList");
private RawSocket socket = null;
delegate void mydelegate();//表單子執行緒代理
public listen()
{
InitializeComponent();
}
private void btn_browser_Click(object sender, EventArgs e)
{
if (!this.btn_ListenStart.Enabled)
{
this.startRequest();
}
else
{
MessageBox.Show("請先開啟監聽,在開始請求");
}
}
private void startRequest()
{
if (!listenUrl.Text.Equals(""))
{
v.winForms.easyBrowser eBrowser = new easyBrowser();
eBrowser.openUrl(listenUrl.Text);
if (chkDebugMode.Checked)
{
eBrowser.Show();
}
}
}
private void btn_ListenStart_Click(object sender, EventArgs e)
{
this.listenList.Invoke(new mydelegate(ListenThread));//初始化合同服務分類
this.btn_ListenStart.Enabled = false;
this.btn_ListenStop.Enabled = true;
}
private void btn_ListenStop_Click(object sender, EventArgs e)
{
this.listenList.Invoke(new mydelegate(ListenStop));//初始化合同服務分類
this.btn_ListenStart.Enabled = true;
this.btn_ListenStop.Enabled = false;
}
private void ListenStop()
{
if (this.socket != null)
{
this.socket.Shutdown();
}
}
/**
* 偵聽執行緒
*/
public void ListenThread()
{
try
{
socket = new RawSocket();
IPAddress hosts = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
socket.CreateAndBindSocket(hosts.ToString());
if (socket.ErrorOccurred)
{
MessageBox.Show("偵聽出錯了");
return;
}
socket.KeepRunning = true;
socket.PacketArrival += socket_PacketArrival;
socket.Run();
this.startRequest();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
throw;
}
finally
{
}
}
private void appendRow(string strUrl,string strContentType)
{
string[] arrSubItem = new string[2];
arrSubItem[0] = strUrl;
arrSubItem[1] = strContentType;
ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
LiItem.Tag = "這裡可以儲存額外的資訊";
this.listenList.Items.Add(LiItem);
}
private string byte2str(byte[] barr)
{
return Encoding.UTF8.GetString(barr).Trim();
/*
*System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
string strRequest = converter.GetString(httpData).Trim();
//string strRequest = Encoding.ASCII.GetString(httpData).Trim();//UTF8
*/
}
void socket_PacketArrival(object sender, RawSocket.PacketArrivedEventArgs args)
{
[color=#FF0000] string localIp = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
if (args.Protocol == "TCP" && args.OriginationAddress == localIp) // && (args.OriginationAddress == localIp || args.DestinationAddress == localIp)
{
byte[] httpData = new byte[args.MessageLength];
Buffer.BlockCopy(args.MessageBuffer, 0, httpData, 0, httpData.Length);
string strRequest = Encoding.UTF8.GetString(httpData).Trim();
v.sniffer.headerSplit hSplit = new v.sniffer.headerSplit();
hSplit.setHeader(strRequest);
string strHost = hSplit.getHost();
string strPath = hSplit.getPath();
string strPort = args.DestinationPort;
string strContentType = hSplit.getContentType();
if (strPort.Equals("80"))
{
strPort = "";
}
else
{
strPort = ":" + strPort;
}
//if (!strHost.Equals(""))
{
string strUrl = "http://" + strHost + strPort + strPath;
string strKey = args.OriginationPort + args.DestinationAddress + args.DestinationPort;
MessageBox.Show(strUrl);
if (ht.Contains(strKey))
{
ht[strKey] = strUrl;
}
else
{
ht.Add(strKey, strUrl);
}
}
if (!strContentType.Equals(""))
{
string strKey = args.DestinationPort + args.OriginationAddress + args.OriginationPort;
string strUrl = "";
if (ht.Contains(strKey))
{
strUrl = ht[strKey].ToString();
ht.Remove(strKey);
}
bool isCheckType=(this.chk_listenType.Checked == false && strContentType.Contains("video/x-flv")||(this.chk_listenType.Checked == true));
if(!strUrl.Equals(""))
{
if (isCheckType)
{
this.appendRow(strUrl, strContentType);
}
DataRow dataRow = httpTable.NewRow();
dataRow["url"] = strUrl;
dataRow["type"] = strContentType;
httpTable.Rows.Add(dataRow);
}[/color]
}
}
}
private void listen_Load(object sender, EventArgs e)
{
httpTable.Columns.Add("url", Type.GetType("System.String"));
httpTable.Columns.Add("type", Type.GetType("System.String"));
/*
System.Windows.Forms.ColumnHeader urlColumn = new System.Windows.Forms.ColumnHeader();
urlColumn.Text = "URL地址";
urlColumn.Width = 500;
this.listenList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { urlColumn });
*/
}
private void btn_listClear_Click(object sender, EventArgs e)
{
this.listenList.Items.Clear();
httpTable.Rows.Clear();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
this.listenList.Items.Clear();
for (int i = 0; i < httpTable.Rows.Count; i++)
{
bool isCheckType = (this.chk_listenType.Checked == false && httpTable.Rows[i]["type"].ToString().Contains("video/x-flv") || (this.chk_listenType.Checked == true));
if (!httpTable.Rows[i]["url"].Equals(""))
{
if (isCheckType)
{
string[] arrSubItem = new string[2];
arrSubItem[0] = httpTable.Rows[i]["url"].ToString();
arrSubItem[1] = httpTable.Rows[i]["type"].ToString();
ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
LiItem.Tag = "這裡可以儲存額外的資訊";
this.listenList.Items.Add(LiItem);
}
}
}
}
private void 開啟ToolStripMenuItem_Click(object sender, EventArgs e)
{
}
}
}
這個是分析http頭用的
using System;
using System.Collections.Generic;
using System.Text;
namespace v.sniffer
{
class headerSplit
{
private string[] Arrheader;
public void setHeader(string strHeader)
{
this.Arrheader = strHeader.Split("/r/n/r/n".ToCharArray());
}
public string getPath()
{
string strPath = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool matchPath = new System.Text.RegularExpressions.Regex("GET /.+ HTTP/").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (matchPath)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("GET").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strPath = tmp[next].Trim();
break;
}
}
}
if (!strPath.Equals(""))
{
break;
}
}
return strPath;
}
public string getHost()
{
string strHost = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool matchHost = new System.Text.RegularExpressions.Regex("HOST: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (matchHost)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("HOST:").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strHost = tmp[next].Trim();
break;
}
}
}
if (!strHost.Equals(""))
{
break;
}
}
return strHost;
}
public string getContentType()
{
string strReturn = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool boomatch = new System.Text.RegularExpressions.Regex("CONTENT-TYPE: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (boomatch)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("CONTENT-TYPE:").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strReturn = tmp[next].Trim();
break;
}
}
}
if (!strReturn.Equals(""))
{
break;
}
}
return strReturn;
}
}
}
這個是呼叫IE的外掛
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace v.winForms
{
public partial class easyBrowser : Form
{
public easyBrowser()
{
InitializeComponent();
}
private void easyBrowser_Load(object sender, EventArgs e)
{
//objBrowser.Navigate(txt_url.Text);
}
private void btn_go_Click(object sender, EventArgs e)
{
objBrowser.Navigate(txt_url.Text);
}
public void openUrl(string url)
{
txt_url.Text = url;
objBrowser.Navigate(url);
}
private void objBrowser_DownloadComplete(object sender, EventArgs e)
{
}
private void objBrowser_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
}
}
}
後來藉助httpwatch的API介面頁很理想,大家有什麼關於.net上的實現思慮麼? vb.net或c#都行
下面這個基類是我仿照網上些的
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;
namespace v.sniffer
{
/**
* IP資料包結構,解釋完畢的包存放到這裡,最終用它來組成總的資料
*/
[StructLayout(LayoutKind.Explicit)]
public struct IPHeader
{
[FieldOffset(0)]
public byte ip_verlen; //I4位首部長度+4位IP版本號
[FieldOffset(1)]
public byte ip_tos; //8位服務型別TOS
[FieldOffset(2)]
public ushort ip_totallength; //16位資料包總長度(位元組)
[FieldOffset(4)]
public ushort ip_id; //16位標識
[FieldOffset(6)]
public ushort ip_offset; //3位標誌位
[FieldOffset(8)]
public byte ip_ttl; //8位生存時間 TTL
[FieldOffset(9)]
public byte ip_protocol; //8位協議(TCP, UDP, ICMP, Etc.)
[FieldOffset(10)]
public ushort ip_checksum; //16位IP首部校驗和
[FieldOffset(12)]
public uint ip_srcaddr; //32位源IP地址
[FieldOffset(16)]
public uint ip_destaddr; //32位目的IP地址
}
public class RawSocket
{
private bool error_occurred; //套接字在接收包時是否產生錯誤
public bool KeepRunning; //是否繼續進行
private int len_receive_buf; //得到的資料流的長度
byte[] receive_buf_bytes; //收到的位元組
private Socket socket = null; //宣告套接字
const int SIO_RCVALL = unchecked((int)0x98000001);//監聽所有的資料包
/**
* 建構函式
*/
public RawSocket()
{
error_occurred = false;//沒有產生錯誤
len_receive_buf = 4096;//接收的資料流的長度
receive_buf_bytes = new byte[len_receive_buf];//接收的內容
}
/**
* 建立並繫結套接字
*
* @param 要監聽的IP地址,單網路卡的可以直接通過Dns.GetHostByName(Dns.GetHostEntry()).AddressList[0].ToString()方式來指定監聽本地
*/
public void CreateAndBindSocket(string IP)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Blocking = false; //設定socket非阻塞狀態
socket.Bind(new IPEndPoint(IPAddress.Parse(IP), 0)); //繫結套接字
if (SetSocketOption() == false) error_occurred = true;//開始偵聽資料
}
/**
* 偵聽資料包的引數
*/
private bool SetSocketOption() //設定raw socket
{
bool ret_value = true;
try
{
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
byte[] IN = new byte[4] { 1, 0, 0, 0 };
byte[] OUT = new byte[4];
//低階別操作模式,接受所有的資料包,這一步是關鍵,必須把socket設成raw和IP Level才可用SIO_RCVALL
int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];//把4個8位位元組合成一個32位整數
if (ret_code != 0) ret_value = false;
}
catch (SocketException)
{
ret_value = false;
}
return ret_value;
}
public bool ErrorOccurred
{
get
{
return error_occurred;
}
}
//解析接收的資料包,形成PacketArrivedEventArgs事件資料類物件,並引發PacketArrival事件
unsafe private void Receive(byte[] buf, int len)
{
byte temp_protocol = 0;//協議
uint temp_version = 0;//版本
uint temp_ip_srcaddr = 0;//源地址
uint temp_ip_destaddr = 0;//目的地址
short temp_srcport = 0;//源埠
short temp_dstport = 0;//目標埠
IPAddress temp_ip;//IP地址
PacketArrivedEventArgs e = new PacketArrivedEventArgs();//新網路資料包資訊事件
fixed (byte* fixed_buf = buf)
{
IPHeader* head = (IPHeader*)fixed_buf;//把資料流整和為IPHeader結構
e.HeaderLength = (uint)(head->ip_verlen & 0x0F) << 2;
e.IPHeaderBuffer = new byte[e.HeaderLength];
temp_protocol = head->ip_protocol;
switch (temp_protocol)//提取協議型別
{
case 1: e.Protocol = "ICMP"; break;
case 2: e.Protocol = "IGMP"; break;
case 6: e.Protocol = "TCP"; break;
case 17: e.Protocol = "UDP"; break;
default: e.Protocol = "UNKNOWN"; break;
}
temp_version = (uint)(head->ip_verlen & 0xF0) >> 4;//提取IP協議版本
e.IPVersion = temp_version.ToString();
//以下語句提取出了PacketArrivedEventArgs物件中的其他引數
temp_ip_srcaddr = head->ip_srcaddr;
temp_ip_destaddr = head->ip_destaddr;
temp_ip = new IPAddress(temp_ip_srcaddr);
e.OriginationAddress = temp_ip.ToString();
temp_ip = new IPAddress(temp_ip_destaddr);
e.DestinationAddress = temp_ip.ToString();
temp_srcport = *(short*)&fixed_buf[e.HeaderLength];
temp_dstport = *(short*)&fixed_buf[e.HeaderLength + 2];
e.OriginationPort = IPAddress.NetworkToHostOrder(temp_srcport).ToString();
e.DestinationPort = IPAddress.NetworkToHostOrder(temp_dstport).ToString();
e.PacketLength = (uint)len;
e.MessageLength = (uint)len - e.HeaderLength;
e.MessageBuffer = new byte[e.MessageLength];
e.ReceiveBuffer = buf;
//把buf中的IP頭賦給PacketArrivedEventArgs中的IPHeaderBuffer
Array.Copy(buf, 0, e.IPHeaderBuffer, 0, (int)e.HeaderLength);
//把buf中的包中內容賦給PacketArrivedEventArgs中的MessageBuffer
Array.Copy(buf, (int)e.HeaderLength, e.MessageBuffer, 0, (int)e.MessageLength);
}
//引發PacketArrival事件
OnPacketArrival(e);
}
public void Run() //開始監聽
{
if (socket != null)
{
IAsyncResult ar = socket.BeginReceive(receive_buf_bytes, 0, len_receive_buf, SocketFlags.None, new AsyncCallback(CallReceive), this);
}
}
private void CallReceive(IAsyncResult ar)//非同步回撥
{
if (socket != null)
{
try
{
int received_bytes;
received_bytes = socket.EndReceive(ar);
Receive(receive_buf_bytes, received_bytes);
if (KeepRunning) Run();
}catch (Exception e) { }
}
}
public void Shutdown() //關閉raw socket
{
if (socket != null)
{
try
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}catch (Exception e) { }
}
}
public delegate void PacketArrivedEventHandler(Object sender, PacketArrivedEventArgs args);
//事件控制程式碼:包到達時引發事件
public event PacketArrivedEventHandler PacketArrival;//宣告時間控制程式碼函式
private void OnPacketArrival(PacketArrivedEventArgs e)
{
PacketArrivedEventHandler temp = PacketArrival;
if (temp != null)
temp(this, e);
}
public class PacketArrivedEventArgs : EventArgs
{
public uint HeaderLength;
public string Protocol;
public string IPVersion;
public string OriginationAddress;
public string DestinationAddress;
public string OriginationPort;
public string DestinationPort;
public uint PacketLength;
public uint MessageLength;
public byte[] ReceiveBuffer;
public byte[] IPHeaderBuffer;
public byte[] MessageBuffer;
public PacketArrivedEventArgs()
{
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("/r/n----------------/r/n");
sb.AppendFormat("src = {0}:{1}, dst= {2}:{3}/r/n", OriginationAddress, OriginationPort,
DestinationAddress, DestinationPort);
sb.AppendFormat("protocol = {0}, ipVersion={1}/r/n", Protocol, IPVersion);
sb.AppendFormat("PacketLength={0},MessageLength={1}", PacketLength, MessageLength);
sb.Append("/r/n----------------/r/n");
return sb.ToString();
}
}
}
}
這個是我的主視窗呼叫
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using v.sniffer;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Collections;
namespace v.winForms
{
public partial class listen : Form
{
private Hashtable ht = new Hashtable();
private System.Data.DataTable httpTable =new DataTable("httpList");
private RawSocket socket = null;
delegate void mydelegate();//表單子執行緒代理
public listen()
{
InitializeComponent();
}
private void btn_browser_Click(object sender, EventArgs e)
{
if (!this.btn_ListenStart.Enabled)
{
this.startRequest();
}
else
{
MessageBox.Show("請先開啟監聽,在開始請求");
}
}
private void startRequest()
{
if (!listenUrl.Text.Equals(""))
{
v.winForms.easyBrowser eBrowser = new easyBrowser();
eBrowser.openUrl(listenUrl.Text);
if (chkDebugMode.Checked)
{
eBrowser.Show();
}
}
}
private void btn_ListenStart_Click(object sender, EventArgs e)
{
this.listenList.Invoke(new mydelegate(ListenThread));//初始化合同服務分類
this.btn_ListenStart.Enabled = false;
this.btn_ListenStop.Enabled = true;
}
private void btn_ListenStop_Click(object sender, EventArgs e)
{
this.listenList.Invoke(new mydelegate(ListenStop));//初始化合同服務分類
this.btn_ListenStart.Enabled = true;
this.btn_ListenStop.Enabled = false;
}
private void ListenStop()
{
if (this.socket != null)
{
this.socket.Shutdown();
}
}
/**
* 偵聽執行緒
*/
public void ListenThread()
{
try
{
socket = new RawSocket();
IPAddress hosts = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
socket.CreateAndBindSocket(hosts.ToString());
if (socket.ErrorOccurred)
{
MessageBox.Show("偵聽出錯了");
return;
}
socket.KeepRunning = true;
socket.PacketArrival += socket_PacketArrival;
socket.Run();
this.startRequest();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
throw;
}
finally
{
}
}
private void appendRow(string strUrl,string strContentType)
{
string[] arrSubItem = new string[2];
arrSubItem[0] = strUrl;
arrSubItem[1] = strContentType;
ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
LiItem.Tag = "這裡可以儲存額外的資訊";
this.listenList.Items.Add(LiItem);
}
private string byte2str(byte[] barr)
{
return Encoding.UTF8.GetString(barr).Trim();
/*
*System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
string strRequest = converter.GetString(httpData).Trim();
//string strRequest = Encoding.ASCII.GetString(httpData).Trim();//UTF8
*/
}
void socket_PacketArrival(object sender, RawSocket.PacketArrivedEventArgs args)
{
[color=#FF0000] string localIp = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
if (args.Protocol == "TCP" && args.OriginationAddress == localIp) // && (args.OriginationAddress == localIp || args.DestinationAddress == localIp)
{
byte[] httpData = new byte[args.MessageLength];
Buffer.BlockCopy(args.MessageBuffer, 0, httpData, 0, httpData.Length);
string strRequest = Encoding.UTF8.GetString(httpData).Trim();
v.sniffer.headerSplit hSplit = new v.sniffer.headerSplit();
hSplit.setHeader(strRequest);
string strHost = hSplit.getHost();
string strPath = hSplit.getPath();
string strPort = args.DestinationPort;
string strContentType = hSplit.getContentType();
if (strPort.Equals("80"))
{
strPort = "";
}
else
{
strPort = ":" + strPort;
}
//if (!strHost.Equals(""))
{
string strUrl = "http://" + strHost + strPort + strPath;
string strKey = args.OriginationPort + args.DestinationAddress + args.DestinationPort;
MessageBox.Show(strUrl);
if (ht.Contains(strKey))
{
ht[strKey] = strUrl;
}
else
{
ht.Add(strKey, strUrl);
}
}
if (!strContentType.Equals(""))
{
string strKey = args.DestinationPort + args.OriginationAddress + args.OriginationPort;
string strUrl = "";
if (ht.Contains(strKey))
{
strUrl = ht[strKey].ToString();
ht.Remove(strKey);
}
bool isCheckType=(this.chk_listenType.Checked == false && strContentType.Contains("video/x-flv")||(this.chk_listenType.Checked == true));
if(!strUrl.Equals(""))
{
if (isCheckType)
{
this.appendRow(strUrl, strContentType);
}
DataRow dataRow = httpTable.NewRow();
dataRow["url"] = strUrl;
dataRow["type"] = strContentType;
httpTable.Rows.Add(dataRow);
}[/color]
}
}
}
private void listen_Load(object sender, EventArgs e)
{
httpTable.Columns.Add("url", Type.GetType("System.String"));
httpTable.Columns.Add("type", Type.GetType("System.String"));
/*
System.Windows.Forms.ColumnHeader urlColumn = new System.Windows.Forms.ColumnHeader();
urlColumn.Text = "URL地址";
urlColumn.Width = 500;
this.listenList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { urlColumn });
*/
}
private void btn_listClear_Click(object sender, EventArgs e)
{
this.listenList.Items.Clear();
httpTable.Rows.Clear();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
this.listenList.Items.Clear();
for (int i = 0; i < httpTable.Rows.Count; i++)
{
bool isCheckType = (this.chk_listenType.Checked == false && httpTable.Rows[i]["type"].ToString().Contains("video/x-flv") || (this.chk_listenType.Checked == true));
if (!httpTable.Rows[i]["url"].Equals(""))
{
if (isCheckType)
{
string[] arrSubItem = new string[2];
arrSubItem[0] = httpTable.Rows[i]["url"].ToString();
arrSubItem[1] = httpTable.Rows[i]["type"].ToString();
ListViewItem LiItem = new ListViewItem(arrSubItem, 0);
LiItem.Tag = "這裡可以儲存額外的資訊";
this.listenList.Items.Add(LiItem);
}
}
}
}
private void 開啟ToolStripMenuItem_Click(object sender, EventArgs e)
{
}
}
}
這個是分析http頭用的
using System;
using System.Collections.Generic;
using System.Text;
namespace v.sniffer
{
class headerSplit
{
private string[] Arrheader;
public void setHeader(string strHeader)
{
this.Arrheader = strHeader.Split("/r/n/r/n".ToCharArray());
}
public string getPath()
{
string strPath = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool matchPath = new System.Text.RegularExpressions.Regex("GET /.+ HTTP/").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (matchPath)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("GET").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strPath = tmp[next].Trim();
break;
}
}
}
if (!strPath.Equals(""))
{
break;
}
}
return strPath;
}
public string getHost()
{
string strHost = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool matchHost = new System.Text.RegularExpressions.Regex("HOST: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (matchHost)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("HOST:").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strHost = tmp[next].Trim();
break;
}
}
}
if (!strHost.Equals(""))
{
break;
}
}
return strHost;
}
public string getContentType()
{
string strReturn = "";
for (int i = 0; i < this.Arrheader.Length; i++)
{
bool boomatch = new System.Text.RegularExpressions.Regex("CONTENT-TYPE: ").IsMatch(this.Arrheader[i].ToUpper()); // 在字串中匹配
if (boomatch)
{
string[] tmp = this.Arrheader[i].Split(" ".ToCharArray());
for (int j = 0; j < tmp.Length; j++)
{
bool matchGet = new System.Text.RegularExpressions.Regex("CONTENT-TYPE:").IsMatch(tmp[j].ToUpper());
int next = j + 1;
if (matchGet && next < tmp.Length)
{
strReturn = tmp[next].Trim();
break;
}
}
}
if (!strReturn.Equals(""))
{
break;
}
}
return strReturn;
}
}
}
這個是呼叫IE的外掛
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace v.winForms
{
public partial class easyBrowser : Form
{
public easyBrowser()
{
InitializeComponent();
}
private void easyBrowser_Load(object sender, EventArgs e)
{
//objBrowser.Navigate(txt_url.Text);
}
private void btn_go_Click(object sender, EventArgs e)
{
objBrowser.Navigate(txt_url.Text);
}
public void openUrl(string url)
{
txt_url.Text = url;
objBrowser.Navigate(url);
}
private void objBrowser_DownloadComplete(object sender, EventArgs e)
{
}
private void objBrowser_DocumentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
}
}
}
相關文章
- 關於介面實現的一個小問題
- 一個基於Java的開源URL嗅探器Java
- 嗅探器(割點)
- 關於多型實現Singleton模式的探討 (轉)多型模式
- HttpOnly 隱私嗅探器HTTP
- 嗅探與偽造原理
- 密碼嗅探工具dsniff密碼
- 關於C語言結構體對齊問題的探討C語言結構體
- C# 關於壓縮、加密、解壓問題C#加密
- 關於IDEA使用xml實現動態sql的問題IdeaXMLSQL
- 關於JTA實現的疑問
- 實驗二 網路嗅探與身份認證
- (緊急求助)關於jive訊息過濾的實現相關問題
- 網路防嗅探工具SniffJoke
- VPN憑證嗅探工具fiked
- 關於硬體及軟體實現條帶化的問題
- 關於實體與值物件的問題物件
- 關於C#中建構函式的繼承的問題C#函式繼承
- 關於網友的獲取MSSQL外來鍵資訊的問題的探討SQL
- 關於SQLServerDriver的問題SQLServer
- 關於 JavaMail 的問題JavaAI
- 關於session的問題Session
- 關於SESSION中出現的奇怪的問題!高手進~~Session
- 請教:關於排課問題的實體關係
- 關於點陣圖索引的split及bitmap to rowid實現問題索引
- 網路資料嗅探工具HexInject
- Spring 下,關於動態資料來源的事務問題的探討Spring
- 關於CSS中的float可能出現的小問題CSS
- 【轉載】關於C#中動態載入AppDomain的問題C#APPAI
- 關於javascript的this指向問題JavaScript
- 關於跨域的問題跨域
- 關於bit code的問題
- 關於序列同步的問題
- 關於IP地址的問題
- 關於橋模式的問題模式
- 求救 關於parallel的問題Parallel
- 關於web start的問題Web
- 關於action的error問題Error