.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "PYTHON-PTRACE" "1" "Apr 27, 2024" "0.9.9" "python-ptrace" .SH NAME python-ptrace \- python-ptrace Documentation \fI\%No Maintenance Intended\fP .sp \fBThis project is no longer maintained and is looking for a new maintainer.\fP .sp python\-ptrace is a debugger using ptrace (Linux, BSD and Darwin system call to trace processes) written in Python. .INDENT 0.0 .IP \(bu 2 \fI\%python\-ptrace documentation\fP .IP \(bu 2 \fI\%python\-ptrace at GitHub\fP .IP \(bu 2 \fI\%python\-ptrace at the Python Cheeseshop (PyPI)\fP .UNINDENT .sp python\-ptrace is an opensource project written in Python under GNU GPLv2 license. It supports Python 3.6 and newer. .SH FEATURES .INDENT 0.0 .IP \(bu 2 High level Python object API : PtraceDebugger and PtraceProcess .IP \(bu 2 Able to control multiple processes: catch fork events on Linux .IP \(bu 2 Read/write bytes to arbitrary address: take care of memory alignment and split bytes to cpu word .IP \(bu 2 Execution step by step using ptrace_singlestep() or hardware interruption 3 .IP \(bu 2 Can use \fI\%distorm\fP disassembler .IP \(bu 2 Dump registers, memory mappings, stack, etc. .IP \(bu 2 \fI\%Syscall tracer and parser\fP (strace.py command) .UNINDENT .sp Status: .INDENT 0.0 .IP \(bu 2 Supported operating systems: Linux, FreeBSD, OpenBSD .IP \(bu 2 Supported architectures: x86, x86_64 (Linux), PPC (Linux), ARM (Linux EAPI) .UNINDENT .sp Missing features: .INDENT 0.0 .IP \(bu 2 Symbols: it\(aqs not possible to break on a function or read a variable value .IP \(bu 2 No C language support: debugger shows assembler code, not your C (C++ or other language) code! .IP \(bu 2 No thread support .UNINDENT .SH TABLE OF CONTENTS .SS Install python\-ptrace .sp python\-ptrace supports Python 3.6 and newer. .SS Linux packages .INDENT 0.0 .IP \(bu 2 Debian: \fI\%python\-ptrace Debian package\fP\&. .IP \(bu 2 Mandriva: \fI\%python\-ptrace Mandriva package\fP .IP \(bu 2 OpenEmbedded: \fI\%python\-ptrace recipe\fP .IP \(bu 2 Arch Linux: \fI\%python\-ptrace Arch Linux package\fP .IP \(bu 2 Gentoo: \fI\%dev\-python/python\-ptrace\fP .UNINDENT .sp See also \fI\%python\-ptrace on Python Package Index (PyPI)\fP .SS Install from source .SS Download tarball .sp Get the latest tarball at the \fI\%Python Package Index (PyPI)\fP\&. .SS Download development version .sp Download the development version using Git: .INDENT 0.0 .INDENT 3.5 .sp .EX git clone https://github.com/vstinner/python\-ptrace.git .EE .UNINDENT .UNINDENT .sp \fI\%Browse python\-ptrace source code\fP\&. .SS Option dependency .INDENT 0.0 .IP \(bu 2 distorm disassembler (optional) \fI\%http://www.ragestorm.net/distorm/\fP .UNINDENT .SS Installation .sp Note: pip is strongly recommanded. .sp Type as root: .INDENT 0.0 .INDENT 3.5 .sp .EX python3 setup.py install .EE .UNINDENT .UNINDENT .sp Or using sudo program: .INDENT 0.0 .INDENT 3.5 .sp .EX sudo python3 setup.py install .EE .UNINDENT .UNINDENT .SS cptrace .sp For faster debug and to avoid ctypes, you can also install cptrace: Python binding of the ptrace() function written in C: .INDENT 0.0 .INDENT 3.5 .sp .EX python3 setup_cptrace.py install .EE .UNINDENT .UNINDENT .SS Run tests .SS Run tests with tox .sp To run all tests, just type: .INDENT 0.0 .INDENT 3.5 .sp .EX tox .EE .UNINDENT .UNINDENT .sp The \fI\%tox project\fP creates a clean virtual environment to run tests. .SS Run tests manually .sp Type: .INDENT 0.0 .INDENT 3.5 .sp .EX python3 runtests.py python3 test_doc.py .EE .UNINDENT .UNINDENT .sp It\(aqs also possible to run a specific test: .INDENT 0.0 .INDENT 3.5 .sp .EX PYTHONPATH=$PWD python3 tests/test_strace.py .EE .UNINDENT .UNINDENT .SS python\-ptrace usage .SS Hello World .sp Short example attaching a running process. It gets the instruction pointer, executes a single step, and gets the new instruction pointer: .INDENT 0.0 .INDENT 3.5 .sp .EX import ptrace.debugger import signal import subprocess import sys def debugger_example(pid): debugger = ptrace.debugger.PtraceDebugger() print(\(dqAttach the running process %s\(dq % pid) process = debugger.addProcess(pid, False) # process is a PtraceProcess instance print(\(dqIP before: %#x\(dq % process.getInstrPointer()) print(\(dqExecute a single step\(dq) 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(\(dqIP after: %#x\(dq % process.getInstrPointer()) process.detach() debugger.quit() def main(): args = [sys.executable, \(aq\-c\(aq, \(aqimport time; time.sleep(60)\(aq] child_popen = subprocess.Popen(args) debugger_example(child_popen.pid) child_popen.kill() child_popen.wait() if __name__ == \(dq__main__\(dq: main() .EE .UNINDENT .UNINDENT .SS API .SS PtraceProcess .sp The PtraceProcess class is an helper to manipulate a traced process. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX 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(\(aqal\(aq) # 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 = \(aq...\(aq ip = tracer.getInstrPointer() # get EIP/RIP register bytes = tracer.writeBytes(ip, shellcode) # write some bytes tracer.setreg(\(aqebx\(aq, 0) # set EBX register value to zero .EE .UNINDENT .UNINDENT .sp Read \fBptrace/debugger/process.py\fP source code to see more methods. .SS Trace system calls (syscalls) .sp python\-ptrace can trace system calls using \fBPTRACE_SYSCALL\fP\&. .SS PtraceSyscall .sp ptrace.syscall module contains PtraceSyscall class: it\(aqs a parser of Linux syscalls similar to strace program. .sp Example: .INDENT 0.0 .INDENT 3.5 .sp .EX connect(5, , 28) = 0 open(\(aq/usr/lib/i686/cmov/libcrypto.so.0.9.8\(aq, 0, 0 ) = 4 mmap2(0xb7e87000, 81920, 3, 2066, 4, 297) = 0xb7e87000 rt_sigaction(SIGWINCH, 0xbfb7d4a8, 0xbfb7d41c, 8) = 0 .EE .UNINDENT .UNINDENT .sp You can get more information: result type, value address, argument types, and argument names. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX long open(const char* filename=\(aq/usr/lib/i686/cmov/libcrypto.so.0.9.8\(aq 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 .EE .UNINDENT .UNINDENT .SS strace.py .sp Program strace.py is very close to strace program: display syscalls of a program. Example: .SS Features .INDENT 0.0 .IP \(bu 2 Nice output of signal: see [[signal|python\-ptrace signal handling]] .IP \(bu 2 Supports multiple processes .IP \(bu 2 Can trace running process .IP \(bu 2 Can display arguments name, type and address .IP \(bu 2 Option \fB\-\-filename\fP to show only syscall using file names .IP \(bu 2 Option \fB\-\-socketcall\fP to show only syscall related to network (socket usage) .IP \(bu 2 Option \fB\-\-syscalls\fP to list all known syscalls .UNINDENT .SS Example .INDENT 0.0 .INDENT 3.5 .sp .EX $ ./strace.py /bin/ls execve(/bin/ls, [[\(aq/bin/ls\(aq],|[/* 40 vars */]]) = 756 brk(0) = 0x0805c000 access(\(aq/etc/ld.so.nohwcap\(aq, 0) = \-2 (No such file or directory) mmap2(NULL, 8192, 3, 34, \-1, 0) = 0xb7f56000 access(\(aq/etc/ld.so.preload\(aq, 4) = \-2 (No such file or directory) (...) close(1) = 0 munmap(0xb7c5c000, 4096) = 0 exit_group(0) \-\-\-done\-\-\- .EE .UNINDENT .UNINDENT .SS Options .sp The program has many options. Example with \fB\-\-socketcall\fP (display only network functions): .INDENT 0.0 .INDENT 3.5 .sp .EX $ ./strace.py \-\-socketcall nc localhost 8080 execve(/bin/nc, [[\(aq/bin/nc\(aq,|\(aqlocalhost\(aq, \(aq8080\(aq]], [[/*|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) (...) .EE .UNINDENT .UNINDENT .SS gdb.py .sp \fBgdb.py\fP is a command line debugger \fIsimilar to gdb\fP, but with fewer features: no symbol support, no C language support, no thread support, etc. .SS Some commands .INDENT 0.0 .IP \(bu 2 \fBcont\fP: continue execution .IP \(bu 2 \fBstepi\fP: execute one instruction .IP \(bu 2 \fBstep\fP: execute one instruction, but don\(aqt enter into calls .UNINDENT .sp Type \fBhelp\fP to list all available commands. .SS Features .INDENT 0.0 .IP \(bu 2 print command displays value as decimal and hexadecimal, but also the related memory mapping (if any): .INDENT 2.0 .INDENT 3.5 .sp .EX (gdb) print $eip Decimal: 3086383120 Hexadecimal: 0xb7f67810 Address is part of mapping: 0xb7f67000\-0xb7f81000 => /lib/ld\-2.6.1.so (r\-xp) .EE .UNINDENT .UNINDENT .IP \(bu 2 Nice output of signal: see [[signal|python\-ptrace signal handling]] .IP \(bu 2 Syscall tracer with command \(dqsys\(dq: see \fIpython\-ptrace system call tracer \fP\&. Short example: .INDENT 2.0 .INDENT 3.5 .sp .EX (gdb) sys long access(char* filename=\(aq/etc/ld.so.nohwcap\(aq at 0xb7f7f35b, int mode=F_OK) = \-2 (No such file or directory) .EE .UNINDENT .UNINDENT .IP \(bu 2 Supports multiple processes: .INDENT 2.0 .INDENT 3.5 .sp .EX (gdb) proclist (active) (gdb) proc Process ID: 24187 (parent: 24182) Process state: T (traced) Process command line: [[\(aqtests/fork_execve\(aq] (...) (gdb)|switch; proc Switch to Process ID: 24188 (parent: 24187) Process state: T (traced) Process command line: [\(aq/bin/ls\(aq]] (...) .EE .UNINDENT .UNINDENT .IP \(bu 2 Allow multiple commands on the same line using \(dq;\(dq separator: .INDENT 2.0 .INDENT 3.5 .sp .EX (gdb) print $eax; set $ax=0xdead; print $eax Decimal: 0 Hexadecimal: 0x00000000 Set $ax to 57005 Decimal: 57005 Hexadecimal: 0x0000dead .EE .UNINDENT .UNINDENT .IP \(bu 2 Only written in pure Python code, so it\(aqs easy to extend .IP \(bu 2 Expression parser supports all arithmetic operator (\fBa+b\fP, \fBa/b\fP, \fBa< Quit gdb. .EE .UNINDENT .UNINDENT .SS python\-ptrace process events .SS Process events .sp All process events are based on ProcessEvent class. .INDENT 0.0 .IP \(bu 2 ProcessExit: process exited with an exitcode, killed by a signal or exited abnormally .IP \(bu 2 ProcessSignal: process received a signal .IP \(bu 2 NewProcessEvent: new process created, e.g. after a fork() syscall .UNINDENT .sp Attributes: .INDENT 0.0 .IP \(bu 2 All events have a \(dqprocess\(dq attribute .IP \(bu 2 ProcessExit has \(dqexitcode\(dq and \(dqsignum\(dq attributes (both can be None) .IP \(bu 2 ProcessSignal has \(dqsignum\(dq and \(dqname\(dq attributes .UNINDENT .sp For NewProcessEvent, use process.parent attribute to get the parent process. .sp Note: ProcessSignal has a display() method to display its content. Use it just after receiving the message because it reads process memory to analyze the reasons why the signal was sent. .SS Wait for any process event .sp The most generic function is waitProcessEvent(): it waits for any process event (exit, signal or new process): .INDENT 0.0 .INDENT 3.5 .sp .EX event = debugger.waitProcessEvent() .EE .UNINDENT .UNINDENT .sp To wait one or more signals, use waitSignals() methods. With no argument, it waits for any signal. Events different than signal are raised as Python exception. Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX signal = debugger.waitSignals() signal = debugger.waitSignals(SIGTRAP) signal = debugger.waitSignals(SIGINT, SIGTERM) .EE .UNINDENT .UNINDENT .sp Note: signal is a ProcessSignal object, use signal.signum to get the signal number. .SS Wait for a specific process events .sp To wait any event from a process, use waitEvent() method: .INDENT 0.0 .INDENT 3.5 .sp .EX event = process.waitEvent() .EE .UNINDENT .UNINDENT .sp To wait one or more signals, use waitSignals() method. With no argument, it waits for any signal. Other process events are raised as Python exception. Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX signal = process.waitSignals() signal = process.waitSignals(SIGTRAP) signal = process.waitSignals(SIGINT, SIGTERM) .EE .UNINDENT .UNINDENT .sp Note: As debugger.waitSignals(), signal is a ProcessSignal object. .SS python\-ptrace signal handling .SS Introduction .sp PtraceSignal tries to display useful information when a signal is received. Depending on the signal number, it shows different information. .sp It uses the current instruction decoded as assembler code to understand why the signal is raised. .sp Only Intel x86 (i386, maybe x86_64) is supported now. .sp When a process receives a signal, python\-ptrace tries to explain why the signal was emitted. .sp General information (not shown for all signals, e.g. not for SIGABRT): .INDENT 0.0 .IP \(bu 2 CPU instruction causing the crash .IP \(bu 2 CPU registers related to the crash .IP \(bu 2 Memory mappings of the memory addresses .UNINDENT .sp Categorize signals: .INDENT 0.0 .IP \(bu 2 SIGFPE .INDENT 2.0 .IP \(bu 2 Division by zero .UNINDENT .IP \(bu 2 SIGSEGV, SIGBUS .INDENT 2.0 .IP \(bu 2 Invalid memory read .IP \(bu 2 Invalid memory write .IP \(bu 2 Stack overflow .IP \(bu 2 Invalid memory access .UNINDENT .IP \(bu 2 SIGABRT .INDENT 2.0 .IP \(bu 2 Program abort .UNINDENT .IP \(bu 2 SIGCHLD .INDENT 2.0 .IP \(bu 2 Child process exit .UNINDENT .UNINDENT .SS Examples .SS Division by zero (SIGFPE) .INDENT 0.0 .INDENT 3.5 .sp .EX Signal: SIGFPE Division by zero \- instruction: IDIV DWORD [[EBP\-0x8] \- register ebp=0xbfdc4a98 .EE .UNINDENT .UNINDENT .SS Invalid memory read/write (SIGSEGV) .INDENT 0.0 .INDENT 3.5 .sp .EX Signal: SIGSEGV Invalid read from 0x00000008 \- instruction: MOV EAX, [EAX+0x8]] \- mapping: 0x00000008 is not mapped in memory \- register eax=0x00000000 .EE .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .sp .EX 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 .EE .UNINDENT .UNINDENT .sp Given information: .INDENT 0.0 .IP \(bu 2 Address of the segmentation fault .IP \(bu 2 (if possible) Size of the invalid memory read/write .IP \(bu 2 CPU instruction causing the crash .IP \(bu 2 CPU registers related to the crash .IP \(bu 2 Memory mappings of the related memory address .UNINDENT .SS Stack overflow (SIGSEGV) .INDENT 0.0 .INDENT 3.5 .sp .EX 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 .EE .UNINDENT .UNINDENT .SS Child exit (SIGCHLD) .INDENT 0.0 .INDENT 3.5 .sp .EX PID: 24008 Signal: SIGCHLD Child process 24009 exited normally Signal sent by user 1000 .EE .UNINDENT .UNINDENT .sp Information: .INDENT 0.0 .IP \(bu 2 Child process identifier .IP \(bu 2 Child process user identifier .UNINDENT .SS Examples .sp Invalid read: .INDENT 0.0 .INDENT 3.5 .sp .EX Signal: SIGSEGV Invalid read from 0x00000008 \- instruction: MOV EAX, [EAX+0x8] \- mapping: (no memory mapping) \- register eax=0x00000000 .EE .UNINDENT .UNINDENT .sp Invalid write (MOV): .INDENT 0.0 .INDENT 3.5 .sp .EX Signal: SIGSEGV Invalid write to 0x00000008 (size=4 bytes) \- instruction: MOV DWORD [EAX+0x8], 0x2a \- mapping: (no memory mapping) \- register eax=0x00000000 .EE .UNINDENT .UNINDENT .sp abort(): .INDENT 0.0 .INDENT 3.5 .sp .EX Signal: SIGABRT Program received signal SIGABRT, Aborted. .EE .UNINDENT .UNINDENT .SS Source code .sp See: .INDENT 0.0 .IP \(bu 2 \fBptrace/debugger/ptrace_signal.py\fP .IP \(bu 2 \fBptrace/debugger/signal_reason.py\fP .UNINDENT .SS cptrace Python module .sp Python binding for ptrace written in C. .SS Example .sp Dummy example: .INDENT 0.0 .INDENT 3.5 .sp .EX >>> import cptrace >>> cptrace.ptrace(1, 1) Traceback (most recent call last): File \(dq\(dq, line 1, in ValueError: ptrace(request=1, pid=1, 0x(nil), 0x(nil)) error #1: Operation not permitted .EE .UNINDENT .UNINDENT .SS Authors .SS Contributors .INDENT 0.0 .IP \(bu 2 Anthony Gelibert \- fix cptrace on Apple .IP \(bu 2 Dimitris Glynos \- follow gdb.py commands .IP \(bu 2 Jakub Wilk \- fix for GNU/kFreeBSD .IP \(bu 2 Mark Seaborn \- Create \-i option for strace .IP \(bu 2 Mickaël Guérin aka KAeL \- OpenBSD port .IP \(bu 2 teythoon \- convert all classes to new\-style classes .IP \(bu 2 .INDENT 2.0 .IP T. 3 Bursztyka aka Tuna \- x86_64 port .UNINDENT .IP \(bu 2 Victor Stinner \- python\-ptrace author and maintainer .UNINDENT .SS Thanks .INDENT 0.0 .IP \(bu 2 procps authors (top and uptime programs) .UNINDENT .SS Changelog .SS python\-ptrace 0.9.9 (2024\-03\-13) .INDENT 0.0 .IP \(bu 2 Fix arguments of pipe/pipe2 system calls for proper display in call format. Patch by José Pereira. .IP \(bu 2 Introduced support for three\-digit minor device IDs in \fBPROC_MAP_REGEX\fP\&. Patch by fab1ano. .IP \(bu 2 Added RISCV (riscv32/riscv64) support. Patch by Andreas Schwab and vimer/yuzibo. .IP \(bu 2 Fix stray exception raised by child processes terminating with exit code 255. Patch by Duane Voth/duanev. .IP \(bu 2 Removed usage of the \fBimp\fP module. Collaboration between Mario Haustein/hamarituc and Stephen Kitt/skitt. .UNINDENT .SS python\-ptrace 0.9.8 (2021\-03\-17) .INDENT 0.0 .IP \(bu 2 Added Arm 64bit (AArch64) support. .IP \(bu 2 Implemented \fBPTRACE_GETREGSET\fP and \fBPTRACE_SETREGSET\fP required on AArch64 and available on Linux. .IP \(bu 2 Issue #66: Fix \fBSIGTRAP|0x80\fP or \fBSIGTRAP\fP wait in syscall_state.exit (\fBPTRACE_O_TRACESYSGOOD\fP). .IP \(bu 2 The development branch \fBmaster\fP was renamed to \fBmain\fP\&. See \fI\%https://sfconservancy.org/news/2020/jun/23/gitbranchname/\fP for the rationale. .UNINDENT .SS python\-ptrace 0.9.7 (2020\-08\-10) .INDENT 0.0 .IP \(bu 2 Add missing module to install directives .IP \(bu 2 Update README.rst .IP \(bu 2 Project back in beta and maintenance .UNINDENT .SS python\-ptrace 0.9.6 (2020\-08\-10) .INDENT 0.0 .IP \(bu 2 Remove RUNNING_WINDOWS constant: python\-ptrace doesn\(aqt not support Windows. .IP \(bu 2 Drop Python 2.7 support. six dependency is no longer needed. .IP \(bu 2 Add close_fds and pass_fds to createChild() function. Patch by Jean\-Baptiste Skutnik. .IP \(bu 2 Enhance strace.py output for open flags and open optional parameters. Patch by Jean\-Baptiste Skutnik. .IP \(bu 2 Add support for PowerPC 64\-bit (ppc64). Patch by Jean\-Baptiste Skutnik. .UNINDENT .SS python\-ptrace 0.9.5 (2020\-04\-13) .INDENT 0.0 .IP \(bu 2 Fix readProcessMappings() for device id on 3 digits. Patch by Cat Stevens. .IP \(bu 2 Drop Python 2 support. .UNINDENT .SS python\-ptrace 0.9.4 (2019\-07\-30) .INDENT 0.0 .IP \(bu 2 Issue #36: Fix detaching from process object created without is_attached=True .IP \(bu 2 The project now requires the six module. .IP \(bu 2 Project moved to: \fI\%https://github.com/vstinner/python\-ptrace\fP .UNINDENT .SS python\-ptrace 0.9.3 (2017\-09\-19) .INDENT 0.0 .IP \(bu 2 Issue #42: Fix test_strace.py: tolerate the openat() syscall. .UNINDENT .SS python\-ptrace 0.9.2 (2017\-02\-12) .INDENT 0.0 .IP \(bu 2 Issue #35: Fix strace.py when tracing multiple processes: use the correct process. Fix suggested by Daniel Trnka. .UNINDENT .SS python\-ptrace 0.9.1 (2016\-10\-12) .INDENT 0.0 .IP \(bu 2 Added tracing of processes created with the clone syscall (commonly known as threads). .IP \(bu 2 gdb.py: add \fBgcore\fP command, dump the process memory. .IP \(bu 2 Allow command names without absolute path. .IP \(bu 2 Fix ptrace binding: clear errno before calling ptrace(). .IP \(bu 2 Fix PtraceSyscall.exit() for unknown error code .IP \(bu 2 Project moved to GitHub: \fI\%https://github.com/haypo/python\-ptrace\fP .IP \(bu 2 Remove the \fBptrace.ctypes_errno\fP module: use directly the \fBctypes.get_errno()\fP function .IP \(bu 2 Remove the \fBptrace.ctypes_errno\fP module: use directly \fBctypes.c_int8\fP, \fBctypes.c_uint32\fP, ... types .UNINDENT .SS python\-ptrace 0.9 (2016\-04\-23) .INDENT 0.0 .IP \(bu 2 Add all Linux syscall prototypes .IP \(bu 2 Add error symbols (e.g. ENOENT), in addition to error text, for strace .IP \(bu 2 Fix open mode so O_RDONLY shows if it\(aqs the only file access mode .IP \(bu 2 Python 3: fix formatting of string syscall arguments (ex: filenames), decode bytes from the locale encoding .IP \(bu 2 Issue #17: syscall parser now supports O_CLOEXEC and SOCK_CLOEXEC, fix unit tests on Python 3.4 and newer .UNINDENT .SS python\-ptrace 0.8.1 (2014\-10\-30) .INDENT 0.0 .IP \(bu 2 Update MANIFEST.in to include all files .IP \(bu 2 Fix to support Python 3.5 .UNINDENT .SS python\-ptrace 0.8 (2014\-10\-05) .INDENT 0.0 .IP \(bu 2 Issue #9: Rewrite waitProcessEvent() and waitSignals() methods of PtraceProcess to not call waitpid() with pid=\-1. There is a race condition with waitpid(\-1) and fork, the status of the child process may be returned before the debugger is noticed of the creation of the new child process. .IP \(bu 2 Issue #10: Fix PtraceProcess.readBytes() for processes not created by the debugger (ex: fork) if the kernel blocks access to private mappings of /proc/pid/mem. Fallback to PTRACE_PEEKTEXT which is slower but a debugger tracing the process is always allowed to use it. .UNINDENT .SS python\-ptrace 0.7 (2013\-03\-05) .INDENT 0.0 .IP \(bu 2 Experimental support of Python 3.3 in the same code base .IP \(bu 2 Drop support of Python 2.5 .IP \(bu 2 Remove the ptrace.compatibility module .IP \(bu 2 Fix Process.readStruct() and Process.readArray() on x86_64 .IP \(bu 2 Experimental support of ARM architecture (Linux EAPI), strace.py has been tested on Raspberry Pi (armv6l) .UNINDENT .SS python\-ptrace 0.6.6 (2013\-12\-16) .INDENT 0.0 .IP \(bu 2 Fix os_tools.RUNNING_LINUX for Python 2.x compiled on Linux kernel 3.x .IP \(bu 2 Support FreeBSD on x86_64 .IP \(bu 2 Add missing prototype of the unlinkat() system call. Patch written by Matthew Fernandez. .UNINDENT .SS python\-ptrace 0.6.5 (2013\-06\-06) .INDENT 0.0 .IP \(bu 2 syscall: fix parsing socketcall on Linux x86 .IP \(bu 2 syscall: fix prototype of socket() .UNINDENT .SS python\-ptrace 0.6.4 (2012\-02\-26) .INDENT 0.0 .IP \(bu 2 Convert all classes to new\-style classes, patch written by teythoon .IP \(bu 2 Fix compilation on Apple, patch written by Anthony Gelibert .IP \(bu 2 Support GNU/kFreeBSD, patch written by Jakub Wilk .IP \(bu 2 Support sockaddr_in6 (IPv6 address) .UNINDENT .SS python\-ptrace 0.6.3 (2011\-02\-16) .INDENT 0.0 .IP \(bu 2 Support distrom3 .IP \(bu 2 Support Python 3 .IP \(bu 2 Rename strace.py option \-\-socketcall to \-\-socket, and fix this option for FreeBSD and Linux/64 bits .IP \(bu 2 Add MANIFEST.in: include all files in source distribution (tests, cptrace module, ...) .UNINDENT .SS python\-ptrace 0.6.2 (2009\-11\-09) .INDENT 0.0 .IP \(bu 2 Fix 64 bits sub registers (set mask for eax, ebx, ecx, edx) .UNINDENT .SS python\-ptrace 0.6.1 (2009\-11\-07) .INDENT 0.0 .IP \(bu 2 Create follow, showfollow, resetfollow, xray commands in gdb.py. Patch written by Dimitris Glynos .IP \(bu 2 Project website moved to: \fBhttp://bitbucket.org/haypo/python\-ptrace/\fP .IP \(bu 2 Replace types (u)intXX_t by c_(u)intXX .IP \(bu 2 Create MemoryMapping.search() method and MemoryMapping now keeps a weak reference to the process .UNINDENT .SS python\-ptrace 0.6 (2009\-02\-13) .sp User visible changes: .INDENT 0.0 .IP \(bu 2 python\-ptrace now depends on Python 2.5 .IP \(bu 2 Invalid memory access: add fault address in the name .IP \(bu 2 Update Python 3.0 conversion patch .IP \(bu 2 Create \-i (\-\-show\-ip) option to strace.py: show instruction pointer .IP \(bu 2 Add a new example (itrace.py) written by Mark Seaborn and based on strace.py .UNINDENT .sp API changes: .INDENT 0.0 .IP \(bu 2 PtraceSyscall: store the instruction pointer at syscall enter (if the option instr_pointer=True, disabled by default) .IP \(bu 2 Remove PROC_DIRNAME and procFilename() from ptrace.linux_proc .UNINDENT .sp Bugfixes: .INDENT 0.0 .IP \(bu 2 Fix locateProgram() for relative path .IP \(bu 2 Fix interpretation of memory fault on MOSVW instruction (source is ESI and destination is EDI, and not the inverse!) .UNINDENT .SS python\-ptrace 0.5 (2008\-09\-13) .sp Visible changes: .INDENT 0.0 .IP \(bu 2 Write an example (the most simple debugger) and begin to document the code .IP \(bu 2 gdb.py: create \(dqdbginfo\(dq command .IP \(bu 2 Parse socket syscalls on FreeBSD .IP \(bu 2 On invalid memory access (SIGSEGV), eval the dereference expression to get the fault address on OS without siginfo (e.g. FreeBSD) .IP \(bu 2 Fixes to get minimal Windows support: fix imports, fix locateProgram() .UNINDENT .sp Other changes: .INDENT 0.0 .IP \(bu 2 Break the API: \- Rename PtraceDebugger.traceSysgood() to PtraceDebugger.enableSysgood() \- Rename PtraceDebugger.trace_sysgood to PtraceDebugger.use_sysgood \- Remove PtraceProcess.readCode() .IP \(bu 2 Create createChild() function which close all files except stdin, stdout and stderr .IP \(bu 2 On FreeBSD, on process exit recalls waitpid(pid) to avoid zombi process .UNINDENT .SS python\-ptrace 0.4.2 (2008\-08\-28) .INDENT 0.0 .IP \(bu 2 BUGFIX: Fix typo in gdb.py (commands => command_str), it wasn\(aqt possible to write more than one command... .IP \(bu 2 BUGFIX: Fix typo in SignalInfo class (remove \(dqself.\(dq). When a process received a signal SIGCHLD (because of a fork), the debugger exited because of this bug. .IP \(bu 2 BUGFIX: Debugger._wait() return abnormal process exit as a normal event, the event is not raised as an exception .IP \(bu 2 PtraceSignal: don\(aqt clear preformatted arguments (e.g. arguments of execve) .UNINDENT .SS python\-ptrace 0.4.1 (2008\-08\-23) .INDENT 0.0 .IP \(bu 2 The project has a new dedicated website: \fI\%http://python\-ptrace.hachoir.org/\fP .IP \(bu 2 Create cptrace: optional Python binding of ptrace written in C (faster than ptrace, the Python binding written in Python with ctypes) .IP \(bu 2 Add name attribute to SignalInfo classes .IP \(bu 2 Fixes to help Python 3.0 compatibility: don\(aqt use sys.exc_clear() (was useless) in writeBacktrace() .IP \(bu 2 ProcessState: create utime, stime, starttime attributes .UNINDENT .SS python\-ptrace 0.4.0 (2008\-08\-19) .sp Visible changes: .INDENT 0.0 .IP \(bu 2 Rename the project to \(dqpython\-ptrace\(dq (old name was \(dqPtrace) .IP \(bu 2 strace.py: create \-\-ignore\-regex option .IP \(bu 2 PtraceSignal: support SIGBUS, display the related registers and the instruction .IP \(bu 2 Support execve() syscall tracing .UNINDENT .sp Developer changes: .INDENT 0.0 .IP \(bu 2 New API is incompatible with 0.3.2 .IP \(bu 2 PtraceProcess.waitProcessEvent() accepts optional blocking=False argument .IP \(bu 2 PtraceProcess.getreg()/setreg() are able to read/write i386 and x86\-64 \(dqsub\-registers\(dq like al or bx .IP \(bu 2 Remove iterProc() function, replaced by openProc() with explicit call to .close() to make sure that files are closed .IP \(bu 2 Create searchProcessesByName() .IP \(bu 2 Replace CPU_PPC constant by CPU_POWERPC and create CPU_PPC32 and CPU_PPC64 .IP \(bu 2 Create MemoryMapping object, used by readMappings() and findStack() methods of PtraceProcess .IP \(bu 2 Always define all PtraceProcess methods but raise an error if the function is not implemented .UNINDENT .SS TODO .SS Main tasks .INDENT 0.0 .IP \(bu 2 Fix strace.py \-\-socketcall: SyscallState.enter() calls ignore_callback before socketcall are proceed .IP \(bu 2 Support other backends: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 GDB MI: \fI\%http://code.google.com/p/pygdb/\fP .IP \(bu 2 ktrace: (FreeBSD and Darwin): would help Darwin support .IP \(bu 2 utrace (new Linux debugger): \fI\%http://sourceware.org/systemtap/wiki/utrace\fP .IP \(bu 2 vtrace? .IP \(bu 2 PyDBG: works on Windows .UNINDENT .UNINDENT .UNINDENT .IP \(bu 2 Backtrace symbols: .INDENT 2.0 .IP \(bu 2 GNU BFD? .IP \(bu 2 elfsh? .IP \(bu 2 addr2line program? .IP \(bu 2 See dl_iterate_phdr() function of libdl .UNINDENT .IP \(bu 2 Support other disassemblers (than distorm), and so both Intel syntax (Intel and AT&T) .INDENT 2.0 .IP \(bu 2 BFD .IP \(bu 2 \fI\%http://www.ragestorm.net/distorm/\fP .IP \(bu 2 libasm (ERESI) .IP \(bu 2 libdisasm (bastard) .IP \(bu 2 \fI\%http://www.woodmann.com/collaborative/tools/index.php/Category:X86_Disassembler_Libraries\fP .UNINDENT .IP \(bu 2 Support threads: other backends (than python\-ptrace) already support threads .UNINDENT .SS Minor tasks .INDENT 0.0 .IP \(bu 2 Fix gdb.py \(dqstep\(dq command on a jump. Example where step will never stop: .INDENT 2.0 .INDENT 3.5 .sp .EX (gdb) where ASM 0xb7e3b917: JMP 0xb7e3b8c4 (eb ab) ASM 0xb7e3b919: LEA ESI, [ESI+0x0] (8db426 00000000) .EE .UNINDENT .UNINDENT .IP \(bu 2 Remove gdb.py \(dqexcept PtraceError, err: if err.errno == ESRCH\(dq hack, process death detection should be done by PtraceProcess or PtraceDebugger .IP \(bu 2 Use Intel hardware breakpoints: set vtrace source code .IP \(bu 2 Support Darwin: .INDENT 2.0 .IP \(bu 2 ktrace? need to recompile Darwin kernel with KTRACE option .IP \(bu 2 get registers: \fI\%http://unixjunkie.blogspot.com/2006/01/darwin\-ptrace\-and\-registers.html\fP .IP \(bu 2 PT_DENY_ATTACH: \fI\%http://steike.com/code/debugging\-itunes\-with\-gdb/\fP .IP \(bu 2 PT_DENY_ATTACH: \fI\%http://landonf.bikemonkey.org/code/macosx/ptrace_deny_attach.20041010201303.11809.mojo.html\fP .UNINDENT .UNINDENT .SH LINKS .SS Project using python\-ptrace .INDENT 0.0 .IP \(bu 2 \fI\%Fusil the fuzzer\fP .UNINDENT .SS python\-ptrace announces .INDENT 0.0 .IP \(bu 2 \fI\%fuzzing mailing list\fP .IP \(bu 2 \fI\%reverse\-engineering.net\fP .UNINDENT .SS ptrace usage .INDENT 0.0 .IP \(bu 2 Sandboxing: \fI\%Plash\fP .UNINDENT .SS Similar projects .INDENT 0.0 .IP \(bu 2 \fI\%vtrace\fP: Python library (Windows and Linux) supporting threads .IP \(bu 2 \fI\%subterfuge\fP by Mike Coleman: Python library (Linux): contains Python binding of ptrace written in C for Python 2.1/2.2. It doesn\(aqt work with Python 2.5 (old project, not maintained since 2002) .IP \(bu 2 \fI\%strace\fP program (Linux, BSD) .IP \(bu 2 ltrace program (Linux) .IP \(bu 2 truss program (Solaris and BSD) .IP \(bu 2 \fI\%pytstop\fP by Philippe Biondi: debugger similar to gdb but in very alpha stage (e.g. no disassembler), using ptrace Python binding written in C (from subterfuge) .IP \(bu 2 \fI\%strace.py\fP by Philippe Biondi .IP \(bu 2 \fI\%Fenris\fP: suite of tools suitable for code analysis, debugging, protocol analysis, reverse engineering, forensics, diagnostics, security audits, vulnerability research .IP \(bu 2 \fI\%PyDBG\fP: Windows debugger written in pure Python .UNINDENT .SS Interesting articles .INDENT 0.0 .IP \(bu 2 (fr) \fI\%Surveiller les connexions avec auditd\fP (2007) .IP \(bu 2 \fI\%Playing with ptrace() for fun and profit\fP (2006) .IP \(bu 2 \fI\%PTRACE_SETOPTIONS tests\fP (2005) .IP \(bu 2 \fI\%Process Tracing Using Ptrace\fP (2002) .UNINDENT .SH AUTHOR Victor Stinner .SH COPYRIGHT 2024, Victor Stinner .\" Generated by docutils manpage writer. .