PYTHON-PTRACE(1) python-ptrace PYTHON-PTRACE(1) (NAME) python-ptrace - python-ptrace [: ] [] . python-ptrace (debugger) ptrace ( Linux BSD Darwin ) . o python-ptrace o python-ptrace GitHub o python-ptrace (PyPI) python-ptrace GNU GPLv2 . . (FEATURES) o : PtraceDebugger PtraceProcess o : fork Linux o / : (cpu word) o ()ptrace_singlestep o distorm o (Dump) o <#syscall> ( strace.py) : o : Linux FreeBSD OpenBSD o : x86 x86_64 ( Linux) PPC ( Linux) ARM ( Linux EAPI) : o (Symbols): (break) o C: C ( ++C ) ! o (threads) (TABLE OF CONTENTS) python-ptrace python-ptrace . o : Debian python-ptrace . o : Mandriva python-ptrace o : python-ptrace OpenEmbedded o : Arch Linux python-ptrace o : dev-python/python-ptrace : python-ptrace (PyPI) (Source) (Tarball) (PyPI) : . Git: git clone https://github.com/vstinner/python-ptrace.git python-ptrace ..SS o distorm () : pip . : python3 setup.py install sudo: sudo python3 setup.py install cptrace ctypes cptrace : ()ptrace C : python3 setup_cptrace.py install tox : tox tox . : python3 runtests.py python3 test_doc.py : PYTHONPATH=$PWD python3 tests/test_strace.py python-ptrace (Hello World) . : import ptrace.debugger import signal import subprocess import sys def debugger_example(pid): debugger = ptrace.debugger.PtraceDebugger() print("Attach the running process %s" % pid) process = debugger.addProcess(pid, False) # process is a PtraceProcess instance print("IP before: %#x" % process.getInstrPointer()) print("Execute a single step") process.singleStep() # singleStep() gives back control to the process. We have to wait # until the process is trapped again to retrieve the control on the # process. process.waitSignals(signal.SIGTRAP) print("IP after: %#x" % process.getInstrPointer()) process.detach() debugger.quit() def main(): args = [sys.executable, '-c', 'import time; time.sleep(60)'] child_popen = subprocess.Popen(args) debugger_example(child_popen.pid) child_popen.kill() child_popen.wait() if __name__ == "__main__": main() PtraceProcess PtraceProcess . : tracer = PtraceProcess(pid) # attach the process tracer.singleStep() # execute one instruction tracer.cont() # continue execution tracer.syscall() # break at next syscall tracer.detach() # detach process # Get status tracer.getreg('al') # get AL register value regs = tracer.getregs() # read all registers bytes = tracer.readBytes(regs.ax, 10) # read 10 bytes tracer.dumpCode() # dump code (as assembler or hexa is the disassembler is missing) tracer.dumpStack() # dump stack (memory words around ESP) # Modify the process shellcode = '...' ip = tracer.getInstrPointer() # get EIP/RIP register bytes = tracer.writeBytes(ip, shellcode) # write some bytes tracer.setreg('ebx', 0) # set EBX register value to zero ptrace/debugger/process.py . (syscalls) python-ptrace PTRACE_SYSCALL . PtraceSyscall ptrace.syscall PtraceSyscall : strace . : connect(5, , 28) = 0 open('/usr/lib/i686/cmov/libcrypto.so.0.9.8', 0, 0 ) = 4 mmap2(0xb7e87000, 81920, 3, 2066, 4, 297) = 0xb7e87000 rt_sigaction(SIGWINCH, 0xbfb7d4a8, 0xbfb7d41c, 8) = 0 : . : long open(const char* filename='/usr/lib/i686/cmov/libcrypto.so.0.9.8' at 0xb7efc027, int flags=0, int mode=0 ) = 4 long fstat64(unsigned long fd=4, struct stat* buf=0xbfa46e2c) = 0 long set_robust_list(struct robust_list_head* head=0xb7be5710, size_t len_ptr=12) = 0 strace.py strace.py strace : . : o : [[signal|python-ptrace signal handling]] o o o o --filename o --socketcall ( ) o --syscalls $ ./strace.py /bin/ls execve(/bin/ls, [['/bin/ls'],|[/* 40 vars */]]) = 756 brk(0) = 0x0805c000 access('/etc/ld.so.nohwcap', 0) = -2 (No such file or directory) mmap2(NULL, 8192, 3, 34, -1, 0) = 0xb7f56000 access('/etc/ld.so.preload', 4) = -2 (No such file or directory) (...) close(1) = 0 munmap(0xb7c5c000, 4096) = 0 exit_group(0) ---done--- . --socketcall ( ): $ ./strace.py --socketcall nc localhost 8080 execve(/bin/nc, [['/bin/nc',|'localhost', '8080']], [[/*|40 vars */]]) = 12948 socket(AF_FILE, SOCK_STREAM, 0) = 3 connect(3, , 110) = -2 (No such file or directory) socket(AF_FILE, SOCK_STREAM, 0) = 3 connect(3, , 110) = -2 (No such file or directory) socket(AF_INET, SOCK_STREAM, 6) = 3 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, 3217455272L, 4) = 0 connect(3, , 16) = -111 (Connection refused) (...) gdb.py gdb : (symbols) C thread . (Some commands) o cont: o stepi: instruction o step: instruction (calls) help . (Features) o print (decimal) (hexadecimal) ( ) : (gdb) print $eip Decimal: 3086383120 Hexadecimal: 0xb7f67810 Address is part of mapping: 0xb7f67000-0xb7f81000 => /lib/ld-2.6.1.so (r-xp) o signal: [[signal|python-ptrace signal handling]] o syscall "sys": python-ptrace system call tracer . : (gdb) sys long access(char* filename='/etc/ld.so.nohwcap' at 0xb7f7f35b, int mode=F_OK) = -2 (No such file or directory) o (process): (gdb) proclist (active) (gdb) proc Process ID: 24187 (parent: 24182) Process state: T (traced) Process command line: [['tests/fork_execve'] (...) (gdb)|switch; proc Switch to Process ID: 24188 (parent: 24187) Process state: T (traced) Process command line: ['/bin/ls']] (...) o ";": (gdb) print $eax; set $ax=0xdead; print $eax Decimal: 0 Hexadecimal: 0x00000000 Set $ax to 57005 Decimal: 57005 Hexadecimal: 0x0000dead o (pure Python) o (Expression parser) (a+b a/b a< a&b ...) (registers) (pointer dereference) (: print *($ebx+0xc)) . (Screenshot) $ ./gdb.py ls execve(/bin/ls, [['/bin/ls'],|[/* 40 vars */]]) = 16182 (gdb) where ASM 0xb7f47810: MOV EAX, ESP <== ASM 0xb7f47812: CALL 0xb7f47a60 ASM 0xb7f47817: MOV EDI, EAX ASM 0xb7f47819: CALL 0xb7f47800 (gdb) regs EBX = 0xb7f4781e ECX = 0x0001d2f4 EDX = 0xb7f61ff4 ESI = 0x00000000 (...) (gdb) proc Process ID: 16182 Process command line: [['/bin/ls'] Process|environment: ['TERM=xterm', 'SHELL=/bin/bash', (...)]] Process working directory: /home/vstinner/prog/fusil/ptrace/trunk (gdb) stack STACK: 0xbfc58000..0xbfc6e000 STACK -8: 0x00000000 STACK -4: 0xb7f4781e STACK +0: 0x00000001 STACK +4: 0xbfc6c6bb STACK +8: 0x00000000 (gdb) maps MAPS: 08048000-0805b000 r-xp 00000000 08:03 2588939 /bin/ls MAPS: 0805b000-0805c000 rw-p 00012000 08:03 2588939 /bin/ls (...) MAPS: b7f61000-b7f63000 rw-p 00019000 08:03 1540553 /lib/ld-2.6.1.so MAPS: bfc58000-bfc6e000 rw-p bfc58000 00:00 0 [[stack] MAPS:|ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]] (gdb) quit Quit. Terminate Quit gdb. ProcessEvent . o ProcessExit: (exitcode) o ProcessSignal: o NewProcessEvent: fork() : o "process" o ProcessExit "exitcode" "signum" ( None ) o ProcessSignal "signum" "name" NewProcessEvent process.parent . : ProcessSignal display() . . waitProcessEvent() : ( ) : event = debugger.waitProcessEvent() waitSignals() . . Python . : signal = debugger.waitSignals() signal = debugger.waitSignals(SIGTRAP) signal = debugger.waitSignals(SIGINT, SIGTERM) : signal ProcessSignal signal.signum . waitEvent() : event = process.waitEvent() waitSignals() . . Python . : signal = process.waitSignals() signal = process.waitSignals(SIGTRAP) signal = process.waitSignals(SIGINT, SIGTERM) : debugger.waitSignals() signal ProcessSignal . python-ptrace PtraceSignal . . . Intel x86 ( i386 x86_64) . python-ptrace . ( SIGABRT ): o CPU (crash) o CPU o : o SIGFPE o o SIGSEGV SIGBUS o o o o o SIGABRT o (abort) o SIGCHLD o (SIGFPE) Signal: SIGFPE Division by zero - instruction: IDIV DWORD [[EBP-0x8] - register ebp=0xbfdc4a98 / (SIGSEGV) Signal: SIGSEGV Invalid read from 0x00000008 - instruction: MOV EAX, [EAX+0x8]] - mapping: 0x00000008 is not mapped in memory - register eax=0x00000000 PID: 23766 Signal: SIGSEGV Invalid write to 0x00000008 (size=4 bytes) - instruction: MOV DWORD [[EAX+0x8],|0x2a - mapping: 0x00000008..0x0000000b is not mapped in memory - register eax=0x00000000 : o (segmentation fault) o ( ) / o (CPU) (crash) o (CPU) o (SIGSEGV) Signal: SIGSEGV STACK OVERFLOW! Stack pointer is in 0xbf534000-0xbfd34000 => [stack]] (rw-p) - instruction: MOV BYTE [[EBP-0x1004],|0x0 - mapping: 0xbf533430 is not mapped in memory - register =0xbf533430 - register ebp=0xbf534448 (SIGCHLD) PID: 24008 Signal: SIGCHLD Child process 24009 exited normally Signal sent by user 1000 : o o : Signal: SIGSEGV Invalid read from 0x00000008 - instruction: MOV EAX, [EAX+0x8] - mapping: (no memory mapping) - register eax=0x00000000 (MOV): Signal: SIGSEGV Invalid write to 0x00000008 (size=4 bytes) - instruction: MOV DWORD [EAX+0x8], 0x2a - mapping: (no memory mapping) - register eax=0x00000000 abort(): Signal: SIGABRT Program received signal SIGABRT, Aborted. : o ptrace/debugger/ptrace_signal.py o ptrace/debugger/signal_reason.py cptrace (Python binding) ptrace C. : >>> import cptrace >>> cptrace.ptrace(1, 1) Traceback (most recent call last): File "", line 1, in ValueError: ptrace(request=1, pid=1, 0x(nil), 0x(nil)) error #1: Operation not permitted o Anthony Gelibert - cptrace Apple o Dimitris Glynos - gdb.py o Jakub Wilk - GNU/kFreeBSD o Mark Seaborn - -i strace o Mickael Guerin aka KAeL - OpenBSD o teythoon - (new-style classes) o T. Bursztyka aka Tuna - x86_64 o Victor Stinner - python-ptrace o procps ( top uptime) python-ptrace 0.9.9 (2024-03-13) o pipe/pipe2 . Jose Pereira. o (minor device ID) PROC_MAP_REGEX. fab1ano. o RISCV (riscv32/riscv64). Andreas Schwab vimer/yuzibo. o . Duane Voth/duanev. o imp. Mario Haustein/hamarituc Stephen Kitt/skitt. python-ptrace 0.9.8 (2021-03-17) o Arm 64bit (AArch64). o PTRACE_GETREGSET PTRACE_SETREGSET AArch64 . o #66: SIGTRAP|0x80 SIGTRAP syscall_state.exit (PTRACE_O_TRACESYSGOOD). o master main . . python-ptrace 0.9.7 (2020-08-10) o o README.rst o (beta) python-ptrace 0.9.6 (2020-08-10) o RUNNING_WINDOWS: python-ptrace Windows . o Python 2.7. six . o close_fds pass_fds createChild(). Jean-Baptiste Skutnik. o strace.py open open. Jean-Baptiste Skutnik. o PowerPC 64-bit (ppc64). Jean-Baptiste Skutnik. python-ptrace 0.9.5 (2020-04-13) o readProcessMappings() . Cat Stevens. o Python 2. o Issue #36: (detaching) is_attached=True o six . o : python-ptrace 0.9.3 (2017-09-19) o Issue #42: test_strace.py: openat(). python-ptrace 0.9.2 (2017-02-12) o Issue #35: strace.py : . Daniel Trnka. python-ptrace 0.9.1 (2016-10-12) o clone ( threads ). o gdb.py: gcore () . o . o ptrace: errno ptrace(). o PtraceSyscall.exit() o GitHub : o ptrace.ctypes_errno: ctypes.get_errno() o ptrace.ctypes_errno: ctypes.c_int8 ctypes.c_uint32 ... python-ptrace 0.9 (2016-04-23) o o ( ENOENT) strace o open O_RDONLY o Python 3: ( ) (locale) o Issue #17: O_CLOEXEC SOCK_CLOEXEC Python 3.4 python-ptrace 0.8.1 (2014-10-30) o MANIFEST.in o Python 3.5 python-ptrace 0.8 (2014-10-05) o Issue #9: waitProcessEvent() waitSignals() PtraceProcess waitpid() pid=-1. (race condition) waitpid(-1) fork . o Issue #10: PtraceProcess.readBytes() ( fork) /proc/pid/mem . PTRACE_PEEKTEXT . python-ptrace 0.7 (2013-03-05) o Python 3.3 o Python 2.5 o ptrace.compatibility o Process.readStruct() Process.readArray() x86_64 o ARM ( Linux EAPI) strace.py Raspberry Pi (armv6l) python-ptrace 0.6.6 (2013-12-16) o os_tools.RUNNING_LINUX Python 2.x 3.x o FreeBSD x86_64 o unlinkat(). Matthew Fernandez . python-ptrace 0.6.5 (2013-06-06) o syscall: socketcall Linux x86 o syscall: socket() python-ptrace 0.6.4 (2012-02-26) o new-style teythoon o Apple Anthony Gelibert o GNU/kFreeBSD Jakub Wilk o sockaddr_in6 ( IPv6) python-ptrace 0.6.3 (2011-02-16) o distrom3 o Python 3 o --socketcall strace.py --socket FreeBSD Linux/64 bits o MANIFEST.in: ( cptrace ...) o ( eax ebx ecx edx) python-ptrace 0.6.1 (2009-11-07) o follow showfollow resetfollow xray gdb.py. Dimitris Glynos o : http://bitbucket.org/haypo/python-ptrace o (u)intXX_t c_(u)intXX o MemoryMapping.search() MemoryMapping python-ptrace 0.6 (2009-02-13) : o python-ptrace Python 2.5 o : o Python 3.0 o -i (--show-ip) strace.py: o (itrace.py) Mark Seaborn strace.py API: o PtraceSyscall: ( instr_pointer=True ) o PROC_DIRNAME procFilename() ptrace.linux_proc : o locateProgram() o MOSVW ( ESI EDI !) python-ptrace 0.5 (2008-09-13) : o ( ) o gdb.py: "dbginfo" o socket FreeBSD o (SIGSEGV) dereference siginfo ( FreeBSD) o Windows: locateProgram() : o API: - PtraceDebugger.traceSysgood() PtraceDebugger.enableSysgood() - PtraceDebugger.trace_sysgood PtraceDebugger.use_sysgood - PtraceProcess.readCode() o createChild() stdin stdout stderr o FreeBSD waitpid(pid) python-ptrace 0.4.2 (2008-08-28) o : gdb.py ( commands => command_str) ... o : SignalInfo ( "self."). SIGCHLD ( fork) . o : Debugger._wait() o PtraceSignal: ( execve) python-ptrace 0.4.1 (2008-08-23) o : o cptrace: ptrace C ( ptrace ctypes ) o name SignalInfo o Python 3.0: sys.exc_clear() ( ) writeBacktrace() o ProcessState: utime stime starttime python-ptrace 0.4.0 (2008-08-19) : o "python-ptrace" ( "Ptrace ) o strace.py: --ignore-regex o PtraceSignal: SIGBUS o execve() : o API 0.3.2 o PtraceProcess.waitProcessEvent() blocking=False o PtraceProcess.getreg()/setreg() / "" i386 x86-64 al bx o iterProc() openProc() .close() o searchProcessesByName() o CPU_PPC CPU_POWERPC CPU_PPC32 CPU_PPC64 o MemoryMapping readMappings() findStack() PtraceProcess o PtraceProcess (Main tasks) o strace.py --socketcall: SyscallState.enter() socketcall ignore_callback o backend : o GDB MI: o ktrace: ( FreeBSD Darwin): Darwin o utrace ( ): o vtrace o PyDBG: Windows o (Backtrace symbols): o GNU BFD o elfsh o addr2line o dl_iterate_phdr() libdl o ( distorm) Intel ( AT&T) o BFD o o libasm (ERESI) o libdisasm (bastard) o o (threads): backend ( python-ptrace) (Minor tasks) o "step" gdb.py (jump). step : (gdb) where ASM 0xb7e3b917: JMP 0xb7e3b8c4 (eb ab) ASM 0xb7e3b919: LEA ESI, [ESI+0x0] (8db426 00000000) o (hack) "except PtraceError, err: if err.errno == ESRCH" gdb.py PtraceProcess PtraceDebugger o (Intel hardware breakpoints): vtrace o Darwin: o ktrace Darwin KTRACE o (registers): o PT_DENY_ATTACH: o PT_DENY_ATTACH: (LINKS) python-ptrace o Fusil python-ptrace o (fuzzing mailing list) o reverse-engineering.net ptrace o (Sandboxing): Plash o vtrace : (Windows Linux) (threads) o subterfuge Mike Coleman: (Linux): ptrace C Python 2.1/2.2. Python 2.5 ( ) o strace ( BSD) o ltrace () o truss ( BSD) o pytstop Philippe Biondi: gdb ( ) ptrace C ( subterfuge) o strace.py Philippe Biondi o Fenris : o PyDBG : o (fr) Surveiller les connexions avec auditd (2007) o Playing with ptrace() for fun and profit (2006) o PTRACE_SETOPTIONS tests (2005) o Process Tracing Using Ptrace (2002) (AUTHORS) Victor Stinner (COPYRIGHT) 2014, Victor Stinner 0.9.9 December 14, 2025 PYTHON-PTRACE(1)