Skip to content

Anti-Debugging: IsDebuggerPresent (Windows)

A textbook anti-analysis check that reads the PEB via the IsDebuggerPresent API to detect whether a user-mode debugger is attached to the current process.

Published on 1 min read
Platform:
Windows
Language:
C
Difficulty:
Beginner

Authorized use only. This snippet is documented for malware analysis, detection engineering, and red-team education. Run it only against systems and samples you own or are explicitly authorized to test.

Overview

IsDebuggerPresent is the simplest anti-debugging primitive on Windows. It returns a non-zero value when a user-mode debugger is attached to the calling process. Under the hood it does nothing more than read the BeingDebugged byte of the Process Environment Block (PEB) — so it is trivial to implement, and equally trivial to bypass.

It shows up constantly in commodity malware as a first-pass sandbox/analyst check, which makes it a useful teaching example for both sides of the fence.

Snippet

#include <windows.h>
#include <stdio.h>

int main(void) {
    if (IsDebuggerPresent()) {
        // A debugger is attached — a real sample would bail out or branch
        // into benign behaviour here. We just report it.
        printf("[!] Debugger detected.\n");
        return 1;
    }

    printf("[+] No debugger detected.\n");
    return 0;
}

Reading the PEB directly

IsDebuggerPresent is a thin wrapper. The same signal can be read without the API call, which evades naive import-table or API-hook based detection:

#include <windows.h>

BOOL BeingDebugged(void) {
#ifdef _WIN64
    PPEB peb = (PPEB)__readgsqword(0x60);
#else
    PPEB peb = (PPEB)__readfsdword(0x30);
#endif
    return peb->BeingDebugged;
}

Detection & defeating it

  • For analysts: patch the BeingDebugged flag to 0, or set a breakpoint on kernel32!IsDebuggerPresent and force the return value. Tools like ScyllaHide automate this.
  • For detection engineers: the API call itself is not malicious, but its presence alongside other evasion primitives (timing checks, CheckRemoteDebuggerPresent, NtQueryInformationProcess) is a strong heuristic signal.

References

  • Microsoft Learn — IsDebuggerPresent function (debugapi.h)
  • The "Ultimate Anti-Debugging Reference" by Peter Ferrie

Discussion