diff options
Diffstat (limited to 'vendor/github.com/radareorg')
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/LICENSE | 23 | ||||
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/Makefile | 12 | ||||
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/README.md | 17 | ||||
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/api.go | 47 | ||||
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/native.go | 161 | ||||
-rw-r--r-- | vendor/github.com/radareorg/r2pipe-go/r2pipe.go | 243 |
6 files changed, 503 insertions, 0 deletions
diff --git a/vendor/github.com/radareorg/r2pipe-go/LICENSE b/vendor/github.com/radareorg/r2pipe-go/LICENSE new file mode 100644 index 0000000..fd92b03 --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2021 radare + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/vendor/github.com/radareorg/r2pipe-go/Makefile b/vendor/github.com/radareorg/r2pipe-go/Makefile new file mode 100644 index 0000000..5dd762a --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/Makefile @@ -0,0 +1,12 @@ +all: + go test + +ex: + cd example ; go run example.go + +sync: + git clone --depth=1 https://github.com/radareorg/radare2-r2pipe + cp -rf radare2-r2pipe/go/*.go . + rm -rf radare2-r2pipe + +.PHONY: all sync diff --git a/vendor/github.com/radareorg/r2pipe-go/README.md b/vendor/github.com/radareorg/r2pipe-go/README.md new file mode 100644 index 0000000..238a1bc --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/README.md @@ -0,0 +1,17 @@ +r2pipe.go +========= + +Go module to interact with radare2 + +Source +------ + +This repository is in sync with [radareorg/r2pipe](https://godoc.org/github.com/radareorg/radare2-r2pipe). + +Run `make sync` to update it after changing things in the source repository. + +Documentation +------------- + +[![GoDoc](https://godoc.org/github.com/radare/r2pipe-go?status.svg)](https://godoc.org/github.com/radare/r2pipe-go) + diff --git a/vendor/github.com/radareorg/r2pipe-go/api.go b/vendor/github.com/radareorg/r2pipe-go/api.go new file mode 100644 index 0000000..9ccf5ca --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/api.go @@ -0,0 +1,47 @@ +// radare - LGPL - Copyright 2021 - pancake + +package r2pipe + +// #cgo CFLAGS: -I/usr/local/include/libr +// #cgo CFLAGS: -I/usr/local/include/libr/sdb +// #cgo LDFLAGS: -L/usr/local/lib -lr_core +// #include <stdio.h> +// #include <stdlib.h> +// extern void r_core_free(void *); +// extern void *r_core_new(void); +// extern char *r_core_cmd_str(void*, const char *); +// +import "C" + +import ( + "unsafe" +) + +func (r2p *Pipe) ApiCmd(cmd string) (string, error) { + res := C.r_core_cmd_str(r2p.Core, C.CString(cmd)) + return C.GoString(res), nil +} + +func (r2p *Pipe) ApiClose() error { + C.r_core_free(unsafe.Pointer(r2p.Core)) + r2p.Core = nil + return nil +} + +func NewApiPipe(file string) (*Pipe, error) { + r2 := C.r_core_new() + r2p := &Pipe{ + File: file, + Core: r2, + cmd: func(r2p *Pipe, cmd string) (string, error) { + return r2p.ApiCmd(cmd) + }, + close: func(r2p *Pipe) error { + return r2p.ApiClose() + }, + } + if file != "" { + r2p.ApiCmd("o " + file) + } + return r2p, nil +} diff --git a/vendor/github.com/radareorg/r2pipe-go/native.go b/vendor/github.com/radareorg/r2pipe-go/native.go new file mode 100644 index 0000000..2283717 --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/native.go @@ -0,0 +1,161 @@ +// radare - LGPL - Copyright 2017 - pancake + +package r2pipe + +//#cgo linux LDFLAGS: -ldl +//#include <stdio.h> +//#include <dlfcn.h> +// #include <stdlib.h> +// void *gor_core_new(void *f) { +// void *(*rcn)(); +// rcn = (void *(*)())f; +// return rcn(); +// } +// +// void gor_core_free(void *f, void *arg) { +// void (*fr)(void *); +// fr = (void (*)(void *))f; +// fr(arg); +// } +// +// char *gor_core_cmd_str(void *f, void *arg, char *arg2) { +// char *(*cmdstr)(void *, char *); +// cmdstr = (char *(*)(void *, char *))f; +// return cmdstr(arg, arg2); +// } +import "C" + +import ( + "errors" + "fmt" + "os" + "runtime" + "unsafe" +) + +type Ptr = unsafe.Pointer + +// *struct{} + +var ( + lib Ptr = nil + r_core_new func() Ptr + r_core_free func(Ptr) + r_core_cmd_str func(Ptr, string) string +) + +type DL struct { + handle unsafe.Pointer + name string +} + +func libpath(libname string) string { + paths := []string{"/usr/local/lib", "/usr/lib", "/lib"} + for _, path := range paths { + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + // path/to/whatever does not exist + } else { + // file exists + return path + "/" + libname + } + } + return libname +} + +func dlOpen(path string) (*DL, error) { + var ret DL + switch runtime.GOOS { + case "darwin": + path = path + ".dylib" + case "windows": + path = path + ".dll" + default: + path = path + ".so" //linux/bsds + } + path = libpath(path) + cpath := C.CString(path) + if cpath == nil { + return nil, errors.New("Failed to get cpath") + } + //r2pioe only uses flag 0 + ret.handle = C.dlopen(cpath, 0) + ret.name = path + C.free(unsafe.Pointer(cpath)) + if ret.handle == nil { + return nil, errors.New(fmt.Sprintf("Failed to open %s", path)) + } + return &ret, nil +} + +func dlSym(dl *DL, name string) (unsafe.Pointer, error) { + cname := C.CString(name) + if cname == nil { + return nil, errors.New("Fail") + } + handle := C.dlsym(dl.handle, cname) + C.free(unsafe.Pointer(cname)) + if handle == nil { + return nil, errors.New("Fail") + } + return handle, nil +} + +func NativeLoad() error { + if lib != nil { + return nil + } + lib, err := dlOpen("libr_core") + _ = lib + if err != nil { + return err + } + handle1, _ := dlSym(lib, "r_core_new") + r_core_new = func() Ptr { + a := (Ptr)(C.gor_core_new(handle1)) + return a + } + handle2, _ := dlSym(lib, "r_core_free") + r_core_free = func(p Ptr) { + C.gor_core_free(handle2, unsafe.Pointer(p)) + } + handle3, _ := dlSym(lib, "r_core_cmd_str") + r_core_cmd_str = func(p Ptr, s string) string { + a := C.CString(s) + b := C.gor_core_cmd_str(handle3, unsafe.Pointer(p), a) + C.free(unsafe.Pointer(a)) + return C.GoString(b) + } + return nil +} + +func (r2p *Pipe) NativeCmd(cmd string) (string, error) { + res := r_core_cmd_str(r2p.Core, cmd) + return res, nil +} + +func (r2p *Pipe) NativeClose() error { + r_core_free(r2p.Core) + r2p.Core = nil + return nil +} + +func NewNativePipe(file string) (*Pipe, error) { + if err := NativeLoad(); err != nil { + return nil, err + } + r2 := r_core_new() + r2p := &Pipe{ + File: file, + Core: r2, + cmd: func(r2p *Pipe, cmd string) (string, error) { + return r2p.NativeCmd(cmd) + }, + close: func(r2p *Pipe) error { + return r2p.NativeClose() + }, + } + if file != "" { + r2p.NativeCmd("o " + file) + } + return r2p, nil +} diff --git a/vendor/github.com/radareorg/r2pipe-go/r2pipe.go b/vendor/github.com/radareorg/r2pipe-go/r2pipe.go new file mode 100644 index 0000000..d87e2fe --- /dev/null +++ b/vendor/github.com/radareorg/r2pipe-go/r2pipe.go @@ -0,0 +1,243 @@ +// radare - LGPL - Copyright 2015 - nibble + +/* +Package r2pipe allows to call r2 commands from Go. A simple hello world would +look like the following snippet: + + package main + + import ( + "fmt" + + "github.com/radare/r2pipe-go" + ) + + func main() { + r2p, err := r2pipe.NewPipe("malloc://256") + if err != nil { + panic(err) + } + defer r2p.Close() + + _, err = r2p.Cmd("w Hello World") + if err != nil { + panic(err) + } + buf, err := r2p.Cmd("ps") + if err != nil { + panic(err) + } + fmt.Println(buf) + } +*/ +package r2pipe + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "os/exec" + "strconv" + "strings" + "unsafe" +) + +// A Pipe represents a communication interface with r2 that will be used to +// execute commands and obtain their results. +type Pipe struct { + File string + r2cmd *exec.Cmd + stdin io.WriteCloser + stdout io.ReadCloser + stderr io.ReadCloser + Core unsafe.Pointer + cmd CmdDelegate + close CloseDelegate +} + +type ( + CmdDelegate func(*Pipe, string) (string, error) + CloseDelegate func(*Pipe) error + EventDelegate func(*Pipe, string, interface{}, string) bool +) + +// NewPipe returns a new r2 pipe and initializes an r2 core that will try to +// load the provided file or URI. If file is an empty string, the env vars +// R2PIPE_{IN,OUT} will be used as file descriptors for input and output, this +// is the case when r2pipe is called within r2. +func NewPipe(file string) (*Pipe, error) { + if file == "" { + return newPipeFd() + } + + return newPipeCmd(file) +} + +func newPipeFd() (*Pipe, error) { + r2pipeIn := os.Getenv("R2PIPE_IN") + r2pipeOut := os.Getenv("R2PIPE_OUT") + + if r2pipeIn == "" || r2pipeOut == "" { + return nil, fmt.Errorf("missing R2PIPE_{IN,OUT} vars") + } + + r2pipeInFd, err := strconv.Atoi(r2pipeIn) + if err != nil { + return nil, fmt.Errorf("failed to convert IN into file descriptor") + } + + r2pipeOutFd, err := strconv.Atoi(r2pipeOut) + if err != nil { + return nil, fmt.Errorf("failed to convert OUT into file descriptor") + } + + stdout := os.NewFile(uintptr(r2pipeInFd), "R2PIPE_IN") + stdin := os.NewFile(uintptr(r2pipeOutFd), "R2PIPE_OUT") + + r2p := &Pipe{ + File: "", + r2cmd: nil, + stdin: stdin, + stdout: stdout, + Core: nil, + } + + return r2p, nil +} + +func newPipeCmd(file string) (*Pipe, error) { + + r2p := &Pipe{File: file, r2cmd: exec.Command("radare2", "-q0", file)} + var err error + r2p.stdin, err = r2p.r2cmd.StdinPipe() + if err == nil { + r2p.stdout, err = r2p.r2cmd.StdoutPipe() + if err == nil { + r2p.stderr, err = r2p.r2cmd.StdoutPipe() + } + if err = r2p.r2cmd.Start(); err == nil { + //Read the initial data + _, err = bufio.NewReader(r2p.stdout).ReadString('\x00') + } + } + return r2p, err +} + +// Write implements the standard Write interface: it writes data to the r2 +// pipe, blocking until r2 have consumed all the data. +func (r2p *Pipe) Write(p []byte) (n int, err error) { + return r2p.stdin.Write(p) +} + +// Read implements the standard Read interface: it reads data from the r2 +// pipe's stdin, blocking until the previously issued commands have finished. +func (r2p *Pipe) Read(p []byte) (n int, err error) { + return r2p.stdout.Read(p) +} + +func (r2p *Pipe) ReadErr(p []byte) (n int, err error) { + return r2p.stderr.Read(p) +} + +func (r2p *Pipe) On(evname string, p interface{}, cb EventDelegate) error { + path, err := r2p.Cmd("===stderr") + if err != nil { + return err + } + f, err := os.OpenFile(path, os.O_RDONLY, 0600) + + if err != nil { + return err + } + go func() { + var buf bytes.Buffer + for { + io.Copy(&buf, f) + if buf.Len() > 0 { + if !cb(r2p, evname, p, buf.String()) { + break + } + } + } + f.Close() + }() + return nil +} + +// Cmd is a helper that allows to run r2 commands and receive their output. +func (r2p *Pipe) Cmd(cmd string) (string, error) { + if r2p.Core != nil { + if r2p.cmd != nil { + return r2p.cmd(r2p, cmd) + } + + return "", nil + } + + if _, err := fmt.Fprintln(r2p, cmd); err != nil { + return "", err + } + + buf, err := bufio.NewReader(r2p).ReadString('\x00') + if err != nil { + return "", err + } + return strings.TrimRight(buf, "\n\x00"), err +} + +//like cmd but formats the command +func (r2p *Pipe) Cmdf(f string, args ...interface{}) (string, error) { + return r2p.Cmd(fmt.Sprintf(f, args...)) +} + +// Cmdj acts like Cmd but interprets the output of the command as json. It +// returns the parsed json keys and values. +func (r2p *Pipe) Cmdj(cmd string) (out interface{}, err error) { + rstr, err := r2p.Cmd(cmd) + if err == nil { + err = json.Unmarshal([]byte(rstr), out) + } + return out, err +} + +//like cmdj but formats the command +func (r2p *Pipe) Cmdjf(f string, args ...interface{}) (interface{}, error) { + return r2p.Cmdj(fmt.Sprintf(f, args...)) +} + +// Close shuts down r2, closing the created pipe. +func (r2p *Pipe) Close() error { + if r2p.close != nil { + return r2p.close(r2p) + } + + if r2p.File == "" { + return nil + } + + if _, err := r2p.Cmd("q"); err != nil { + return err + } + + return r2p.r2cmd.Wait() +} + +// Forcing shutdown of r2, closing the created pipe. +func (r2p *Pipe) ForceClose() error { + if r2p.close != nil { + return r2p.close(r2p) + } + + if r2p.File == "" { + return nil + } + + if _, err := r2p.Cmd("q!"); err != nil { + return err + } + + return r2p.r2cmd.Wait() +} |