anti-debugging-techniques
Skill9 starsChanged 3 months agoMITView on GitHub
Anti-debugging detection and bypass playbook. Use when reversing protected binaries that detect debuggers via ptrace, PEB flags, timing checks, or signal/exception handlers on Linux and Windows.
4 other projects use a version of this, 4 of them edited.
Adopted by
Most recently taken up by
- ptn1411/skilledited, first seen Nov 7, 2026
- light0921/skillsedited, first seen Oct 13, 2026
- JustineDevs/premortemedited, first seen Jun 9, 2026
- yaklang/hack-skillsedited, first seen Apr 29, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 4
- yaklang/hack-skills★ 2.4k100% same
- ptn1411/skill★ 32213% same
- JustineDevs/premortem★ 2100% same
- light0921/skills★ 1100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository29 other files it gives its agents.
- AGENTS.mdAGENTS.md
- analyze-failuresSkill
- anti-drift-disciplineSkill
- binary-protection-bypassSkill
- code-obfuscation-deobfuscationSkill
- distillSkill
- dwarf-expertSkill
- emulation-reSkill
- find-skillsSkill
- ida-mcpSkill
- code-reviewSkill
- diagnosing-bugsSkill
- domain-modelingSkill
- implementSkill
- prototypeSkill
- researchSkill
- resolving-merge-conflictsSkill
- tddSkill
- to-specSkill
- writing-great-skillsSkill
- mobile-dynamic-reSkill
- native-static-reSkill
- physarumSkill
- re-escalationSkill
- re-routerSkill
- stormSkill
- symbolic-execution-toolsSkill
- vm-and-bytecode-reverseSkill
- web-reverse-engineeringSkill
The file
We split this skill into the rules it gives an agent
5 rules. 3 are common, 1 is distinctive, and 1 is very specific to this project.
3
Common
Most of the 4 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 94
When a debugger is attached, SIGTRAP is consumed by the debugger rather than delivered to the handler.
- Common: line 197
After this call, the thread becomes invisible to the debugger — breakpoints and single-stepping stop working silently.
- Common: line 403
Check: PEB BeingDebugged, NtGlobalFlag, HeapFlags
- Common: line 404
Check: NtQueryInformationProcess (all classes)
- Distinctive: line 540
If ALL of these are true, stop trying Frida and switch to emulation:
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SKILL: Anti-Debugging Techniques — Detection & Bypass Playbook
AI LOAD INSTRUCTION: Expert anti-debug techniques across Linux and Windows. Covers ptrace, PEB flags, NtQueryInformationProcess, timing attacks, signal-based detection, TLS callbacks, VEH tricks, and all corresponding bypass methods. Base models often miss the distinction between user-mode and kernel-mode detection and the correct patching strategy for each.
0. RELATED ROUTING
- code-obfuscation-deobfuscation when the binary also uses control flow flattening, VM protection, or string encryption
- vm-and-bytecode-reverse when the anti-debug sits inside a custom VM dispatcher
- symbolic-execution-tools when you want to symbolically skip anti-debug checks entirely
Advanced Reference
Also load ANTI_DEBUG_MATRIX.md when you need:
- Complete cross-reference matrix of technique × OS × detection method × bypass method
- Per-technique reliability ratings and false-positive notes
- Tool compatibility chart (GDB, x64dbg, WinDbg, Frida, ScyllaHide)
Quick bypass picks
| Detection Class | First Bypass | Backup |
| ptrace-based (Linux) | LD_PRELOAD hook ptrace() → return 0 | Kernel module to hide tracer |
| PEB.BeingDebugged (Windows) | Patch PEB byte at fs:[0x30]+0x2 | ScyllaHide auto-patch |
| Timing check (rdtsc) | Conditional BP after rdtsc, fix registers | Frida hook rdtsc return |
| IsDebuggerPresent | NOP the call / hook return 0 | x64dbg built-in hide |
| INT 2D / UD2 exception | Set VEH to handle gracefully | TitanHide driver |
1. LINUX ANTI-DEBUG TECHNIQUES
1.1 ptrace(PTRACE_TRACEME)
The classic self-attach: a process calls ptrace(PTRACE_TRACEME, 0, 0, 0). If a debugger is already attached, the call fails (returns -1).
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
exit(1); // debugger detected
}Bypass methods:
| Method | How |
LD_PRELOAD shim | Compile shared lib: long ptrace(int r, ...) { return 0; } and set LD_PRELOAD |
| Binary patch | NOP the ptrace call or patch return value check |
| GDB catch | catch syscall ptrace → modify $rax to 0 on return |
| Kernel module | Hook sys_ptrace to allow multiple tracers |
1.2 /proc/self/status — TracerPid
FILE *f = fopen("/proc/self/status", "r");
// parse TracerPid: if non-zero → debugger attachedBypass: Mount a FUSE filesystem over /proc/self, or LD_PRELOAD hook fopen/fread to filter TracerPid to 0.
1.3 Timing Checks (rdtsc / clock_gettime)
Measures elapsed time between two points; debugger single-stepping causes noticeable delay.
rdtsc
mov ebx, eax ; save low 32 bits
; ... protected code ...
rdtsc
sub eax, ebx
cmp eax, 0x1000 ; threshold
ja debugger_detectedBypass: Set hardware breakpoint after second rdtsc, modify eax to pass the comparison. Or use Frida to replace the timing function.
1.4 Signal-Based Detection (SIGTRAP)
volatile int caught = 0;
void handler(int sig) { caught = 1; }
signal(SIGTRAP, handler);
raise(SIGTRAP);
if (!caught) exit(1); // debugger swallowed the signalWhen a debugger is attached, SIGTRAP is consumed by the debugger rather than delivered to the handler. Bypass: In GDB, use handle SIGTRAP nostop pass to forward the signal.
1.5 /proc/self/maps & LD_PRELOAD Detection
Checks for injected libraries or memory regions characteristic of debuggers/instrumentation.
FILE *f = fopen("/proc/self/maps", "r");
while (fgets(buf, sizeof(buf), f)) {
if (strstr(buf, "frida") || strstr(buf, "LD_PRELOAD"))
exit(1);
}Bypass: Hook fopen("/proc/self/maps") to return a filtered version, or rename Frida's agent library.
1.6 Environment Variable Checks
Some protections check for LD_PRELOAD, LINES, COLUMNS (set by GDB's terminal), or debugger-specific env vars.
Bypass: Unset suspicious env vars before launch, or hook getenv().
2. WINDOWS ANTI-DEBUG TECHNIQUES
2.1 IsDebuggerPresent / CheckRemoteDebuggerPresent
if (IsDebuggerPresent()) ExitProcess(1);
BOOL debugged = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debugged);
if (debugged) ExitProcess(1);Bypass: Hook kernel32!IsDebuggerPresent to return 0, or patch PEB directly.
2.2 PEB Flags
| Field | Offset (x64) | Debugged Value | Normal Value |
BeingDebugged | PEB+0x02 | 1 | 0 |
NtGlobalFlag | PEB+0xBC | 0x70 (FLG_HEAP_*) | 0 |
ProcessHeap.Flags | Heap+0x40 | 0x40000062 | 0x00000002 |
ProcessHeap.ForceFlags | Heap+0x44 | 0x40000060 | 0 |
mov rax, gs:[0x60] ; PEB
movzx eax, byte [rax+0x02] ; BeingDebugged
test eax, eax
jnz debugger_detectedBypass: Zero all four fields. ScyllaHide does this automatically.
2.3 NtQueryInformationProcess
| InfoClass | Value | Debugged Return |
ProcessDebugPort | 0x07 | Non-zero port |
ProcessDebugObjectHandle | 0x1E | Valid handle |
ProcessDebugFlags | 0x1F | 0 (inverted!) |
Bypass: Hook ntdll!NtQueryInformationProcess to return clean values per info class.
2.4 Hardware Breakpoint Detection
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &ctx);
if (ctx.Dr0 || ctx.Dr1 || ctx.Dr2 || ctx.Dr3)
ExitProcess(1);Bypass: Hook GetThreadContext to zero DR0–DR3, or use NtSetInformationThread(ThreadHideFromDebugger) preemptively (ironically, the anti-debug technique itself).
2.5 INT 2D / INT 3 / UD2 Exception Tricks
INT 2D is the kernel debug service interrupt. Without a debugger, it raises STATUS_BREAKPOINT; with a debugger, behavior differs (byte skipping).
xor eax, eax
int 2dh
nop ; debugger may skip this byte
; ... divergent execution path ...Bypass: Handle in VEH or patch the interrupt instruction.
2.6 TLS Callbacks
TLS callbacks execute before main() / WinMain(). Anti-debug checks placed here run before the debugger's initial break.
Bypass: In x64dbg, set "Break on TLS Callbacks" option. In WinDbg, use sxe ld to break on module load.
2.7 NtSetInformationThread(ThreadHideFromDebugger)
NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);After this call, the thread becomes invisible to the debugger — breakpoints and single-stepping stop working silently.
Bypass: Hook NtSetInformationThread to NOP when ThreadInfoClass == 0x11.
2.8 VEH-Based Detection
Registers a Vectored Exception Handler that checks EXCEPTION_RECORD for debugger-specific behavior (single-step flag, guard page violations with debugger semantics).
Bypass: Understand the VEH logic and ensure the exception chain behaves identically to non-debugged execution.
3. ADVANCED MULTI-LAYER TECHNIQUES
3.1 Self-Debugging (fork + ptrace)
The process forks a child that attaches to the parent via ptrace. If an external debugger is already attached, the child's ptrace fails.
pid_t child = fork();
if (child == 0) {
if (ptrace(PTRACE_ATTACH, getppid(), 0, 0) == -1)
kill(getppid(), SIGKILL);
else
ptrace(PTRACE_DETACH, getppid(), 0, 0);
_exit(0);
}
wait(NULL);Bypass: Patch the fork() return or kill/detach the watchdog child.
3.2 Multi-Process Debugging Detection
Parent and child cooperatively check each other's debug state, creating a mutual-watch pattern.
Bypass: Attach to both processes (GDB follow-fork-mode, or two debugger instances).
3.3 Timing-Based with Multiple Checkpoints
Distributes timing checks across multiple functions, comparing cumulative drift. Single patches fail because the total still exceeds threshold.
Bypass: Frida Interceptor.replace all timing sources (rdtsc, clock_gettime, QueryPerformanceCounter) to return controlled values.
3.4 Nanomite / INT3 Patching
Original conditional jumps are replaced with INT3 (0xCC). A parent debugger process handles each INT3, evaluates the condition, and sets the child's EIP accordingly.
Bypass: Reconstruct the original jump table by tracing all INT3 handlers, then patch the binary.
4. COUNTERMEASURE TOOLS
| Tool | Platform | Capability |
| ScyllaHide | Windows (x64dbg/IDA/OllyDbg) | Auto-patches PEB, hooks NtQuery*, hides threads, fixes timing |
| TitanHide | Windows (kernel driver) | Kernel-level hiding for all user-mode checks |
| Frida | Cross-platform | Script-based hooking of any function, timing spoofing |
| LD_PRELOAD shims | Linux | Replace ptrace, getenv, fopen at load time |
| GDB scripts | Linux | catch syscall, conditional BP, register fixup |
| Qiling | Cross-platform | Full-system emulation, bypass all hardware checks |
5. SYSTEMATIC BYPASS METHODOLOGY
Step 1: Static analysis — identify anti-debug calls
└─ Search for: ptrace, IsDebuggerPresent, NtQuery, rdtsc,
GetTickCount, SIGTRAP, INT 2D, TLS directory entries
Step 2: Classify each check
├─ API-based → hook or patch the call
├─ Flag-based → patch PEB/proc fields
├─ Timing-based → spoof time source
├─ Exception-based → forward/handle exception correctly
└─ Multi-process → handle both processes
Step 3: Apply bypass (order matters)
1. Load ScyllaHide / set LD_PRELOAD (covers 80% of checks)
2. Handle TLS callbacks (break before main)
3. Patch remaining custom checks (Frida or binary patch)
4. Verify: run with breakpoints, confirm no premature exit
Step 4: Validate bypass completeness
└─ Set BP on ExitProcess/exit/_exit — if hit unexpectedly,
a check was missed → trace back from exit call6. DECISION TREE
Binary exits/crashes under debugger?
│
├─ Crashes immediately before main?
│ └─ TLS callback anti-debug
│ └─ Enable TLS callback breaking in debugger
│
├─ Crashes at startup?
│ ├─ Linux: check for ptrace(TRACEME)
│ │ └─ LD_PRELOAD hook or NOP patch
│ └─ Windows: check IsDebuggerPresent / PEB
│ └─ ScyllaHide or manual PEB patch
│
├─ Crashes after some execution?
│ ├─ Consistent crash point → API-based check
│ │ ├─ NtQueryInformationProcess → hook return values
│ │ ├─ /proc/self/status → filter TracerPid
│ │ └─ Hardware BP detection → hook GetThreadContext
│ │
│ ├─ Variable crash point → timing-based check
│ │ └─ Hook rdtsc / QueryPerformanceCounter
│ │
│ └─ Crash on breakpoint hit → exception-based check
│ ├─ INT 2D / INT 3 trick → handle in VEH
│ └─ SIGTRAP handler → GDB: handle SIGTRAP pass
│
├─ Debugger loses control silently?
│ └─ ThreadHideFromDebugger
│ └─ Hook NtSetInformationThread
│
├─ Child process detects and kills parent?
│ └─ Self-debugging (fork+ptrace)
│ └─ Patch fork() or handle both processes
│
└─ All basic bypasses applied but still detected?
└─ Multi-layer / custom checks
├─ Use Frida for comprehensive API hooking
├─ Full emulation with Qiling
└─ Trace all calls to exit/abort to find remaining checks7. CTF & REAL-WORLD PATTERNS
Common CTF Anti-Debug Patterns
| Pattern | Frequency | Quick Bypass |
Single ptrace(TRACEME) | Very common | LD_PRELOAD one-liner |
IsDebuggerPresent + NtGlobalFlag | Common | ScyllaHide |
| rdtsc timing in loop | Moderate | Patch comparison threshold |
| signal(SIGTRAP) + raise | Moderate | GDB signal forwarding |
| fork + ptrace watchdog | Rare but tricky | Kill child or patch fork |
| Nanomite INT3 replacement | Rare (advanced) | Reconstruct jump table |
Real-World Protections
| Protector | Primary Anti-Debug | Recommended Tool |
| VMProtect | PEB + timing + driver-level | TitanHide + ScyllaHide |
| Themida | Multi-layer PEB + SEH + timing | ScyllaHide + manual patches |
| Enigma Protector | IsDebuggerPresent + CRC checks | x64dbg + ScyllaHide |
| UPX (custom) | Usually none (just packing) | Standard unpack |
| Custom (malware) | Varies widely | Frida + Qiling for analysis |
8. QUICK REFERENCE — BYPASS CHEAT SHEET
Linux One-Liners
# LD_PRELOAD anti-ptrace
echo 'long ptrace(int r, ...) { return 0; }' > /tmp/ap.c
gcc -shared -o /tmp/ap.so /tmp/ap.c
LD_PRELOAD=/tmp/ap.so ./target
# GDB: catch and bypass ptrace
(gdb) catch syscall ptrace
(gdb) commands
> set $rax = 0
> continue
> endFrida Anti-Debug Bypass (Cross-Platform)
// Hook IsDebuggerPresent (Windows)
Interceptor.replace(
Module.getExportByName('kernel32.dll', 'IsDebuggerPresent'),
new NativeCallback(() => 0, 'int', [])
);
// Hook ptrace (Linux)
Interceptor.replace(
Module.getExportByName(null, 'ptrace'),
new NativeCallback(() => 0, 'long', ['int', 'int', 'pointer', 'pointer'])
);
// Timing spoof
Interceptor.attach(Module.getExportByName(null, 'clock_gettime'), {
onLeave(retval) {
// manipulate timespec to hide debugger delay
}
});x64dbg ScyllaHide Quick Setup
- Plugins → ScyllaHide → Options
- Check: PEB BeingDebugged, NtGlobalFlag, HeapFlags
- Check: NtQueryInformationProcess (all classes)
- Check: NtSetInformationThread (HideFromDebugger)
- Check: GetTickCount, QueryPerformanceCounter
- Apply → restart debugging session
9. iOS ANTI-DEBUG & ANTI-JAILBREAK DETECTION
Detection Vectors
| # | Detection Method | API/Mechanism | What It Checks | Reliability |
| 1 | sysctl P_TRACED | sysctl(CTL_KERN, KERN_PROC, KERN_PROC_PID, pid) | kp_proc.p_flag & P_TRACED | High |
| 2 | ptrace deny | ptrace(PT_DENY_ATTACH, 0, 0, 0) | Prevents debugger attachment | High |
| 3 | File existence | access() / stat() / NSFileManager | Cydia.app, sshd, apt, bash, etc. | Medium (easy to hook) |
| 4 | URL scheme | UIApplication canOpenURL: | cydia://, sileo:// | Low (easy to hook) |
| 5 | Dylib enumeration | _dyld_image_count() + _dyld_get_image_name() | Substrate, Frida dylibs in load list | High |
| 6 | Environment vars | getenv("DYLD_INSERT_LIBRARIES") | Injected library paths | Medium |
| 7 | Sandbox integrity | sandbox_check(pid, "process-fork", ...) | Fork allowed = jailbroken | Medium |
| 8 | Symbol resolution | dlsym(RTLD_DEFAULT, "MSHookFunction") | Substrate/Frida symbols in memory | High |
| 9 | Integrity check | Code hash validation at runtime | Detects inline hooks / patches | Very High |
| 10 | Port scan | Connect to localhost:27042 (Frida default) | Frida server running | Medium |
| 11 | Exception-based | Set invalid instruction, catch signal | Debugger alters signal delivery | Medium |
| 12 | Timing check | mach_absolute_time() between instructions | Debugger slows execution | Low (unstable) |
Bypass Quick Reference
| Detection | Bypass Method | Frida Script Pattern |
| sysctl P_TRACED | Hook sysctl, clear P_TRACED flag in result | Interceptor.attach(Module.findExportByName(null, "sysctl"), ...) |
| ptrace deny | Hook ptrace, return 0 when PT_DENY_ATTACH | Interceptor.attach(Module.findExportByName(null, "ptrace"), { onEnter: if(args[0]==31) ... }) |
| File checks | Hook access/stat/NSFileManager, return ENOENT for blacklisted paths | See mobile-dynamic-re §4.1 |
| Dylib enum | Hook _dyld_get_image_name, filter suspicious names | Filter strings containing "frida", "substrate", "substitute" |
| getenv | Hook getenv, return NULL for DYLD_* keys | Interceptor.attach(Module.findExportByName(null, "getenv"), ...) |
| dlsym | Hook dlsym, return NULL for hook-framework symbols | Return NULL for "MSHookFunction", "frida_agent_main" |
| Integrity check | Avoid inline hooks (use Stalker), or hook the check function itself | Load re-escalation if integrity check is comprehensive |
| Port scan | Use non-default Frida port (-l 0.0.0.0:12345) | Configuration change, not code |
iOS Bypass Priority (覆盖率分析)
| Priority | Checks to Bypass | Effort | Covers |
| 1st (do these first) | File existence + URL scheme + getenv | 5 min | ~60% of apps |
| 2nd | Dylib enum + dlsym + sysctl | 15 min | ~85% of apps |
| 3rd | Integrity checks + timing | 30-60 min | ~95% of apps |
| 4th | Custom/proprietary detection | Hours | Remaining 5% |
10. ANDROID ANTI-DEBUG & ANTI-ROOT DETECTION
Detection Vectors
| # | Detection Method | Mechanism | What It Checks | Reliability |
| 1 | TracerPid | Read /proc/self/status | TracerPid != 0 means being traced | High |
| 2 | /proc/self/maps | Read process memory map | Look for frida-agent, xposed entries | High |
| 3 | su binary | access("/system/bin/su") / which su | su exists = rooted | Medium |
| 4 | Root packages | Check installed packages | SuperSU, Magisk Manager, KernelSU | Medium |
| 5 | Build props | android.os.Build fields | test-keys, userdebug | Low |
| 6 | SELinux status | getenforce | Permissive = likely rooted | Medium |
| 7 | Mount points | Parse /proc/mounts | Magisk overlay mounts | High (hard to hide) |
| 8 | Native fork detection | fork() + ptrace(PTRACE_TRACEME) | If ptrace fails, debugger attached | High |
| 9 | Thread enumeration | /proc/self/task/ | Unexpected threads (Frida agent) | Medium |
| 10 | Socket scan | Enumerate /proc/net/tcp | Frida default port 27042 | Medium |
| 11 | Java debugger | android.os.Debug.isDebuggerConnected() | JDWP attached | High |
| 12 | Signal handling | SIGTRAP delivery timing | Debugger intercepts signals | Medium |
Bypass Quick Reference
| Detection | Bypass Method | Implementation |
| TracerPid | Hook open("/proc/self/status"), replace TracerPid line | Return "TracerPid:\t0" in hooked read |
| /proc/self/maps | Hook file read, filter frida/xposed lines | String filtering in read() result |
| su binary | Hook access(), return -1 for su paths | Interceptor on access syscall |
| Root packages | Hook PackageManager.getPackageInfo | Java.use → return PackageNotFoundException |
| Build props | Hook SystemProperties.get | Return "release-keys" for ro.build.tags |
| Magisk | Use MagiskHide / Zygisk DenyList | Configuration, not code |
| isDebuggerConnected | Hook method, return false | Java.use("android.os.Debug").isDebuggerConnected.implementation = () => false |
| Fork+ptrace | Hook ptrace, return 0 | Native Interceptor |
Android Bypass Priority
| Priority | Checks | Effort | Covers |
| 1st | su/root packages + Build props | 5 min | ~50% of apps |
| 2nd | TracerPid + /proc/self/maps | 10 min | ~75% of apps |
| 3rd | Magisk detection + mount points | 15 min | ~90% (use Zygisk) |
| 4th | Custom native checks | 30+ min | Remaining |
11. FRIDA DETECTION & COUNTERMEASURES
How Apps Detect Frida
| # | Detection Vector | Mechanism | Difficulty to Bypass |
| 1 | Default port (27042) | TCP connect to localhost:27042 | Easy (change port) |
| 2 | frida-server process name | Enumerate /proc, check cmdline | Easy (rename binary) |
| 3 | D-Bus protocol | Send D-Bus AUTH message on connections | Medium |
| 4 | Library mapping | /proc/self/maps contains "frida-agent" | Medium (hook read) |
| 5 | Thread naming | frida threads have distinctive names | Medium (hook pthread) |
| 6 | Inline hook detection | Check function prologues for hook trampolines | Hard |
| 7 | Memory scanning | Scan for known Frida gadget strings/signatures | Hard |
| 8 | Code page permissions | RWX pages indicate JIT (Frida Stalker) | Medium |
| 9 | Exception port (iOS) | Mach exception ports registered by Frida | Hard |
| 10 | Symbol scanning | dladdr/dlsym for Frida internal symbols | Medium |
Stealth Configuration
# Basic stealth (defeats 70% of detection)
frida -l script.js -H device:12345 --runtime=v8 # non-default port
# Rename frida-server (defeats process name scan)
cp frida-server /usr/bin/fs-daemon
/usr/bin/fs-daemon -l 0.0.0.0:12345
# Use frida-gadget (inject into app, no server process)
# Most stealthy — no external process, no default portAdvanced: Avoid Hook Detection
| Technique | When to Use | Trade-off |
| Stalker (code tracing) | When target checks for inline hooks | Slower, but zero code modification |
| Spawn + early hook | When timing-based detection runs at init | Must hook before detection code runs |
| LD_PRELOAD injection | When Frida itself is detected | Different injection vector |
| Kernel-level (kprobes) | Last resort, all userland methods failed | Requires root + kernel module |
| Emulation (→ emulation-re) | When all dynamic approaches blocked | Different paradigm entirely |
Decision: When to Switch from Dynamic to Emulation
If ALL of these are true, stop trying Frida and switch to emulation:
- App uses integrity checks (can't modify code)
- App detects Frida by memory scanning (can't inject)
- App uses anti-tamper on detection functions themselves (can't bypass)
→ Load emulation-re for offline approach → Load re-escalation for systematic upgrade
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

