NetAnalyzer笔记 之 四. C#版的抓包软件
[创建时间:2015-09-10 22:37:04]
不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^
NetAnalyzer实现结构
在上一篇中介绍一点VC++开发环境的配置,与基本的运行方式。因为NetAnalyzer使用的C#作为开发语言,所以在此主要介绍一些在C#环境下的开发环境的配置,与一些基本开发情况,力求在完成本篇后后,读者可以制作一个简单的抓包程序。
在开始编程前先要介绍连个.Net类库SharpPcap.dll与PacketDotNet.dll。在2004年Tamir Gal为了完成他的毕业设计,其中有一些内容需要使用Winpcap来实现网络数据分析,但希望可以使用简单易用的C#开发语言。于是建立了SharpPcap项目,Tamir Gal为了节省时间,并没用将网络数据采集部分与分析部分分开,甚至有些代码混杂在UI代码中。而且在实现了很少的WinPcapAPI接口,并没用提供相关的开发文档。
因为这样,Tamir决定重新设计SharPcap,并推出了1.x一些列的版本,最终在2007年完成了SharpPcap1.6.2版本。
在2008年11月Chris Morgan接替了Tamir的工作,重新设计了SharpPcap的API,开始支持Linux 和MAC(在Linux 与MAC平台的相关技术请参见Mono开发平台)。之后将数据采集于协议分析分别封装在不同的程序集类库中即形成了SharpPcap于Packet.Net。
下载地址:http://sourceforge.net/projects/sharppcap/ 在GNU协议下的开源代码。
(1) SharpPcap.dll
SharpPcap中封装了Winpcap提供的大部分API函数,在该类库中,我们可以获取主机网卡,及其信息。并定义了对网卡的各种操作方法,如打开网卡,开始抓包,停止抓包等,再抓包中提供了,同步方式与异步方式,方便进行不同的环境,对于更加详细的介绍,将会在下一章提到。
(2) Packet.Net
在程序集中的名称为PacketDotNet,该类库负责对捕获的数据进行分析解析,目前提供可以分析的协议:
Ethernet、SLL (Linux Cooked-Mode Capture) 、ARP、IPv4 、IPv6 、TCP 、UDP 、ICMPv4、ICMPv6 、IGMPv2 、PPPoE 、PTP 、LLDP 、Wake-on-LAN(WOL)
在NetAnalyzer此基础上,在类库中增加了PPP、LCP、CiscoHDLC等协议。
为了可以分析应用层协议,在NetAnalyzer设计了ApplicationProtocol类库,目前提供HTTP、FTP、DNS、SMTP、POP3、SSDP协议的解析,本节中不会对应用层协议进行分析。
在以下的内容中,我们将分七个部分,来完成一个简单的抓包程序。同上面一样,所有的程序都在Visual Studio2013中完成,只是在这里我们首先要得到:
SharpPcap.dll版本4.0.0
PacketDotNet.dl版本0.11.0
可以通过上面的网址获取。
1 获取网络适配器(网卡)
首先新建工程,开发语言选择C#,类型选择Windows窗体应用程序,命名为MySniffer,图形界面如图1所示。
图1 建立MySniffer工程
点击确定,在解决方案资源管理器中右击引用添加引用, 此时打开添加应用对话框,选择浏览选项卡,并找到SharpPcap与PacketDotNet类库将其添加至工程中。如图2所示,
图2从引用中右击添加引用
在添加完成之后,项目应用中应该可以看到这两个类库的的引用文件。
首先我们来获取需要监听的网卡,在窗体中添加如下代码:
- private void loadDevice()// 获取网卡方法
- {
- try
- {
- foreach (var i in CaptureDeviceList.Instance)
- {
- comDeviceList.Items.Add(i.Description); //在combox中添加
- }
- if (comDeviceList.Items.Count > )
- {
- comDeviceList.SelectedIndex = ;//自动选中第一个
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- return;
- }
- }
我们通过调用SharpPcap.CaptureDeviceList.Instance 单例,获取一个包含所用网卡的列表CaptureDeviceList,然后把以此把网卡的描述信息添加到顶部工具栏comDeviceList 中
在代码中我们加一个全局变量device用来指示当前控制的网卡,
- ICaptureDevice device;// 定义设备
所以当我们每次去选择不同的网卡时调用下面的方法
- //选择网卡
- private void comDeviceList_SelectedIndexChanged(object sender, EventArgs e)
- {
- device = CaptureDeviceList.Instance[comDeviceList.SelectedIndex];
- }
完成运行如图
图3获取的网卡以及其信息
接下来我们直接来点精彩的,加入如下代码:
- List<RawCapture> packetList = new List<RawCapture>();//捕获的数据列表
- List<RawCapture> bufferList;//缓存列表
- Thread AnalyzerThread;//分析数据的线程
- object threadLock = new object();//线程锁定
- bool isStartAnalyzer;//用于表示是否启动分析线程的标志
- DeviceMode devMode = DeviceMode.Promiscuous;//数据采集模式
- int readTimeOut = ;
- delegate void DataGridRowsShowHandler(RawCapture packet);
- /// <summary>
- /// 启动网卡
- /// </summary>
- private void Start()
- {
- if (device == null || device.Started)
- return;
- bufferList = new List<RawCapture>();
- Clear();//清理原有的数据
- isStartAnalyzer = true;
- StartAnalyzer();//启动分析线程
- try
- {
- device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
- //默认使用混杂模式,超时 1000
- device.Open(devMode, readTimeOut);
- device.Filter = comFilter.Text;
- device.StartCapture();
- UIConfig(true);
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- UIConfig(false);
- }
- }
- /// <summary>
- /// 启动分析
- /// </summary>
- private void StartAnalyzer()
- {
- AnalyzerThread = new Thread(new ThreadStart(analysrThreadMethod));
- AnalyzerThread.IsBackground = true;
- AnalyzerThread.Start();
- }
- /// <summary>
- /// 停止
- /// </summary>
- private void Stop()
- {
- try
- {
- if (device != null && device.Started)
- {
- device.StopCapture();
- device.Close();
- }
- isStartAnalyzer = false;
- if (AnalyzerThread !=null && AnalyzerThread.IsAlive)
- {
- AnalyzerThread.Abort();
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.Message);
- }
- UIConfig(false);
- }
- /// <summary>
- /// Sharpcap 获取数据包之后的回调
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- void device_OnPacketArrival(object sender, CaptureEventArgs e)
- {
- lock (threadLock)
- {
- bufferList.Add(e.Packet);
- }
- }
- /// <summary>
- /// 数据分析线程 (使用缓存方式,可避免数据堵塞)
- /// </summary>
- private void analysrThreadMethod()
- {
- while (isStartAnalyzer)
- {
- bool isShoudSleep = true;
- lock (threadLock)
- {
- if (bufferList.Count != )
- isShoudSleep = false;
- }
- if (isShoudSleep)//
- {
- Thread.Sleep();
- }
- else
- {
- List<RawCapture> tmpPacketList;
- lock (threadLock) //获取数据
- {
- tmpPacketList = bufferList;
- bufferList = new List<RawCapture>();//构建新列表
- packetList.AddRange(tmpPacketList);
- }
- foreach (var i in tmpPacketList)
- {
- this.Invoke(new DataGridRowsShowHandler(ShowDataRows), i);
- }
- }
- }
- }
- /// <summary>
- /// 在datagridview中显示获取的网络数据
- /// </summary>
- /// <param name="packet"></param>
- private void ShowDataRows(RawCapture packet)
- {
- try
- {
- dataGridPacket.Rows.Add(rowsBulider.Row(packet, ++packetIndex));//加载DataGridRows;
- }
- catch (Exception ex)
- {
- }
- }
这里通过在抓包启动之前,预先启动一个分析线程,用于独立进行数据解析,接下来就是在DataGridView中添加数据了,这部分写的比较渣,请轻喷,毕竟是几年前的代码了,代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using SharpPcap;
- using PacketDotNet;
- using System.Xml;
- namespace MySniffer
- {
- class DataBuilder
- {
- //标记当前数据是否有效
- #region 构建数据行
- /// <summary>
- /// DataGridRow
- /// </summary>
- /// <returns>返回字符串数据</returns>
- public string[] Row(RawCapture rawPacket, uint packetID)
- {
- string[] rows = new string[];
- rows[] = string.Format("{0:D7}", packetID);//编号
- rows[] = "Unknown";
- rows[] = rawPacket.Data.Length.ToString();//数据长度bytes
- rows[] = "--";
- rows[] = "--";
- rows[] = "--";
- Packet packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);
- EthernetPacket ep = EthernetPacket.GetEncapsulated(packet);
- if (ep != null)
- {
- rows[] = "Ethernet(v2)";
- rows[] = Format.MacFormat(ep.SourceHwAddress.ToString());
- rows[] = Format.MacFormat(ep.DestinationHwAddress.ToString());
- rows[] = "[" + ep.Type.ToString() + "]";
- #region IP
- IpPacket ip = IpPacket.GetEncapsulated(packet);
- if (ip != null)
- {
- if (ip.Version == IpVersion.IPv4)
- {
- rows[] = "IPv4";
- }
- else
- {
- rows[] = "IPv6";
- }
- rows[] = ip.SourceAddress.ToString();
- rows[] = ip.DestinationAddress.ToString();
- rows[] = "[下层协议:" + ip.NextHeader.ToString() + "] [版本:" + ip.Version.ToString() + "]";
- TcpPacket tcp = TcpPacket.GetEncapsulated(packet);
- if (tcp != null)
- {
- rows[] = "TCP";
- rows[] += " [" + tcp.SourcePort.ToString() + "]";
- rows[] += " [" + tcp.DestinationPort.ToString() + "]";
- return rows;
- }
- UdpPacket udp = UdpPacket.GetEncapsulated(packet);
- if (udp != null)
- {
- rows[] = "UDP";
- rows[] += " [" + udp.SourcePort.ToString() + "]";
- rows[] += " [" + udp.DestinationPort.ToString() + "]";
- return rows;
- }
- ICMPv4Packet icmpv4 = ICMPv4Packet.GetEncapsulated(packet);
- if (icmpv4 != null)
- {
- rows[] = "ICMPv4";
- rows[] = "[校验:" + icmpv4.Checksum.ToString() + "] [类型:" + icmpv4.TypeCode.ToString() + "] [序列号:" + icmpv4.Sequence.ToString() + "]";
- return rows;
- }
- ICMPv6Packet icmpv6 = ICMPv6Packet.GetEncapsulated(packet);
- if (icmpv6 != null)
- {
- rows[] = "ICMPv6";
- rows[] = "[Code:" + icmpv6.Code.ToString() + "] [Type" + icmpv6.Type.ToString() + "]";
- return rows;
- }
- IGMPv2Packet igmp = IGMPv2Packet.GetEncapsulated(packet);
- if (igmp != null)
- {
- rows[] = "IGMP";
- rows[] = "[只适用于IGMPv2] [组地址:" + igmp.GroupAddress.ToString() + "] [类型:" + igmp.Type.ToString() + "]";
- return rows;
- }
- return rows;
- }
- #endregion
- ARPPacket arp = ARPPacket.GetEncapsulated(packet);
- if (arp != null)
- {
- rows[] = "ARP";
- rows[] = Format.MacFormat(arp.SenderHardwareAddress.ToString());
- rows[] = Format.MacFormat(arp.TargetHardwareAddress.ToString());
- rows[] = "[Arp操作方式:" + arp.Operation.ToString() + "] [发送者:" + arp.SenderProtocolAddress.ToString() + "] [目标:" + arp.TargetProtocolAddress.ToString() + "]";
- return rows;
- }
- WakeOnLanPacket wp = WakeOnLanPacket.GetEncapsulated(packet);
- if (wp != null)
- {
- rows[] = "Wake On Lan";
- rows[] = Format.MacFormat(ep.SourceHwAddress.ToString());
- rows[] = Format.MacFormat(wp.DestinationMAC.ToString());
- rows[] = "[唤醒网络地址:" + wp.DestinationMAC.ToString() + "] [有效性:" + wp.IsValid().ToString() + "]";
- return rows;
- }
- PPPoEPacket poe = PPPoEPacket.GetEncapsulated(packet);
- if (poe != null)
- {
- rows[] = "PPPoE";
- rows[] = poe.Type.ToString() + " " + poe.Version.ToString();
- return rows;
- }
- LLDPPacket llp = LLDPPacket.GetEncapsulated(packet);
- if (llp != null)
- {
- rows[] = "LLDP";
- rows[] = llp.ToString();
- return rows;
- }
- return rows;
- }
- //链路层
- PPPPacket ppp = PPPPacket.GetEncapsulated(packet);
- if (ppp != null)
- {
- rows[] = "PPP";
- rows[] = "--";
- rows[] = "--";
- rows[] = "协议类型:" + ppp.Protocol.ToString();
- return rows;
- }
- //PPPSerial
- PppSerialPacket ppps = PppSerialPacket.GetEncapsulated(packet);
- if (ppps != null)
- {
- rows[] = "PPP";
- rows[] = "--";
- rows[] = "0x" + ppps.Address.ToString("X2");
- rows[] = "地址:" + ppps.Address.ToString("X2") + " 控制:" + ppps.Control.ToString() + " 协议类型:" + ppps.Protocol.ToString();
- return rows;
- }
- //Cisco HDLC
- CiscoHDLCPacket hdlc = CiscoHDLCPacket.GetEncapsulated(packet);
- if (hdlc != null)
- {
- rows[] = "Cisco HDLC";
- rows[] = "--";
- rows[] = "0x" + hdlc.Address.ToString("X2");
- rows[] = "地址:" + hdlc.Address.ToString("X2") + " 控制:" + hdlc.Control.ToString() + " 协议类型:" + hdlc.Protocol.ToString();
- return rows;
- }
- #warning 需要测试
- PacketDotNet.Ieee80211.MacFrame ieee = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as PacketDotNet.Ieee80211.MacFrame;
- if (ieee != null)
- {
- rows[] = "IEEE802.11 MacFrame";
- rows[] = "--";
- rows[] = "--";
- rows[] = "帧校验序列:" + ieee.FrameCheckSequence.ToString() + " 封装帧:" + ieee.FrameControl .ToString();
- return rows;
- }
- PacketDotNet.Ieee80211.RadioPacket ieeePacket = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as PacketDotNet.Ieee80211.RadioPacket;
- if (ieeePacket != null)
- {
- rows[] = "IEEE Radio";
- rows[] = "Version=" + ieeePacket.Version.ToString();
- }
- LinuxSLLPacket linux = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as LinuxSLLPacket;
- if (linux != null)
- {
- rows[] = "LinuxSLL";
- rows[] = "Tyep=" + linux.Type.ToString() + " Protocol=" + linux.EthernetProtocolType.ToString();
- }
- return rows;
- }
- }
- #endregion
- }
虽然写的比较渣,但是思路还是蛮清晰的,额~~有砖头~~~~~
先不管了,来一起看看结果吧
图4 采集到网络数据
终于有点激动了,那么我们接下来就是要实现详细的数据了,不过看了上面的方式代码的解析方式,你会不会有点想法呢。好吧,我这边只把TCP的解析方式放在这里了
- //Tcp
- TreeNode TCPNode;
- TreeNode TcpFlagNode;
- TreeNode TcpChecksumNode;
- TreeNode TcpOptionsNode;
- private void TCP(TcpPacket tcp)
- {
- if (TCPNode == null)
- {
- TCPNode = CreatNode("TCP", );
- }
- TCPNode.Nodes.Clear();
- //port
- TCPNode.Nodes.Add("Source Port: " + tcp.SourcePort.ToString());
- TCPNode.Nodes.Add("Destination Port: " + tcp.DestinationPort.ToString());
- // Seq and Ack
- TCPNode.Nodes.Add("Sequence Number: " + tcp.SequenceNumber.ToString() + " [0x" + tcp.SequenceNumber.ToString("X") + "]");
- TCPNode.Nodes.Add("Acknowledgement Number: " + tcp.AcknowledgmentNumber.ToString() + " [0x" + tcp.AcknowledgmentNumber.ToString("X") + "]");
- //Data Offset
- TCPNode.Nodes.Add("Data Offset: " + (tcp.DataOffset * ).ToString() + " [0x" + tcp.DataOffset.ToString("X") + "]");
- //Flags
- #region Flags
- if (TcpFlagNode == null)
- {
- TcpFlagNode = new TreeNode();
- }
- TcpFlagNode.Nodes.Clear();
- TcpFlagNode.Text = "Flags: [" + Format.TcpFlagType(tcp) + "] [0x" + string.Format("{0:X2}", tcp.AllFlags) + "]";
- TcpFlagNode.Nodes.Add("000. .... .... = Reserved");
- TcpFlagNode.Nodes.Add("...0 .... .... = Nonce");
- TcpFlagNode.Nodes.Add(".... " + Format.getStaus(tcp.CWR) + "... .... = CWR");
- TcpFlagNode.Nodes.Add(".... ." + Format.getStaus(tcp.ECN) + ".. .... = ECN-Echo");
- TcpFlagNode.Nodes.Add(".... .." + Format.getStaus(tcp.Urg) + ". .... = URG");
- TcpFlagNode.Nodes.Add(".... ..." + Format.getStaus(tcp.Ack) + " .... = ACK");
- TcpFlagNode.Nodes.Add(".... .... " + Format.getStaus(tcp.Psh) + "... = PSH");
- TcpFlagNode.Nodes.Add(".... .... ." + Format.getStaus(tcp.Rst) + ".. = RST");
- TcpFlagNode.Nodes.Add(".... .... .." + Format.getStaus(tcp.Syn) + ". = SYN");
- TcpFlagNode.Nodes.Add(".... .... ..." + Format.getStaus(tcp.Fin) + " = FIN");
- TCPNode.Nodes.Add(TcpFlagNode);
- #endregion
- //WinSize
- TCPNode.Nodes.Add("Window Size: " + tcp.WindowSize.ToString());
- //check Sum
- if (TcpChecksumNode == null)
- {
- TcpChecksumNode = new TreeNode();
- }
- TcpChecksumNode.Nodes.Clear();
- TcpChecksumNode.Text = "Checksum: 0x" + tcp.Checksum.ToString("X") + " [" + (tcp.ValidChecksum ? "Valid" : "Invalid") + "]";
- if (!tcp.ValidChecksum)
- {
- TCPNode.BackColor = TcpChecksumNode.BackColor = System.Drawing.Color.Red;
- TCPNode.ForeColor = TcpChecksumNode.ForeColor = System.Drawing.Color.White;
- }
- else
- {
- TCPNode.BackColor = TcpChecksumNode.BackColor = Tree.BackColor;
- TCPNode.ForeColor = TcpChecksumNode.ForeColor = Tree.ForeColor;
- }
- TcpChecksumNode.Nodes.Add("Correct: " + tcp.ValidTCPChecksum.ToString());
- TCPNode.Nodes.Add(TcpChecksumNode);
- //Urgent
- TCPNode.Nodes.Add("Urgent Pointer: " + tcp.UrgentPointer.ToString() + " [0x" + tcp.UrgentPointer.ToString("X") + "]");
- //Options
- if (tcp.Options.Length > )
- {
- if (TcpOptionsNode == null)
- {
- TcpOptionsNode = new TreeNode();
- }
- TcpOptionsNode.Nodes.Clear();
- TcpOptionsNode.Text = "Options: " + tcp.Options.Length.ToString() + " bytes";
- // [0x" + BitConverter.ToString(tcp.Options).Replace("-", "").PadLeft(12, '0') + "]
- if (tcp.OptionsCollection != null)
- {
- var tmpColl = tcp.OptionsCollection;
- for (int i = ; i < tmpColl.Count; i++)
- {
- TcpOptionsNode.Nodes.Add(tmpColl[i].ToString());
- }
- }
- TCPNode.Nodes.Add(TcpOptionsNode);
- }
- Tree.Nodes.Add(TCPNode);
- AppNode(tcp.PayloadData, tcp.SourcePort, tcp.DestinationPort);
- }
好了接下来让我们看看最终的结果吧
图5 带有数据协议解析的成果图
接下来就是一个关于文件存取的功能,毕竟可以把数据保存下来也是一件很酷的事情,(好吧,我是真的想不出一个好的理由……)
- //打开文件
- private void btnOpen_Click(object sender, EventArgs e)
- {
- OpenFileDialog od = new OpenFileDialog();
- od.Filter = "pcap文件|*.pcap";
- if (od.ShowDialog() == DialogResult.OK)
- {
- Clear();
- ICaptureDevice offDev = new SharpPcap.LibPcap.CaptureFileReaderDevice(od.FileName);
- RawCapture tempPacket;
- offDev.Open();
- while ((tempPacket = offDev.GetNextPacket()) != null)
- {
- packetList.Add(tempPacket);
- ShowDataRows(tempPacket);
- }
- offDev.Close();
- }
- }
- //文件保存
- private void btnSave_Click(object sender, EventArgs e)
- {
- SaveFileDialog sd = new SaveFileDialog();
- sd.Filter = "Pcap文件|*.pcap";
- if (sd.ShowDialog() == DialogResult.OK)
- {
- var offDev = new SharpPcap.LibPcap.CaptureFileWriterDevice(sd.FileName);
- foreach (var i in packetList)
- {
- offDev.Write(i);
- }
- MessageBox.Show("文件保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- }
因为这里我们是直接通过Sharppcap调用winpcap内置的数据包存取方式,这样的好处是,我们可以用Wrieshark等一些其他抓包工具打开这些文件,当然如果你愿意也可以用自己的方式存取,只要保证在内存中可以转为RawCapture的数据列表就可以了
到这里了,制作一个简单的协议分析基本是完成了,这里是代码下载地址:http://yun.baidu.com/s/1dDDELzF
最后是一些个别说明,我们在监听网卡的时候有个模式的选项
- DeviceMode devMode = DeviceMode.Promiscuous;//数据采集模式
这里有连个模式一个常规模式 DeviceMode.Normal 和一个混杂模式 DeviceMode.Promiscuous主要是用于判断在网卡的数据监听方式,混杂模式就是接收所有经过网卡的数据包,包括不是发给本机的包。默认情况下网卡只把发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃。简单的讲,混杂模式就是指网卡能接受所有通过它的数据流,不管是什么格式,什么地址的。事实上,计算机收到数据包后,由网络层进行判断,确定是递交上层(传输层),还是丢弃,还是递交下层(数据链路层、MAC子层)转发。(这段来自百度)
还有一个就是关于超时设定,我们直接在程序中定义为1000ms 也就是1秒,也就是说通过winpcap每个1s向程序推送一次监听到的数据,这个值一定要合理设置,如果设置过短,就可能以为频繁提交数据造成性能开销和引起丢包,而如果过长再回造成界面响应慢,总之自己看情况设定吧
好了今天就写到这里吧,不足之处还请指正,祝你阅读愉快
NetAnalzyer交流群:39753670 (PS 只提供交流平台,群主基本不说话^_^)
[转载请保留作者信息 作者:冯天文 网址:http://www.cnblogs.com/twzy/p/4769797.html ]
NetAnalyzer笔记 之 四. C#版的抓包软件的更多相关文章
- C#版的抓包软件
C#版的抓包软件 [创建时间:2015-09-10 22:37:04] NetAnalyzer下载地址 不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^ NetAnaly ...
- 手机抓包软件Charles安装使用实例 (流媒体播放测试可去下载的时刻检测)
手机抓包软件Charles安装使用实例 浏览:5258 发布日期:2015/07/17 分类:技术分享 关键字: 手机抓包软件 Charles 大胡子的博客Charles安装使用实例 Charle ...
- 如何在Windows系统上用抓包软件Wireshark截获iPhone等网络通讯数据
http://www.jb51.net/os/windows/189090.html 今天给大家介绍一种如何在Windows操作系统上使用著名的抓包工具软件Wireshark来截获iPhone.iPa ...
- Mac用户抓包软件Charles 4.0 破解 以及 抓取Https链接设置
相信大家曾经都是Window的用户,作为前端哪能没有一款抓包工具,抓包工具可以非常便捷的帮助我们分析接口返回报文数据,快速定位问题. 曾经横扫window用户的Fiddler便是我们的挚爱,然而,作为 ...
- CatchPacket网络抓包软件
CatchPacket网络抓包软件 qq 22945088431.技术特点:基于WinPcap库,c# winform2.实现获取机器所有网卡,可任意选择监听3.可以捕获常见网络协议arp dns ...
- 抓包软件PowerSniff开发计划
目前抓包的工具不顺手: (1)smartsniff, minisniffer不支持插件 (2)wireshark,omnipeek插件过于复杂,还有不是要装驱动就是admin权限 打算重写一个,第一个 ...
- 比Wireshark更轻量、更方便的抓包软件:Charles
转:http://blog.csdn.net/lixing333/article/details/42776187 之前写过一篇通过Wireshark进行抓包,分析网络连接的文章<通过WireS ...
- 第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解
第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解 封装模块 #!/usr/bin/env python # -*- coding: utf- ...
- 分享三个USB抓包软件---Bus Hound,USBlyzer 和-USBTrace(转)
源:分享三个USB抓包软件---Bus Hound,USBlyzer 和-USBTrace Bus Hound官方下载地址:http://perisoft.net/bushound/Bus Hound ...
随机推荐
- C#使用jmail组件发送邮件
1.安装 命令行环境下,到jmail.dll所在目录,运行regsvr32 jmail.dll 2.代码 #region 发送邮件 /// <summary> /// 发送邮件 ...
- 简单的通过NSFileManager 存储图片
UIImage *image = [UIImage imageNamed:@"Default.png"]; NSData *data = UIImageJPEGRepresenta ...
- Android的深度定制版阿里云os(Android的山寨)
阿里云OS(YunOS)是阿里巴巴集团的智能手机操作系统,依托于阿里巴巴集团电子商务领域积累的经验和强大的云计算平台,基于LINUX开发. 魅族4阿里yun OS版已上市.[1] 1简介 阿 里云OS ...
- c# WPF 项目优化
业务流程图 优化前后对比: 优化过程: 1. 界面刷新,特别是表格刷新 把ListView.DataContext = DataSet 这些代码替换成以下: public static void S ...
- mvc中使用jsonp进行跨域请求详细说明
在web开发中,如果你要在不同域下进行数据异步请求,会出现一个No ‘Access-Control-Allow-Origin’ header is present on the requested r ...
- Myself
每次过来写博客,一定是遇到什么问题,并且自己还解决不来. 并不是单纯的安静下来书写心得体会-->讨厌之余都有点看不起自己. 闲话少说,回归正题. C语言之于我可是骄傲与挫败并存. 当我做程式遇到 ...
- Eclipse,hadoop2.7.2 hadoop-eclipse-plugin.jar的制作
装好了hadoop后发现有装个eclipse的必要,于是参照文章A(http://www.powerxing.com/hadoop-build-project-using-eclipse/)进行安装, ...
- 【iOS之runtime、runloop】
什么是runtime runtime就是运行时,是系统在运行时的一些动态机制,它是一套底层的API,我们平时编写的OC代码,最终会转换为runtime实现. runtime的作用 可以利用runtim ...
- mybati之day02
今天开始讲解mybatis的第二天内容 一,拼接sql 在mapper.xml中,会多次使用到同一条sql片段,这时为了简便书写,将其定义出来 <sql id="base_sql&q ...
- C#。3 循环
循环:可以反复执行某段代码,直到不满足循环条件为止. 一.循环的四要素:初始条件.循环条件.状态改变.循环体. 1.初始条件:循环最开始的状态. 2.循环条件:在什么条件下进行循环,不满足此条件,则循 ...