github.com/criyle/go-sandbox@v0.10.3/ptracer/context_helper_linux.go (about) 1 package ptracer 2 3 import ( 4 "syscall" 5 "unsafe" 6 7 unix "golang.org/x/sys/unix" 8 ) 9 10 // TODO: make this method not to call ptrace too much 11 func ptraceReadStr(pid int, addr uintptr, buff []byte) { 12 syscall.PtracePeekData(pid, addr, buff) 13 } 14 15 func processVMReadv(pid int, localIov, remoteIov []unix.Iovec, 16 flags uintptr) (r1, r2 uintptr, err syscall.Errno) { 17 return syscall.Syscall6(unix.SYS_PROCESS_VM_READV, uintptr(pid), 18 uintptr(unsafe.Pointer(&localIov[0])), uintptr(len(localIov)), 19 uintptr(unsafe.Pointer(&remoteIov[0])), uintptr(len(remoteIov)), 20 flags) 21 } 22 23 func vmRead(pid int, addr uintptr, buff []byte) (int, error) { 24 l := len(buff) 25 localIov := getIovecs(&buff[0], l) 26 remoteIov := getIovecs((*byte)(unsafe.Pointer(addr)), l) 27 n, _, err := processVMReadv(pid, localIov, remoteIov, uintptr(0)) 28 if err == 0 { 29 return int(n), nil 30 } 31 return int(n), err 32 } 33 34 func getIovecs(base *byte, l int) []unix.Iovec { 35 return []unix.Iovec{getIovec(base, l)} 36 } 37 38 func vmReadStr(pid int, addr uintptr, buff []byte) error { 39 // Deal with unaligned addr 40 n := 0 41 r := pageSize - int(addr%uintptr(pageSize)) 42 if r == 0 { 43 r = pageSize 44 } 45 46 for len(buff) > 0 { 47 if l := len(buff); r < l { 48 r = l 49 } 50 51 nn, err := vmRead(pid, addr+uintptr(n), buff[:r]) 52 if err != nil { 53 return err 54 } 55 56 if hasNull(buff[:nn]) { 57 return nil 58 } 59 60 n += nn 61 buff = buff[nn:] 62 r = pageSize 63 } 64 return nil 65 } 66 67 func hasNull(buff []byte) bool { 68 for _, b := range buff { 69 if b == 0 { 70 return true 71 } 72 } 73 return false 74 } 75 76 func clen(b []byte) int { 77 for i := 0; i < len(b); i++ { 78 if b[i] == 0 { 79 return i 80 } 81 } 82 return len(b) + 1 83 }