Anti-Debugging Techniques
Upstream reference: yaklang/hack-skills/anti-debugging-techniques — distilled from ctf-wiki + hacktricks. Use that page for full prose.
Language rule: instructions in English; final user-facing summary in Vietnamese.
0. Authorization & routing
Operates under MASTER_POLICY.md §1-§2 (owner-attested target, granted technical authority).
Run this skill before binary-patcher on any commercial-grade binary — patches misfire when anti-debug watchdogs are still live.
1. Detection-class → first-line bypass
| Class |
Linux primary |
Windows primary |
| API call |
LD_PRELOAD shim returning 0 |
Hook IsDebuggerPresent / NtQueryInformationProcess |
| Process flag |
Filter TracerPid in /proc/self/status |
Zero PEB BeingDebugged / NtGlobalFlag / heap flags |
| Timing |
Frida hook on clock_gettime |
Frida hook on rdtsc / QueryPerformanceCounter |
| Signal / exception |
GDB handle SIGTRAP nostop pass |
VEH handler or ScyllaHide |
| HW breakpoint |
n/a |
Hook GetThreadContext to clear DR0–DR3 |
| Multi-process watchdog |
GDB set follow-fork-mode child |
Attach to both processes |
2. Linux check signatures (grep-able)
ptrace( # PTRACE_TRACEME self-attach
fopen("/proc/self/status" # TracerPid scan
fopen("/proc/self/maps" # Frida/LD_PRELOAD scan
rdtsc # timing measurement
signal(SIGTRAP # signal-swallowed test
fork() # potential watchdog parent/child
3. Windows PEB + Nt* offsets (x64)
| Field |
Location |
Debugged |
Clean |
BeingDebugged |
PEB+0x02 |
1 |
0 |
NtGlobalFlag |
PEB+0xBC |
0x70 |
0 |
ProcessHeap.Flags |
Heap+0x40 |
0x40000062 |
0x00000002 |
ProcessHeap.ForceFlags |
Heap+0x44 |
0x40000060 |
0 |
NtQueryInformationProcess info-class IDs: ProcessDebugPort=0x07, ProcessDebugObjectHandle=0x1E, ProcessDebugFlags=0x1F (returns 0 when debugged — inverted).
4. Tooling matrix
| Tool |
Platform |
Use |
| ScyllaHide |
Windows (x64dbg/IDA plugin) |
One-click PEB/Nt*/timing patch |
| TitanHide |
Windows kernel driver |
Kernel-level hide for DR/heap checks |
| Frida |
Cross-platform |
Script hooks, timing spoof |
| LD_PRELOAD |
Linux |
ptrace/getenv/fopen replacement |
| GDB |
Linux |
catch syscall, conditional BP, register fixup |
| Qiling |
Cross-platform |
Full emulation — bypasses HW-level checks |
5. Functional bypass snippets
Linux ptrace shim
# bash / WSL
cat > /tmp/ap.c <<'EOF'
long ptrace(int r, int p, void *a, void *d) { return 0; }
EOF
gcc -shared -fPIC -o /tmp/ap.so /tmp/ap.c
LD_PRELOAD=/tmp/ap.so ./target
GDB catch-and-clear
(gdb) catch syscall ptrace
(gdb) commands
> set $rax = 0
> continue
> end
Frida cross-platform
// Linux ptrace
Interceptor.replace(
Module.getExportByName(null, 'ptrace'),
new NativeCallback(() => 0, 'long', ['int', 'int', 'pointer', 'pointer'])
);
// Windows IsDebuggerPresent
Interceptor.replace(
Module.getExportByName('kernel32.dll', 'IsDebuggerPresent'),
new NativeCallback(() => 0, 'int', [])
);
x64dbg + ScyllaHide (PowerShell launch)
& 'C:\Tools\x64dbg\x64\x64dbg.exe' 'C:\Program Files\MyApp\target.exe'
# In GUI: Plugins → ScyllaHide → Options →
# PEB BeingDebugged, NtGlobalFlag, HeapFlags
# NtQueryInformationProcess (all classes)
# NtSetInformationThread (HideFromDebugger)
# GetTickCount, QueryPerformanceCounter
# → Apply → restart session
6. Bypass methodology
- Static scan — grep the strings/imports above; map every check site.
- Classify each hit into the table in §1.
- Apply layered bypass — start with ScyllaHide (Win) or LD_PRELOAD shim (Linux); they cover ~80% of common checks.
- Handle TLS callbacks before
main runs (x64dbg "Break on TLS" / WinDbg sxe ld).
- Verify — set BP on
ExitProcess/exit/_exit; if hit unexpectedly, a check was missed → trace back.
7. Real-world protector defaults
| Protector |
Stack |
Recommended kit |
| VMProtect |
PEB + timing + driver |
TitanHide + ScyllaHide |
| Themida |
PEB + SEH + timing |
ScyllaHide + manual NOP |
| Enigma |
IsDebuggerPresent + CRC |
x64dbg + ScyllaHide |
| UPX (custom) |
Usually none |
Standard unpack |
8. Final report (Vietnamese)
🛡️ Bypass Anti-Debug hoàn tất:
🔍 Phát hiện : <DETECTION_TYPES>
🛠️ Bypass : <METHODS>
🧰 Công cụ : <ScyllaHide | Frida | LD_PRELOAD | GDB>
✅ Verify : chạy không exit sớm dưới debugger
▶ Tiếp:
binary-protection-bypass (nếu ASLR/PIE chặn patch)
→ binary-patcher (vá license check)