experimental/windivert: P2.1+P2.2 with WinDivert NETWORK+SOCKET layers
WIP snapshot before pivot to sing-box+TUN. Reached: - TCP redirect via streamdump pattern (swap+Outbound=0+reinject) - SOCKET layer for SYN-stage flow detection (avoids FLOW Establish-too-late race) - Lazy PID→name resolution (catches Update.exe inside procscan tick) - UDP forward via SOCKS5 UDP ASSOCIATE relay + manual reinject - Result: chat works, voice times out (Discord IP discovery / RTC handshake fails) Reason for pivot: WinDivert NAT-reinject pattern has subtle layer-3 semantics issues that DLL-injection / TUN-based proxies sidestep entirely. Going with embedded sing-box + wintun as the engine — proven path for Discord voice through SOCKS5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,8 @@ import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// DriverPaths records where the WinDivert binaries landed after install.
|
||||
@@ -56,9 +58,34 @@ func installDriverInto(dst string) (*DriverPaths, error) {
|
||||
if err := writeIfDifferent(dllPath, winDivertDll, WinDivertDllSHA256); err != nil {
|
||||
return nil, fmt.Errorf("install WinDivert.dll: %w", err)
|
||||
}
|
||||
// imgk/divert-go's LazyDLL("WinDivert.dll") relies on the standard
|
||||
// Windows DLL search path. Our extracted binaries live in
|
||||
// %PROGRAMDATA%\Drover\windivert\ which isn't on that path by
|
||||
// default. SetDllDirectoryW prepends our directory so the lazy
|
||||
// load resolves it. Must be called BEFORE the first divert.Open.
|
||||
if err := setDllDirectory(dst); err != nil {
|
||||
return nil, fmt.Errorf("SetDllDirectory %q: %w", dst, err)
|
||||
}
|
||||
return &DriverPaths{SysPath: sysPath, DllPath: dllPath}, nil
|
||||
}
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procSetDllDirectoryW = kernel32.NewProc("SetDllDirectoryW")
|
||||
)
|
||||
|
||||
func setDllDirectory(path string) error {
|
||||
p, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r1, _, e1 := syscall.SyscallN(procSetDllDirectoryW.Addr(), uintptr(unsafe.Pointer(p)))
|
||||
if r1 == 0 {
|
||||
return e1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeIfDifferent compares the existing file's SHA256 to the expected
|
||||
// hash; if it matches, no-op. Otherwise overwrite atomically and verify
|
||||
// the resulting on-disk SHA matches expected.
|
||||
|
||||
Reference in New Issue
Block a user