介绍

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++版)相关推荐

  1. charles电脑手机抓包上不了网的细节设置

    charles电脑手机抓包上不了网的细节设置 >>>每次用charles抓包时,都会出现电脑或者手机上不了网的问题.设置好后一换电脑又得一番麻烦的设置.今天就总结下细节方面的设置,不 ...

  2. LiveGBS流媒体服务平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包

    LiveGBS流媒体服务平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包 1.第一步:抓包工具准备 1.1.Linux 1.2.windows 2.第二步:找到级联的上级i ...

  3. 模拟弱网,和弱网工具的使用对比 facebook ATC 和 clumsy

    模拟弱网,和弱网工具的使用对比 针对弱网测试工具(facebook ATC,clumsy等)的部署和测试对比,实现模拟弱网测试的部署和测试实施.并对当前XXXX项目进行基础测试,以及在弱网情况,XXX ...

  4. 通过windows官网工具制作win10启动盘并安装win10系统

    通过windows官网工具制作win10启动盘并安装win10系统 1.准备一个至少8G的U盘或者内存卡,制作时需要格式化,请提前备份U盘内容以及非系统盘资料. 2.插上U盘,进入win10官网,点击 ...

  5. Android抓包 - Okhttp混淆导致Hook工具失效

    Android抓包 - Okhttp混淆导致Hook工具失效 本文部分内容参考 loco 大佬的文章,同时借用loco大佬文章中的2个APP(有无混淆). 微信公众号: yeshengit 这篇文章的 ...

  6. iOS开发之弱网测试

    前言 有时候我们需要对APP进行捉包.弱网测试等等,相信大家对弱网测试并不陌生,下面记录一下. 一.捉包 分享之前写个的两篇文章: 抓包工具Charles下载以及简单使用 iOS Charles捉取正 ...

  7. 青龙面板小黄鸟抓包软件,断网模块,vmos虚拟机

    有的友友学习会怎么抓包,但是没有抓包软件今天我就给友友分享一下这三个软件 主要用于安卓抓包的 断网模块下载地址 小黄鸟抓包软件 vmos虚拟机下载地址

  8. Fiddler抓包指南:结合Proxifier工具

    本文介绍如何使用Fiddler抓取HTTP和HTTPS协议的包,同时还介绍了如何结合Proxifier工具来处理Filddler无法抓取到包的情况. 一.HTTP基本抓包 Fiddler官网下载安装: ...

  9. http抓包神器:Charles for Mac 特别版v4.6

    Charles for mac功能强大且功能齐全的Web调试代理和监视实用程序,Charles mac在您的计算机上运行,以帮助您更轻松,更快地测试桌面和Web应用程序,Charles帮助您密切注意计 ...

最新文章

  1. AppStore审核2.1被拒大礼包过审经历
  2. DELL服务器安装过程中出现的ERROR及解决方案
  3. C语言通过链表指针删除链表节点的算法(附完整源码)
  4. Win的cmd中文乱码
  5. python实现连续数列相加_技术 | Python经典面试题解析实现斐波那契数列
  6. python文件图标变成小电脑_手把手教你给Python程序写图形界面,并且打包成exe文件-exe文件...
  7. 【NOI2007】货币兑换【任意坐标斜率优化】【CDQ分治】
  8. html用转义字符画菱形,JavaScript生成字符画(ASCII Art)
  9. 懒加载Lazy Loading
  10. Luogu P2664 树上游戏 dfs+树上统计
  11. oracle --union和union all
  12. 配置标准IP ACL实验
  13. 山地车中轴进水表现_4种自行车中轴的拆卸和保养方法
  14. android中Uri.parse()用法,调用电话短信浏览器等
  15. error:R3InjectorError(AppModule)[HttpClient -> HttpClient -> HttpClient]:
  16. axis2之webservice
  17. ZYNQ图像处理|静态图像通路|VDMA寄存器、DDR内存操作
  18. 100个Myeclipse6.5免费注册码
  19. Imagine-快速的图片压缩工具
  20. 上学期c语言作业答案,C语言作业答案4

热门文章

  1. BERGER LAHR施耐德运动控制器维修BLC382TCNUC1S概述
  2. 60+富有创意的宣传册设计
  3. 网易云信(验证码短信接口接入)
  4. CONTRIBUTING
  5. java 姓名替换,java姓名星号替换
  6. api 定位 微信小程序 精度_微信小程序JavaScript SDK
  7. 非985大学生, 你和别人的差距在哪里? (中国青年报03-24)
  8. “杭州最惨创业者”事件初步法律分析
  9. java判断时间是否在时间区间里(适用格式HH:mm)
  10. 第六章函数与宏定义实验报告(后半部分)