wraith/manipulation/antidebug/
mod.rs

1//! Anti-debugging techniques
2//!
3//! This module provides functionality to detect and evade debugger
4//! presence through various Windows anti-debug techniques.
5
6mod heap_flags;
7mod peb_flags;
8#[cfg(feature = "std")]
9mod thread_hide;
10
11pub use heap_flags::{check_heap_flags, clear_heap_flags};
12pub use peb_flags::{
13    check_being_debugged, check_nt_global_flag, clear_being_debugged, clear_nt_global_flag,
14    full_peb_cleanup,
15};
16#[cfg(feature = "std")]
17pub use thread_hide::{get_hidden_threads, hide_current_thread, hide_thread, is_thread_hidden};
18
19use crate::error::Result;
20
21/// perform full anti-debug cleanup
22///
23/// clears all common debug indicators:
24/// - PEB.BeingDebugged flag
25/// - PEB.NtGlobalFlag debug bits
26/// - Heap debug flags
27pub fn full_cleanup() -> Result<()> {
28    full_peb_cleanup()?;
29    clear_heap_flags()?;
30    Ok(())
31}
32
33/// check if any debug indicators are present
34pub fn is_debugger_present() -> Result<bool> {
35    // check PEB.BeingDebugged
36    if check_being_debugged()? {
37        return Ok(true);
38    }
39
40    // check NtGlobalFlag
41    if check_nt_global_flag()? {
42        return Ok(true);
43    }
44
45    // check heap flags
46    if check_heap_flags()? {
47        return Ok(true);
48    }
49
50    Ok(false)
51}
52
53/// debug indicator status
54#[derive(Debug, Clone)]
55pub struct DebugStatus {
56    pub being_debugged: bool,
57    pub nt_global_flag: bool,
58    pub heap_flags: bool,
59}
60
61impl DebugStatus {
62    /// check if any indicator is set
63    pub fn any_detected(&self) -> bool {
64        self.being_debugged || self.nt_global_flag || self.heap_flags
65    }
66}
67
68impl core::fmt::Display for DebugStatus {
69    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70        writeln!(f, "Debug Status:")?;
71        writeln!(
72            f,
73            "  BeingDebugged: {}",
74            if self.being_debugged { "YES" } else { "no" }
75        )?;
76        writeln!(
77            f,
78            "  NtGlobalFlag: {}",
79            if self.nt_global_flag { "YES" } else { "no" }
80        )?;
81        writeln!(
82            f,
83            "  HeapFlags: {}",
84            if self.heap_flags { "YES" } else { "no" }
85        )
86    }
87}
88
89/// get detailed debug status
90pub fn get_debug_status() -> Result<DebugStatus> {
91    Ok(DebugStatus {
92        being_debugged: check_being_debugged()?,
93        nt_global_flag: check_nt_global_flag()?,
94        heap_flags: check_heap_flags()?,
95    })
96}