Anti-Analysisintermediate
ptrace Self-Attach
On Linux, a process calls ptrace(PTRACE_TRACEME) on itself so that any debugger trying to attach later fails — a single process can only be traced once.
A Linux process may be traced by only one tracer at a time. Malware exploits
this by tracing itself: if ptrace(PTRACE_TRACEME, 0, 0, 0) succeeds, no
debugger is attached and a later gdb/strace attach will fail with EPERM.
If the call returns -1, a debugger is already present.
Example
#include <sys/ptrace.h>
if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) {
// Already being traced — bail out.
_exit(1);
}The same self-attach via the raw syscall convention disassembles like this:
; ptrace(PTRACE_TRACEME=0, 0, 0, 0) via syscall(2)
xor edi, edi ; arg1 request = PTRACE_TRACEME (0)
xor esi, esi ; arg2 pid = 0
xor edx, edx ; arg3 addr = 0
xor r10d, r10d ; arg4 data = 0
mov eax, 101 ; __NR_ptrace = 101
syscall ; rax = result (-1 on EPERM if already traced)
cmp rax, -1 ; return == -1 ?
je already_traced ; debugger attached -> bail outBypass
LD_PRELOADa stub that makesptracealways return0.- Patch the syscall / check at runtime, or set
/proc/sys/kernel/yama/ptrace_scope. - Under GDB,
catch syscall ptraceand force the return value, or run with a seccomp-basedptraceinterposer.
Votes