iOS + Android
Debugger attachedDebugger
Checks the P_TRACED process flag via sysctl — the Apple-documented debugger check.
At a glance
- Platform
- iOS · Android
- Category
- Debugger
- Source (iOS)
- DIIntegrityChecks.m · isDebuggerAttached
- Source (Android)
- IntegrityChecks.kt · checkDebuggerAttached
- Default status
- Makes status compromised
- Seen firing (iOS)
- Seen firing in D06. Based on validated scenarios whose observed result includes this signal; see below.
- Seen firing (Android)
- Not yet seen firing in a validated run. Based on validated scenarios whose observed result includes this signal; see below.
- OWASP MASTG
- MASTG-TEST-0089, MASTG-TEST-0046
How it works
What the code inspects.
iOS · DIIntegrityChecks.m · isDebuggerAttached
Calls sysctl with {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()} to read the kinfo_proc for the current process, then tests the P_TRACED flag in kp_proc.p_flag.
P_TRACED is set by the kernel whenever a debugger (lldb, or a ptrace-based tool) is attached. This is the technique Apple documents in QA1361.
Android · IntegrityChecks.kt · checkDebuggerAttached
Calls android.os.Debug.isDebuggerConnected() and Debug.waitingForDebugger(). Either being true means a JDWP debugger (e.g. Android Studio) is attached to, or is being awaited by, the process.
The exploit it addresses
Why this matters.The threat.
iOS · DIIntegrityChecks.m · isDebuggerAttached
A debugger lets an attacker pause the app, read and modify memory and registers, and single-step through security logic — the foundation of most runtime reverse engineering and of patching out checks like this one.
Android · IntegrityChecks.kt · checkDebuggerAttached
A debugger lets an attacker inspect and alter the running app — stepping through logic, reading variables, and modifying control flow — which is the basis for reverse engineering and for defeating other checks.
How it can be bypassed
No single check is sufficient.Known evasions.
iOS · DIIntegrityChecks.m · isDebuggerAttached
Frida and similar tools attach without setting P_TRACED, so this flag does not catch them.
An attacker who is already debugging can patch the sysctl result, or overwrite the comparison, to force the check to return NO.
Android · IntegrityChecks.kt · checkDebuggerAttached
This API only reports the Java/JDWP debugger; a native debugger (ptrace via gdb/lldb) or Frida attaches without setting it, so those are not caught here.
On a rooted device an attacker can hook Debug.isDebuggerConnected to return false.
Validation scenarios
Where this check is exercised.2 scenarios.
References & further reading
- MASTG-TEST-0089: Testing Anti-Debugging Detection (iOS)Open ↗
https://mas.owasp.org/MASTG/tests/ios/MASVS-RESILIENCE/MASTG-TEST-0089/
- Apple QA1361 — detecting the debugger (sysctl KERN_PROC)Open ↗
https://developer.apple.com/library/archive/qa/qa1361/_index.html
- ptrace(2)Open ↗
https://man7.org/linux/man-pages/man2/ptrace.2.html
- Frida — dynamic instrumentation toolkitOpen ↗
The hooking framework these checks are primarily defending against.
https://frida.re/docs/home/
- MASTG-TEST-0046: Testing Anti-Debugging Detection (Android)Open ↗
https://mas.owasp.org/MASTG/tests/android/MASVS-RESILIENCE/MASTG-TEST-0046/
- android.os.Debug.isDebuggerConnected()Open ↗
https://developer.android.com/reference/android/os/Debug