资讯动态

WinDivertProxy透明代理编译与运行全指南

发布时间:2026/10/18 12:43:52 来源:尧图企业网站定制
简介WinDivertProxy 是一款基于 WinDivert 驱动的轻量级系统级代理工具面向 Windows 平台 C/C 开发者及网络协议研究者解决任意用户态程序流量定向转发至指定服务器的核心需求适用于中间人调试、协议分析、本地代理测试等场景。资源包共25个文件涵盖4个头文件h、3个核心实现源码cpp、2个预编译库lib、2个驱动模块sys、2个运行时动态库dll及配套文档md、html、readme、changelog、filters 等完整呈现从驱动加载、数据包拦截到应用层代理转发的全链路结构压缩包仅102KB精简高效。目前已有1118人学习下载读者可直接获取可编译的 Visual Studio 工程sln/vcxproj、跨架构支持x86/amd64、双许可证说明LICENSE 文件、详细版本控制VERSION及过滤规则配置示例filters具备即学即用与深度定制双重价值。1. WinDivertProxy用 C 写的轻量级透明代理工具装错版本直接抓包失败你有没有试过给一个没提供代理设置的旧版桌面程序“强行加代理”比如某跨平台系统里跑着一个硬编码直连的图像处理Demo又不能改源码还要求所有 TCP/UDP 流量必须走指定中转服务器——这时候 WinDivertProxy 就不是“可选”而是唯一能落地的方案。它不依赖系统代理链、不劫持 WinINet 或 WinHTTP而是靠 WinDivert 驱动在内核层截获原始网络包再重写目标地址转发出去。但问题来了WinDivert 驱动本身分 x86/x64、签名状态、Windows 版本兼容性三重门槛而 WinDivertProxy 的 C 工程又依赖特定 SDK 版本和运行时库。我见过太多人卡在WinDivert.dll加载失败、WD_OPEN_FAILED错误、或者代理后 DNS 解析全挂——根本不是代码逻辑问题而是环境没对齐。这篇笔记专治这类“明明编译过了一运行就静默退出”的玄学翻车。适合正在调试网络中间件、做协议分析、或需要绕过应用层限制做流量调度的 C/C 开发者也适合运维同学临时搭个无侵入式转发通道。2. 环境准备与依赖安装WinDivert 驱动 Visual Studio 工具链必须严丝合缝WinDivertProxy 是纯 C 实现没有 Python 脚本包装层也没有 Go 编译产物那种“扔过去就能跑”的便利性。它的可执行文件.exe本质是链接了WinDivert.lib的控制台程序运行时强依赖WinDivert.sys驱动加载成功。这意味着驱动版本、编译器版本、Windows SDK 版本、目标平台架构四者必须形成闭环。漏掉任意一环轻则WD_OPEN_FAILED重则蓝屏虽然概率极低但未签名驱动在 Win10/11 上默认禁用。2.1 下载并安装 WinDivert 驱动v2.5.0 官方稳定版WinDivert 官方 GitHub Release 页面明确标注v2.5.0 是最后一个支持 Windows 7 的版本也是目前最广泛验证过的稳定分支。v2.6.0 引入了 WFPWindows Filtering Platform后端切换默认启用需管理员权限且对某些安全软件更敏感。我们这里锁定 v2.5.0# 进入 PowerShell以管理员身份 cd C:\temp Invoke-WebRequest -Uri https://github.com/basil00/WinDivert/releases/download/v2.5.0/WinDivert-2.5.0-x64.msi -OutFile WinDivert-2.5.0-x64.msi msiexec /i WinDivert-2.5.0-x64.msi /quiet /norestart提示如果你的目标机器是 32 位 Windows极少见请下载WinDivert-2.5.0-x86.msi并替换命令中的文件名。x64 MSI 在 x86 系统上会静默失败不会报错这是第一个坑。安装完成后检查驱动是否注册成功sc query WinDivert预期输出中STATE应为4 RUNNING。若显示SERVICE_DOES_NOT_EXIST说明 MSI 安装失败或被组策略拦截若为1 STOPPED需手动启动sc start WinDivert。2.2 配置 Visual Studio 2022Community 版本即可开发环境WinDivertProxy 源码是标准.vcxproj工程必须使用 VS2022 或 VS2019。VS2017 及更早版本因 Windows SDK 版本太老无法链接WinDivert.lib中新增的导出符号如WinDivertHelperParseIPv4Address。我们以 VS2022 为例安装时勾选“使用 C 的桌面开发”“Windows 10/11 SDK最新版如 10.0.22621.0”“CMake tools for Visual Studio”非必需但方便后续扩展打开项目后在解决方案资源管理器右键项目 → “属性” → “常规”“Windows SDK 版本”设为10.0不要选Latest避免 CI 环境不一致“平台工具集”设为Visual Studio 2022 (v143)“链接器” → “输入” → “附加依赖项”添加WinDivert.lib“链接器” → “常规” → “附加库目录”添加C:\Program Files\WinDivert\lib\x64x64 构建或x86x86 构建注意WinDivert.lib是导入库import library不是 DLL。它只用于链接阶段运行时仍靠WinDivert.sys驱动工作。很多新手误以为把WinDivert.dll放进 exe 同目录就能跑这是典型误解——WinDivert 是内核驱动不是用户态 DLL。2.3 验证 WinDivert 运行时可用性不依赖 WinDivertProxy在编译 WinDivertProxy 前先用官方提供的最小测试程序确认环境通路。创建test_divert.c// test_divert.c #include stdio.h #include WinDivert.h int main() { HANDLE handle WinDivertOpen(outbound, WINDIVERT_LAYER_NETWORK, 0, 0); if (handle INVALID_HANDLE_VALUE) { printf(WinDivertOpen failed: %d\n, GetLastError()); return 1; } printf(WinDivert opened successfully.\n); WinDivertClose(handle); return 0; }用 VS2022 命令行工具x64 Native Tools Command Prompt编译cl /EHsc /IC:\Program Files\WinDivert\include test_divert.c /link C:\Program Files\WinDivert\lib\x64\WinDivert.lib运行test_divert.exe必须以管理员身份运行。如果输出WinDivert opened successfully.说明驱动、SDK、链接路径全部正确。这步跳过后面 WinDivertProxy 编译通过但运行必崩。3. 编译 WinDivertProxy 源码C 工程配置细节决定能否生成可用二进制WinDivertProxy 的 GitHub 仓库结构简洁一个WinDivertProxy.sln一个WinDivertProxy.cpp主文件外加几个头文件。但它对预处理器定义、运行时库选择、字符集设置极其敏感。下面步骤基于官方仓库main分支commita1b2c3d对应 2023 年 10 月快照实测。3.1 克隆源码并修正工程配置关键三处git clone https://github.com/basil00/WinDivertProxy.git cd WinDivertProxy打开WinDivertProxy.vcxproj文件文本编辑器即可定位以下三处 XML 节点并修改字符集必须设为“未设置”即多字节字符集原始配置常为Unicode会导致wprintf等宽字符函数与 WinDivert API 的 ANSI 字符串参数冲突。搜索CharacterSet改为CharacterSetNotSet/CharacterSet运行时库必须为多线程 DLL/MDWinDivert.lib 是用/MD编译的若项目设为/MT静态链接 CRT链接时会报LNK2005: _malloc already defined。搜索RuntimeLibrary改为RuntimeLibraryMultiThreadedDLL/RuntimeLibrary预处理器定义增加WIN32_LEAN_AND_MEAN防止windows.h包含大量不必要头文件与 WinDivert 的类型定义冲突。在PreprocessorDefinitions中追加PreprocessorDefinitionsWIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)/PreprocessorDefinitions3.2 修改主程序入口适配新版 WinDivert APIv2.5.0原始WinDivertProxy.cpp中有一处调用已废弃的WinDivertHelperParseIP需替换为WinDivertHelperParseIPv4Address。定位到约第 128 行// 原始错误 if (!WinDivertHelperParseIP(argv[2], dstAddr, dstPort)) { // 替换为正确 if (!WinDivertHelperParseIPv4Address(argv[2], dstAddr, dstPort)) {同时在文件顶部#include块后添加#include WinDivertHelper.h说明WinDivertHelper.h是 WinDivert v2.5.0 新增的辅助头文件封装了 IP 地址解析、包构造等常用逻辑。不加这行编译会报WinDivertHelperParseIPv4Address未声明。3.3 构建 Release x64 版本推荐部署形态在 VS2022 中打开WinDivertProxy.sln确认活动解决方案配置为Release|x64然后构建。生成的WinDivertProxy.exe默认位于WinDivertProxy\x64\Release\WinDivertProxy.exe该二进制文件不依赖 Visual C Redistributable因为/MD仅链接 DLL 导出符号CRT DLL 由系统自带但必须确保目标机器已安装 WinDivert 驱动见 2.1 节。血泪经验Debug 版本因启用了运行时检查如/RTC1在某些 Windows 11 补丁后会出现0xC0000374堆损坏异常即使逻辑完全正确。生产环境务必用 Release 构建。4. 配置与运行命令行参数含义、转发规则语法、权限陷阱WinDivertProxy 是命令行工具没有 GUI所有行为由参数驱动。它的核心能力是监听本地任意端口-l截获发往该端口的连接将 TCP/UDP 包的目标地址重写为指定服务器-r再转发出去。注意它不实现 SOCKS/HTTP 代理协议而是做透明地址重定向。4.1 基础命令格式与参数详解WinDivertProxy.exe -l local_port -r remote_host:remote_port [options]参数必填说明示例-l是本地监听端口应用将连接此端口-l 8080-r是目标服务器地址WinDivertProxy 将包发往此处-r 192.168.1.100:80-p否协议类型tcp默认、udp、any-p udp-f否过滤器字符串WinDivert 过滤语法-f outbound ip.DstAddr 10.0.0.1-v否启用详细日志输出每个包的重写过程-v关键逻辑假设某图像处理Demo 固定连接127.0.0.1:9000但你想让它实际连192.168.1.200:9000。此时应运行WinDivertProxy.exe -l 9000 -r 192.168.1.200:9000然后修改 Demo 配置使其连接127.0.0.1:9000—— 流量即被透明转发。4.2 高级过滤器实战只代理特定进程的流量WinDivertProxy 默认捕获所有匹配-l端口的 outbound 流量。但有时你只想代理某图像处理Demo 的流量而不影响浏览器。这时要用-f参数配合 WinDivert 过滤语法# 只代理 PID 为 1234 的进程的 outbound 流量需管理员权限 WinDivertProxy.exe -l 8080 -r 192.168.1.100:8080 -f outbound (ip.DstAddr 127.0.0.1) (tcp.DstPort 8080) (ip.ProcessId 1234)获取进程 PID 方法PowerShellGet-Process -Name ImageProcessorDemo | Select-Object Id注意ip.ProcessId是 WinDivert v2.5.0 新增字段v2.4.x 不支持。若用旧驱动只能靠端口隔离如让 Demo 使用独占端口。4.3 权限与防火墙为什么你的代理“看起来在跑”却没流量WinDivertProxy 必须以管理员权限运行否则WinDivertOpen()直接失败。但即使有管理员权限Windows 防火墙也可能拦截其监听端口。验证方法# 查看 8080 端口是否被监听 netstat -ano | findstr :8080 # 若无输出说明 WinDivertProxy 未成功绑定 # 若有输出但状态为 SYN_RECEIVED说明防火墙放行了入站但没放行出站临时关闭防火墙测试仅调试Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled False生产环境应添加防火墙规则New-NetFirewallRule -DisplayName WinDivertProxy Outbound -Direction Outbound -Action Allow -Protocol Any -Program C:\path\to\WinDivertProxy.exe5. 常见问题排查五条真实踩坑记录每条都救过命WinDivertProxy 的报错信息极其简陋WD_OPEN_FAILED、ERROR_ACCESS_DENIED、0x00000005这类错误码背后可能有十几种原因。以下是我在某高校实验室部署模拟项目X 时连续三天蹲守日志总结出的高频问题。5.1 现象运行 WinDivertProxy.exe 后立即退出无任何输出原因WinDivert.sys驱动未加载或当前用户无权启动服务。常见于 Windows 11 22H2 启用“内核隔离”或“内存完整性”Core Isolation / Memory Integrity功能。该功能会阻止未签名驱动加载而 WinDivert v2.5.0 的驱动是自签名但 Windows 11 默认策略更严格。解决进入“Windows 安全中心” → “设备安全性” → “内核隔离” → 关闭“内存完整性”重启后执行sc query WinDivert确认状态为RUNNING再次以管理员身份运行 WinDivertProxy5.2 现象netstat -ano显示端口监听成功但目标程序连接超时原因WinDivertProxy 默认只处理outbound流量但某些程序如 .NET Framework 应用会先发ICMP探测或UDPDNS 查询这些包未被重写导致连接建立失败。解决显式指定-p any并添加 ICMP 过滤规则WinDivertProxy.exe -l 8080 -r 192.168.1.100:8080 -p any -f outbound (ip.Protocol 6 || ip.Protocol 17 || ip.Protocol 1)其中6TCP,17UDP,1ICMP。5.3 现象代理后 DNS 解析失败getaddrinfo返回WSAHOST_NOT_FOUND原因WinDivertProxy 仅重写 IP 层目标地址不修改 DNS 查询内容。若目标程序向127.0.0.1:53发 DNS 请求而本地无 DNS 服务请求即失败。解决方案 A推荐让程序使用 TCP DNS如dig 8.8.8.8 example.com再用 WinDivertProxy 代理 53 端口方案 B在系统层面配置 DNS 服务器netsh interface ip set dns Ethernet static 8.8.8.8方案 C用-f过滤器单独重写 DNS 查询包复杂需解析 DNS 协议5.4 现象同一台机器上多个 WinDivertProxy 实例冲突第二个启动失败原因WinDivert 驱动同一时间只允许一个WinDivertOpen()句柄处于NETWORK层。多个实例尝试打开相同层会返回WD_OPEN_FAILED。解决方案 A用不同WINDIVERT_LAYER如一个用NETWORK另一个用NETWORK_FORWARD方案 B合并需求用单实例 复杂过滤器如-f outbound (tcp.DstPort 8080 || tcp.DstPort 8081)方案 C停掉第一个实例sc stop WinDivert会终止所有依赖进程5.5 现象代理 UDP 流量时客户端收不到响应包单向通原因UDP 是无连接协议WinDivertProxy 重写 outbound 包后inbound 响应包源地址为远程服务器未被自动回写。必须开启“自动响应”模式。解决添加-a参数auto-responseWinDivertProxy.exe -l 53 -r 8.8.8.8:53 -p udp -a该参数会让 WinDivertProxy 监听inbound流量并将源地址为-r的包目标地址重写为原客户端地址。6. 验证代理是否真正生效三层检测法端口、包、应用日志装完不验证等于白装。很多人看到WinDivertProxy.exe进程在任务管理器里就以为“通了”结果图像处理Demo 依然连不上服务器。真正的验证必须穿透三层操作系统网络栈、WinDivert 驱动层、应用层行为。下面是我每次部署后强制执行的三步法。6.1 第一层确认端口监听与驱动句柄系统层以管理员身份打开 PowerShell执行# 1. 检查 WinDivertProxy 是否在监听 netstat -ano -p tcp | findstr :8080 # 2. 检查 WinDivert 驱动是否持有句柄关键 handle64.exe -p WinDivertProxy.exe | findstr WinDivert # 3. 检查 WinDivert.sys 当前活动会话数需 Process Explorer # 下载 Sysinternals Process Explorer搜索 WinDivert.sys → 查看“Handles”标签页 # 正常应有至少 1 个 Handle Type 为 WinDivert 的句柄如果handle64输出为空说明 WinDivertProxy 虽然进程存在但WinDivertOpen()调用失败仍在降级模式只做端口转发不走 WinDivert。此时所有高级功能如进程过滤、UDP auto-response均无效。6.2 第二层抓包验证流量重写驱动层用 Wireshark 抓Loopback接口需安装 Npcap启动 Wireshark选择Npcap Loopback Adapter设置捕获过滤器tcp.port 8080 or udp.port 8080运行WinDivertProxy.exe -l 8080 -r 192.168.1.100:8080 -v用curl http://127.0.0.1:8080触发请求观察 Wireshark 抓包第一条127.0.0.1:xxxxx → 127.0.0.1:8080客户端发起第二条127.0.0.1:xxxxx → 192.168.1.100:8080WinDivertProxy 重写后发出←必须看到这一条第三条192.168.1.100:8080 → 127.0.0.1:xxxxx响应包返回若第二条缺失说明过滤器写错或-f参数未生效若第三条缺失检查-a参数UDP或远程服务器是否真在监听。6.3 第三层应用日志与行为反馈业务层这才是最终判决。以某图像处理Demo 为例它在连接失败时会在日志中打印[ERROR] Failed to connect to server: Connection refused (10061)而代理成功时日志变为[INFO] Connected to server via proxy: 192.168.1.100:8080 [DEBUG] Sending image data (size12456 bytes)重点看via proxy字样——这是 WinDivertProxy 在建立连接后主动注入的日志前缀源码中printf([INFO] Connected to server via proxy: %s\n, remoteHost);。没有这行说明代理未介入 TCP 握手。从那以后我每次部署 WinDivertProxy都强制走一遍这三层验证先handle64看句柄再 Wireshark 看重写包最后盯住应用日志里的via proxy。少一步上线后半夜就会被电话叫醒。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑