pub fn is_debugger_present() -> Result<bool, std::io::Error> {
#[cfg(target_os = "windows")] {
unsafe {
let result = windows_sys::Win32::System::Diagnostics::Debug::IsDebuggerPresent();
if result != windows_sys::Win32::Foundation::FALSE {
return Ok(true);
}
}
#[cfg(feature = "deep-detect")]
unsafe {
let mut p_debugger_present = windows_sys::Win32::Foundation::FALSE;
let result = windows_sys::Win32::System::Diagnostics::Debug::CheckRemoteDebuggerPresent(
windows_sys::Win32::System::Threading::GetCurrentProcess(),
&mut p_debugger_present,
);
if result == windows_sys::Win32::Foundation::FALSE {
return Err(errno::errno().into());
}
if p_debugger_present != windows_sys::Win32::Foundation::FALSE {
return Ok(true);
}
}
#[cfg(feature = "deep-detect")]
unsafe {
let mut p_debug_port = 0i32;
let result = windows_sys::Wdk::System::Threading::NtQueryInformationProcess(
windows_sys::Win32::System::Threading::GetCurrentProcess(),
windows_sys::Wdk::System::Threading::ProcessDebugPort,
&mut p_debug_port as *mut _ as _,
size_of::<i32>() as _,
&mut 0,
);
let result = windows_sys::Win32::Foundation::RtlNtStatusToDosError(result);
if result != 0 {
return Err(errno::Errno(result as _).into());
}
if p_debug_port != 0 {
return Ok(true);
}
}
return Ok(false);
}
#[cfg(any(target_os = "linux", target_os = "android"))] {
{
let proc = std::fs::read_to_string("/proc/self/status")?;
let pid = proc
.lines()
.filter_map(|line| line.strip_prefix("TracerPid:"))
.filter_map(|pid| pid.trim().parse::<i32>().ok())
.next()
.ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid pid format"))?;
if pid != 0 {
return Ok(true);
}
}
return Ok(false);
}
#[cfg(target_os = "macos")] {
{
let pid = std::process::id() as i32;
let result = libproc::proc_pid::pidinfo::<libproc::bsd_info::BSDInfo>(pid, 0);
let proc_bsdinfo = match result {
Ok(proc_bsdinfo) => proc_bsdinfo,
Err(_message) => return Err(errno::errno().into()),
};
const PROC_FLAG_TRACED: u32 = 2; if proc_bsdinfo.pbi_flags & PROC_FLAG_TRACED != 0 { return Ok(true); }
}
return Ok(false);
}
#[cfg(not(any(
target_os = "windows",
target_os = "linux",
target_os = "android",
target_os = "macos",
)))]
compile_error!("Anti-Debug doesn't support current platform.")
}
#[cfg(test)]
mod tests {
#[test]
fn test_is_debugger_present() {
assert!(!super::is_debugger_present().unwrap_or(false));
assert!(!super::is_debugger_present().unwrap_or(false));
assert!(!super::is_debugger_present().unwrap_or(false));
}
}