Files
drover-go/internal/sboxrun/embed.go
T
root 48097f8671
Build / test (push) Failing after 31s
Build / build-windows (push) Has been skipped
pivot: replace WinDivert engine with embedded sing-box + wintun
After 5+ hours of WinDivert NETWORK-layer NAT-rewrite debugging
(streamdump pattern, SOCKET-layer SYN preemption, lazy PID resolution,
UDP ASSOCIATE relay + manual reinject), Discord voice still wouldn't
connect. The fundamental issue is that WinDivert reinjected UDP
packets don't always reach connect()-bound application sockets — the
demux happens at a layer above the reinject point.

dvp/force-proxy avoids this entirely via DLL injection (above the
kernel demux). We avoid it the other way: embed sing-box, let it run
TUN inbound + per-process routing rule + SOCKS5 outbound. TUN packets
are read by sing-box from kernel as a normal flow; the application
socket sees a normal flow back. No reinject hairpin, no SYN race, no
spoofing concerns.

What this commit does:
  - Drops internal/divert, internal/engine, internal/redirect,
    internal/socks5, internal/procscan, plus cmd/drover/{proxy,
    debugflow}_*.go subcommands (all WinDivert-only).
  - Adds internal/sboxrun — embed sing-box.exe (1.12.25) + wintun.dll
    (0.14.1) via //go:embed, install to %PROGRAMDATA%\Drover\sboxrun\
    with SHA256 verify, generate JSON config from form, spawn as
    subprocess, manage lifecycle.
  - Wires sboxrun into internal/gui/app.go: StartEngine/StopEngine
    now call sboxrun.Engine instead of windivert engine.
  - Fixes Wails binding: StartEngine(cfg) now passes the form config
    (was zero-arg, hit ProxyHost-required validation silently).

Manual test: Discord chat + voice work end-to-end through mihomo
upstream. Yandex Music / svchost / etc continue direct via
process_name routing rule.

Binary grew from 12 MB → 49 MB (37 MB sing-box embedded), but ships
fully self-contained. AV-friendly: wintun is Microsoft-signed, no
DLL injection.

WinDivert work preserved on experimental/windivert branch in case we
ever want to come back to that path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 23:02:12 +03:00

35 lines
1.3 KiB
Go

// Package sboxrun manages an embedded sing-box subprocess that
// implements the actual proxy engine (TUN inbound + per-process
// routing rule + SOCKS5 outbound).
//
// On first Start, the package extracts sing-box.exe + wintun.dll from
// embedded bytes into %PROGRAMDATA%\Drover\sboxrun\ (SHA256-verified),
// generates a JSON config from the GUI's proxy form, and launches
// sing-box as a child process. Stop kills the child cleanly.
package sboxrun
import _ "embed"
//go:embed assets/sing-box.exe
var singBoxExe []byte
//go:embed assets/wintun.dll
var wintunDLL []byte
// SHA256 sentinels for the embedded binaries — verified after extract.
// Update both when bumping versions:
//
// sing-box: https://github.com/SagerNet/sing-box/releases
// wintun: https://www.wintun.net/
const (
// Pinned to 1.12.25 — last release on the 1.12 line that still
// accepts the legacy TUN inbound config layout. 1.13.0 removed
// `address` from inbound and requires migration to rule-based
// `endpoints` — when our config generator gets updated to that
// shape, we can move to 1.13.x.
SingBoxVersion = "1.12.25"
SingBoxSHA256 = "fc7b65219abe8a0166d0b4891a2f7cabcbcc13b3adcf89e6d5913743a67aba10"
WintunVersion = "0.14.1"
WintunSHA256 = "e5da8447dc2c320edc0fc52fa01885c103de8c118481f683643cacc3220dafce"
)