main.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "syscall"
  7. sec "github.com/seccomp/libseccomp-golang"
  8. )
  9. /*
  10. * Register setup:
  11. * rax system call number
  12. * rdi arg0
  13. * rcx return address for syscall/sysret, C arg3
  14. * rsi arg1
  15. * rdx arg2
  16. * r10 arg3 (--> moved to rcx for C)
  17. * r8 arg4
  18. * r9 arg5
  19. * r11 eflags for syscall/sysret, temporary for C
  20. * r12-r15,rbp,rbx saved by C code, not touched.
  21. */
  22. func main() {
  23. var regs syscall.PtraceRegs
  24. fmt.Printf("Run %v\n", os.Args[1:])
  25. // Uncommenting this will cause the open syscall to return with Operation Not Permitted error
  26. // disallow("open")
  27. cmd := exec.Command(os.Args[1], os.Args[2:]...)
  28. cmd.Stderr = os.Stderr
  29. cmd.Stdin = os.Stdin
  30. cmd.Stdout = os.Stdout
  31. cmd.SysProcAttr = &syscall.SysProcAttr{
  32. Ptrace: true,
  33. }
  34. cmd.Start()
  35. err := cmd.Wait()
  36. if err != nil {
  37. fmt.Printf("Wait returned: %v\n", err)
  38. }
  39. pid := cmd.Process.Pid
  40. exit := true
  41. for {
  42. if exit {
  43. err = syscall.PtraceGetRegs(pid, &regs)
  44. if err != nil {
  45. break
  46. }
  47. // Uncomment to show each syscall as it's called
  48. name := getSyscallName(regs.Orig_rax)
  49. fmt.Printf("%s: %d(%x,%x,%x)\n", name, regs.Rax, regs.Rdi, regs.Rsi, regs.Rdx)
  50. }
  51. err = syscall.PtraceSyscall(pid, 0)
  52. if err != nil {
  53. panic(err)
  54. }
  55. _, err = syscall.Wait4(pid, nil, 0, nil)
  56. if err != nil {
  57. panic(err)
  58. }
  59. exit = !exit
  60. }
  61. }
  62. func getSyscallName(syscallID uint64) string {
  63. name, _ := sec.ScmpSyscall(syscallID).GetName()
  64. return name
  65. }