Mar18

【原创】使用pcap.net在windows下实现自定义的抓包分析工具

Author: leeon  Click: 12920   Date: 2014.03.18 @ 22:10:18 pm Category: 网络

      最近需要在windows平台下通过抓包分析工具把http的GET请求地址抓出来,其实在很多应用场景下我们都需要这样类似的工具,比如httpwatch,fiddler,chrome,firefox下的开发者工具,这些都必须绑定到浏览器才能使用,如果我们需要一个可以自定义的抓包分析工具来分析这些http get和post请求,那么我们该怎么做呢? 搜索了一番有python在windows下抓包分析的实现,也有c++原生使用winpcap库来使用,python的兼容性不好不方便部署使用,c++的开发难度系数较大,维护成本较高,最后发现有国外有人介绍说winpcap在c#的封装实现不错,果断去官方网站 http://pcapdotnet.codeplex.com/ 下载了开发包来学习。

     官方文档说要装.net framework 4.0 和winpcap 4.1.2 其实在自己的开发环境中我选用的是.net framework 4.5版本和winpcap 4.1.3 都是可以兼容的。下载的开发包中已经涵盖了官网上介绍的一些示例代码。只要在vs中打开工程进行编译生成就好了。

    鉴于官方网站上示例代码非常有限,而且提供的api手册比较粗糙,导致撸主在官网论坛查阅了很长时间那陈旧的帖子内容才得到一些启示。撸主想实现的功能非常简单,就是想不通过浏览器附带的http抓包工具来实现底层的http抓包过滤,例如wireshark中的过滤规则一样可以把我所访问的所有http请求都过滤出来。这样我们只要启用这个小工具,就可以在底层上实现透明抓包,任何通过本机网卡访问的http请求都不会被放过! 废话不多说,放上实现代码:


using System;
using System.Collections.Generic;
using PcapDotNet.Core;
using PcapDotNet.Packets;
using PcapDotNet.Packets.IpV4;
using PcapDotNet.Packets.Transport;
using PcapDotNet.Packets.Http;
using System.Text;

namespace InterpretingThePackets
{
class Program
{
static void Main(string[] args)
{
// Retrieve the device list from the local machine
IList allDevices = LivePacketDevice.AllLocalMachine;

if (allDevices.Count == 0)
{
Console.WriteLine("No interfaces found! Make sure WinPcap is installed.");
return;
}

// Print the list
for (int i = 0; i != allDevices.Count; ++i)
{
LivePacketDevice device = allDevices[i];
Console.Write((i + 1) + ". " + device.Name);
if (device.Description != null)
Console.WriteLine(" (" + device.Description + ")");
else
Console.WriteLine(" (No description available)");
}

int deviceIndex = 0;
do
{
Console.WriteLine("Enter the interface number (1-" + allDevices.Count + "):");
string deviceIndexString = Console.ReadLine();
if (!int.TryParse(deviceIndexString, out deviceIndex) ||
deviceIndex < 1 || deviceIndex > allDevices.Count)
{
deviceIndex = 0;
}
} while (deviceIndex == 0);

// Take the selected adapter
PacketDevice selectedDevice = allDevices[deviceIndex - 1];

// Open the device
using (PacketCommunicator communicator =
selectedDevice.Open(65536, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode
1000)) // read timeout
{
// Check the link layer. We support only Ethernet for simplicity.
if (communicator.DataLink.Kind != DataLinkKind.Ethernet)
{
Console.WriteLine("This program works only on Ethernet networks.");
return;
}

// Compile the filter
using (BerkeleyPacketFilter filter = communicator.CreateFilter("ip and tcp and dst port 80"))
{
// Set the filter
communicator.SetFilter(filter);
}

Console.WriteLine("Listening on " + selectedDevice.Description + "...");

// start the capture
communicator.ReceivePackets(0, PacketHandler);
}
}

// Callback function invoked by libpcap for every incoming packet
private static void PacketHandler(Packet packet)
{
if (packet == null) { return; }
if (packet.Ethernet == null) { return; }
if (packet.Ethernet.IpV4 == null) { return; }
if (packet.Ethernet.IpV4.Tcp == null) { return; }
if (packet.Ethernet.IpV4.Tcp.Http == null) { return; }
try
{
HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http;

if (http.IsRequest && http.IsValid) {
String msg = http.Decode(Encoding.UTF8).Split('\n')[0];
if (msg.StartsWith("GET ") || msg.StartsWith("POST "))
{
Console.WriteLine(msg);
}
}
}
catch (Exception e)
{

}
}
}
}


这里的实现是过滤出访问远端服务器80端口的tcp请求报文,同时截取http头部是get或者post开头的单行字符串。这样我们就可以捕获所有http协议访问的url了。



TAG:   winpcap csharp pcapdotnet

    评论
    • 提交

    分类

    标签

    归档

    最新评论

    Abyss在00:04:28评论了
    Linux中ramdisk,tmpfs,ramfs的介绍与性能测试
    shallwe99在10:21:17评论了
    【原创】如何在微信小程序开发中正确的使用vant ui组件
    默一在09:04:53评论了
    Berkeley DB 由浅入深【转自架构师杨建】
    Memory在14:09:22评论了
    【原创】最佳PHP框架选择(phalcon,yaf,laravel,thinkphp,yii)
    leo在17:57:04评论了
    shell中使用while循环ssh的注意事项

    我看过的书

    链接

    其他

    访问本站种子 本站平均热度:8823 c° 本站链接数:1 个 本站标签数:464 个 本站被评论次数:94 次