package main import ( "fmt" "os" "os/exec" "syscall" sec "github.com/seccomp/libseccomp-golang" ) /* * Register setup: * rax system call number * rdi arg0 * rcx return address for syscall/sysret, C arg3 * rsi arg1 * rdx arg2 * r10 arg3 (--> moved to rcx for C) * r8 arg4 * r9 arg5 * r11 eflags for syscall/sysret, temporary for C * r12-r15,rbp,rbx saved by C code, not touched. */ func main() { var regs syscall.PtraceRegs fmt.Printf("Run %v\n", os.Args[1:]) // Uncommenting this will cause the open syscall to return with Operation Not Permitted error // disallow("open") cmd := exec.Command(os.Args[1], os.Args[2:]...) cmd.Stderr = os.Stderr cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.SysProcAttr = &syscall.SysProcAttr{ Ptrace: true, } cmd.Start() err := cmd.Wait() if err != nil { fmt.Printf("Wait returned: %v\n", err) } pid := cmd.Process.Pid exit := true for { if exit { err = syscall.PtraceGetRegs(pid, ®s) if err != nil { break } // Uncomment to show each syscall as it's called name := getSyscallName(regs.Orig_rax) fmt.Printf("%s: %d(%x,%x,%x)\n", name, regs.Rax, regs.Rdi, regs.Rsi, regs.Rdx) } err = syscall.PtraceSyscall(pid, 0) if err != nil { panic(err) } _, err = syscall.Wait4(pid, nil, 0, nil) if err != nil { panic(err) } exit = !exit } } func getSyscallName(syscallID uint64) string { name, _ := sec.ScmpSyscall(syscallID).GetName() return name }