func init_debug(filename string) int { attr := &os.ProcAttr{Sys: &syscall.SysProcAttr{Ptrace: true}} if proc, err := os.StartProcess(filename, []string{"/"}, attr); err == nil { proc.Wait() foo := syscall.PtraceAttach(proc.Pid) fmt.Printf("Started New Process: %v.\n", proc.Pid) fmt.Printf("PtraceAttach res: %v.\n", foo) return 0 } return 2 }
func main() { tpid := flag.Int("pid", 0, "the pid you want to f**k with") tname := flag.String("rename", "", "the name you want it to be called") flag.Parse() if *tpid == 0 || *tname == "" { flag.Usage() // RTFM os.Exit(1) } StackLocation := FindStack(*tpid) if StackLocation == "" { log.Fatal("Unable to find stack. this shouldnt happen.") } log.Printf("Found stack at %s", StackLocation) cmdline := GetCmdLine(*tpid) offset := GetRamOffset(*tpid, StackLocation, cmdline) data := []byte(fmt.Sprint(*tname)) data = append(data, 0x00) eh, _ := os.FindProcess(*tpid) err := syscall.PtraceAttach(eh.Pid) if err != nil { log.Fatalf("Could not attach to the PID. Why? %s", err) } _, err = syscall.PtracePokeData(eh.Pid, uintptr(offset), data) if err != nil { log.Fatalf("now I've f****d up! %s is the error", err) } // fmt.Printf("No idea what it means, but here is 'c' : %d", c) err = syscall.PtraceDetach(eh.Pid) if err != nil { log.Fatalf("Unable to detach?? Why? %s", err) } err = syscall.Kill(eh.Pid, syscall.SIGCONT) if err != nil { log.Fatalf("Unable to detach?? Why? %s", err) } }
// attachThread attaches a running thread to the process. // // Must NOT be run from the monitor thread. func (p *process) attachThread(tid int) (*thread, os.Error) { p.logTrace("attaching to thread %d", tid) var thr *thread err := p.do(func() os.Error { errno := syscall.PtraceAttach(tid) if errno != 0 { return os.NewSyscallError("ptrace(ATTACH)", errno) } var err os.Error thr, err = p.newThread(tid, syscall.SIGSTOP, false) return err }) return thr, err }
func Attach(proc *os.Process) (*Tracer, error) { err := syscall.PtraceAttach(proc.Pid) if err == syscall.EPERM { _, err := syscall.PtraceGetEventMsg(proc.Pid) if err != nil { return nil, err } } else if err != nil { return nil, err } return &Tracer{ Process: proc, }, nil }
func RenamePid(tpid int, tname string) { log.Printf("Attempting to rename pid %d to %s", tpid, tname) StackLocation := FindStack(tpid) if StackLocation == "" { log.Printf("Unable to find stack. this shouldnt happen.") return } cmdline := GetCmdLine(tpid) offset := GetRamOffset(tpid, StackLocation, cmdline) data := []byte(fmt.Sprint(tname)) data = append(data, 0x00) eh, _ := os.FindProcess(tpid) err := syscall.PtraceAttach(eh.Pid) if err != nil { log.Printf("Could not attach to the PID. Why? %s", err) return } _, err = syscall.PtracePokeData(eh.Pid, uintptr(offset), data) if err != nil { log.Printf("now I've f****d up! %s is the error", err) return } // fmt.Printf("No idea what it means, but here is 'c' : %d", c) err = syscall.PtraceDetach(eh.Pid) if err != nil { log.Printf("Unable to detach?? Why? %s", err) return } err = syscall.Kill(eh.Pid, syscall.SIGCONT) if err != nil { log.Printf("Unable to detach?? Why? %s", err) return } }
func (t *Task) Tracer() error { runtime.LockOSThread() if err := syscall.PtraceAttach(t.pid); err != nil { return err } defer func() { // syscall.PtraceCont(t.pid, 0) syscall.PtraceDetach(t.pid) }() regsout := new(syscall.PtraceRegs) status := new(syscall.WaitStatus) var timer *time.Timer refresh := func() { t.RefreshFiles(); timer.Stop(); timer = nil } for { if _, err := syscall.Wait4(t.pid, status, 0, nil); err != nil { log.Println("wait failed", err) return err } if status.Exited() { log.Println("exited") return nil } if err := syscall.PtraceGetRegs(t.pid, regsout); err != nil { log.Println("getregs failed", err) return err } // linux_amd64 if regsout.Orig_rax == syscall.SYS_OPEN { if timer != nil { if timer.Stop() == false { log.Println("cannot stop the timer") } } timer = time.AfterFunc(1e9, refresh) // Wait until open()s "settle". } if err := PtraceSyscall(t.pid); err != nil { log.Println("PtraceSyscall failed", err) return err } } panic("can't reach") }
func TestGoshDoesNotReportSigStopOrContinueAsExitEvenUnderPtrace(t *testing.T) { assert := assrt.NewAssert(t) cmdr := NewRunningCommand( exec.Command("bash", "-c", "sleep 1; exit 4;"), ) cmdr.Start() // Ride the wild wind if err := syscall.PtraceAttach(cmdr.Pid()); err != nil { panic(err) } NewRunningCommand(exec.Command("kill", "-SIGSTOP", Itoa(cmdr.Pid()))).Start().Wait() assert.Equal( false, cmdr.WaitSoon(1500*time.Millisecond), ) NewRunningCommand(exec.Command("kill", "-SIGCONT", Itoa(cmdr.Pid()))).Start().Wait() // Must detach ptrace again for the wait to return. if err := syscall.PtraceDetach(cmdr.Pid()); err != nil { // This boggles my mind. You can pause before and after this, and that pid most certainly does exist, but here we occationally get errors nonetheless. // Have to skip, because we are attached, that process does exist, and if we can't detach, waiting for exit is going to hang forever. t.Skipf("error detaching ptrace: %+v -- pid=%v\n", err, cmdr.Pid()) } assert.Equal( 4, cmdr.GetExitCode(), ) assert.Equal( nil, cmdr.err, ) assert.Equal( FINISHED, cmdr.State(), ) }
func (t *PTracer) traceThread(pid int, process *process) *thread { result := make(chan *thread) t.ops <- func() { thread := newThread(pid, process, t) t.threads[pid] = thread err := syscall.PtraceAttach(pid) if err != nil { log.Printf("Attach %d failed: %v", pid, err) return } result <- thread select { case t.childAttached <- struct{}{}: default: } } return <-result }
func main() { var wstat syscall.WaitStatus var complete func(syscall.PtraceRegs) = nil var die = false regs := syscall.PtraceRegs{} isSyscall := func(wstat syscall.WaitStatus) bool { return (((uint32(wstat) & 0xff00) >> 8) & 0x80) != 0 } sc := initSyscalls() c := make(chan os.Signal, 1) signal.Notify(c, os.Kill, os.Interrupt) go check(c, &die) if pid == -1 { log.Fatal("No pid set") } err := syscall.PtraceAttach(pid) if err != nil { log.Print("attach") log.Print(err) goto fail } _, err = syscall.Wait4(pid, &wstat, 0, nil) if err != nil { log.Printf("wait %d err %s\n", pid, err) goto fail } err = syscall.PtraceSetOptions(pid, syscall.PTRACE_O_TRACESYSGOOD) if err != nil { log.Print("ptrace set options") log.Print(err) goto fail } for !die { err = syscall.PtraceSyscall(pid, 0) if err != nil { log.Print("syscall") log.Print(err) goto fail } _, err = syscall.Wait4(pid, &wstat, 0, nil) if err != nil { log.Printf("wait %d err %s\n", pid, err) goto fail } // ENTER if wstat.Stopped() { if isSyscall(wstat) { err = syscall.PtraceGetRegs(pid, ®s) if err != nil { log.Print("regs") log.Print(err) goto fail } complete = sc.Call(regs) } } err = syscall.PtraceSyscall(pid, 0) if err != nil { log.Print("syscall 2") log.Print(err) goto fail } _, err = syscall.Wait4(pid, &wstat, 0, nil) if err != nil { log.Printf("wait %d err %s\n", pid, err) goto fail } os.Stdout.Sync() if wstat.Stopped() { if isSyscall(wstat) { err = syscall.PtraceGetRegs(pid, ®s) if err != nil { log.Print("regs") log.Print(err) goto fail } //log.Printf("NUM: %d ::%#v", syscallNum, regs) if complete != nil { complete(regs) complete = nil } } } } fail: syscall.Kill(pid, 18) err = syscall.PtraceDetach(pid) if err != nil { log.Print("detach") log.Print(err) } }