The tagline was "strace meets expect". You could write a Python script to control what happened when the process being traced made a syscall of your choice! This was super-fun and super-educational and also came with a little manifesto about ensuring users' control over software rather than the other way around.
Unfortunately subterfugue hasn't been maintained in years and I think it hasn't worked with the last few major releases of the Linux kernel. It would be amazing to see a similar tool nowadays.
Cool! I did this a while ago for some CPU-bound stuff, and ran into a bunch of performance bottlenecks.
Some things that helped me scale ptrace-interception up:
- SECCOMP_BPF filter (getting these right matters a lot)
- moving all of your intercept work to a single side (enter or exit)
- ensure affinity between the traced and tracing processes
- nuke vdso
- remove vdso from the aux vector (otherwise good libc's will find it again)
At the end of the day unfortunately the better solution would have been to write kernel support for what I wanted to do, but it's a fun exercise in learning about system calls.
It’s a nice write up and the part on system call interception is only serving as an example, but be careful if you’re considering ptrace in something where security matters.
> The catch is that a process can only have one tracer attached at a time, so it's not possible emulate a foreign operating system while also debugging that process with, say, GDB.
This is actually possible. How? The obvious way... You intercept and emulate ptrace calls with ptrace.
This is (basically?) the technique used by PRoot, which has issues with using SECCOMP [1]. If anyone has the expertise, they'd doubtless be grateful of help with the problem.
PRoot is pretty useful as a pure-userland solution for jobs that container-ish things might otherwise do, e.g. user-mode installation of Nix/Guix.
Hello, actually WINE works in a different way, it does not attempt to intercept system calls (it is not possible because Windows system calls work in an incompatible way), instead it reimplements Windows DLLs, and normal application code never calls syscalls directly, but always via the DLLs implementing the libc or other libraries. So the DLLs of the core Windows functions are simply replaced with the WINE implementation on top of the POSIX API.
FWIW, Micorsoft's implementations of Win32 have swapped out the kernel a few times anyway, so it's not the biggest leap for a third party (DOS/Win32s, Win9x, WinNT).
Because of this, Microsoft considers the system call layer to be unstable, and appears to go out of their way to change the system call table every service pack. So the dll entry points are the stable ABI, and that's what 99.99% of developers rely on.
Windows has a much more powerful process-poking layer than Linux does. This layer is pretty much consolidated into the ptrace syscall on Linux systems (I honestly prefer Windows' APIs here). Doing any of these calls in a Windows application is going to require WINE to use ptrace.
Now why are those calls needed? I think some of it relates to DRM provisions. I also want to say that some of it is necessary to implement various features of COM (i.e., remote procedure call stuff), but that might not be the case, given that the reports suggest that ptrace support is often unnecessary.
> The request field selects a specific Ptrace function, just like the ioctl(2) interface. For strace, only two are needed:
PTRACE_TRACEME: This process is to be traced by its parent.
PTRACE_SYSCALL: Continue, but stop at the next system call entrance or exit.
PTRACE_GETREGS: Get a copy of the tracee’s registers.
The tagline was "strace meets expect". You could write a Python script to control what happened when the process being traced made a syscall of your choice! This was super-fun and super-educational and also came with a little manifesto about ensuring users' control over software rather than the other way around.
Unfortunately subterfugue hasn't been maintained in years and I think it hasn't worked with the last few major releases of the Linux kernel. It would be amazing to see a similar tool nowadays.