Any good guides on using PTRACE_SYSEMU?

Active3 hr before
Viewed126 times

5 Answers


A solution is to change the behaviour of ptrace() to not call the real syscall and thus we don't have to replace it by a call to getpid(). How ?,What I found interesting:,Link in comment was redirecting to secret site from 2004:, 1 Hey its 2016 I don't know if you found any resources but the man pages still state PTRACE_SINGLESTEP, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP Details of these kinds of stops are yet to be documented. So did you find a resource? – Valarauca Sep 25 '16 at 17:27

186 struct user_regs_struct regs;
188 printf("[RUN]\tSYSEMU\n");
if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
   190 err(1, "PTRACE_SYSCALL");
191 wait_trap(chld);
if (ptrace(PTRACE_GETREGS, chld, 0, & regs) != 0)
   194 err(1, "PTRACE_GETREGS");
if (regs.user_syscall_nr != SYS_gettid ||
   197 regs.user_arg0 != 10 || regs.user_arg1 != 11 ||
   198 regs.user_arg2 != 12 || regs.user_arg3 != 13 ||
   199 regs.user_arg4 != 14 || regs.user_arg5 != 15) {
   200 printf("[FAIL]\tInitial args are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long) regs.user_syscall_nr, (unsigned long) regs.user_arg0, (unsigned long) regs.user_arg1, (unsigned long) regs.user_arg2, (unsigned long) regs.user_arg3, (unsigned long) regs.user_arg4, (unsigned long) regs.user_arg5);
   201 nerrs++;
} else {
   203 printf("[OK]\tInitial nr and args are correct\n");
206 printf("[RUN]\tRestart the syscall (ip = 0x%lx)\n",
   207(unsigned long) regs.user_ip);
210  * This does exactly what it appears to do if syscall is int80 or
211  * SYSCALL64.  For SYSCALL32 or SYSENTER, though, this is highly
212  * magical.  It needs to work so that ptrace and syscall restart
213  * work as expected.
214  */
215 regs.user_ax = regs.user_syscall_nr;
216 regs.user_ip -= 2;
if (ptrace(PTRACE_SETREGS, chld, 0, & regs) != 0)
   218 err(1, "PTRACE_SETREGS");
if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
   221 err(1, "PTRACE_SYSCALL");
222 wait_trap(chld);
if (ptrace(PTRACE_GETREGS, chld, 0, & regs) != 0)
   225 err(1, "PTRACE_GETREGS");
load more v

For details of in-depth Linux/UNIX system programming training courses that I teach, look here. , HTML rendering created 2021-08-27 by Michael Kerrisk, author of The Linux Programming Interface, maintainer of the Linux man-pages project.

PTRACE(2) Linux Programmer 's Manual              PTRACE(2)
load more v

The ptrace platform uses PTRACE_SYSEMU to execute user code without allowing it to execute host system calls. This platform can run anywhere that ptrace works (even VMs without nested virtualization), which is ubiquitous.,The KVM platform uses the kernel’s KVM functionality to allow the Sentry to act as both guest OS and VMM. The KVM platform can run on bare-metal or in a VM with nested virtualization enabled. While there is no virtualized hardware layer – the sandbox retains a process model – gVisor leverages virtualization extensions available on modern processors in order to improve isolation and performance of address space switches.,The choice of platform depends on the context in which runsc is executing. In general, virtualized platforms may be limited to platforms that do not require hardware virtualized support (since the hardware is already in use):,There are a number of different ways to implement this interface that come with various trade-offs, generally around performance and hardware requirements.

type Platform interface {
   NewAddressSpace()(AddressSpace, error)
   NewContext() Context

type Context interface {
   Switch(as AddressSpace, ac arch.Context)(..., error)

type AddressSpace interface {
   MapFile(addr hostarch.Addr, f File, fr FileRange, at hostarch.AccessType, ...) error
   Unmap(addr hostarch.Addr, length uint64)

load more v

To run binaries for the same architecture from any system with a stable (enough) system call ABI, you just need this PTRACE_SYSEMU tracer, a loader (to take the place of exec(2)), and whatever system libraries the binary needs (or only run static binaries).,The operating system will return ENOSYS (Function not implemented) since this isn’t a real system call. So on the way out I overwrite this with a success (0).,The PTRACE_SYSCALL request is used in both waiting for the next system call to begin, and waiting for that system call to exit. As before, a wait(2) is needed to wait for the tracee to enter the desired state.,In the xpledge tracer, I just need to check for this system call:

long ptrace(int request, pid_t pid, void * addr, void * data);
load more v

Other "using-undefined" queries related to "Any good guides on using PTRACE_SYSEMU?"