本文简要介绍windows下驱动层kit开发包windivert的改包操作。
windivert官网:windivert官网资料
下载源码后,双击 *.vcxproj工程文件或者拖入vs,即可打开相应的工程,点击build即可完成项目编译。
windivert核心代码运行于驱动层,但是也提供了应用层的接口,通过这些应用层接口,开发者可以实现对windows平台上数据包的任意修改。不过需要注意的是:windivert只能修改ip层以及以后的tcp层(udp层)和数据部分的内容,而不能修改mac层以及相对应的链路层。wireshark中winpcap开发包可以修改数据包中的任意内容(包括mac层),但是windivert是用修改后的数据包替换掉原来的包,修改后原来的数据包不见了,而wireshark是修改后原来的数据包的发送不受影响,当然修改后的数据包也可以发送出去。从这点上看,两个开发包各有优劣。
代码如下。
例子代码主要是将dns的目的ip地址改为了8.8.8.8,可以抓包看到修改后的数据包。数据包发送前被修改,但是并不需要修改接收的包的ip地址。
注意:
- 工程项目同目录下要有windivert64.sys和windivert.dll。而且位数要匹配,比如,64位程序需要64位驱动windivert64.sys和64位windivert.dll。
- #include "windivert.h"要放在#include "windivert_device.h"之前。
#include <windows.h>
#include <stdio.h>
#include "./windivert_device.h"
#include "./windivert.h"
#pragma comment(lib,"./windivert.lib")
#pragma comment(lib,"windivert.lib")
#ifdef WINDIVERT_KERNEL
#undef WINDIVERT_KERNEL
#endif
int mainwork() {
int result = 0;
char* packet = malloc(0x10000);
int packetLen = 0x10000;
WINDIVERT_ADDRESS addr;
UINT32 recvSize = 0;
PWINDIVERT_IPHDR iphdr;
WINDIVERT_TCPHDR tcphdr;
WINDIVERT_UDPHDR udphdr;
// 打开过滤对象
HANDLE mHandle = WinDivertOpen("udp.DstPort == 53", //过滤规则
WINDIVERT_LAYER_NETWORK, //过滤的层
0, 0);
if (mHandle == INVALID_HANDLE_VALUE) //开启过滤对象,可以通过错误码识别错误
{
result = GetLastError();
return; //error
}
while (1)
{
result = WinDivertRecv(mHandle, // windivert对象
packet, packetLen, //char* packet和buff长度
&recvSize, // int 实际读取的数据长度
&addr);
// 接收过滤到的网络包内容
if (result == 0) //WINDIVERT_ADDRESS
{
result = GetLastError();
break;
// error
}
// 网络包头部解析
result = WinDivertHelperParsePacket(packet, recvSize,
&iphdr, NULL, NULL, NULL, NULL,
&tcphdr, &udphdr, NULL, NULL, NULL, NULL);
if (result == 0)
{
result = GetLastError();
break;
// error
}
*(DWORD*)(packet + 16) = 0X08080808;
// 计算校验和
result = WinDivertHelperCalcChecksums(packet, packetLen, &addr, 0);
// 把修改后的包发送出去
result = WinDivertSend(mHandle, packet, packetLen, &recvSize, &addr);
if (result == 0)
{
result = GetLastError();
break;
// send error
}
}
}
int main(int argc, char** argv) {
mainwork();
return 0;
}
wireshark同时开启抓包,截图如下: