使用WinDivert抓包,开发windows弱网工具(C++版)
介绍
WinDivert最简单的接入教程,以及使用的一些心得
目录
- 介绍
- 前言
- 一、WinDivert是什么?
- 二、使用步骤
- 1.下载库
- 2.接入项目
- 3.使用
- 测试:
- 总结
前言
-最近开发的实时战斗游戏,在国外某国测试了,有很多其他国家的也想体验,通过梯子来到了我们游戏,我们发现他们在直播玩的时候,拉扯很严重,延迟较高,我们当时在这种极度弱网下表现并不是很好,因此打算找一个弱网工具模拟这种情况。经过分析,我发现主要原因在于UDP包的堆积,然后大量同时到达导致。
曾经用过一个叫NEWT(Network Emulator for Windows Toolkit)模拟,效果挺好,但是只支持win7,现在我们公司以及全部普及win10了,win10下只能断网,但是再难找到这么好用的工具了,因此,打算自己造轮子,做一个弱网工具。那么难点主要在于怎么捕获通过windows的包?WinDivert就是一个最好的工具
提示:以下是本篇文章正文内容,下面案例可供参考
一、WinDivert是什么?
WinDivert是一个功能强大的用户模式capture/sniffing/modification/blocking/re-injection工具,适用于Windows 7、Windows 8和Windows 10。WinDivert可用于实现用户模式包过滤器、包嗅探器、防火墙、NAT、VPN、隧道应用程序等,而无需编写内核模式代码。
二、使用步骤
由于还没上升到需要改源码的程度,因此以下为直接使用库的方法,并没有去自己编译源码,后续如果有需求可以自己编译
1.下载库
主页地址:https://reqrypt.org/windivert.html
进入网站以后点击如下,直接下载WinDivert-2.2.0-A.zip,当然你也可以下载源码查看,编译
下载解压后内容如下
2.接入项目
代码如下(示例):
新建一个C++控制台应用程序
在项目目录下新增Include文件夹Src文件夹与Libs文件夹
在项目中包含Include文件夹Src文件夹,方法如下:
在链接器中包含Libs文件夹:
- 我这里使用x64进行测试,因此把x64/WinDivert.lib 拷贝到Libs文件夹,然后在将Lib库包含在链接器中:
- 我这里选择在64位下测试,因此把调试模式设置问debug x64:
- 预先生成一次,会在项目指定的生成目录下生成x64文件,以及.exe,如下,
- 把对应的x64/WinDivert.dll,x64/WinDivert64.sys拷贝到该执行目录下:
- 把include/windivert.h 放到前面配置的include目录,然后在项目中把此文件包含在项目,配置完成。
3.使用
先包含头文件:
#include "windivert.h"
创建一个带网络包筛选器的WinDivert handle:
HANDLE divertHandle = WinDivertOpen("inbound and udp and ip.SrcAddr == 10.234.36.130", WINDIVERT_LAYER_NETWORK, 1, 0);if (divertHandle == INVALID_HANDLE_VALUE){std::cout << "divertHandle == INVALID_HANDLE_VALUE : error " << GetLastError();return 0;}
第一个参数筛选方式,这里有很多筛选方式,用的最多的就是:
- inbound / outbound :表示处理收包 跟发包
- udp / tcp 筛选不同的传输层协议
- ip.* ip地址筛选
- udp.* / tcp.* 针对某一传输层进行更具体的筛选
第二个参数,枚举类型,layer选择如下:
/*
* WinDivert layers.
*/
typedef enum
{WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */WINDIVERT_LAYER_NETWORK_FORWARD = 1,/* Network layer (forwarded packets) */WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
第三个参数,优先级,用于定义多个handle,值越大,优先级越高:
第四个参数,flag,可以对抓取的包进行更精确的控制,暂不详讲:
/*
* WinDivert flags.
*/
#define WINDIVERT_FLAG_SNIFF 0x0001
#define WINDIVERT_FLAG_DROP 0x0002
#define WINDIVERT_FLAG_RECV_ONLY 0x0004
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
#define WINDIVERT_FLAG_SEND_ONLY 0x0008
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
#define WINDIVERT_FLAG_NO_INSTALL 0x0010
#define WINDIVERT_FLAG_FRAGMENTS 0x0020
更多细节,可以下载源码,通过看examples理解:
这里有一些坑,可以通过打印GetLastError() 的错误号处理:
可以对照错误,知道为什么,我遇到的主要是要管理员权限,错误号5,可以通过使用用管理员权限运行VS解决。还有就是第一个参数筛选方式,错误号87
接下来接收捕获的数据的class:
#define DIVERT_MAX_PACKETSIZE 0xFFFF
#define DIVERT_INIT_PACKETSIZE 128
class DivertPacket
{
public:DivertPacket(){Reset();}~DivertPacket(){}char packet[DIVERT_MAX_PACKETSIZE];UINT packetLength;WINDIVERT_ADDRESS addr;void Reset(){packetLength = 0;memset(packet, 0, DIVERT_MAX_PACKETSIZE);}
};
数据处理的代码:
DivertPacket* dPacket = new DivertPacket();while (true){if (WinDivertRecv(divertHandle, dPacket->packet, DIVERT_MAX_PACKETSIZE, &dPacket->packetLength, &dPacket->addr)){/*PWINDIVERT_IPHDR ppIpHdr;PWINDIVERT_UDPHDR udpHDR;WinDivertHelperParsePacket(dPacket->packet, dPacket->packetLength, &ppIpHdr, nullptr, nullptr, nullptr, nullptr, nullptr, &udpHDR, nullptr, nullptr, nullptr, nullptr);if (ppIpHdr != NULL && udpHDR != NULL){memset(buffer, 0, 64);WinDivertHelperFormatIPv4Address(ppIpHdr->SrcAddr, buffer, 64);spdlog::debug("ip src", buffer);memset(buffer, 0, 64);WinDivertHelperFormatIPv4Address(ppIpHdr->DstAddr, buffer, 64);spdlog::debug("ip dst", buffer);spdlog::debug("port srt", to_string(udpHDR->SrcPort));spdlog::debug("port dst", to_string(udpHDR->DstPort));}*/WinDivertHelperCalcChecksums(dPacket->packet, dPacket->packetLength, &dPacket->addr, 0);if (!WinDivertSend(divertHandle, dPacket->packet, dPacket->packetLength, NULL, &dPacket->addr)){// Handle send errorstd::cout << "WinDivertSend : error " << GetLastError();continue;}spdlog::debug("packege len : {}", dPacket->packetLength);spdlog::debug("Timestamp : {}", dPacket->addr.Timestamp);spdlog::debug("now : {}", GetTicks());//std::cout <<"packege len : " << dPacket->packetLength <<"\n";memset(dPacket, 0, DIVERT_MAX_PACKETSIZE);}else{std::cout << "WinDivertRecv : error " << GetLastError();continue;}Sleep(10);}
spdlog可以看我之前一篇文章,接入的c++日志库,注释部分为具体解析包的代码
WinDivertRecv 与 WinDivertSend 分别为捕获与再次转发包的代码。
具体我们对包的处理还在做,属于机密就不公开了,思路是:链表保存捕获的数据包,增加一个多模块的处理,通过后的,转发给本地应用或者发出,否则保存直到满足每一个module的条件了。
更加详细的说明可以去官方查看:
官方:https://reqrypt.org/windivert.html
github:https://github.com/basil00/Divert/tree/master/examples
文档:file:///E:/study/Document/WinDivert-2.2.0-A/WinDivert-2.2.0-A/doc/WinDivert.html
测试:
修改筛选器,14.215.177.38 是百度的网址:
HANDLE divertHandle = WinDivertOpen("inbound and ip.SrcAddr == 14.215.177.38", WINDIVERT_LAYER_NETWORK, 1, 0);
然后我们在cmd中:ping 14.215.177.38
打印如下:
总结
本文主要用于学习使用,具体的业务逻辑可以根据自己的需求去做,接入流程挺容易出问题的,欢迎留言,看到定会回复。
使用WinDivert抓包,开发windows弱网工具(C++版)相关推荐
- charles电脑手机抓包上不了网的细节设置
charles电脑手机抓包上不了网的细节设置 >>>每次用charles抓包时,都会出现电脑或者手机上不了网的问题.设置好后一换电脑又得一番麻烦的设置.今天就总结下细节方面的设置,不 ...
- LiveGBS流媒体服务平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包
LiveGBS流媒体服务平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包 1.第一步:抓包工具准备 1.1.Linux 1.2.windows 2.第二步:找到级联的上级i ...
- 模拟弱网,和弱网工具的使用对比 facebook ATC 和 clumsy
模拟弱网,和弱网工具的使用对比 针对弱网测试工具(facebook ATC,clumsy等)的部署和测试对比,实现模拟弱网测试的部署和测试实施.并对当前XXXX项目进行基础测试,以及在弱网情况,XXX ...
- 通过windows官网工具制作win10启动盘并安装win10系统
通过windows官网工具制作win10启动盘并安装win10系统 1.准备一个至少8G的U盘或者内存卡,制作时需要格式化,请提前备份U盘内容以及非系统盘资料. 2.插上U盘,进入win10官网,点击 ...
- Android抓包 - Okhttp混淆导致Hook工具失效
Android抓包 - Okhttp混淆导致Hook工具失效 本文部分内容参考 loco 大佬的文章,同时借用loco大佬文章中的2个APP(有无混淆). 微信公众号: yeshengit 这篇文章的 ...
- iOS开发之弱网测试
前言 有时候我们需要对APP进行捉包.弱网测试等等,相信大家对弱网测试并不陌生,下面记录一下. 一.捉包 分享之前写个的两篇文章: 抓包工具Charles下载以及简单使用 iOS Charles捉取正 ...
- 青龙面板小黄鸟抓包软件,断网模块,vmos虚拟机
有的友友学习会怎么抓包,但是没有抓包软件今天我就给友友分享一下这三个软件 主要用于安卓抓包的 断网模块下载地址 小黄鸟抓包软件 vmos虚拟机下载地址
- Fiddler抓包指南:结合Proxifier工具
本文介绍如何使用Fiddler抓取HTTP和HTTPS协议的包,同时还介绍了如何结合Proxifier工具来处理Filddler无法抓取到包的情况. 一.HTTP基本抓包 Fiddler官网下载安装: ...
- http抓包神器:Charles for Mac 特别版v4.6
Charles for mac功能强大且功能齐全的Web调试代理和监视实用程序,Charles mac在您的计算机上运行,以帮助您更轻松,更快地测试桌面和Web应用程序,Charles帮助您密切注意计 ...
最新文章
- AppStore审核2.1被拒大礼包过审经历
- DELL服务器安装过程中出现的ERROR及解决方案
- C语言通过链表指针删除链表节点的算法(附完整源码)
- Win的cmd中文乱码
- python实现连续数列相加_技术 | Python经典面试题解析实现斐波那契数列
- python文件图标变成小电脑_手把手教你给Python程序写图形界面,并且打包成exe文件-exe文件...
- 【NOI2007】货币兑换【任意坐标斜率优化】【CDQ分治】
- html用转义字符画菱形,JavaScript生成字符画(ASCII Art)
- 懒加载Lazy Loading
- Luogu P2664 树上游戏 dfs+树上统计
- oracle --union和union all
- 配置标准IP ACL实验
- 山地车中轴进水表现_4种自行车中轴的拆卸和保养方法
- android中Uri.parse()用法,调用电话短信浏览器等
- error:R3InjectorError(AppModule)[HttpClient -> HttpClient -> HttpClient]:
- axis2之webservice
- ZYNQ图像处理|静态图像通路|VDMA寄存器、DDR内存操作
- 100个Myeclipse6.5免费注册码
- Imagine-快速的图片压缩工具
- 上学期c语言作业答案,C语言作业答案4
热门文章
- BERGER LAHR施耐德运动控制器维修BLC382TCNUC1S概述
- 60+富有创意的宣传册设计
- 网易云信(验证码短信接口接入)
- CONTRIBUTING
- java 姓名替换,java姓名星号替换
- api 定位 微信小程序 精度_微信小程序JavaScript SDK
- 非985大学生, 你和别人的差距在哪里? (中国青年报03-24)
- “杭州最惨创业者”事件初步法律分析
- java判断时间是否在时间区间里(适用格式HH:mm)
- 第六章函数与宏定义实验报告(后半部分)