anti-debugging-techniques
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSKILL: Anti-Debugging Techniques — Detection & Bypass Playbook
SKILL:反调试技术——检测与绕过指南
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.
AI加载说明:涵盖Linux和Windows平台的专业反调试技术,包括ptrace、PEB标志、NtQueryInformationProcess、时序攻击、基于信号的检测、TLS回调、VEH技巧,以及所有对应的绕过方法。基础模型通常会混淆用户态和内核态检测的区别,也无法给出每种场景对应的正确补丁策略。
0. RELATED ROUTING
0. 相关路由
- 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
- 若二进制文件还使用了控制流平坦化、VM保护或字符串加密,参考code-obfuscation-deobfuscation
- 若反调试逻辑位于自定义VM分发器内部,参考vm-and-bytecode-reverse
- 若你想通过符号执行完全跳过反调试检查,参考symbolic-execution-tools
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)
若你需要以下内容,请同时加载ANTI_DEBUG_MATRIX.md:
- 技术×操作系统×检测方法×绕过方法的完整交叉参考矩阵
- 每项技术的可靠性评级和误报说明
- 工具兼容性对照表(GDB, x64dbg, WinDbg, Frida, ScyllaHide)
Quick bypass picks
快速绕过方案
| Detection Class | First Bypass | Backup |
|---|---|---|
| ptrace-based (Linux) | | Kernel module to hide tracer |
| PEB.BeingDebugged (Windows) | Patch PEB byte at | ScyllaHide auto-patch |
| Timing check (rdtsc) | Conditional BP after rdtsc, fix registers | Frida hook |
| IsDebuggerPresent | NOP the call / hook return 0 | x64dbg built-in hide |
| INT 2D / UD2 exception | Set VEH to handle gracefully | TitanHide driver |
| 检测类别 | 首选绕过方法 | 备选方法 |
|---|---|---|
| 基于ptrace(Linux) | | 内核模块隐藏调试器 |
| PEB.BeingDebugged(Windows) | 修补 | ScyllaHide自动补丁 |
| 时序检查(rdtsc) | 在rdtsc后设置条件断点,修复寄存器值 | Frida hook |
| IsDebuggerPresent | NOP掉调用 / hook返回0 | x64dbg内置隐藏功能 |
| INT 2D / UD2 异常 | 设置VEH优雅处理 | TitanHide驱动 |
1. LINUX ANTI-DEBUG TECHNIQUES
1. Linux反调试技术
1.1 ptrace(PTRACE_TRACEME)
1.1 ptrace(PTRACE_TRACEME)
The classic self-attach: a process calls . If a debugger is already attached, the call fails (returns -1).
ptrace(PTRACE_TRACEME, 0, 0, 0)c
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
exit(1); // debugger detected
}Bypass methods:
| Method | How |
|---|---|
| Compile shared lib: |
| Binary patch | NOP the |
| GDB catch | |
| Kernel module | Hook |
经典的自附加逻辑:进程调用,如果已有调试器附加,调用会失败(返回-1)。
ptrace(PTRACE_TRACEME, 0, 0, 0)c
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
exit(1); // 检测到调试器
}绕过方法:
| 方法 | 实现方式 |
|---|---|
| 编译共享库: |
| 二进制补丁 | NOP掉 |
| GDB捕获 | |
| 内核模块 | Hook |
1.2 /proc/self/status — TracerPid
1.2 /proc/self/status — TracerPid
c
FILE *f = fopen("/proc/self/status", "r");
// parse TracerPid: if non-zero → debugger attachedBypass: Mount a FUSE filesystem over , or hook / to filter to 0.
/proc/selfLD_PRELOADfopenfreadTracerPidc
FILE *f = fopen("/proc/self/status", "r");
// 解析TracerPid:如果非零 → 有调试器附加绕过:在上挂载FUSE文件系统,或者通过 hook /将过滤为0。
/proc/selfLD_PRELOADfopenfreadTracerPid1.3 Timing Checks (rdtsc / clock_gettime)
1.3 时序检查(rdtsc / clock_gettime)
Measures elapsed time between two points; debugger single-stepping causes noticeable delay.
asm
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 , modify to pass the comparison. Or use Frida to replace the timing function.
rdtsceax测量两个节点之间的耗时,调试器单步执行会产生明显的延迟。
asm
rdtsc
mov ebx, eax ; 保存低32位
; ... 受保护代码 ...
rdtsc
sub eax, ebx
cmp eax, 0x1000 ; 阈值
ja debugger_detected绕过:在第二个后设置硬件断点,修改值通过比较。或者使用Frida替换计时函数。
rdtsceax1.4 Signal-Based Detection (SIGTRAP)
1.4 基于信号的检测(SIGTRAP)
c
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, is consumed by the debugger rather than delivered to the handler. Bypass: In GDB, use to forward the signal.
SIGTRAPhandle SIGTRAP nostop passc
volatile int caught = 0;
void handler(int sig) { caught = 1; }
signal(SIGTRAP, handler);
raise(SIGTRAP);
if (!caught) exit(1); // 调试器吞噬了信号当有调试器附加时,会被调试器消费而不会传递给处理函数。绕过:在GDB中使用转发信号。
SIGTRAPhandle SIGTRAP nostop pass1.5 /proc/self/maps & LD_PRELOAD Detection
1.5 /proc/self/maps & LD_PRELOAD检测
Checks for injected libraries or memory regions characteristic of debuggers/instrumentation.
c
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 to return a filtered version, or rename Frida's agent library.
fopen("/proc/self/maps")检查是否存在调试器/插桩工具注入的库或特征内存区域。
c
FILE *f = fopen("/proc/self/maps", "r");
while (fgets(buf, sizeof(buf), f)) {
if (strstr(buf, "frida") || strstr(buf, "LD_PRELOAD"))
exit(1);
}绕过:Hook 返回过滤后的内容,或者重命名Frida的agent库。
fopen("/proc/self/maps")1.6 Environment Variable Checks
1.6 环境变量检查
Some protections check for , , (set by GDB's terminal), or debugger-specific env vars.
LD_PRELOADLINESCOLUMNSBypass: Unset suspicious env vars before launch, or hook .
getenv()部分保护机制会检查、、(GDB终端设置)或者调试器专属环境变量。
LD_PRELOADLINESCOLUMNS绕过:启动前清除可疑环境变量,或者hook 。
getenv()2. WINDOWS ANTI-DEBUG TECHNIQUES
2. Windows反调试技术
2.1 IsDebuggerPresent / CheckRemoteDebuggerPresent
2.1 IsDebuggerPresent / CheckRemoteDebuggerPresent
c
if (IsDebuggerPresent()) ExitProcess(1);
BOOL debugged = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debugged);
if (debugged) ExitProcess(1);Bypass: Hook to return 0, or patch PEB directly.
kernel32!IsDebuggerPresentc
if (IsDebuggerPresent()) ExitProcess(1);
BOOL debugged = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debugged);
if (debugged) ExitProcess(1);绕过:Hook 返回0,或者直接修改PEB。
kernel32!IsDebuggerPresent2.2 PEB Flags
2.2 PEB标志
| Field | Offset (x64) | Debugged Value | Normal Value |
|---|---|---|---|
| | 1 | 0 |
| | | 0 |
| Heap+0x40 | | |
| Heap+0x44 | | 0 |
asm
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.
| 字段 | 偏移(x64) | 被调试时值 | 正常时值 |
|---|---|---|---|
| | 1 | 0 |
| | | 0 |
| Heap+0x40 | | |
| Heap+0x44 | | 0 |
asm
mov rax, gs:[0x60] ; PEB
movzx eax, byte [rax+0x02] ; BeingDebugged
test eax, eax
jnz debugger_detected绕过:将这四个字段清零,ScyllaHide会自动完成该操作。
2.3 NtQueryInformationProcess
2.3 NtQueryInformationProcess
| InfoClass | Value | Debugged Return |
|---|---|---|
| 0x07 | Non-zero port |
| 0x1E | Valid handle |
| 0x1F | 0 (inverted!) |
Bypass: Hook to return clean values per info class.
ntdll!NtQueryInformationProcess| 信息类 | 值 | 被调试时返回值 |
|---|---|---|
| 0x07 | 非零端口 |
| 0x1E | 有效句柄 |
| 0x1F | 0(反向判断!) |
绕过:Hook 根据信息类返回正常数值。
ntdll!NtQueryInformationProcess2.4 Hardware Breakpoint Detection
2.4 硬件断点检测
c
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &ctx);
if (ctx.Dr0 || ctx.Dr1 || ctx.Dr2 || ctx.Dr3)
ExitProcess(1);Bypass: Hook to zero DR0–DR3, or use preemptively (ironically, the anti-debug technique itself).
GetThreadContextNtSetInformationThread(ThreadHideFromDebugger)c
CONTEXT ctx;
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &ctx);
if (ctx.Dr0 || ctx.Dr1 || ctx.Dr2 || ctx.Dr3)
ExitProcess(1);绕过:Hook 将DR0–DR3清零,或者提前调用(讽刺的是,这本身就是反调试技术)。
GetThreadContextNtSetInformationThread(ThreadHideFromDebugger)2.5 INT 2D / INT 3 / UD2 Exception Tricks
2.5 INT 2D / INT 3 / UD2 异常技巧
INT 2DSTATUS_BREAKPOINTasm
xor eax, eax
int 2dh
nop ; debugger may skip this byte
; ... divergent execution path ...Bypass: Handle in VEH or patch the interrupt instruction.
INT 2DSTATUS_BREAKPOINTasm
xor eax, eax
int 2dh
nop ; 调试器可能跳过该字节
; ... 执行路径分歧 ...绕过:在VEH中处理或者补丁中断指令。
2.6 TLS Callbacks
2.6 TLS回调
TLS callbacks execute before / . Anti-debug checks placed here run before the debugger's initial break.
main()WinMain()Bypass: In x64dbg, set "Break on TLS Callbacks" option. In WinDbg, use to break on module load.
sxe ldTLS回调会在 / 之前执行,放在这里的反调试检查会在调试器初始断点之前运行。
main()WinMain()绕过:在x64dbg中开启“TLS回调时中断”选项,在WinDbg中使用在模块加载时中断。
sxe ld2.7 NtSetInformationThread(ThreadHideFromDebugger)
2.7 NtSetInformationThread(ThreadHideFromDebugger)
c
NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);After this call, the thread becomes invisible to the debugger — breakpoints and single-stepping stop working silently.
Bypass: Hook to NOP when .
NtSetInformationThreadThreadInfoClass == 0x11c
NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);调用后线程对调试器不可见,断点和单步执行会静默失效。
绕过:Hook ,当时NOP掉调用。
NtSetInformationThreadThreadInfoClass == 0x112.8 VEH-Based Detection
2.8 基于VEH的检测
Registers a Vectored Exception Handler that checks for debugger-specific behavior (single-step flag, guard page violations with debugger semantics).
EXCEPTION_RECORDBypass: Understand the VEH logic and ensure the exception chain behaves identically to non-debugged execution.
注册向量化异常处理程序,检查中调试器专属行为(单步标志、符合调试器特征的守卫页违规)。
EXCEPTION_RECORD绕过:理解VEH逻辑,确保异常链行为和非调试状态完全一致。
3. ADVANCED MULTI-LAYER TECHNIQUES
3. 高级多层技术
3.1 Self-Debugging (fork + ptrace)
3.1 自调试(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.
c
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 return or kill/detach the watchdog child.
fork()进程fork出子进程,子进程通过ptrace附加到父进程。如果已有外部调试器附加,子进程的ptrace会失败。
c
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);绕过:修改返回值,或者杀死/解绑监控子进程。
fork()3.2 Multi-Process Debugging Detection
3.2 多进程调试检测
Parent and child cooperatively check each other's debug state, creating a mutual-watch pattern.
Bypass: Attach to both processes (GDB , or two debugger instances).
follow-fork-mode父进程和子进程合作检查对方的调试状态,形成互相监控的模式。
绕过:同时附加到两个进程(GDB使用,或者启动两个调试器实例)。
follow-fork-mode3.3 Timing-Based with Multiple Checkpoints
3.3 多检查点时序检测
Distributes timing checks across multiple functions, comparing cumulative drift. Single patches fail because the total still exceeds threshold.
Bypass: Frida all timing sources (, , ) to return controlled values.
Interceptor.replacerdtscclock_gettimeQueryPerformanceCounter时序检查分散在多个函数中,对比累计偏差。单次补丁会失效,因为总耗时仍然超过阈值。
绕过:使用Frida 替换所有计时源(、、)返回可控值。
Interceptor.replacerdtscclock_gettimeQueryPerformanceCounter3.4 Nanomite / INT3 Patching
3.4 Nanomite / INT3补丁
Original conditional jumps are replaced with (0xCC). A parent debugger process handles each , evaluates the condition, and sets the child's EIP accordingly.
INT3INT3Bypass: Reconstruct the original jump table by tracing all handlers, then patch the binary.
INT3原始条件跳转被替换为(0xCC),父调试器进程处理每个,判断条件后设置子进程的EIP。
INT3INT3绕过:跟踪所有处理逻辑重建原始跳转表,然后补丁二进制文件。
INT34. COUNTERMEASURE TOOLS
4. 对抗工具
| 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 | |
| Qiling | Cross-platform | Full-system emulation, bypass all hardware checks |
| 工具 | 平台 | 能力 |
|---|---|---|
| ScyllaHide | Windows(x64dbg/IDA/OllyDbg) | 自动补丁PEB、hook NtQuery*接口、隐藏线程、修正时序 |
| TitanHide | Windows(内核驱动) | 内核级隐藏,绕过所有用户态检查 |
| Frida | 跨平台 | 基于脚本的任意函数hook、时序伪造 |
| LD_PRELOAD垫片 | Linux | 加载时替换ptrace、getenv、fopen等函数 |
| GDB脚本 | Linux | |
| Qiling | 跨平台 | 全系统仿真,绕过所有硬件级检查 |
5. SYSTEMATIC BYPASS METHODOLOGY
5. 系统化绕过方法论
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 call步骤1:静态分析 —— 识别反调试调用
└─ 搜索关键词:ptrace、IsDebuggerPresent、NtQuery、rdtsc、
GetTickCount、SIGTRAP、INT 2D、TLS目录条目
步骤2:分类每个检查
├─ 基于API → hook或者补丁调用
├─ 基于标志 → 补丁PEB/proc字段
├─ 基于时序 → 伪造计时源
├─ 基于异常 → 正确转发/处理异常
└─ 多进程 → 同时处理所有进程
步骤3:应用绕过(顺序很重要)
1. 加载ScyllaHide / 设置LD_PRELOAD(覆盖80%的检查)
2. 处理TLS回调(在main前中断)
3. 补丁剩余自定义检查(Frida或二进制补丁)
4. 验证:设置断点运行,确认没有提前退出
步骤4:验证绕过完整性
└─ 在ExitProcess/exit/_exit上设置断点 —— 如果意外命中,
说明遗漏了检查 → 从exit调用回溯排查6. DECISION TREE
6. 决策树
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 checks二进制在调试器下退出/崩溃?
│
├─ 在main前立即崩溃?
│ └─ TLS回调反调试
│ └─ 在调试器中开启TLS回调中断
│
├─ 启动时崩溃?
│ ├─ Linux:检查ptrace(TRACEME)
│ │ └─ LD_PRELOAD hook或NOP补丁
│ └─ Windows:检查IsDebuggerPresent / PEB
│ └─ ScyllaHide或手动PEB补丁
│
├─ 运行一段时间后崩溃?
│ ├─ 崩溃点固定 → 基于API的检查
│ │ ├─ NtQueryInformationProcess → hook返回值
│ │ ├─ /proc/self/status → 过滤TracerPid
│ │ └─ 硬件断点检测 → hook GetThreadContext
│ │
│ ├─ 崩溃点不固定 → 基于时序的检查
│ │ └─ Hook rdtsc / QueryPerformanceCounter
│ │
│ └─ 断点命中时崩溃 → 基于异常的检查
│ ├─ INT 2D / INT 3 技巧 → 在VEH中处理
│ └─ SIGTRAP处理函数 → GDB:配置SIGTRAP转发
│
├─ 调试器静默失去控制?
│ └─ ThreadHideFromDebugger
│ └─ Hook NtSetInformationThread
│
├─ 子进程检测到调试器并杀死父进程?
│ └─ 自调试(fork+ptrace)
│ └─ 补丁fork()或同时处理两个进程
│
└─ 所有基础绕过都应用后仍然被检测?
└─ 多层/自定义检查
├─ 使用Frida进行全量API hook
├─ 用Qiling进行全仿真
└─ 跟踪所有exit/abort调用找到剩余检查7. CTF & REAL-WORLD PATTERNS
7. CTF与真实场景模式
Common CTF Anti-Debug Patterns
常见CTF反调试模式
| Pattern | Frequency | Quick Bypass |
|---|---|---|
Single | Very common | |
| 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 |
| 模式 | 出现频率 | 快速绕过 |
|---|---|---|
单个 | 非常常见 | |
| 常见 | ScyllaHide |
| 循环中的rdtsc时序检查 | 中等 | 修改比较阈值 |
| signal(SIGTRAP) + raise | 中等 | GDB信号转发 |
| fork + ptrace监控进程 | 少见但复杂 | 杀死子进程或补丁fork |
| Nanomite INT3替换 | 少见(高级) | 重建跳转表 |
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 |
| 保护工具 | 核心反调试手段 | 推荐工具 |
|---|---|---|
| VMProtect | PEB + 时序 + 驱动级 | TitanHide + ScyllaHide |
| Themida | 多层PEB + SEH + 时序 | ScyllaHide + 手动补丁 |
| Enigma Protector | IsDebuggerPresent + CRC校验 | x64dbg + ScyllaHide |
| 自定义UPX | 通常无(仅加壳) | 标准脱壳 |
| 自定义(恶意软件) | 差异极大 | Frida + Qiling分析 |
8. QUICK REFERENCE — BYPASS CHEAT SHEET
8. 快速参考——绕过速查表
Linux One-Liners
Linux单行命令
bash
undefinedbash
undefinedLD_PRELOAD anti-ptrace
LD_PRELOAD反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
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:捕获并绕过ptrace
(gdb) catch syscall ptrace
(gdb) commands
set $rax = 0 continue end
undefined(gdb) catch syscall ptrace
(gdb) commands
set $rax = 0 continue end
undefinedFrida Anti-Debug Bypass (Cross-Platform)
Frida反调试绕过(跨平台)
javascript
// 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
}
});javascript
// 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'])
);
// 时序伪造
Interceptor.attach(Module.getExportByName(null, 'clock_gettime'), {
onLeave(retval) {
// 调整timespec隐藏调试器延迟
}
});x64dbg ScyllaHide Quick Setup
x64dbg ScyllaHide快速配置
- Plugins → ScyllaHide → Options
- Check: PEB BeingDebugged, NtGlobalFlag, HeapFlags
- Check: NtQueryInformationProcess (all classes)
- Check: NtSetInformationThread (HideFromDebugger)
- Check: GetTickCount, QueryPerformanceCounter
- Apply → restart debugging session
- 插件 → ScyllaHide → 选项
- 勾选:PEB BeingDebugged、NtGlobalFlag、HeapFlags
- 勾选:NtQueryInformationProcess(所有类)
- 勾选:NtSetInformationThread(HideFromDebugger)
- 勾选:GetTickCount、QueryPerformanceCounter
- 应用 → 重启调试会话