From 9dc10544b9ff62d8c014a601d76a0100bbecaca8 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Mon, 5 Jun 2023 03:53:51 -0400 Subject: [PATCH] Embed wintun inside of the Windows binary Burrow writes the driver to a temporary file and then loads it. --- Cargo.lock | 2 ++ tun/Cargo.toml | 2 ++ tun/src/windows/mod.rs | 25 +++++++++++++++---------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0b913e..c779b81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1299,12 +1299,14 @@ dependencies = [ "anyhow", "bindgen", "fehler", + "lazy_static", "libc", "libloading", "nix", "reqwest", "socket2", "ssri", + "tempfile", "tokio", "widestring", "windows", diff --git a/tun/Cargo.toml b/tun/Cargo.toml index f054eb8..e0a5e45 100644 --- a/tun/Cargo.toml +++ b/tun/Cargo.toml @@ -11,7 +11,9 @@ socket2 = "0.4" tokio = { version = "1.28", features = [] } [target.'cfg(windows)'.dependencies] +lazy_static = "1.4" libloading = "0.7" +tempfile = "3.5" widestring = "1.0" windows = { version = "0.48", features = ["Win32_Foundation", "Win32_NetworkManagement_IpHelper"] } diff --git a/tun/src/windows/mod.rs b/tun/src/windows/mod.rs index 92f8092..6c0a19c 100644 --- a/tun/src/windows/mod.rs +++ b/tun/src/windows/mod.rs @@ -8,7 +8,6 @@ mod queue; pub use queue::TunQueue; pub struct TunInterface { - wintun: sys::wintun, handle: sys::WINTUN_ADAPTER_HANDLE, name: String, } @@ -17,14 +16,12 @@ impl TunInterface { #[throws] pub fn new() -> TunInterface { let name = U16CString::from(u16cstr!("Burrow")); - let wintun = sys::wintun::default(); let handle = - unsafe { wintun.WintunCreateAdapter(name.as_ptr(), name.as_ptr(), ptr::null()) }; + unsafe { sys::WINTUN.WintunCreateAdapter(name.as_ptr(), name.as_ptr(), ptr::null()) }; if handle.is_null() { unsafe { GetLastError() }.ok()? } TunInterface { - wintun, handle, name: String::from("Burrow"), } @@ -37,17 +34,25 @@ impl TunInterface { impl Drop for TunInterface { fn drop(&mut self) { - unsafe { self.wintun.WintunCloseAdapter(self.handle) } + unsafe { sys::WINTUN.WintunCloseAdapter(self.handle) } } } pub(crate) mod sys { - #![allow(dead_code, non_camel_case_types, non_snake_case)] + #![allow(clippy::all, dead_code, non_camel_case_types, non_snake_case)] include!(concat!(env!("OUT_DIR"), "/wintun.rs")); - impl Default for wintun { - fn default() -> Self { - unsafe { wintun::new(format!("{}/wintun.dll", env!("OUT_DIR"))).unwrap() } - } + const WINTUN_BINARY: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/wintun.dll")); + + lazy_static::lazy_static! { + pub static ref WINTUN: wintun = { + use std::io::Write; + + let mut temp_file = tempfile::NamedTempFile::new().unwrap(); + temp_file.write_all(&WINTUN_BINARY).unwrap(); + let (_, path) = temp_file.keep().unwrap(); + + unsafe { wintun::new(&path) }.unwrap() + }; } }