Python3 Ptrace 重复系统调用
Python3 Ptrace duplicate syscalls
我正在尝试构建一个简单版本的 starce,它向您展示了一个进程进行的第一个 x 系统调用。问题是目前似乎每个系统调用都出现两次(execve
和 exit_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
如您所见,我的代码输出每个系统调用两次。
什么会导致这个?以及如何解决?
在这里深入了解其他线程后,我发现每个系统调用都应该出现两次,一次是在调用之前,另一次是在调用之后。
因此,解决方案是每两次迭代仅将系统调用添加到列表中一次。
我正在尝试构建一个简单版本的 starce,它向您展示了一个进程进行的第一个 x 系统调用。问题是目前似乎每个系统调用都出现两次(execve
和 exit_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
如您所见,我的代码输出每个系统调用两次。
什么会导致这个?以及如何解决?
在这里深入了解其他线程后,我发现每个系统调用都应该出现两次,一次是在调用之前,另一次是在调用之后。
因此,解决方案是每两次迭代仅将系统调用添加到列表中一次。