内容纲要

WFP (Windows Filtering Platform) 在 vista 以上平台提供了一组 API 用来对应 TCP 协议栈,注册不通的层级,可以访问不同层的数据。WinDivert 封装了 WFP 的 API,提供了 .sys 和 代理 dll。用户端只需与 dll 交互即可完成包捕获和包注入。WinDivert 也可以注册不通的层。

WinDivert 提供的层:

/*
* 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;

在 WINDIVERT_LAYER_NETWORK 和 WINDIVERT_LAYER_NETWORK_FORWARD 层中并不能访问关联的进程 Id,其他层可以访问进程 Id。可以根据 ip.src 和 tcp.SrcPort 来关联到 WINDIVERT_LAYER_SOCKET 层的 processId。

在 C++ 中可以声明一个 map ,ip.src 和 tcp.SrcPort 做 key,value 放一个 sessiont 对象, session 对象放的是本次连接会话的关联的 ip.dst、tcp.DstPort、proxy.ip、proxy.port、processId、processName。 proxy.ip 和 proxy.port 从配置文件读取。如果是加速器的话,从远程拉取某个游戏的配置就行。

typedef struct {
UINT32 ip_src,
UINT32 ip_dst,
UINT16 tcp_src_port,
UINT16 tcp_dst_port,
UINT32 proxy_ip,
UINT16 proxy_port,
UINT32 processId,
wchar_t processName[MAX_PATH + 1]
} Session;

注册 WinDivert 不同的层级,在不同的状态下填充 Session 结构体。 WINDIVERT_LAYER_NETWORK 优先级最高,先填充 processId 和 processName(本地游戏 EXE 路径)。在 WINDIVERT_LAYER_NETWORK 层下修改目的 IP 和端口到 proxy 进程开启的端口,不直接转发到远程 proxy,直接转发到本地 proxy,相当于 shadowsocks 的 sslocal, sslocal 再转发到 ssremote。这相当于原始协议的转发。

WinDivert 的数据包处理要注册在多个线程上,一个用于出站,修改出站端口到 proxy 端口,一个用于入站,修改 proxy ip 和 port 到原始请求的 ip 和 port。

TCP 状态标记

[FIN]
[RST]
[URG]
[SYN]
[PSH]
[ACK]

 

对于Windows 7 / Vista,您可以使用Windows过滤平台(WFP)API进行简单的数据包过滤,类似于使用iptables可以实现的过滤。然而,API有点冗长。

对于更复杂的过滤,例如说有效负载解析/检查的URL过滤,您需要(1)编写设备驱动程序(如WFP标注驱动程序),或(2)使用可将数据包转移给用户的第三方程序包模式应用程序。

对于后者,有WinDivert(GLPv3)和WinpkFilter(商业许可证)。这两个包都是C / C ++,因此您需要编写适当的MatLab绑定。 披露:我是WinDivert的作者。

警告技术:像Winpcap这样的软件包不会丢弃数据包,因为它使用的驱动程序类型(确切地说是NDIS协议驱动程序)。协议潜水员只能看到数据包的副本,无法阻止原始数据包。为此,他们需要将Winpcap驱动程序重新实现为NDIS IM或LWF驱动程序。

隧道技术(Overlay Networks)

隧道技术是把封包(IP)再通过传输层(TCP/UDP)传输,在远程再解包的过程,通常用于 VPN。新型的 WireGuard VPN 协议就工作在 UDP 层,VXLAN 也工作在 UDP 层。WireGuard 可以做到手机端 wifi 热点切换无感知。

WireGuard 官方并没有出一个 windows 下的客户端, https://github.com/TunSafe/TunSafe 提供了一个。TunSafe 比 OpenVpn 代码大大减少,且支持 payload 混淆, 速度也快很多。 TunSafe 使用了 OpenVpn 提供的 windows 下 tap 驱动来发包,应用层的内核虽然流程复杂,但是封装的接口简单,便于修改二次开发。

参考

  • https://github.com/basil00/Divert
  • https://reqrypt.org/windivert-doc.html
  • https://github.com/TunSafe/TunSafe

发表评论

电子邮件地址不会被公开。 必填项已用*标注