Python3 Ptrace 重复系统调用

Python3 Ptrace duplicate syscalls

我正在尝试构建一个简单版本的 starce,它向您展示了一个进程进行的第一个 x 系统调用。问题是目前似乎每个系统调用都出现两次(execveexit_group 除外)。

这是我用来获取系统调用的代码:

import os
import ctypes


# Get libc:
libc = ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')


# Define Constants:

PTRACE_PEEKTEXT   = 1
PTRACE_PEEKDATA   = 2
PTRACE_POKETEXT   = 4
PTRACE_POKEDATA   = 5
PTRACE_CONT       = 7
PTRACE_SINGLESTEP = 9
PTRACE_GETREGS    = 12
PTRACE_SETREGS    = 13
PTRACE_ATTACH     = 16
PTRACE_DETACH     = 17
PTRACE_TRACEME    = 0
PTRACE_SYSCALL    = 24
PTRACE_PEEKUSER   = 32


class user_regs_struct(ctypes.Structure):
    _fields_ = [
        ("r15", ctypes.c_ulonglong),
        ("r14", ctypes.c_ulonglong),
        ("r13", ctypes.c_ulonglong),
        ("r12", ctypes.c_ulonglong),
        ("rbp", ctypes.c_ulonglong),
        ("rbx", ctypes.c_ulonglong),
        ("r11", ctypes.c_ulonglong),
        ("r10", ctypes.c_ulonglong),
        ("r9", ctypes.c_ulonglong),
        ("r8", ctypes.c_ulonglong),
        ("rax", ctypes.c_ulonglong),
        ("rcx", ctypes.c_ulonglong),
        ("rdx", ctypes.c_ulonglong),
        ("rsi", ctypes.c_ulonglong),
        ("rdi", ctypes.c_ulonglong),
        ("orig_rax", ctypes.c_ulonglong),
        ("rip", ctypes.c_ulonglong),
        ("cs", ctypes.c_ulonglong),
        ("eflags", ctypes.c_ulonglong),
        ("rsp", ctypes.c_ulonglong),
        ("ss", ctypes.c_ulonglong),
        ("fs_base", ctypes.c_ulonglong),
        ("gs_base", ctypes.c_ulonglong),
        ("ds", ctypes.c_ulonglong),
        ("es", ctypes.c_ulonglong),
        ("fs", ctypes.c_ulonglong),
        ("gs", ctypes.c_ulonglong),
    ]

ptrace = libc.ptrace
ptrace.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p]
ptrace.restype = ctypes.c_int



pid = 123 # whatever PID you need

syscalls = []
while len(syscalls) < 1024:
    try:
        _, status = os.waitpid(pid, os.WUNTRACED)
        if os.WIFEXITED(status):
            break
    except:
        break

    regs = user_regs_struct()
    ptrace(PTRACE_GETREGS, pid, 0, ctypes.byref(regs))
    syscalls.append(regs.orig_rax)

    ptrace(PTRACE_SYSCALL, pid, 0, 0)

例如,当 运行ning on ls 时,我得到的前 16 个系统调用是:
execve, brk, brk, arch_prctl, arch_prctl, access, access, openat, openat, fstat, fstat, mmap, mmap, close, close, openat
如果我 运行 strace,前 16 个是这些:
execve, brk, arch_prctl, access, openat, fstat, mmap, close, openat, read, fstat, mmap, mmap, mprotect, mmap, mmap

如您所见,我的代码输出每个系统调用两次。
什么会导致这个?以及如何解决?

在这里深入了解其他线程后,我发现每个系统调用都应该出现两次,一次是在调用之前,另一次是在调用之后。
因此,解决方案是每两次迭代仅将系统调用添加到列表中一次。