1pub fn is_debugger_present() -> Result<bool, std::io::Error> {
2 #[cfg(target_os = "windows")] {
3 unsafe {
5 let result = windows_sys::Win32::System::Diagnostics::Debug::IsDebuggerPresent();
6 if result != windows_sys::Win32::Foundation::FALSE {
7 return Ok(true);
8 }
9 }
10 #[cfg(feature = "deep-detect")]
12 unsafe {
13 let mut p_debugger_present = windows_sys::Win32::Foundation::FALSE;
14 let result = windows_sys::Win32::System::Diagnostics::Debug::CheckRemoteDebuggerPresent(
15 windows_sys::Win32::System::Threading::GetCurrentProcess(),
16 &mut p_debugger_present,
17 );
18 if result == windows_sys::Win32::Foundation::FALSE {
19 return Err(errno::errno().into());
20 }
21 if p_debugger_present != windows_sys::Win32::Foundation::FALSE {
22 return Ok(true);
23 }
24 }
25 #[cfg(feature = "deep-detect")]
27 unsafe {
28 let mut p_debug_port = 0i32;
29 let result = windows_sys::Wdk::System::Threading::NtQueryInformationProcess(
30 windows_sys::Win32::System::Threading::GetCurrentProcess(),
31 windows_sys::Wdk::System::Threading::ProcessDebugPort,
32 &mut p_debug_port as *mut _ as _,
33 size_of::<i32>() as _,
34 &mut 0,
35 );
36 let result = windows_sys::Win32::Foundation::RtlNtStatusToDosError(result);
37 if result != 0 {
38 return Err(errno::Errno(result as _).into());
39 }
40 if p_debug_port != 0 {
41 return Ok(true);
42 }
43 }
44 return Ok(false);
45 }
46 #[cfg(any(target_os = "linux", target_os = "android"))] {
47 {
49 let proc = std::fs::read_to_string("/proc/self/status")?;
50 let pid = proc
51 .lines()
52 .filter_map(|line| line.strip_prefix("TracerPid:"))
53 .filter_map(|pid| pid.trim().parse::<i32>().ok())
54 .next()
55 .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid pid format"))?;
56 if pid != 0 {
57 return Ok(true);
58 }
59 }
60 return Ok(false);
61 }
62 #[cfg(target_os = "macos")] {
63 {
65 let pid = std::process::id() as i32;
66 let result = libproc::proc_pid::pidinfo::<libproc::bsd_info::BSDInfo>(pid, 0);
67 let proc_bsdinfo = match result {
68 Ok(proc_bsdinfo) => proc_bsdinfo,
69 Err(_message) => return Err(errno::errno().into()),
70 };
71 const PROC_FLAG_TRACED: u32 = 2; if proc_bsdinfo.pbi_flags & PROC_FLAG_TRACED != 0 { return Ok(true); }
73 }
74 return Ok(false);
75 }
76 #[cfg(not(any(
77 target_os = "windows",
78 target_os = "linux",
79 target_os = "android",
80 target_os = "macos",
81 )))]
82 compile_error!("Anti-Debug doesn't support current platform.")
83}
84
85#[cfg(test)]
86mod tests {
87 #[test]
88 fn test_is_debugger_present() {
89 assert!(!super::is_debugger_present().unwrap_or(false));
90 assert!(!super::is_debugger_present().unwrap_or(false));
91 assert!(!super::is_debugger_present().unwrap_or(false));
92 }
93}