From 3bc2c38aecaec868daee56960d2956af15e4c5b0 Mon Sep 17 00:00:00 2001 From: Bufferization Date: Wed, 26 Feb 2025 19:55:13 +0800 Subject: [PATCH] rel: v0.1.1 --- Cargo.lock | 7 + Cargo.toml | 5 +- src/main.rs | 129 ++++++++--------- src/modules/memory_devices.rs | 176 ++++++++++++++---------- src/modules/mod.rs | 4 + src/modules/monitor_edid.rs | 209 ++++++++++++++-------------- src/modules/system_reg.rs | 251 ++++++++++++++++++---------------- src/modules/system_uuid.rs | 110 ++++++++------- 8 files changed, 471 insertions(+), 420 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1edb39e..8837529 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" + [[package]] name = "autocfg" version = "1.4.0" @@ -220,6 +226,7 @@ dependencies = [ name = "roblox-hwid-spoofer" version = "0.1.0" dependencies = [ + "anyhow", "chrono", "rand", "uuid", diff --git a/Cargo.toml b/Cargo.toml index 1a4535c..5e9d75e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "roblox-hwid-spoofer" -version = "0.1.0" +version = "0.1.1" edition = "2021" authors = ["bufferization"] description = "A tool to spoof hardware identifiers used by Roblox Hyperion" @@ -11,10 +11,11 @@ rand = "0.8" winreg = "0.11" winapi = { version = "0.3", features = ["winnt", "processthreadsapi", "securitybaseapi", "handleapi", "minwindef", "winreg", "winbase"] } chrono = "0.4.39" +anyhow = "1.0" [profile.release] opt-level = 3 lto = true codegen-units = 1 strip = true -panic = "abort" +panic = "abort" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2794826..352d0ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ mod modules; -use std::io::{self, Write}; -use std::error::Error; +use std::io; +use anyhow::{Result, Context}; use modules::system_uuid::SystemUuidSpoofer; use modules::memory_devices::MemoryDevicesSpoofer; use modules::monitor_edid::MonitorEdidSpoofer; @@ -11,10 +11,9 @@ use std::thread; use winreg::enums::*; use winreg::RegKey; -fn main() -> Result<(), Box> { +fn main() -> Result<()> { print_banner(); - if !is_running_as_admin() { println!("[ERROR] This program must be run with Administrator privileges!"); println!("Please right-click and select 'Run as Administrator'"); @@ -22,44 +21,38 @@ fn main() -> Result<(), Box> { return Ok(()); } - - setup_main_config()?; - + setup_main_config().context("Failed to setup main configuration")?; loop { - match show_menu()? { - 1 => spoof_all()?, + match show_menu().context("Failed to display menu")? { + 1 => spoof_all().context("Failed to spoof all hardware IDs")?, 2 => { println!("\n[-] Running System UUID Spoofer"); - match run_system_uuid_spoofer() { - Ok(_) => println!("[+] System UUID Spoofing Successful"), - Err(e) => println!("[!] System UUID Spoofing Failed: {}", e), - } - wait_to_continue()?; + run_system_uuid_spoofer() + .map(|_| println!("[+] System UUID Spoofing Successful")) + .unwrap_or_else(|e| println!("[!] System UUID Spoofing Failed: {}", e)); + wait_to_continue().context("Failed to wait for user input")?; }, 3 => { println!("\n[-] Running Memory Devices Spoofer"); - match run_memory_devices_spoofer() { - Ok(_) => println!("[+] Memory Devices Spoofing Successful"), - Err(e) => println!("[!] Memory Devices Spoofing Failed: {}", e), - } - wait_to_continue()?; + run_memory_devices_spoofer() + .map(|_| println!("[+] Memory Devices Spoofing Successful")) + .unwrap_or_else(|e| println!("[!] Memory Devices Spoofing Failed: {}", e)); + wait_to_continue().context("Failed to wait for user input")?; }, 4 => { println!("\n[-] Running Monitor EDID Spoofer"); - match run_monitor_edid_spoofer() { - Ok(_) => println!("[+] Monitor EDID Spoofing Successful"), - Err(e) => println!("[!] Monitor EDID Spoofing Failed: {}", e), - } - wait_to_continue()?; + run_monitor_edid_spoofer() + .map(|_| println!("[+] Monitor EDID Spoofing Successful")) + .unwrap_or_else(|e| println!("[!] Monitor EDID Spoofing Failed: {}", e)); + wait_to_continue().context("Failed to wait for user input")?; }, 5 => { println!("\n[-] Running System Registry Spoofer"); - match run_system_reg_spoofer() { - Ok(_) => println!("[+] System Registry Spoofing Successful"), - Err(e) => println!("[!] System Registry Spoofing Failed: {}", e), - } - wait_to_continue()?; + run_system_reg_spoofer() + .map(|_| println!("[+] System Registry Spoofing Successful")) + .unwrap_or_else(|e| println!("[!] System Registry Spoofing Failed: {}", e)); + wait_to_continue().context("Failed to wait for user input")?; }, 6 => { println!("\nExiting. Hardware ID Spoofer closed."); @@ -72,7 +65,7 @@ fn main() -> Result<(), Box> { Ok(()) } -fn show_menu() -> Result> { +fn show_menu() -> Result { println!("\n==== Hardware ID Spoofer Menu ===="); println!("1. Spoof All Hardware IDs"); println!("2. Spoof System UUID only"); @@ -80,56 +73,48 @@ fn show_menu() -> Result> { println!("4. Spoof Monitor EDID only"); println!("5. Spoof System Registry only"); println!("6. Exit"); - - print!("\nEnter your choice (1-6): "); - io::stdout().flush()?; + println!("\nEnter your choice (1-6): "); let mut input = String::new(); - io::stdin().read_line(&mut input)?; + io::stdin().read_line(&mut input).context("Failed to read user input")?; - match input.trim().parse() { - Ok(num) => Ok(num), - Err(_) => Ok(0), - } + let parsed = input.trim().parse::().unwrap_or(0); + Ok(parsed) } -fn spoof_all() -> Result<(), Box> { +fn spoof_all() -> Result<()> { println!("\n[+] Beginning HWID spoofing sequence..."); - let spoofers = [ - ("System UUID", run_system_uuid_spoofer as fn() -> Result<(), Box>), - ("Memory Devices", run_memory_devices_spoofer as fn() -> Result<(), Box>), - ("Monitor EDID", run_monitor_edid_spoofer as fn() -> Result<(), Box>), - ("System Registry", run_system_reg_spoofer as fn() -> Result<(), Box>), + ("System UUID", run_system_uuid_spoofer as fn() -> Result<()>), + ("Memory Devices", run_memory_devices_spoofer as fn() -> Result<()>), + ("Monitor EDID", run_monitor_edid_spoofer as fn() -> Result<()>), + ("System Registry", run_system_reg_spoofer as fn() -> Result<()>), ]; - for (name, spoofer_fn) in spoofers.iter() { + spoofers.iter().for_each(|(name, spoofer_fn)| { println!("\n[-] Running {} Spoofer", name); - match spoofer_fn() { - Ok(_) => println!("[+] {} Spoofing Successful", name), - Err(e) => println!("[!] {} Spoofing Failed: {}", name, e), - } - + spoofer_fn() + .map(|_| println!("[+] {} Spoofing Successful", name)) + .unwrap_or_else(|e| println!("[!] {} Spoofing Failed: {}", name, e)); thread::sleep(Duration::from_millis(500)); - } + }); println!("\n[+] HWID spoofing complete! Your hardware identifiers have been modified."); println!("[*] Roblox will now detect different hardware identifiers on this machine."); println!("[*] Remember that spoofed IDs persist across reboots but may reset with Windows updates."); - wait_to_continue()?; + wait_to_continue().context("Failed to wait for user input")?; Ok(()) } -fn setup_main_config() -> Result<(), Box> { +fn setup_main_config() -> Result<()> { let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - let (config_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\SecurityProviders")?; - + let (config_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\SecurityProviders") + .context("Failed to create config registry key")?; let prev_run: Option = config_key.get_value("ConfigVersion").ok(); @@ -137,19 +122,20 @@ fn setup_main_config() -> Result<(), Box> { println!("[*] Detected previous configuration (version {})", version); } else { println!("[*] First-time setup detected, creating new configuration"); - config_key.set_value("ConfigVersion", &1u32)?; - config_key.set_value("SetupDate", &chrono::Local::now().to_rfc3339())?; + config_key.set_value("ConfigVersion", &1u32) + .context("Failed to set ConfigVersion registry value")?; + config_key.set_value("SetupDate", &chrono::Local::now().to_rfc3339()) + .context("Failed to set SetupDate registry value")?; } Ok(()) } -fn wait_to_continue() -> Result<(), Box> { - print!("\nPress Enter to continue..."); - io::stdout().flush()?; +fn wait_to_continue() -> Result<()> { + println!("\nPress Enter to continue..."); let mut input = String::new(); - io::stdin().read_line(&mut input)?; + io::stdin().read_line(&mut input).context("Failed to read user input")?; Ok(()) } @@ -166,6 +152,7 @@ fn is_running_as_admin() -> bool { }; let mut sid = std::ptr::null_mut(); + // Initialize SID let result = AllocateAndInitializeSid( &mut authority, 2, @@ -179,9 +166,11 @@ fn is_running_as_admin() -> bool { return false; } + // Check if user is a member of the admin group let mut is_member = 0; let member_check = CheckTokenMembership(std::ptr::null_mut(), sid, &mut is_member); + // Free allocated SID winapi::um::securitybaseapi::FreeSid(sid); member_check != 0 && is_member != 0 @@ -209,18 +198,18 @@ fn print_banner() { println!(""); } -fn run_system_uuid_spoofer() -> Result<(), Box> { - SystemUuidSpoofer::spoof() +fn run_system_uuid_spoofer() -> Result<()> { + SystemUuidSpoofer::spoof().context("System UUID spoofing failed") } -fn run_memory_devices_spoofer() -> Result<(), Box> { - MemoryDevicesSpoofer::spoof() +fn run_memory_devices_spoofer() -> Result<()> { + MemoryDevicesSpoofer::spoof().context("Memory devices spoofing failed") } -fn run_monitor_edid_spoofer() -> Result<(), Box> { - MonitorEdidSpoofer::spoof() +fn run_monitor_edid_spoofer() -> Result<()> { + MonitorEdidSpoofer::spoof().context("Monitor EDID spoofing failed") } -fn run_system_reg_spoofer() -> Result<(), Box> { - SystemRegSpoofer::spoof() +fn run_system_reg_spoofer() -> Result<()> { + SystemRegSpoofer::spoof().context("System registry spoofing failed") } diff --git a/src/modules/memory_devices.rs b/src/modules/memory_devices.rs index 6e3f194..35a4fc4 100644 --- a/src/modules/memory_devices.rs +++ b/src/modules/memory_devices.rs @@ -1,98 +1,122 @@ -use std::error::Error; +use anyhow::{Result, Context}; use rand::{distributions::Alphanumeric, Rng}; use rand::seq::SliceRandom; use winreg::enums::*; use winreg::RegKey; +/// Handles spoofing of memory devices information (RAM) to prevent hardware fingerprinting pub struct MemoryDevicesSpoofer; impl MemoryDevicesSpoofer { - pub fn spoof() -> Result<(), Box> { + /// Main entry point for memory device spoofing + /// Generates random serials and configures registry entries for RAM modules + pub fn spoof() -> Result<()> { println!("Spoofing Memory Device Information..."); - let serials = Self::generate_random_serials(4)?; + let serials = generate_random_serials(4) + .context("Failed to generate random serials")?; - Self::setup_memory_device_spoofing(&serials)?; + setup_memory_device_spoofing(&serials) + .context("Failed to setup memory device spoofing")?; - Self::setup_memory_device_info(&serials)?; + setup_memory_device_info(&serials) + .context("Failed to setup memory device info")?; println!("Memory device information spoofing complete"); Ok(()) } +} + +/// Creates a set of random memory module serial numbers with realistic manufacturer prefixes +fn generate_random_serials(count: usize) -> Result> { + let mut rng = rand::thread_rng(); + let mut serials = Vec::with_capacity(count); - fn generate_random_serials(count: usize) -> Result, Box> { - let mut rng = rand::thread_rng(); - let mut serials = Vec::with_capacity(count); - - let prefixes = ["KHX", "CMK", "BLS", "TF", "CT", "HX", "F4", "TD"]; - - for _ in 0..count { - let prefix = prefixes.choose(&mut rng).unwrap_or(&"CM"); - - let random_chars: String = (&mut rng) - .sample_iter(&Alphanumeric) - .take(12) - .map(char::from) - .collect(); - - let serial = format!("{}{}", prefix, random_chars); - serials.push(serial); - } - - for (i, serial) in serials.iter().enumerate() { - println!("Generated memory serial #{}: {}", i+1, serial); - } - - Ok(serials) - } + let prefixes = ["KHX", "CMK", "BLS", "TF", "CT", "HX", "F4", "TD"]; - fn setup_memory_device_spoofing(serials: &[String]) -> Result<(), Box> { - println!("Setting up memory device registry entries..."); - - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - let (mem_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Memory")?; - - mem_key.set_value("DeviceCount", &(serials.len() as u32))?; - - for (i, serial) in serials.iter().enumerate() { - mem_key.set_value(&format!("Device{}_Serial", i), serial)?; - } - - mem_key.set_value("MemoryDevicePrefix", &"C8j3kLs9wxF4Pq2Z7tR6")?; - - let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE)?; - parent_key.set_value("EnableMemoryProtection", &1u32)?; - - println!("Memory device spoofing configuration created successfully"); - Ok(()) - } + (0..count).for_each(|_| { + let prefix = prefixes.choose(&mut rng).unwrap_or(&"CM"); + + let random_chars: String = (&mut rng) + .sample_iter(&Alphanumeric) + .take(12) + .map(char::from) + .collect(); + + let serial = format!("{}{}", prefix, random_chars); + serials.push(serial); + }); - fn setup_memory_device_info(serials: &[String]) -> Result<(), Box> { - println!("Setting up memory device information..."); - - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - let (memory_info_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\MemoryInfo")?; - - let manufacturers = ["Kingston", "Corsair", "G.Skill", "Crucial", "HyperX"]; - let mut rng = rand::thread_rng(); - - for (i, serial) in serials.iter().enumerate() { - let manufacturer = manufacturers.choose(&mut rng).unwrap_or(&"Kingston"); - let sizes = [8, 16, 32]; - let size = sizes.choose(&mut rng).unwrap_or(&16); - - let (device_key, _) = memory_info_key.create_subkey(&format!("Device{}", i))?; - - device_key.set_value("SerialNumber", serial)?; - device_key.set_value("Manufacturer", manufacturer)?; - device_key.set_value("Capacity", &format!("{} GB", size))?; - device_key.set_value("Speed", &format!("{} MHz", 1600 + (rng.gen::() % 2400)))?; - device_key.set_value("DeviceLocator", &format!("DIMM{}", i))?; - } + serials.iter().enumerate().for_each(|(i, serial)| { + println!("Generated memory serial #{}: {}", i+1, serial); + }); + + Ok(serials) +} + +/// Configures registry entries for memory device spoofing +fn setup_memory_device_spoofing(serials: &[String]) -> Result<()> { + println!("Setting up memory device registry entries..."); + + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + let (mem_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Memory") + .context("Failed to create memory registry key")?; + + mem_key.set_value("DeviceCount", &(serials.len() as u32)) + .context("Failed to set DeviceCount registry value")?; + + serials.iter().enumerate().try_for_each(|(i, serial)| { + mem_key.set_value(&format!("Device{}_Serial", i), serial) + .context(format!("Failed to set Device{}_Serial registry value", i)) + })?; + + mem_key.set_value("MemoryDevicePrefix", &"C8j3kLs9wxF4Pq2Z7tR6") + .context("Failed to set MemoryDevicePrefix registry value")?; + + let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE) + .context("Failed to open security providers registry key with write access")?; + parent_key.set_value("EnableMemoryProtection", &1u32) + .context("Failed to set EnableMemoryProtection registry value")?; + + println!("Memory device spoofing configuration created successfully"); + Ok(()) +} + +/// Sets up detailed memory device information with realistic manufacturer details +fn setup_memory_device_info(serials: &[String]) -> Result<()> { + println!("Setting up memory device information..."); + + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + let (memory_info_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\MemoryInfo") + .context("Failed to create memory info registry key")?; + + let manufacturers = ["Kingston", "Corsair", "G.Skill", "Crucial", "HyperX"]; + let mut rng = rand::thread_rng(); + + serials.iter().enumerate().try_for_each(|(i, serial)| -> Result<()> { + let manufacturer = manufacturers.choose(&mut rng).unwrap_or(&"Kingston"); + let sizes = [8, 16, 32]; + let size = sizes.choose(&mut rng).unwrap_or(&16); + + let (device_key, _) = memory_info_key.create_subkey(&format!("Device{}", i)) + .context(format!("Failed to create Device{} registry key", i))?; + + device_key.set_value("SerialNumber", serial) + .context("Failed to set SerialNumber registry value")?; + device_key.set_value("Manufacturer", manufacturer) + .context("Failed to set Manufacturer registry value")?; + device_key.set_value("Capacity", &format!("{} GB", size)) + .context("Failed to set Capacity registry value")?; + device_key.set_value("Speed", &format!("{} MHz", 1600 + (rng.gen::() % 2400))) + .context("Failed to set Speed registry value")?; + device_key.set_value("DeviceLocator", &format!("DIMM{}", i)) + .context("Failed to set DeviceLocator registry value")?; - println!("Memory device information setup successfully"); Ok(()) - } + })?; + + println!("Memory device information setup successfully"); + Ok(()) } \ No newline at end of file diff --git a/src/modules/mod.rs b/src/modules/mod.rs index f9ad458..05abba1 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -1,3 +1,7 @@ +/// This module contains the core spoofing implementations for various hardware identifiers +/// Each submodule handles a specific hardware component that needs spoofing to prevent tracking +/// +/// All modules use anyhow for error handling and follow functional programming patterns where possible. pub mod system_uuid; pub mod memory_devices; pub mod monitor_edid; diff --git a/src/modules/monitor_edid.rs b/src/modules/monitor_edid.rs index f818262..276f50b 100644 --- a/src/modules/monitor_edid.rs +++ b/src/modules/monitor_edid.rs @@ -1,129 +1,126 @@ -use std::error::Error; +use anyhow::{Result, Context}; use rand::Rng; use winreg::enums::*; use winreg::RegKey; +/// Handles spoofing of monitor EDID (Extended Display Identification Data) to prevent hardware fingerprinting pub struct MonitorEdidSpoofer; impl MonitorEdidSpoofer { - pub fn spoof() -> Result<(), Box> { + /// Main entry point for monitor EDID spoofing + /// Modifies the monitor serial numbers stored in the EDID data + pub fn spoof() -> Result<()> { println!("Spoofing Monitor EDID Information..."); + let display_paths = find_display_devices() + .context("Failed to find display devices")?; - let display_paths = Self::find_display_devices()?; + let modified_count = display_paths.iter() + .filter_map(|path| modify_edid_for_display(path).ok()) + .count(); - - let mut modified_count = 0; - - - for display_path in display_paths { - if let Ok(()) = Self::modify_edid_for_display(&display_path) { - modified_count += 1; - } - } - - - Self::create_edid_intercept_config(modified_count)?; + create_edid_intercept_config(modified_count) + .context("Failed to create EDID intercept configuration")?; println!("Monitor EDID spoofing complete"); Ok(()) } +} + +/// Locates all display devices in the registry that may contain EDID data +fn find_display_devices() -> Result> { + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + let display_path = r"SYSTEM\CurrentControlSet\Enum\DISPLAY"; + let display_key = hklm.open_subkey(display_path) + .context("Failed to open display registry key")?; - fn find_display_devices() -> Result, Box> { - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - let display_path = r"SYSTEM\CurrentControlSet\Enum\DISPLAY"; - let display_key = hklm.open_subkey(display_path)?; - - let mut result = Vec::new(); - - - for manufacturer in display_key.enum_keys().map(|x| x.unwrap()) { - let manufacturer_key = display_key.open_subkey(&manufacturer)?; - - - for instance in manufacturer_key.enum_keys().map(|x| x.unwrap()) { - let full_path = format!("{}\\{}\\{}", display_path, manufacturer, instance); - result.push(full_path); - } - } - - println!("Found {} display devices", result.len()); - Ok(result) - } + let mut result = Vec::new(); - fn modify_edid_for_display(display_path: &str) -> Result<(), Box> { - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - - - let params_path = format!("{}\\Device Parameters", display_path); - let params_key = match hklm.open_subkey_with_flags(¶ms_path, KEY_READ | KEY_WRITE) { - Ok(key) => key, - Err(_) => return Err("No Device Parameters key".into()), - }; - - - let edid: Vec = match params_key.get_raw_value("EDID") { - Ok(value) => value.bytes, - Err(_) => return Err("No EDID value".into()), - }; - - - if edid.len() < 128 { - return Err("EDID too short".into()); - } - - - let mut new_edid = edid.clone(); - - - let mut rng = rand::thread_rng(); - let mut new_serial = [0u8; 4]; - rng.fill(&mut new_serial); - - - new_edid[12] = new_serial[0]; - new_edid[13] = new_serial[1]; - new_edid[14] = new_serial[2]; - new_edid[15] = new_serial[3]; - - - - let sum = new_edid[0..127].iter().map(|&x| x as u32).sum::() % 256; - let checksum = if sum == 0 { 0 } else { (256 - sum) as u8 }; - new_edid[127] = checksum; - - - let reg_value = winreg::RegValue { - bytes: new_edid, - vtype: REG_BINARY, - }; - params_key.set_raw_value("EDID", ®_value)?; - + let manufacturers = display_key.enum_keys() + .filter_map(Result::ok) + .collect::>(); + + for manufacturer in manufacturers { + let manufacturer_key = display_key.open_subkey(&manufacturer) + .context(format!("Failed to open manufacturer key '{}'", manufacturer))?; - println!("Modified display EDID at {} - New serial: {:02X}{:02X}{:02X}{:02X}, Checksum: {:02X}", - display_path, new_serial[0], new_serial[1], new_serial[2], new_serial[3], checksum); + let instances = manufacturer_key.enum_keys() + .filter_map(Result::ok) + .map(|instance| format!("{}\\{}\\{}", display_path, manufacturer, instance)) + .collect::>(); - Ok(()) + result.extend(instances); } - fn create_edid_intercept_config(modified_count: usize) -> Result<(), Box> { - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - - let (edid_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Display")?; - - - edid_key.set_value("ModifiedDisplayCount", &(modified_count as u32))?; - edid_key.set_value("LastModifiedTime", &chrono::Local::now().to_rfc3339())?; - - - edid_key.set_value("DisplayIdentifierPrefix", &"D7t5Rq2Z9sXw3F6yPl4J")?; - - - let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE)?; - parent_key.set_value("EnableDisplayProtection", &1u32)?; - - println!("EDID interception configuration created successfully"); - Ok(()) + println!("Found {} display devices", result.len()); + Ok(result) +} + +/// Modifies the EDID data for a specific display device to spoof its serial number +fn modify_edid_for_display(display_path: &str) -> Result<()> { + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + + let params_path = format!("{}\\Device Parameters", display_path); + let params_key = hklm.open_subkey_with_flags(¶ms_path, KEY_READ | KEY_WRITE) + .context(format!("No Device Parameters key for '{}'", display_path))?; + + let edid: Vec = params_key.get_raw_value("EDID") + .context(format!("No EDID value for '{}'", display_path))?.bytes; + + if edid.len() < 128 { + return Err(anyhow::anyhow!("EDID too short for '{}'", display_path)); } + + let mut new_edid = edid.clone(); + + let mut rng = rand::thread_rng(); + let mut new_serial = [0u8; 4]; + rng.fill(&mut new_serial); + + // Bytes 12-15 in the EDID contain the monitor serial number + new_edid[12] = new_serial[0]; + new_edid[13] = new_serial[1]; + new_edid[14] = new_serial[2]; + new_edid[15] = new_serial[3]; + + // Recalculate EDID checksum (byte 127) + let sum = new_edid[0..127].iter().map(|&x| x as u32).sum::() % 256; + let checksum = if sum == 0 { 0 } else { (256 - sum) as u8 }; + new_edid[127] = checksum; + + let reg_value = winreg::RegValue { + bytes: new_edid, + vtype: REG_BINARY, + }; + params_key.set_raw_value("EDID", ®_value) + .context(format!("Failed to set EDID value for '{}'", display_path))?; + + println!("Modified display EDID at {} - New serial: {:02X}{:02X}{:02X}{:02X}, Checksum: {:02X}", + display_path, new_serial[0], new_serial[1], new_serial[2], new_serial[3], checksum); + + Ok(()) +} + +/// Creates configuration entries for the EDID interception mechanism +fn create_edid_intercept_config(modified_count: usize) -> Result<()> { + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + let (edid_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Display") + .context("Failed to create display registry key")?; + + edid_key.set_value("ModifiedDisplayCount", &(modified_count as u32)) + .context("Failed to set ModifiedDisplayCount registry value")?; + edid_key.set_value("LastModifiedTime", &chrono::Local::now().to_rfc3339()) + .context("Failed to set LastModifiedTime registry value")?; + + edid_key.set_value("DisplayIdentifierPrefix", &"D7t5Rq2Z9sXw3F6yPl4J") + .context("Failed to set DisplayIdentifierPrefix registry value")?; + + let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE) + .context("Failed to open security providers registry key with write access")?; + parent_key.set_value("EnableDisplayProtection", &1u32) + .context("Failed to set EnableDisplayProtection registry value")?; + + println!("EDID interception configuration created successfully"); + Ok(()) } \ No newline at end of file diff --git a/src/modules/system_reg.rs b/src/modules/system_reg.rs index 38caa14..def1319 100644 --- a/src/modules/system_reg.rs +++ b/src/modules/system_reg.rs @@ -1,4 +1,4 @@ -use std::error::Error; +use anyhow::{Result, Context}; use rand::Rng; use rand::seq::IteratorRandom; use winapi::um::winnt::PSID; @@ -7,137 +7,154 @@ use winreg::enums::*; use winreg::RegKey; use std::ptr; +/// Handles spoofing of system registry information to prevent hardware identification pub struct SystemRegSpoofer; impl SystemRegSpoofer { - pub fn spoof() -> Result<(), Box> { + /// Main entry point for system registry spoofing + /// Generates and applies random registry data to prevent tracking + pub fn spoof() -> Result<()> { println!("Spoofing System Registry Information..."); - - let user_sid = Self::get_current_user_sid()?; + let user_sid = get_current_user_sid() + .context("Failed to get current user SID")?; println!("Current user SID: {}", user_sid); - - let random_data = Self::generate_random_data()?; + let random_data = generate_random_data() + .context("Failed to generate random data")?; println!("Generated random registry data ({} bytes)", random_data.len()); - - Self::create_spoofed_registry(&user_sid, &random_data)?; + create_spoofed_registry(&user_sid, &random_data) + .context("Failed to create spoofed registry")?; println!("System registry information spoofing complete"); Ok(()) } +} + +/// Retrieves or generates the current user's Security Identifier (SID) +fn get_current_user_sid() -> Result { + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + let key = hkcu.open_subkey("Software") + .context("Failed to open HKCU\\Software key")?; - fn get_current_user_sid() -> Result> { - - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - let key = hkcu.open_subkey("Software")?; - - - let sid_str = Self::extract_sid_from_key(&key)?; - - Ok(sid_str) - } + let sid_str = extract_sid_from_key(&key) + .context("Failed to extract SID from registry key")?; - fn extract_sid_from_key(key: &RegKey) -> Result> { - - let _handle = key.raw_handle(); - - unsafe { - - let sid_ptr: PSID = ptr::null_mut(); - let mut sid_size: u32 = 0; - let mut domain_name_size: u32 = 0; - let mut name_use: u32 = 0; - - - LookupAccountSidW( - ptr::null(), - sid_ptr, - ptr::null_mut(), - &mut sid_size, - ptr::null_mut(), - &mut domain_name_size, - &mut name_use - ); - - - let sid_str = "S-1-5-21-".to_string() + - &rand::thread_rng().gen::().to_string() + "-" + - &rand::thread_rng().gen::().to_string() + "-" + - &rand::thread_rng().gen::().to_string() + "-" + - &rand::thread_rng().gen_range(500..1000).to_string(); - - Ok(sid_str) - } - } + Ok(sid_str) +} + +/// Extracts SID information from registry key or generates a random one +fn extract_sid_from_key(_key: &RegKey) -> Result { + // Generate a random SID with format matching Windows security identifiers + // This is outside the unsafe block since it doesn't use any unsafe code + let mut rng = rand::thread_rng(); + let sid_str = format!( + "S-1-5-21-{}-{}-{}-{}", + rng.gen::(), + rng.gen::(), + rng.gen::(), + rng.gen_range(500..1000) + ); - fn generate_random_data() -> Result, Box> { - let mut rng = rand::thread_rng(); - - - let length = rng.gen_range(128..256); - - - let mut data = Vec::with_capacity(length); - - - data.extend_from_slice(&[0x53, 0x59, 0x53, 0x54, 0x45, 0x4D]); - - - for _ in 0..3 { - let str_len = rng.gen_range(8..16); - let chars: Vec = (0..str_len) - .map(|_| rng.gen_range(65..91) as u8) - .collect(); - data.extend_from_slice(&chars); - data.push(0); - } - - - while data.len() < length { - data.push(rng.gen()); - } - - Ok(data) - } + // The unsafe block is only needed for the actual Windows API calls + // We can make this a fallback instead of the primary approach - fn create_spoofed_registry(user_sid: &str, data: &[u8]) -> Result<(), Box> { - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - - let (config_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Security")?; - - - config_key.set_value("UserIdentifier", &user_sid.to_string())?; - - - let reg_value = winreg::RegValue { - bytes: data.to_vec(), - vtype: REG_BINARY, - }; - config_key.set_raw_value("SecurityData", ®_value)?; - - - let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE)?; - parent_key.set_value("EnableSecurityDataProtection", &1u32)?; - - - - let names = ["SystemConfig", "SecurityProvider", "DeviceManager"]; - let mut rng = rand::thread_rng(); - let selected_name = names.iter().choose(&mut rng).unwrap_or(&"SystemConfig"); - - let special_name = format!("{}\0Config", selected_name); - - - let special_value = winreg::RegValue { - bytes: data.to_vec(), - vtype: REG_BINARY, - }; - parent_key.set_raw_value(&special_name, &special_value)?; - - println!("System registry spoofing configuration created successfully"); - Ok(()) + // Attempt to get the real SID via Windows API (this might fail) + let _real_sid = unsafe { + let sid_ptr: PSID = ptr::null_mut(); + let mut sid_size: u32 = 0; + let mut domain_name_size: u32 = 0; + let mut name_use: u32 = 0; + + // Just query buffer sizes, this call is expected to fail + LookupAccountSidW( + ptr::null(), + sid_ptr, + ptr::null_mut(), + &mut sid_size, + ptr::null_mut(), + &mut domain_name_size, + &mut name_use + ); + + // We're not actually using the real SID lookup results, + // as we want to generate a fake one anyway + }; + + Ok(sid_str) +} + +/// Generates random binary data for registry spoofing +fn generate_random_data() -> Result> { + let mut rng = rand::thread_rng(); + + let length = rng.gen_range(128..256); + + let mut data = Vec::with_capacity(length); + + // Start with "SYSTEM" signature bytes + data.extend_from_slice(&[0x53, 0x59, 0x53, 0x54, 0x45, 0x4D]); + + // Generate a few null-terminated random strings + (0..3).for_each(|_| { + let str_len = rng.gen_range(8..16); + let chars: Vec = (0..str_len) + .map(|_| rng.gen_range(65..91) as u8) + .collect(); + data.extend_from_slice(&chars); + data.push(0); + }); + + // Fill remaining space with random bytes + while data.len() < length { + data.push(rng.gen()); } -} \ No newline at end of file + + Ok(data) +} + +/// Creates or updates registry keys with spoofed data +fn create_spoofed_registry(user_sid: &str, data: &[u8]) -> Result<()> { + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + // Create security configuration subkey + let (config_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\Security") + .context("Failed to create security registry key")?; + + // Set user identifier value + config_key.set_value("UserIdentifier", &user_sid.to_string()) + .context("Failed to set UserIdentifier registry value")?; + + // Set binary security data + let reg_value = winreg::RegValue { + bytes: data.to_vec(), + vtype: REG_BINARY, + }; + config_key.set_raw_value("SecurityData", ®_value) + .context("Failed to set SecurityData registry value")?; + + // Enable security data protection + let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE) + .context("Failed to open security providers registry key with write access")?; + parent_key.set_value("EnableSecurityDataProtection", &1u32) + .context("Failed to set EnableSecurityDataProtection registry value")?; + + // Select a random name for the special configuration + let names = ["SystemConfig", "SecurityProvider", "DeviceManager"]; + let mut rng = rand::thread_rng(); + let selected_name = names.iter().choose(&mut rng).unwrap_or(&"SystemConfig"); + + let special_name = format!("{}\0Config", selected_name); + + // Create the special binary value with null character in name (anti-forensic technique) + let special_value = winreg::RegValue { + bytes: data.to_vec(), + vtype: REG_BINARY, + }; + parent_key.set_raw_value(&special_name, &special_value) + .context("Failed to set special registry value")?; + + println!("System registry spoofing configuration created successfully"); + Ok(()) +} \ No newline at end of file diff --git a/src/modules/system_uuid.rs b/src/modules/system_uuid.rs index 1c527c6..32760ee 100644 --- a/src/modules/system_uuid.rs +++ b/src/modules/system_uuid.rs @@ -1,72 +1,84 @@ -use std::error::Error; +use anyhow::{Result, Context}; use uuid::Uuid; use winreg::enums::*; use winreg::RegKey; +/// Handles spoofing of the system UUID/GUID to prevent hardware fingerprinting pub struct SystemUuidSpoofer; impl SystemUuidSpoofer { - pub fn spoof() -> Result<(), Box> { + /// Main entry point for system UUID spoofing + /// Generates a random UUID and applies it to system registry + pub fn spoof() -> Result<()> { println!("Spoofing System UUID..."); - - let current_uuid = Self::get_current_system_uuid()?; + let current_uuid = get_current_system_uuid() + .context("Failed to retrieve current system UUID")?; println!("Current system UUID: {}", current_uuid); - let new_uuid = Uuid::new_v4(); println!("Generated new system UUID: {}", new_uuid); + set_spoofed_uuid(&new_uuid) + .context("Failed to set spoofed UUID")?; - Self::set_spoofed_uuid(&new_uuid)?; - - - Self::create_uuid_intercept_config(¤t_uuid, &new_uuid)?; + create_uuid_intercept_config(¤t_uuid, &new_uuid) + .context("Failed to create UUID intercept configuration")?; println!("System UUID spoofing complete"); Ok(()) } +} + +/// Retrieves the current system UUID from the registry +fn get_current_system_uuid() -> Result { + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + let info_key = hklm.open_subkey(r"SYSTEM\CurrentControlSet\Control\SystemInformation") + .context("Failed to open system information registry key")?; - fn get_current_system_uuid() -> Result> { - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - let info_key = hklm.open_subkey(r"SYSTEM\CurrentControlSet\Control\SystemInformation")?; - - let uuid_string: String = info_key.get_value("ComputerHardwareId")?; - let uuid = Uuid::parse_str(&uuid_string)?; - - Ok(uuid) - } + let uuid_string: String = info_key.get_value("ComputerHardwareId") + .context("Failed to read ComputerHardwareId value")?; + let uuid = Uuid::parse_str(&uuid_string) + .context("Failed to parse UUID string")?; - fn set_spoofed_uuid(uuid: &Uuid) -> Result<(), Box> { - let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); - let info_key = hklm.open_subkey_with_flags( - r"SYSTEM\CurrentControlSet\Control\SystemInformation", - KEY_SET_VALUE - )?; - - info_key.set_value("ComputerHardwareId", &uuid.to_string())?; - - Ok(()) - } + Ok(uuid) +} + +/// Sets the spoofed UUID in the registry to replace the original one +fn set_spoofed_uuid(uuid: &Uuid) -> Result<()> { + let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); + let info_key = hklm.open_subkey_with_flags( + r"SYSTEM\CurrentControlSet\Control\SystemInformation", + KEY_SET_VALUE + ).context("Failed to open system information registry key with write access")?; - fn create_uuid_intercept_config(original_uuid: &Uuid, spoofed_uuid: &Uuid) -> Result<(), Box> { - let hkcu = RegKey::predef(HKEY_CURRENT_USER); - - - let (uuid_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\SystemIdentifiers")?; - - - uuid_key.set_value("OriginalIdentifier", &original_uuid.to_string())?; - uuid_key.set_value("SystemIdentifier", &spoofed_uuid.to_string())?; - - - uuid_key.set_value("IdentifierPrefix", &"B5x2T8nP6kQz7mJy3wRe")?; - - - let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE)?; - parent_key.set_value("EnableIdentifierProtection", &1u32)?; - - println!("UUID interception configuration created successfully"); - Ok(()) - } + info_key.set_value("ComputerHardwareId", &uuid.to_string()) + .context("Failed to set ComputerHardwareId registry value")?; + + Ok(()) +} + +/// Creates configuration entries for UUID interception mechanism +/// Stores both original and spoofed UUIDs for reference +fn create_uuid_intercept_config(original_uuid: &Uuid, spoofed_uuid: &Uuid) -> Result<()> { + let hkcu = RegKey::predef(HKEY_CURRENT_USER); + + let (uuid_key, _) = hkcu.create_subkey(r"Software\Microsoft\DeviceManagement\SystemIdentifiers") + .context("Failed to create system identifiers registry key")?; + + uuid_key.set_value("OriginalIdentifier", &original_uuid.to_string()) + .context("Failed to set OriginalIdentifier registry value")?; + uuid_key.set_value("SystemIdentifier", &spoofed_uuid.to_string()) + .context("Failed to set SystemIdentifier registry value")?; + + uuid_key.set_value("IdentifierPrefix", &"B5x2T8nP6kQz7mJy3wRe") + .context("Failed to set IdentifierPrefix registry value")?; + + let parent_key = hkcu.open_subkey_with_flags(r"Software\Microsoft\DeviceManagement\SecurityProviders", KEY_WRITE) + .context("Failed to open security providers registry key with write access")?; + parent_key.set_value("EnableIdentifierProtection", &1u32) + .context("Failed to set EnableIdentifierProtection registry value")?; + + println!("UUID interception configuration created successfully"); + Ok(()) } \ No newline at end of file