func (t *thread) ptracePokeText(addr uintptr, out []byte) (int, os.Error) { c, err := syscall.PtracePokeText(t.tid, addr, out) if traceMem { fmt.Printf("poke(%#x, %v) => %v\n", addr, out, err) } return c, os.NewSyscallError("ptrace(POKETEXT)", err) }
func poke(pid int, addr uint64, data []byte) error { n, err := syscall.PtracePokeText(pid, uintptr(addr), data) if err != nil { return err } if n != len(data) { return fmt.Errorf("poke: got %d bytes, want %d", len(data)) } return nil }
// writeMemoryAligned is a wrapper for ptrace(PTRACE_POKETEXT) that attempts to // make all calls wordsize-aligned. For some reason, this is completely // different from readMemoryAligned and they should be merged. func (p *Process) writeMemoryAligned(where uint64, bytes []byte) (count int, err error) { wordsize := int(unsafe.Sizeof(uintptr(0))) rem := len(bytes) % wordsize if rem > 0 { pad := make([]byte, wordsize) syscall.PtracePokeText(p.Pid, uintptr(where+uint64(len(bytes)-rem)), pad) bytes = append(bytes, pad[rem:]...) } for offset := 0; offset < len(bytes); offset += wordsize { toWrite := bytes[offset : offset+wordsize] cnt, err := syscall.PtracePokeText(p.Pid, uintptr(where+uint64(offset)), toWrite) if err != nil { return cnt, err } count += cnt } return }
func (s *Server) ptracePoke(pid int, addr uintptr, data []byte) (err error) { s.fc <- func() error { n, err := syscall.PtracePokeText(pid, addr, data) if err != nil { return err } if n != len(data) { return fmt.Errorf("ptracePoke: poked %d bytes, want %d", n, len(data)) } return nil } return <-s.ec }
// SwapBytesText simple writes the slice 'what' to the location 'where' in the // target process, returning the content that used to be at that address in // the 'what' slice. func (p *Process) SwapBytesText(where uint64, what []byte) bool { p.ensureNotRunning() saved := make([]byte, len(what)) //cnt, err := syscall.PtracePeekText(p.Pid, uintptr(where), saved) cnt, err := p.readMemoryAligned(where, saved) if cnt != len(what) || err != nil { return false } cnt, err = syscall.PtracePokeText(p.Pid, uintptr(where), what) if cnt != len(what) || err != nil { fmt.Printf("failed writing") return false } copy(what, saved) return true }
func (t *Tracer) PokeText(addr uintptr, data []byte) (int, error) { return syscall.PtracePokeText(t.Process.Pid, addr, data) }