mod heap_flags;
mod peb_flags;
#[cfg(feature = "std")]
mod thread_hide;
pub use heap_flags::{check_heap_flags, clear_heap_flags};
pub use peb_flags::{
check_being_debugged, check_nt_global_flag, clear_being_debugged, clear_nt_global_flag,
full_peb_cleanup,
};
#[cfg(feature = "std")]
pub use thread_hide::{get_hidden_threads, hide_current_thread, hide_thread, is_thread_hidden};
use crate::error::Result;
pub fn full_cleanup() -> Result<()> {
full_peb_cleanup()?;
clear_heap_flags()?;
Ok(())
}
pub fn is_debugger_present() -> Result<bool> {
if check_being_debugged()? {
return Ok(true);
}
if check_nt_global_flag()? {
return Ok(true);
}
if check_heap_flags()? {
return Ok(true);
}
Ok(false)
}
#[derive(Debug, Clone)]
pub struct DebugStatus {
pub being_debugged: bool,
pub nt_global_flag: bool,
pub heap_flags: bool,
}
impl DebugStatus {
pub fn any_detected(&self) -> bool {
self.being_debugged || self.nt_global_flag || self.heap_flags
}
}
impl core::fmt::Display for DebugStatus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
writeln!(f, "Debug Status:")?;
writeln!(
f,
" BeingDebugged: {}",
if self.being_debugged { "YES" } else { "no" }
)?;
writeln!(
f,
" NtGlobalFlag: {}",
if self.nt_global_flag { "YES" } else { "no" }
)?;
writeln!(
f,
" HeapFlags: {}",
if self.heap_flags { "YES" } else { "no" }
)
}
}
pub fn get_debug_status() -> Result<DebugStatus> {
Ok(DebugStatus {
being_debugged: check_being_debugged()?,
nt_global_flag: check_nt_global_flag()?,
heap_flags: check_heap_flags()?,
})
}