├── .gitignore ├── swift ├── .swift-version ├── Cartfile ├── ccall │ ├── Makefile │ ├── module.modulemap │ └── main.swift ├── r2plugin │ ├── main.swift │ ├── r2swift-Bridging-Header.h │ ├── struct.c │ ├── Makefile │ └── r2.h ├── Package.swift ├── Makefile └── README.md ├── python ├── .gitignore ├── examples │ ├── syscall │ │ ├── int.sh │ │ ├── int.r2 │ │ └── int.py │ ├── ls │ ├── ccall.py │ ├── batch.py │ ├── test.py │ ├── test2.py │ ├── bug.py │ ├── test-backends.py │ ├── 010-to-r2.py │ ├── libgraph.py │ └── sync │ │ └── talkto.py ├── requirements-test.txt ├── test │ ├── ls │ ├── .DS_Store │ ├── ccall.py │ ├── race.sh │ ├── race.py │ └── test_unit.py ├── TODO ├── MANIFEST.in ├── lang-pipe.py ├── dbgtest.py ├── setup.cfg ├── except.py ├── setup.py ├── README.md ├── python-wrapper ├── LICENSE └── Makefile ├── v ├── Makefile ├── v.mod ├── test.v └── README.md ├── crystal ├── Makefile └── core.cr ├── go ├── ORIGIN ├── go.mod ├── Makefile ├── example │ └── example.go ├── README.md ├── r2pipe_native_test.go ├── errside_test.go ├── r2pipe_test.go ├── LICENSE └── api.go ├── haskell ├── .gitignore ├── Setup.hs ├── example_r2pipe.hs ├── r2pipe.cabal ├── LICENSE └── R2Pipe.hs ├── rust ├── ORIGIN └── README.md ├── erlang ├── ORIGIN ├── rebar.config ├── Makefile ├── src │ ├── r2pipe_erl.app.src │ ├── r2pipe.erl │ └── r2pipe_handler.erl ├── testr2pipe.erl ├── README.md └── LICENSE ├── nodejs ├── r2pipe │ ├── examples │ │ ├── syscall │ │ │ ├── int.sh │ │ │ ├── int.r2 │ │ │ └── int.js │ │ ├── typescript │ │ │ ├── test.ts │ │ │ ├── package.json │ │ │ └── package-lock.json │ │ ├── exectest.js │ │ ├── http │ │ │ ├── Makefile │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── index.js │ │ ├── ircbot │ │ │ └── package.json │ │ ├── test-simple.js │ │ ├── tgbot │ │ │ ├── package.json │ │ │ └── README.md │ │ ├── hello.js │ │ ├── test-malloc.js │ │ ├── test-lpipeSync.js │ │ ├── test-http.js │ │ ├── set-get-tcp.js │ │ ├── test-pipeSync.js │ │ ├── test-pipe.js │ │ ├── promise.js │ │ ├── test-r2io-plugin.js │ │ ├── test-channels.js │ │ ├── test-connect.js │ │ ├── test-open.js │ │ ├── promise2.js │ │ ├── r2co.js │ │ ├── load-tcp.js │ │ └── test-r2.js │ ├── testsuite │ │ ├── README.md │ │ ├── b │ │ │ └── ls │ │ ├── r2 │ │ │ ├── hello.js │ │ │ └── async.js │ │ ├── node │ │ │ ├── json.js │ │ │ ├── sync.js │ │ │ ├── bugs.js │ │ │ ├── cloud.js │ │ │ └── async.js │ │ ├── index.js │ │ └── package.json │ ├── Makefile │ ├── util.js │ ├── package.json │ ├── r2pipe.d.ts │ └── sync.js └── r2pipe-promise │ ├── .travis.yml │ ├── ts │ ├── tsconfig.json │ ├── package.json │ ├── test.ts │ └── test.js │ ├── test-promise.js │ ├── test-async-await.js │ ├── test-bluebird.js │ ├── test-co.js │ ├── test-hang-bug.js │ ├── r2pipe-promise.d.ts │ ├── test-timeout.js │ └── package.json ├── cxx-qt ├── check.sh ├── r2pipe.pro ├── test.cxx ├── r2pipe-api.cxx ├── r2pipe.h └── r2pipe.cxx ├── perl ├── MANIFEST ├── Makefile.PL ├── t │ └── readme_example.pl └── README.md ├── dotnet ├── FSharpExample │ ├── Makefile │ └── test.fs ├── r2pipe │ ├── Makefile │ ├── Program.cs │ ├── project.json │ ├── IR2Pipe.cs │ ├── OldApi │ │ └── HttpR2Pipe.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── CmdQueue.cs │ └── DllR2Pipe.cs ├── FormExample │ └── Makefile ├── DllExample │ ├── App.config │ └── Program.cs ├── HttpExample │ ├── App.config │ ├── Program.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── LocalExample │ ├── App.config │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Program.cs ├── JsonExample │ ├── Makefile │ └── main.cs ├── LICENSE ├── r2pipe.csproj.nuspec ├── r2pipe-portable │ └── Properties │ │ └── AssemblyInfo.cs └── Makefile ├── newlisp ├── Makefile ├── test-spawn.lsp ├── test-lib.lsp └── main.lsp ├── nim ├── Makefile ├── main.nim └── r2pipe.nim ├── shell ├── Makefile ├── test.sh ├── r2pipe.sh └── r2cmd.c ├── dlang ├── Makefile ├── test.d └── r2pipe.d ├── r2pipe.png ├── java ├── javax.json-1.1.jar ├── javax.json-api-1.0.jar ├── examples │ ├── groovy │ │ ├── Makefile │ │ └── test.groovy │ ├── TestJNI.java │ ├── Makefile │ ├── Test.java │ └── TestJSON.java ├── config.mk ├── Makefile ├── src │ └── main │ │ └── java │ │ └── org │ │ └── radare │ │ └── r2pipe │ │ └── R2PipeJNI.java └── jni │ ├── Makefile │ └── r2pipe-jni.c ├── r2core-js ├── tuto │ ├── crackme │ ├── make.js │ ├── Makefile │ ├── index.html │ ├── crackme.c │ ├── package.json │ ├── style.css │ ├── main.html │ ├── engine.js │ └── tuto01.yaml ├── test.js ├── index.js ├── nodetest.js ├── package.json ├── Makefile └── README.md ├── zig ├── Makefile ├── test.zig ├── README.md ├── main.zig ├── build.zig └── src │ └── r2pipe.zig ├── vim ├── Makefile ├── r2pipe.vim └── README.md ├── websocket ├── Makefile ├── index.html ├── ws.py └── r2ws.js ├── typescript ├── examples │ └── hello │ │ ├── index.ts │ │ ├── Makefile │ │ ├── tsconfig.json │ │ └── package.json ├── Makefile ├── test-spawn.ts ├── test-local.ts ├── r2pipe │ ├── index.ts │ ├── base.ts │ ├── http.ts │ ├── local.ts │ └── queue.ts ├── tsconfig.json ├── package.json ├── test-http.ts └── README.md ├── clojure ├── test │ └── r2pipe │ │ └── clj_test.clj ├── project.clj └── src │ └── r2pipe │ ├── spawn.clj │ ├── proto.clj │ ├── core.clj │ ├── tcp.clj │ └── http.clj ├── configure.acr ├── dart ├── README.md ├── pubspec.yaml ├── Makefile ├── r2pipe-r2js.dart └── r2pipe-ffi.dart ├── rexx ├── README.md └── r2pipe.rexx ├── vala ├── r2pipe.pc.acr ├── README.md ├── main.vala └── Makefile ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── ci.yml │ └── codeql.yml ├── Package.swift ├── ruby ├── test.rb └── r2pipe.rb ├── c ├── test-pipe.c ├── test-pipe2.c ├── test-spawn.c ├── Makefile └── README.md ├── ocaml └── README.md ├── lisp ├── main.lisp └── r2pipe.lisp ├── autogen.sh ├── Makefile.acr ├── php └── poc.php └── prolog └── r2pipe.pl /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /swift/.swift-version: -------------------------------------------------------------------------------- 1 | 5.8 2 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | .coverage 2 | -------------------------------------------------------------------------------- /v/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | v test.v 3 | -------------------------------------------------------------------------------- /crystal/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | crystal build core.cr 3 | -------------------------------------------------------------------------------- /go/ORIGIN: -------------------------------------------------------------------------------- 1 | https://github.com/radare/r2pipe.go 2 | -------------------------------------------------------------------------------- /haskell/.gitignore: -------------------------------------------------------------------------------- 1 | .ghc.* 2 | *.local 3 | dist-* 4 | -------------------------------------------------------------------------------- /python/examples/syscall/int.sh: -------------------------------------------------------------------------------- 1 | r2 -qi int.r2 - 2 | -------------------------------------------------------------------------------- /python/requirements-test.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | coverage 3 | -------------------------------------------------------------------------------- /rust/ORIGIN: -------------------------------------------------------------------------------- 1 | https://github.com/radare/r2pipe.rs 2 | -------------------------------------------------------------------------------- /swift/Cartfile: -------------------------------------------------------------------------------- 1 | github "SwiftyJSON/SwiftyJSON" 2 | -------------------------------------------------------------------------------- /erlang/ORIGIN: -------------------------------------------------------------------------------- 1 | https://github.com/radare/r2pipe_erl 2 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/syscall/int.sh: -------------------------------------------------------------------------------- 1 | r2 -qi int.r2 - 2 | -------------------------------------------------------------------------------- /cxx-qt/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | r2 -qc '#!pipe ./r2pipe' /bin/ls 3 | -------------------------------------------------------------------------------- /go/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/radareorg/r2pipe-go 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /perl/MANIFEST: -------------------------------------------------------------------------------- 1 | lib/Radare/r2pipe.pm 2 | Makefile.PL 3 | t/test.pl 4 | -------------------------------------------------------------------------------- /haskell/Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /swift/ccall/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | swiftc -L/usr/local/lib -I. main.swift 3 | -------------------------------------------------------------------------------- /dotnet/FSharpExample/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | fsharpc -r ../r2pipe.dll test.fs 3 | -------------------------------------------------------------------------------- /newlisp/Makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | test: 4 | r2 -qi main.lsp /bin/ls 5 | -------------------------------------------------------------------------------- /nim/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | nim -d:release c --opt:size main.nim 3 | ./main 4 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/typescript/test.ts: -------------------------------------------------------------------------------- 1 | import { R2Pipe } from "../../"; 2 | -------------------------------------------------------------------------------- /shell/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc r2cmd.c -o r2cmd 3 | r2 -qi test.sh /bin/ls 4 | -------------------------------------------------------------------------------- /dlang/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | dmd test.d r2pipe.d 3 | r2 -qc '#!pipe ./test' - 4 | -------------------------------------------------------------------------------- /r2pipe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/r2pipe.png -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "node" 5 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/README.md: -------------------------------------------------------------------------------- 1 | Testsuite for r2pipe.js 2 | ======================= 3 | -------------------------------------------------------------------------------- /python/test/ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/python/test/ls -------------------------------------------------------------------------------- /python/TODO: -------------------------------------------------------------------------------- 1 | * Implement async api 2 | * Implement stderr-stream api 3 | * Support https:// 4 | -------------------------------------------------------------------------------- /python/examples/ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/python/examples/ls -------------------------------------------------------------------------------- /java/javax.json-1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/java/javax.json-1.1.jar -------------------------------------------------------------------------------- /python/test/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/python/test/.DS_Store -------------------------------------------------------------------------------- /r2core-js/tuto/crackme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/r2core-js/tuto/crackme -------------------------------------------------------------------------------- /zig/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | zig fmt main.zig src/r2pipe.zig 3 | zig build-exe -freference-trace main.zig 4 | -------------------------------------------------------------------------------- /python/test/ccall.py: -------------------------------------------------------------------------------- 1 | import r2pipe 2 | r=r2pipe.open("ccall:///bin/ls") 3 | print(r.cmd("x")) 4 | r = None 5 | -------------------------------------------------------------------------------- /vim/Makefile: -------------------------------------------------------------------------------- 1 | 2 | D=${HOME}/.vim/ftdetect 3 | 4 | all: 5 | 6 | mkdir -p $(D) 7 | cp -f r2pipe.vim $(D) 8 | -------------------------------------------------------------------------------- /websocket/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | -pkill python 3 | -pkill Python 4 | python -m http.server & 5 | python ws.py 6 | -------------------------------------------------------------------------------- /erlang/rebar.config: -------------------------------------------------------------------------------- 1 | {deps, [ 2 | {jsx, ".*", {git, "https://github.com/talentdeficit/jsx.git"}} 3 | ] 4 | }. -------------------------------------------------------------------------------- /java/javax.json-api-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/java/javax.json-api-1.0.jar -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/b/ls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radareorg/radare2-r2pipe/master/nodejs/r2pipe/testsuite/b/ls -------------------------------------------------------------------------------- /v/v.mod: -------------------------------------------------------------------------------- 1 | Module { 2 | name: 'test', 3 | description: 'hello world using v api', 4 | dependencies: ['radare.r2'] 5 | } 6 | -------------------------------------------------------------------------------- /dotnet/r2pipe/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | rm -f project.lock.json 3 | xbuild 4 | 5 | dotnet: 6 | dotnet run 7 | # dotnet build 8 | -------------------------------------------------------------------------------- /swift/r2plugin/main.swift: -------------------------------------------------------------------------------- 1 | func main() { 2 | print("the begining is now") 3 | test_me(that: 3) 4 | } 5 | 6 | main() 7 | -------------------------------------------------------------------------------- /swift/r2plugin/r2swift-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | extern int r_core_cmd(void *core, const char *cmd, int log); 5 | 6 | -------------------------------------------------------------------------------- /python/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py 2 | include r2pipe/__init__.py 3 | include LICENSE 4 | include README.md 5 | include MANIFEST.in -------------------------------------------------------------------------------- /typescript/examples/hello/index.ts: -------------------------------------------------------------------------------- 1 | import * as r2pipe from "@r2pipe"; 2 | 3 | const r2 = r2pipe.open(); 4 | console.log(r2.cmd("?e hello")); 5 | -------------------------------------------------------------------------------- /clojure/test/r2pipe/clj_test.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe-test 2 | (:require [clojure.test :refer :all] 3 | [r2pipe.clj :refer :all])) 4 | 5 | ;; WRITE TESTS! -------------------------------------------------------------------------------- /configure.acr: -------------------------------------------------------------------------------- 1 | PKGNAME radare2-r2pipe 2 | VERSION 5.9.0 3 | CONTACT pancake ; pancake@nopcode.org 4 | 5 | SUBDIRS ./Makefile ; 6 | 7 | REPORT PREFIX ; 8 | -------------------------------------------------------------------------------- /swift/ccall/module.modulemap: -------------------------------------------------------------------------------- 1 | module r_core [system] [extern_c] { 2 | header "/usr/local/include/libr/r2naked.h" 3 | link "r_core" 4 | export * 5 | } 6 | -------------------------------------------------------------------------------- /dotnet/FormExample/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | ln -fs ../r2pipe/bin/Release/r2pipe.dll r2pipe.dll 3 | mcs -pkg:dotnet rasm2net.cs /r:r2pipe.dll 4 | mono rasm2net.exe 5 | -------------------------------------------------------------------------------- /r2core-js/tuto/make.js: -------------------------------------------------------------------------------- 1 | const YAML = require('yamljs'); 2 | console.log('var tutorial = ' + JSON.stringify(YAML.parseFile('tuto01.yaml'), null, ' ') + ';'); 3 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "module": "commonjs", 5 | "strict": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /java/examples/groovy/Makefile: -------------------------------------------------------------------------------- 1 | all: r2pipe.jar 2 | r2pm -r groovy -cp r2pipe.jar test 3 | 4 | r2pipe.jar: 5 | r2pm -i r2pipe-java 6 | 7 | clean: 8 | rm -f r2pipe.jar 9 | -------------------------------------------------------------------------------- /python/examples/ccall.py: -------------------------------------------------------------------------------- 1 | import r2pipe 2 | 3 | r2 = r2pipe.open("ccall:///bin/ls") 4 | # r2 = r2pipe.open("/bin/ls") 5 | # r2.cmd("o /bin/ls") 6 | print r2.cmd("pd 10") 7 | r2.quit() 8 | -------------------------------------------------------------------------------- /zig/test.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void { 4 | const stdout = std.io.getStdOut().writer(); 5 | try stdout.print("Hello, {s}!\n", .{"world"}); 6 | } 7 | -------------------------------------------------------------------------------- /go/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | go test 3 | cd example ; go run example.go 4 | 5 | sync: 6 | rm -rf tmp 7 | git clone `cat ORIGIN` tmp 8 | cp -f tmp/*.go . 9 | 10 | .PHONY: all sync 11 | -------------------------------------------------------------------------------- /python/lang-pipe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import r2pipe 3 | 4 | r2 = r2pipe.open("#!pipe") 5 | 6 | _dis = r2.cmd("pd 5") 7 | print(_dis) 8 | _hex = r2.cmd("px 64") 9 | print(_hex) 10 | -------------------------------------------------------------------------------- /swift/ccall/main.swift: -------------------------------------------------------------------------------- 1 | import r_core 2 | 3 | let r = r_core.r_core_new() 4 | r_core.r_core_cmd_str(r, "o /bin/ls") 5 | let str = String(cString: r_core.r_core_cmd_str(r, "pd 10")) 6 | print(str) 7 | -------------------------------------------------------------------------------- /typescript/examples/hello/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | rm -f r2pipe 3 | ln -fs ../../r2pipe r2pipe 4 | r2frida-compile -So index.r2.js index.ts 5 | r2 -qi index.r2.js - 6 | tsc index.ts 7 | r2 -qi index.js - 8 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/exectest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const r2pipe = require('../'); 4 | 5 | r2pipe.syscmd(['/bin/ls', '-l', '/'], (err, r) => { 6 | if (err) throw err; 7 | console.log(r); 8 | }); 9 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/r2/hello.js: -------------------------------------------------------------------------------- 1 | require('colors'); 2 | var r2p = require('../..'); 3 | var r2 = r2p.open(); 4 | console.log('[OK] '.green + r2.cmd('?e r2 sync r2pipe.js').trim().yellow); 5 | r2.quit(); 6 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/http/Makefile: -------------------------------------------------------------------------------- 1 | all: node_modules 2 | (sleep 1; open http://localhost:8080/p/ ) & 3 | r2 -qc '#!pipe node index.js' /bin/ls 4 | 5 | node_modules: 6 | mkdir -p node_modules 7 | npm install 8 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/ircbot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-ircbot", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "r2pipe": "*", 6 | "optimist": "*", 7 | "irc.js": "*" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /r2core-js/tuto/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | node make.js > tuto01.js 3 | node_modules/.bin/browserify loadbro.js > loadbro-browser.js 4 | 5 | pub: 6 | rsync -e 'ssh -p 2299' -avz * cloud.rada.re:prg/r2cloud/www/asmjs/tuto 7 | -------------------------------------------------------------------------------- /v/test.v: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | import radare.r2 4 | 5 | fn main() { 6 | c := r2.new() 7 | print(c.cmd('?E Hello')) 8 | c.free() // this is automatic with -autofree segfaults if not commented 9 | } 10 | -------------------------------------------------------------------------------- /dotnet/DllExample/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python/examples/syscall/int.r2: -------------------------------------------------------------------------------- 1 | e asm.arch=x86 2 | e asm.bits=32 3 | wx 43 b940000000 ba0c000000 31c040404040cd80cc 4 | w Hello World @ 0x40 5 | "e cmd.esil.intr=#!pipe python int.py" 6 | aei 7 | pd 10 8 | 10aes 9 | ae* 10 | -------------------------------------------------------------------------------- /websocket/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /dotnet/HttpExample/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dotnet/LocalExample/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/syscall/int.r2: -------------------------------------------------------------------------------- 1 | e asm.arch=x86 2 | e asm.bits=32 3 | wx 43 b940000000 ba0c000000 31c040404040cd80cc 4 | w Hello World @ 0x40 5 | "e cmd.esil.intr=#!pipe node int.js" 6 | aei 7 | pd 10 8 | 10aes 9 | ae* 10 | -------------------------------------------------------------------------------- /v/README.md: -------------------------------------------------------------------------------- 1 | # Using r2 from vlang 2 | 3 | See https://github.com/radare/v-r2 for more details 4 | 5 | 6 | ## Compile test program 7 | 8 | ``` 9 | $ v install radare.r2 10 | $ v -prod test.v 11 | $ ./test 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /dotnet/FSharpExample/test.fs: -------------------------------------------------------------------------------- 1 | open System 2 | open r2pipe 3 | 4 | [] 5 | let main argv = 6 | let a = new R2Pipe "/bin/ls" 7 | let v: string = a.RunCommand "?V" 8 | printfn "Hello r2pipe version %s" v 9 | 0 10 | -------------------------------------------------------------------------------- /dart/README.md: -------------------------------------------------------------------------------- 1 | # Dart 2 | 3 | For now there's nothing usable here, but just random snippets of code 4 | 5 | But ideally a proper r2pipe module should be published in https://pub.dev 6 | 7 | ``` 8 | $ r2 -i hello.r2.dart /bin/ls 9 | ``` 10 | -------------------------------------------------------------------------------- /newlisp/test-spawn.lsp: -------------------------------------------------------------------------------- 1 | ;; native r2pipe api example 2 | (load "r2pipe.lsp") 3 | (context 'r2pipe-spawn) 4 | (let (r2 (r2pipe-spawn:new "/bin/ls")) 5 | (println (cmd r2 "?V")) 6 | (println (cmdj r2 "ij")) 7 | (quit r2) 8 | ) 9 | (exit) 10 | -------------------------------------------------------------------------------- /python/dbgtest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import r2pipe 4 | 5 | r2 = r2pipe.open("/bin/ls", ["-nd"]) 6 | for a in range(1, 10): 7 | regs = r2.cmdj("drj") 8 | print("0x%x 0x%x" % (regs["rip"], regs["rsp"])) 9 | r2.cmd("ds") 10 | -------------------------------------------------------------------------------- /rexx/README.md: -------------------------------------------------------------------------------- 1 | r2pipe for REXX 2 | =============== 3 | 4 | There are different implementations of the rexx interpreter for many operating systems. 5 | 6 | This directory aims to provide example programs that talk to r2 using different methods. 7 | 8 | -------------------------------------------------------------------------------- /swift/r2plugin/struct.c: -------------------------------------------------------------------------------- 1 | // #import 2 | #include "r2.h" // to be replaced with r_core.h when -Xcc -I works 3 | 4 | R_API RLibStruct radare_plugin = { 5 | .type = R_LIB_TYPE_CORE, 6 | .data = &swift_plugin, 7 | .version = R2_VERSION 8 | }; 9 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-simple.js: -------------------------------------------------------------------------------- 1 | var r2pipe = require('r2pipe'); 2 | 3 | r2pipe.open(function (err, r2) { 4 | if (err) throw err; 5 | r2.cmd('?e hello world', (err, res) => { 6 | console.log(res); 7 | r2.quit(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /newlisp/test-lib.lsp: -------------------------------------------------------------------------------- 1 | ;; native r2pipe api example 2 | (load "r2pipe.lsp") 3 | (context 'r2pipe-lib) 4 | (let (r2 (r2pipe-lib:new)) 5 | (print (cmd r2 "o /bin/ls")) 6 | (print (cmd r2 "?V")) 7 | (print (cmdj r2 "ij")) 8 | (quit r2) 9 | ) 10 | (exit) 11 | -------------------------------------------------------------------------------- /java/config.mk: -------------------------------------------------------------------------------- 1 | #JAVACFLAGS=-source 1.7 -target 1.7 2 | JAVACFLAGS+=-classpath $(JARPATH)/javax.json-api-1.0.jar:$(JARPATH)/r2pipe.jar:examples:. 3 | JAVACFLAGS+=-classpath $(JARPATH)/javax.json-1.1.jar:$(JARPATH)/javax.json-api-1.0.jar:$(JARPATH)/r2pipe.jar:examples:. 4 | -------------------------------------------------------------------------------- /python/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | license_files = LICENSE 3 | name = r2pipe 4 | author = pancake 5 | author_email = pancake@nopcode.org 6 | description = Pipe interface for radare2 7 | long_description = file:README.md 8 | long_description_content_type = text/markdown 9 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/tgbot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-tgbot", 3 | "version": "0.0.1", 4 | "dependencies": { 5 | "r2pipe": "*" 6 | }, 7 | "optionalDependencies": { 8 | "js-beautify": "*" 9 | }, 10 | "scripts": { 11 | "bot": "node index.js" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /erlang/Makefile: -------------------------------------------------------------------------------- 1 | all: deps 2 | 3 | deps: 4 | rebar get-deps 5 | rebar compile 6 | 7 | app: 8 | rebar compile 9 | 10 | tests: 11 | rebar eunit 12 | 13 | clean: 14 | rebar clean 15 | 16 | distclean: clean 17 | rebar delete-deps 18 | 19 | .PHONY: all deps app tests clean distclean -------------------------------------------------------------------------------- /vala/r2pipe.pc.acr: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=@LIBDIR@ 4 | includedir=${prefix}/include 5 | 6 | Name: r2pipe 7 | Description: r2pipe vala api library 8 | Version: @VERSION@ 9 | Requires: 10 | Libs: -L${libdir} -lr2pipe 11 | Cflags: -I${includedir}/r2pipe 12 | -------------------------------------------------------------------------------- /r2core-js/tuto/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | r2core.js shell 4 | 5 | 6 |
7 | Click here to enter the r2 web tutorial in asm.js (beware! it's 20MB of Javascript) 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /erlang/src/r2pipe_erl.app.src: -------------------------------------------------------------------------------- 1 | {application, r2pipe_erl, 2 | [ 3 | {description, "Erlang radare2 pipe bindings"}, 4 | {vsn, "0.0.1"}, 5 | {registered, []}, 6 | {applications, [ 7 | kernel, 8 | stdlib 9 | ]}, 10 | {env, []} 11 | ]}. 12 | -------------------------------------------------------------------------------- /python/test/race.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | fail() { 4 | echo "ERROR" 5 | exit 1 6 | } 7 | 8 | C=0 9 | while : ; do 10 | PYTHONPATH=${PWD}/.. python race.py /bin/ls | grep FAIL 11 | [ $? = 0 ] && fail 12 | printf "... $C\r" 13 | C=$(($C+1)) 14 | [ "$C" = 32 ] && break 15 | done 16 | echo "PASS" 17 | exit 0 18 | -------------------------------------------------------------------------------- /dlang/test.d: -------------------------------------------------------------------------------- 1 | import std.stdio; 2 | import r2pipe; 3 | 4 | void main() { 5 | auto r2 = r2pipe.open (); 6 | writeln ("Hello "~ r2.cmd("?e World")); 7 | writeln ("Hello "~ r2.cmd("?e Works")); 8 | string file = r2.cmdj("ij")["core"]["file"].str; 9 | writeln ("File: ", file); 10 | } 11 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/hello.js: -------------------------------------------------------------------------------- 1 | const r2pipe = require('../'); 2 | 3 | r2pipe.syscmd('ls', { cwd: '/' }, (err, x) => { 4 | if (err) { 5 | throw err; 6 | } 7 | console.log(x); 8 | }); 9 | r2pipe.options = ['-n']; 10 | 11 | const r2 = r2pipe.open('/bin/ls'); 12 | console.log(r2.cmd('x')); 13 | r2.quit(); 14 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/http/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2-express.js", 3 | "version": "0.0.1", 4 | "description": "Express-based webserver for radare2", 5 | "author": "pancake ", 6 | "dependencies": { 7 | "express": "*", 8 | "r2pipe": "*" 9 | }, 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/r2/async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | require('colors'); 3 | 4 | require('../..').open((err, r2) => { 5 | if (err) throw err; 6 | r2.cmd('?e r2 async r2pipe.js', (err, res) => { 7 | if (err) throw err; 8 | console.log('[OK] '.green + res.trim().yellow); 9 | r2.quit(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /swift/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.8 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "r2pipe", 7 | products: [ 8 | .library(name: "r2pipe", targets: ["R2Pipe"]), 9 | ], 10 | dependencies: [], 11 | targets: [ 12 | .target(name: "R2Pipe") 13 | ] 14 | ) 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | ## Description 8 | 9 | *Please describe what are you missing or wanting to be improved* 10 | 11 | *Provide images, ascii-art, test files and anything that may help us understand your request* 12 | -------------------------------------------------------------------------------- /dart/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: mxflutter 2 | description: JavaScript Flutter Framework,Using mxflutter lib, you can use JavaScript to develop flutter or use Dart to develop and compile to JS. 3 | version: 0.9.0 4 | homepage: https://github.com/mxflutter/mxflutter 5 | 6 | environment: 7 | sdk: '^3.3.0' 8 | dependencies: 9 | js: ^0.6.2 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Checklist** 2 | 3 | - [ ] Mark it when ready to merge 4 | - [ ] Closing issues: #issue 5 | - [ ] I've added tests (optional) 6 | 7 | **Description** 8 | 9 | 10 | -------------------------------------------------------------------------------- /r2core-js/tuto/crackme.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | main() { 4 | char buf[32]; 5 | printf ("Password: "); 6 | fflush (stdout); 7 | buf[0] = 0; 8 | fgets (buf, 32, stdin); 9 | if (!strcmp (buf, "th3p4ss") ) { 10 | printf ("Password Correct!\n"); 11 | return 0; 12 | } else { 13 | printf ("Invalid Password\n"); 14 | return 1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dart/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(MAKE) r2js 3 | 4 | r2js: 5 | dart pub get 6 | # dart compile js -O4 -o r2pipe.r2.js r2pipe-r2js.dart 7 | dart compile js -o _r2pipe.r2.js r2pipe-r2js.dart 8 | (echo 'var self = global;' ; cat _r2pipe.r2.js ) > r2pipe.r2.js ; rm -f _r2pipe.r2.js 9 | r2 -qi r2pipe.r2.js /bin/ls 10 | 11 | ffi: 12 | dart compile exe r2pipe-ffi.dart 13 | -------------------------------------------------------------------------------- /shell/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #. r2pipe.sh 4 | #R=./r2cmd 5 | R=r2p 6 | 7 | echo "Running analysis..." 8 | $R aaa 9 | echo "Disassembling code..." 10 | 11 | $R pdj | jq . 12 | 13 | exit 0 14 | 15 | $R "pd 3" 16 | $R "px 32" 17 | $R "pd 3" 18 | $R "px 32" 19 | pd3=`$R "pd 3"` 20 | pxs=`$R "px 64"` 21 | 22 | echo "$pd3" 23 | echo "$pxs" 24 | 25 | exit 0 26 | -------------------------------------------------------------------------------- /newlisp/main.lsp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env newlisp 2 | ;-- main 3 | 4 | (load "r2pipe.lsp") 5 | 6 | (println "pd 3:\n" (r2pipe:cmd "pd 3")) 7 | 8 | (define (aoj addr) (first (r2pipe:cmdj (string "aoj @ " addr)))) 9 | 10 | (set 'opinfo (aoj "entry0")) 11 | (println (lookup "opcode" opinfo)) 12 | (println (lookup "esil" opinfo)) 13 | 14 | ; (println opinfo) 15 | (exit 0) 16 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-ts-example", 3 | "version": "1.0.0", 4 | "description": "just a test", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "typescript": "^2.9.2" 8 | }, 9 | "scripts": { 10 | "prepublish": "npm run build", 11 | "build": "tsc", 12 | "watch": "tsc -w" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-promise.js: -------------------------------------------------------------------------------- 1 | 2 | const r2promise = require('./'); // r2pipe-promise'); 3 | var a = r2promise.open('/bin/ls'); 4 | 5 | console.log('AAA', a); 6 | 7 | a 8 | .then(r2 => { 9 | r2.cmd('?e hello world') 10 | .then(res => { 11 | console.log(res); 12 | r2.quit(); 13 | }) 14 | .catch(console.error); 15 | }) 16 | .catch(console.error); 17 | -------------------------------------------------------------------------------- /r2core-js/tuto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2core-webtutorial", 3 | "version": "1.0.0", 4 | "description": "radare2 web tutorial in asmjs", 5 | "main": "webserver.js", 6 | "scripts": { 7 | "make": "node make.js > tuto01.js" 8 | }, 9 | "author": "pancake@nopcode.org", 10 | "license": "MIT", 11 | "dependencies": { 12 | "yamljs": "*" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /typescript/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | tsc 3 | tsc -d r2pipe/index.ts 4 | # tsc 5 | tsc test-spawn.ts 6 | node test-spawn.js 7 | tsc test-local.ts 8 | r2 -q -i test-local.js /bin/ls 9 | 10 | vs vsc: 11 | open -a "Visual Studio Code" . 12 | 13 | test: 14 | make -C examples/hello 15 | 16 | lint: 17 | ./node_modules/.bin/eslint --fix r2pipe/*.ts 18 | pub: 19 | npm pub 20 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-async-await.js: -------------------------------------------------------------------------------- 1 | const r2promise = require('./'); 2 | 3 | const radare2FTW = async () => { 4 | try { 5 | const r2 = await r2promise.open('/bin/ls'); 6 | const msg = await r2.cmd('?E hello world'); 7 | console.log(msg); 8 | return r2.quit(); 9 | } catch (err) { 10 | console.error(err); 11 | } 12 | }; 13 | 14 | radare2FTW(); 15 | -------------------------------------------------------------------------------- /python/test/race.py: -------------------------------------------------------------------------------- 1 | import r2pipe 2 | import sys 3 | 4 | # _pipe = r2pipe.open("ccall://" + sys.argv[1], flags=["-2", "-S"]) 5 | _pipe = r2pipe.open(sys.argv[1], flags=["-2"]) #, "-S"]) 6 | res = _pipe.cmdj('iIj') 7 | if res is None: 8 | print("{} - FAIL".format(sys.argv[1])) 9 | res = _pipe.cmdj('iIj') 10 | if res is None: 11 | print("{} - FAIL".format(sys.argv[1])) 12 | -------------------------------------------------------------------------------- /perl/Makefile.PL: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use ExtUtils::MakeMaker; 4 | 5 | WriteMakefile ( 6 | NAME => 'Radare::r2pipe', 7 | AUTHOR => 'adri', 8 | VERSION_FROM => 'lib/Radare/r2pipe.pm', 9 | ABSTRACT_FROM => 'lib/Radare/r2pipe.pm', 10 | PREREQ_PM => {'JSON' => 0, 'IO::Pty::Easy' => 0, 'IO::Socket::INET' => 0, 'LWP::UserAgent' => 0, 'URI::Escape' => 0}, 11 | ); 12 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-malloc.js: -------------------------------------------------------------------------------- 1 | /* pancake - 2016 - radare project */ 2 | 3 | const r2pipe = require('..'); 4 | 5 | r2pipe.open('malloc://1024', (err, r2) => { 6 | if (err) { 7 | throw err; 8 | } 9 | r2.cmd('wx 11223344; p8 4', (err, res) => { 10 | if (err) { 11 | throw err; 12 | } 13 | console.log('wx', res); 14 | r2.quit(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /cxx-qt/r2pipe.pro: -------------------------------------------------------------------------------- 1 | CONFIG += qt 2 | SOURCES += r2pipe.cxx \ 3 | r2pipe-api.cxx 4 | SOURCES += test.cxx 5 | 6 | QT += network 7 | QT += core 8 | 9 | QMAKE_CXXFLAGS_RELEASE += -g 10 | QMAKE_CFLAGS += -g 11 | QMAKE_LFLAGS_RELEASE += -g 12 | 13 | HEADERS += \ 14 | r2pipe.h 15 | 16 | INCLUDEPATH += /usr/local/radare2/include/libr 17 | LIBS += -L/usr/local/radare2/lib -lr_core -lr_util 18 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.8 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "r2pipe", 7 | products: [ 8 | .library(name: "r2pipe", targets: ["R2Pipe"]), 9 | ], 10 | dependencies: [], 11 | targets: [ 12 | .target( 13 | name: "R2Pipe", 14 | path: "swift/Sources" 15 | ) 16 | ] 17 | ) 18 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-bluebird.js: -------------------------------------------------------------------------------- 1 | const Promise = require('bluebird'); 2 | const r2pipe = Promise.promisifyAll(require('r2pipe')); 3 | 4 | r2pipe.openAsync('/bin/ls').then(r => { 5 | const r2 = Promise.promisifyAll(r); 6 | r2.cmdAsync('?E hello').then(msg => { 7 | console.log(msg); 8 | r2.quitAsync(); 9 | }); 10 | }) 11 | .catch(err => { 12 | console.error(err.message); 13 | }); 14 | -------------------------------------------------------------------------------- /ruby/test.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # author pancake@nopcode.org 4 | 5 | require './r2pipe' 6 | 7 | puts 'r2pipe ruby api demo' 8 | puts '====================' 9 | 10 | begin 11 | r2p = R2Pipe.new 12 | rescue Exception => e 13 | r2p = R2Pipe.new '/bin/ls' 14 | end 15 | puts r2p.cmd 'pi 5' 16 | puts r2p.cmd 'pij 1' 17 | puts r2p.cmdj 'pij 1' 18 | puts r2p.cmd 'px 64' 19 | r2p.quit 20 | -------------------------------------------------------------------------------- /dotnet/r2pipe/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using r2pipe; 3 | 4 | namespace ConsoleApplication 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | Console.WriteLine("Hello World!"); 11 | var a = new DllR2Pipe(); 12 | Console.WriteLine("-> {0}", a.RunCommand("?V")); 13 | a.Dispose(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/node/json.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var r2pipe = require('../..'); 4 | var ts = require('..'); 5 | 6 | ts.addTest('testJSON', function (fin) { 7 | try { 8 | var r2 = r2pipe.openSync('../b/ls'); 9 | if (r2) { 10 | fin(r2.cmdj('ij').core.file); 11 | r2.quit(); 12 | } 13 | } catch (e) { 14 | fin(e.toString()); 15 | } 16 | }, '../b/ls'); 17 | 18 | ts.inParalel(); 19 | -------------------------------------------------------------------------------- /go/example/example.go: -------------------------------------------------------------------------------- 1 | // radare - LGPL - Copyright 2017 - pancake 2 | 3 | package main 4 | 5 | import ".." 6 | 7 | func main() { 8 | r2p, err := r2pipe.NewPipe("/bin/ls") 9 | if err != nil { 10 | print("ERROR: ", err) 11 | 12 | return 13 | } 14 | defer r2p.Close() 15 | 16 | disasm, err := r2p.Cmd("pd 20") 17 | if err != nil { 18 | print("ERROR: ", err) 19 | } else { 20 | print(disasm, "\n") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /python/examples/batch.py: -------------------------------------------------------------------------------- 1 | import os 2 | import r2pipe 3 | 4 | r2 = r2pipe.open("http://cloud.radare.org") 5 | print(r2.cmd("?e one")) 6 | r2.quit() 7 | 8 | r2 = r2pipe.open("/bin/ls") 9 | print(r2.cmd("?e one")) 10 | print(r2.cmd("?e two")) 11 | r2.quit() 12 | 13 | r2 = r2pipe.open("/bin/ls") 14 | os.system("ps auxw| grep radare2") 15 | print(r2.cmd("?e tri")) 16 | r2.quit() 17 | 18 | os.system("ps auxw| grep radare2") 19 | -------------------------------------------------------------------------------- /dotnet/JsonExample/Makefile: -------------------------------------------------------------------------------- 1 | all: Newtonsoft.Json.dll 2 | ln -fs ../r2pipe/bin/Release/r2pipe.dll r2pipe.dll 3 | mcs -pkg:dotnet main.cs /r:r2pipe.dll /r:Newtonsoft.Json.dll 4 | mono main.exe main.exe 5 | 6 | Newtonsoft.Json.dll: 7 | rm -rf Bin 8 | wget -c https://github.com/JamesNK/Newtonsoft.Json/releases/download/8.0.3/Json80r3.zip 9 | unzip Json80r3.zip Bin/Net40/Newtonsoft.Json.dll 10 | mv Bin/Net40/* . 11 | rm -rf Json80r3.zip Bin 12 | -------------------------------------------------------------------------------- /swift/r2plugin/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=-Xcc -I/usr/local/include/libr 2 | CFLAGS+=-Xcc -L/usr/local/lib 3 | 4 | all: 5 | swiftc $(CFLAGS) -emit-library -module-name r2swift struct.c coreplugin.swift 6 | # swiftc -O -o main coreplugin.swift main.swift 7 | swiftc $(CFLAGS) -o main struct.c coreplugin.swift main.swift 8 | mkdir -p $(shell r2 -H R2_USER_PLUGINS) 9 | cp -f libr2swift.dylib $(shell r2 -H R2_USER_PLUGINS) 10 | r2 -qc 'swift jeje' /bin/ls 11 | -------------------------------------------------------------------------------- /c/test-pipe.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static void r2cmd(R2Pipe *r2, const char *cmd) { 4 | char *msg = r2pipe_cmd (r2, cmd); 5 | if (msg) { 6 | printf ("%s\n", msg); 7 | free (msg); 8 | } 9 | } 10 | 11 | int main() { 12 | R2Pipe *r2 = r2pipe_open (NULL); 13 | if (r2) { 14 | r2cmd (r2, "?e Hello World"); 15 | r2cmd (r2, "x"); 16 | r2cmd (r2, "?e Hello World"); 17 | r2pipe_close (r2); 18 | return 0; 19 | } 20 | return 1; 21 | } 22 | -------------------------------------------------------------------------------- /r2core-js/test.js: -------------------------------------------------------------------------------- 1 | const r2asmjs = require('./'); 2 | 3 | const c = new r2asmjs(); 4 | console.log(c.cmd("e asm.arch=?")); 5 | c.cmd("e asm.arch=x86"); 6 | c.cmd("o malloc://1024"); 7 | c.cmd("w hello world"); 8 | console.log(c.cmd("pd 10")); 9 | console.log(c.cmd("p8 10")); 10 | 11 | const c2 = new r2asmjs(); 12 | c2.cmd("e asm.arch=x86;e asm.bits=32"); 13 | c2.cmd("o malloc://1024"); 14 | console.log(c2.cmd("p8 10")); 15 | console.log(c.cmd("p8 10")); 16 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-promise-ts-example", 3 | "version": "1.0.0", 4 | "description": "just a test", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "typescript": "^2.9.2" 8 | }, 9 | "scripts": { 10 | "prepublish": "npm run build", 11 | "build": "tsc", 12 | "watch": "tsc -w" 13 | }, 14 | "dependencies": { 15 | "@types/node": "^10.5.1", 16 | "jshint": "^2.9.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /cxx-qt/test.cxx: -------------------------------------------------------------------------------- 1 | #include "r2pipe.h" 2 | 3 | static QTextStream& cout() { 4 | static QTextStream ts(stdout); 5 | return ts; 6 | } 7 | 8 | int main() { 9 | R2Pipe *r2; 10 | try { 11 | r2 = new R2Pipe(); 12 | } catch (QString err) { 13 | cout() << err << "\n"; 14 | r2 = new R2Pipe("/bin/ls"); 15 | } 16 | cout() << r2->cmd ("?e hello world"); 17 | cout() << r2->cmd ("x"); 18 | cout() << r2->cmd ("pd 3"); 19 | r2->close(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /java/examples/TestJNI.java: -------------------------------------------------------------------------------- 1 | import org.radare.r2pipe.R2PipeJNI; 2 | 3 | public class TestJNI { 4 | public static void main (String[] args) { 5 | try { 6 | R2PipeJNI r2 = new R2PipeJNI (); 7 | r2.cmd ("o /bin/ls"); 8 | System.out.println (r2.cmd ("pd 10")); 9 | System.out.println ("=============="); 10 | System.out.println (r2.cmd ("px 32")); 11 | r2.quit(); 12 | } catch (Exception e) { 13 | System.err.println (e); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /typescript/test-spawn.ts: -------------------------------------------------------------------------------- 1 | import * as r2pipe from "./dist/index.js"; 2 | // import * as r2pipe from "r2pipe-ts"; 3 | 4 | async function main() { 5 | console.log("Hello R2Pipe for TypeScript"); 6 | // const r2 = await r2pipe.open("http://127.0.0.1:9090"); 7 | const r2 = await r2pipe.open("/bin/ls"); 8 | const res = await r2.cmd("?E Hello TypeScript"); 9 | console.log(res); 10 | await r2.quit(); 11 | } 12 | 13 | main().then((x)=>{}).catch(console.error); 14 | -------------------------------------------------------------------------------- /clojure/project.clj: -------------------------------------------------------------------------------- 1 | (defproject org.radare/r2pipe "0.5.1" 2 | :description "Communicate with radare2 via pipes" 3 | :license "MIT" 4 | :url "https://radare.org/" 5 | :dependencies [[org.clojure/clojure "1.8.0"] 6 | 7 | [cheshire "5.10.0"] 8 | 9 | [me.raynes/conch "0.8.0"] 10 | [clj-http "3.12.0"]]) 11 | ;; :plugins [[lein-codox "0.9.5"]] ; code as documentation for now? 12 | -------------------------------------------------------------------------------- /java/examples/Makefile: -------------------------------------------------------------------------------- 1 | JARPATH=$(shell pwd)/.. 2 | include ../config.mk 3 | 4 | # used to test that r2pipe.java works without the javax.json apis loaded 5 | JCF+=-classpath $(JARPATH)/r2pipe.jar:$(JARPATH)/examples 6 | 7 | all: 8 | javac $(JAVACFLAGS) TestJNI.java 9 | javac $(JAVACFLAGS) TestJSON.java 10 | javac $(JAVACFLAGS) Test.java 11 | 12 | run: 13 | java $(JCF) Test 14 | java $(JAVACFLAGS) TestJSON 15 | java -Djava.library.path=../jni/ $(JCF) TestJNI 16 | -------------------------------------------------------------------------------- /typescript/test-local.ts: -------------------------------------------------------------------------------- 1 | import * as r2pipe from "./dist/index.js"; 2 | // import * as r2pipe from "r2pipe-ts"; 3 | 4 | async function main() { 5 | console.log("Hello R2Pipe for TypeScript"); 6 | const r2 = await r2pipe.open(); 7 | const res = await r2.cmd("?E Hello TypeScript"); 8 | console.log(res); 9 | const r2s = await r2.cmd("?E Hello World"); 10 | console.log(r2s); 11 | await r2.quit(); 12 | } 13 | 14 | main().then((x)=>{}).catch(console.error); 15 | 16 | -------------------------------------------------------------------------------- /go/README.md: -------------------------------------------------------------------------------- 1 | r2pipe.go 2 | ========= 3 | 4 | Go module to interact with radare2 5 | 6 | Source 7 | ------ 8 | 9 | This repository is in sync with [radareorg/r2pipe](https://godoc.org/github.com/radareorg/radare2-r2pipe). 10 | 11 | Run `make sync` to update it after changing things in the source repository. 12 | 13 | Documentation 14 | ------------- 15 | 16 | [![GoDoc](https://godoc.org/github.com/radare/r2pipe-go?status.svg)](https://godoc.org/github.com/radare/r2pipe-go) 17 | 18 | -------------------------------------------------------------------------------- /rexx/r2pipe.rexx: -------------------------------------------------------------------------------- 1 | -- r2pipe hello world program in rexx 2 | -- known to work on regina's rexx on macos 3 | -- getenv is not portable, we can use '8' 4 | 5 | Say r2cmd('?E hello from rexx') 6 | 7 | Exit 8 | 9 | r2cmd: PROCEDURE EXPOSE globals. 10 | arg cmd 11 | fin = '/dev/fd/'Getenv(R2PIPE_IN) 12 | fou = '/dev/fd/'Getenv(R2PIPE_OUT) 13 | o = CharOut(fou, cmd''D2C(0)) 14 | len = 0 15 | DO while len == 0 16 | len = Chars(fin) 17 | END 18 | return CharIn(fin,,len) 19 | -------------------------------------------------------------------------------- /vim/r2pipe.vim: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | let s:host = "localhost" 5 | let s:port = "9090" 6 | 7 | function! r2pipe#endpoint(host, port) 8 | let s:host = a:host 9 | let s:port = a:port 10 | endfunction 11 | 12 | function! r2pipe#cmd(c) 13 | " TODO: use r2p instead of curl when it supports http endpoints 14 | let res = system("curl -s http://".s:host.":".s:port."/cmd/" . a:c) 15 | put=res 16 | endfunction 17 | 18 | " :r2("pd 10") <--- shortest form 19 | cnoreabbrev r2 call r2pipe#cmd 20 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-lpipeSync.js: -------------------------------------------------------------------------------- 1 | /* Small tests for r2pipe */ 2 | // return true; 3 | 4 | const r2pipe = require('..'); 5 | 6 | try { 7 | const r2 = r2pipe.lpipeSync(); 8 | const res = r2.cmd('pd 4'); 9 | const resj = r2.cmdj('pdj 4'); 10 | 11 | console.log('Normal output'); 12 | console.log(res); 13 | 14 | console.log('JSON output'); 15 | console.log(resj); 16 | r2.quit(); 17 | } catch (e) { 18 | console.error(e.toString()); 19 | process.exit(1); 20 | } 21 | -------------------------------------------------------------------------------- /typescript/examples/hello/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "es6", 5 | "module": "esnext", 6 | "lib": ["es6"], 7 | "declaration": true, 8 | "esModuleInterop": true, 9 | "moduleResolution": "nodenext", 10 | "strict": true, 11 | "skipLibCheck": true, 12 | "outDir": "./dist", 13 | "paths": { 14 | "@r2pipe": ["./r2pipe/index.js"] 15 | } 16 | }, 17 | "include": [ 18 | "index.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /dotnet/r2pipe/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "debugType": "portable", 5 | "emitEntryPoint": true 6 | }, 7 | "dependencies": {}, 8 | "frameworks": { 9 | "net45":{}, 10 | "dnxcore50": { }, 11 | "netcoreapp1.0": { 12 | "dependencies": { 13 | "Microsoft.NETCore.App": { 14 | "type": "platform", 15 | "version": "1.0.0" 16 | } 17 | }, 18 | "imports": "dnxcore50" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/typescript/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-ts-example", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "typescript": { 8 | "version": "2.9.2", 9 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", 10 | "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", 11 | "dev": true 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java/examples/Test.java: -------------------------------------------------------------------------------- 1 | import org.radare.r2pipe.R2Pipe; 2 | 3 | public class Test { 4 | public static void main (String[] args) { 5 | try { 6 | R2Pipe r2p = new R2Pipe ("/bin/ls"); 7 | //R2Pipe r2p = new R2Pipe ("http://cloud.rada.re/cmd/", true); 8 | System.out.println (r2p.cmd ("pd 10")); 9 | System.out.println ("=============="); 10 | System.out.println (r2p.cmd ("px 32")); 11 | r2p.quit(); 12 | } catch (Exception e) { 13 | System.err.println (e); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/node/sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var r2pipe = require('../..'); 4 | var ts = require('..'); 5 | 6 | function testSync (fin) { 7 | try { 8 | var r2 = r2pipe.openSync('../b/ls'); 9 | if (r2) { 10 | fin(r2.cmd('?e hello world')); 11 | r2.quit(); 12 | } 13 | } catch (e) { 14 | fin(e.toString()); 15 | } 16 | } 17 | 18 | ts.addTest('testSync', testSync, 'hello world\n', { 19 | broken: true 20 | }); 21 | 22 | ts.inSerial(); 23 | // ts.inParalel(); 24 | -------------------------------------------------------------------------------- /python/examples/syscall/int.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import r2pipe 4 | 5 | r2p = r2pipe.open() 6 | num = int(sys.argv[1]) 7 | if num == 0x80: 8 | r = r2p.cmdj("arj") 9 | if r["eax"] == 1: 10 | print "[SYSCALL EXIT] %d" % (r["ebx"]) 11 | elif r["eax"] == 4: 12 | msg = r2p.cmd("psz %d@%d" % (r["edx"], r["ecx"])) 13 | print "[WRITE SYSCALL] ==> %s" % (msg) 14 | elif num == 3: 15 | print "[INT3]" 16 | else: 17 | print ("[unhandled SYSCALL %d]" % num) 18 | -------------------------------------------------------------------------------- /python/examples/test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import r2pipe 4 | 5 | curdir = os.path.dirname(os.path.realpath(__file__)) 6 | 7 | r2 = r2pipe.open(curdir + "/ls", ["-2"]) 8 | 9 | # print(r2pipe.__file__) 10 | # print(r2pipe.VERSION) 11 | 12 | r2.cmd("aa") 13 | 14 | sys.stdout.write("/bin/ls ") 15 | 16 | pi1 = r2.cmd("pi 1 @e:scr.color=0").strip() 17 | if pi1 == "push rbp": 18 | print("OK") 19 | else: 20 | print("FAIL") 21 | # print(pi1) 22 | # print (r2.cmd("pd 10")); 23 | r2.quit() 24 | -------------------------------------------------------------------------------- /python/except.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import r2pipe 4 | import sys 5 | 6 | r = r2pipe.open("/bin/ls") 7 | try: 8 | print("r2 version: %s" % r.cmd("?V")) 9 | pid = int(r.cmd("?vi $p")) 10 | print("Killing r2 PID %d" % (pid)) 11 | r.cmd('"!(sleep 1; kill -9 %d) &"' % pid) 12 | r.cmd("!sleep 3") 13 | print(r.cmd("x")) 14 | r.cmd("q") 15 | print("This was not expected!") 16 | except: 17 | print("r2 was killed as expected") 18 | sys.exit(0) 19 | 20 | sys.exit(1) 21 | -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from distutils.core import setup 3 | import r2pipe 4 | 5 | # with open('README.rst') as readme_file: 6 | # readme = readme_file.read() 7 | 8 | setup( 9 | name="r2pipe", 10 | version=r2pipe.version(), 11 | license="MIT", 12 | description="Pipe interface for radare2", 13 | author="pancake", 14 | author_email="pancake@nopcode.org", 15 | url="https://rada.re", 16 | package_dir={"r2pipe": "r2pipe"}, 17 | packages=["r2pipe"], 18 | ) 19 | -------------------------------------------------------------------------------- /haskell/example_r2pipe.hs: -------------------------------------------------------------------------------- 1 | import R2Pipe 2 | import qualified Data.ByteString.Lazy as L 3 | 4 | showMainFunction ctx = do 5 | cmd ctx "s main" 6 | L.putStr =<< cmd ctx "pD `fl $$`" 7 | 8 | main = do 9 | -- Run r2 locally 10 | open (Just "/bin/ls") >>= showMainFunction 11 | -- Pick up pipes from parent r2 process 12 | open Nothing >>= showMainFunction 13 | -- Connect to r2 via HTTP (e.g. if "r2 -qc=h /bin/ls" is running) 14 | open (Just "http://127.0.0.1:9090") >>= showMainFunction 15 | -------------------------------------------------------------------------------- /zig/README.md: -------------------------------------------------------------------------------- 1 | # r2pipe for zig 2 | 3 | ## Compilation 4 | 5 | You can do `make` or `zig build-exe main.zig` to get the program to run 6 | 7 | ``` 8 | make 9 | ``` 10 | 11 | ## Usage 12 | 13 | Now you are ready to use this executable as via `#!pipe` inside radare2: 14 | 15 | ``` 16 | $ r2 /bin/ls 17 | > #!pipe ./main 18 | Hello, World 19 | ╭──╮ ╭─────────────╮ 20 | │ _│ │ │ 21 | │ O O < Hello World │ 22 | │ │╭ │ │ 23 | ││ ││ ╰─────────────╯ 24 | │└─┘│ 25 | ╰───╯ 26 | ``` 27 | -------------------------------------------------------------------------------- /go/r2pipe_native_test.go: -------------------------------------------------------------------------------- 1 | // radare - LGPL - Copyright 2017-2021 - pancake 2 | 3 | package r2pipe 4 | 5 | import "testing" 6 | import "fmt" 7 | 8 | func TestNativeCmd(t *testing.T) { 9 | fmt.Println("[*] Testing r2 native api pipe") 10 | r2p, err := NewNativePipe("/bin/ls") 11 | // r2p, err := NewPipe("/bin/ls") 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | defer r2p.Close() 16 | version, err := r2p.Cmd("pd 10 @ entry0") 17 | if err != nil { 18 | t.Fatal(err) 19 | } 20 | print(version + "\n") 21 | } 22 | -------------------------------------------------------------------------------- /python/examples/test2.py: -------------------------------------------------------------------------------- 1 | import r2pipe 2 | 3 | r2 = r2pipe.open("-") 4 | r2.cmd("aa") 5 | hello = r2.cmd("?e hello").strip() 6 | if hello != "hello": 7 | exit(1) 8 | print(hello) 9 | world = r2.cmd("?e world").strip() 10 | if world != "world": 11 | exit(1) 12 | print(world) 13 | r2.quit() 14 | 15 | r2 = r2pipe.open("-") 16 | hello = r2.cmd("?e hello").strip() 17 | if hello != "hello": 18 | exit(1) 19 | print(hello) 20 | world = r2.cmd("?e world").strip() 21 | if world != "world": 22 | exit(1) 23 | print(world) 24 | -------------------------------------------------------------------------------- /shell/r2pipe.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z "${R2PIPE_IN}" ]; then 4 | echo 'r2 -i test.sh -qcq /bin/ls' 5 | exit 1 6 | fi 7 | 8 | r2cmd() { 9 | if [ -z "${R2PIPE_IN}" ]; then 10 | echo "No r2pipe environment found" >&2 11 | exit 1 12 | fi 13 | printf "$1\x00" >&${R2PIPE_OUT} 14 | while : ; do 15 | A="" 16 | read -t 1 A <&${R2PIPE_IN} 17 | [ -z "$A" ] && break 18 | echo "$A" 19 | done 20 | } 21 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/ts/test.ts: -------------------------------------------------------------------------------- 1 | import { R2Pipe } from ".."; 2 | import { inspect } from "util"; 3 | 4 | async function main(): Promise { 5 | const r2 = await R2Pipe.open("/bin/ls"); 6 | try { 7 | const res = await r2.cmd("?E Hello World") 8 | console.log(res); 9 | const info = await r2.cmdj("ij"); 10 | console.error(inspect(info.core, { depth: null, colors: true} )) 11 | } finally { 12 | r2.quit(); 13 | } 14 | } 15 | 16 | main().catch(err => { console.error(err); }); 17 | -------------------------------------------------------------------------------- /java/Makefile: -------------------------------------------------------------------------------- 1 | JARPATH=$(shell pwd) 2 | JAVASRC=src/main/java/org/radare/r2pipe 3 | JAVAC?=javac 4 | include config.mk 5 | 6 | all: 7 | $(JAVAC) $(JAVACFLAGS) $(JAVASRC)/*.java examples/Test.java 8 | $(MAKE) mvn 9 | # cd src/main/java && jar cvf ../../../r2pipe.jar org 10 | # $(MAKE) -C jni 11 | $(MAKE) -C examples 12 | 13 | m mvn maven: 14 | mvn clean compile 15 | mvn install 16 | cp target/*.jar . 17 | 18 | run: 19 | $(MAKE) -C examples run 20 | 21 | clean: 22 | rm -f *.class org/radare/r2pipe/*.class 23 | rm -f r2pipe.jar 24 | -------------------------------------------------------------------------------- /ocaml/README.md: -------------------------------------------------------------------------------- 1 | # OCaml 2 | 3 | OCaml r2pipe bindings are maintained at [fxfactorial/ocaml-radare2](https://github.com/fxfactorial/ocaml-radare2). 4 | They are also published in opam repository as [`radare2`](https://opam.ocaml.org/packages/radare2). 5 | 6 | Note, the lowest supported version of radare2 is **2.3.0** - it's the first that started to support 7 | JSON r2pipe API consistently. Still, using newer versions is preferred. 8 | 9 | You can install it with [`opam`](https://opam.ocaml.org): 10 | ```sh 11 | opam install radare2 12 | ``` 13 | -------------------------------------------------------------------------------- /typescript/r2pipe/index.ts: -------------------------------------------------------------------------------- 1 | import {R2PipeCmdInterface} from "./base.js"; 2 | import {R2PipeHttp} from "./http.js"; 3 | import {R2PipeSpawn} from "./spawn.js"; 4 | import {R2PipeLocal} from "./local.js"; 5 | 6 | 7 | // Function to create an instance of R2Pipe 8 | export function open(filePath: string = ""): R2PipeCmdInterface { 9 | if (filePath === "") { 10 | return new R2PipeLocal(); 11 | } 12 | if (filePath.startsWith("http://")) { 13 | return new R2PipeHttp(filePath); 14 | } 15 | return new R2PipeSpawn(filePath); 16 | } 17 | -------------------------------------------------------------------------------- /c/test-pipe2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static void r2cmd(R2Pipe *r2, const char *cmd) { 4 | char *msg = r2pipe_cmd (r2, cmd); 5 | if (msg) { 6 | printf ("%s\n", msg); 7 | free (msg); 8 | } 9 | } 10 | 11 | int main() { 12 | // R2Pipe *r2 = r2pipe_open ("/bin/ls"); 13 | R2Pipe *r2 = r2pipe_open ("radare2 -q0 /bin/ls"); 14 | if (r2) { 15 | r2cmd (r2, "?e Hello World"); 16 | r2cmd (r2, "x"); 17 | r2cmd (r2, "?e Hello World"); 18 | r2cmd (r2, "pd 20"); 19 | r2pipe_close (r2); 20 | return 0; 21 | } 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /c/test-spawn.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static void r2cmd(R2Pipe *r2, const char *cmd) { 4 | char *msg = r2pipe_cmd (r2, cmd); 5 | if (msg) { 6 | printf ("%s\n", msg); 7 | free (msg); 8 | } 9 | } 10 | 11 | int main() { 12 | // XXX R2Pipe *r2 = r2pipe_open ("/bin/ls"); 13 | R2Pipe *r2 = r2pipe_open ("radare2 -q0 /bin/ls"); 14 | if (r2) { 15 | r2cmd (r2, "?e Hello World"); 16 | r2cmd (r2, "x"); 17 | r2cmd (r2, "?e Hello World"); 18 | r2cmd (r2, "pd 20"); 19 | r2pipe_close (r2); 20 | return 0; 21 | } 22 | return 1; 23 | } 24 | -------------------------------------------------------------------------------- /erlang/testr2pipe.erl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env escript 2 | %% -*- erlang -*- 3 | %%! -smp enable 4 | 5 | %% -sname hr 6 | -mode(compile). 7 | 8 | -export([main/1]). 9 | 10 | main(_Args) -> 11 | %% adding r2pipe to modulepath, set it to your r2pipe_erl location 12 | R2pipePATH = filename:dirname(escript:script_name()) ++ "/ebin", 13 | true = code:add_pathz(R2pipePATH), 14 | 15 | %% initializing the link with r2 16 | H = r2pipe:init(lpipe), 17 | 18 | %% all work goes here 19 | io:format("~s", [r2pipe:cmd(H, "i")]). 20 | -------------------------------------------------------------------------------- /nim/main.nim: -------------------------------------------------------------------------------- 1 | include r2pipe 2 | import asyncdispatch 3 | 4 | proc test {.async.} = 5 | # let r2p = R2PipeHttp(url: "http://cloud.radare.org") 6 | let r2p = R2PipeHttp(url: "http://localhost:8080") 7 | let res = await r2p.cmd("?V") 8 | echo(res); 9 | 10 | proc testApi = 11 | let r2p = R2PipeApi(); 12 | discard r2p.cmd("o /bin/ls") 13 | let res = r2p.cmd("pd 20") 14 | echo(res); 15 | echo(r2p.cmd("?e hello world")) 16 | let info = r2p.cmdj("ij"); 17 | echo(info["core"]["file"].str); 18 | 19 | testApi() 20 | waitFor test() 21 | -------------------------------------------------------------------------------- /nodejs/r2pipe/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | ln -fs /usr/share/radare2/last/www/t/r2.js 3 | cd examples ; node test-channels.js 4 | 5 | indent: node_modules/jsfmt 6 | node_modules/.bin/jsfmt -w index.js 7 | node_modules/.bin/jsfmt -w test.js 8 | 9 | node_modules/jsfmt: 10 | mkdir -p node_modules 11 | npm install jsfmt 12 | 13 | MODVER=$(shell node -e 'console.log(JSON.parse(require("fs").readFileSync("package.json"))["version"])') 14 | 15 | npm publish pub: 16 | ${MAKE} 17 | npm publish 18 | 19 | unpublish: 20 | ${MAKE} 21 | npm unpublish @${MODVER} 22 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-http.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function assert (a, b) { 4 | if (a === b) { 5 | console.error('test passes ok'); 6 | } else { 7 | console.error('assert', a, b); 8 | process.exit(1); 9 | } 10 | } 11 | 12 | const r2p = require('../'); 13 | r2p.open('http://cloud.rada.re/cmd/', (error, r2) => { 14 | assert(error, null); 15 | r2.cmd('p8 1 @ entry0', (error, result) => { 16 | assert(error, null); 17 | assert(result.trim(), '31'); 18 | r2.quit(); 19 | console.log('done'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /vala/README.md: -------------------------------------------------------------------------------- 1 | r2pipe.vala 2 | =========== 3 | 4 | C/Vala glib-based API for use radare2 via the r2pipe protocol. 5 | 6 | Installation 7 | ------------ 8 | 9 | You can type `make install` or `make uninstall` here. 10 | 11 | Example: 12 | ------- 13 | 14 | ``` 15 | var r2 = new R2Pipe.sync("/bin/ls"); 16 | print (r2.cmd("?e Hello World")); 17 | ``` 18 | 19 | Compile this example with this: 20 | ``` 21 | $ valac --pkg r2pipe main.vala 22 | $ ./main 23 | ``` 24 | 25 | Or just run it in a shot: 26 | 27 | ``` 28 | $ vala --pkg=r2pipe main.vala 29 | ``` 30 | -------------------------------------------------------------------------------- /typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "r2pipe", 4 | "moduleResolution": "nodenext", 5 | "target": "esnext", 6 | "esModuleInterop": true, 7 | "resolveJsonModule": true, 8 | "module": "nodenext", 9 | "lib": ["esnext"], 10 | "declaration": true, 11 | "strict": false, 12 | "skipLibCheck": true, 13 | "outDir": "./dist", 14 | "rootDir": "./r2pipe" 15 | }, 16 | "paths": { 17 | "*": ["node_modules/*", "src/types/*"] 18 | }, 19 | "include": [ 20 | "r2pipe/index.ts", 21 | "test.ts" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/set-get-tcp.js: -------------------------------------------------------------------------------- 1 | /* pancake - 2016 - radare project */ 2 | 3 | const r2pipe = require('..'); 4 | 5 | const buf = new Buffer([1, 2, 3, 4]); 6 | 7 | r2pipe.openBuffer(buf, (err, r2) => { 8 | // r2pipe.open('malloc://9999', (err, r2) => { 9 | if (err) { 10 | throw err; 11 | } 12 | r2.cmd('wx 90909090', (err, res) => { 13 | if (err) { 14 | throw err; 15 | } 16 | r2.getBuffer(0, 4, (err, res) => { 17 | if (err) { 18 | throw err; 19 | } 20 | console.log('BufBack', res); 21 | r2.quit(); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | ## Environment 8 | 9 | Specify r2pipe language, version of the module, r2 version and OS/arch details. 10 | 11 | ```sh 12 | # copypaste this script into your shell and replace it with the output 13 | date 14 | r2 -v 15 | uname -ms 16 | python -c 'import r2pipe;print(r2pipe.version())' 17 | ``` 18 | 19 | ## Description 20 | 21 | 22 | 23 | ## Test 24 | 25 | 26 | -------------------------------------------------------------------------------- /java/examples/groovy/test.groovy: -------------------------------------------------------------------------------- 1 | /* Groovy.r2pipe hello world -- 2016 - pancake@nopcode.org */ 2 | 3 | import org.radare.r2pipe.*; 4 | import groovy.json.JsonSlurper; 5 | import groovy.json.JsonOutput; 6 | 7 | class R2 { 8 | def r2; 9 | def cmd = { x -> r2.cmd(x).trim() } 10 | def cmdj = { x -> new JsonSlurper().parseText(this.cmd(x)) } 11 | def quit = { r2.quit() } 12 | } 13 | 14 | def r2 = new R2(r2: new R2Pipe("/bin/ls")) 15 | println r2.cmd("?V") 16 | def obj = r2.cmdj("ij").bin 17 | println JsonOutput.prettyPrint(JsonOutput.toJson(obj)) 18 | println ("Interpreter: " + obj.intrp); 19 | r2.quit() 20 | -------------------------------------------------------------------------------- /zig/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const print = @import("std").debug.print; 3 | const r2pipe = @import("src/r2pipe.zig"); 4 | 5 | pub fn main() !void { 6 | try inr2(); 7 | // try inspawn(); 8 | } 9 | 10 | fn inr2() !void { 11 | const r2 = try r2pipe.open(""); 12 | const res = try r2.cmd("?E Hello World"); 13 | print("Hello, {s}\n{s}\n", .{ "world", res }); 14 | } 15 | 16 | fn inspawn() !void { 17 | const r2 = try r2pipe.open("/bin/ls"); 18 | const res = try r2.cmd("?E Hello World"); 19 | print("Hello, {s}\n{s}\n", .{ "world", res }); 20 | r2.quit(); 21 | } 22 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/ts/test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const __1 = require(".."); 4 | const util_1 = require("util"); 5 | async function main() { 6 | const r2 = await __1.R2Pipe.open("/bin/ls"); 7 | try { 8 | const res = await r2.cmd("?E Hello World"); 9 | console.log(res); 10 | const info = await r2.cmdj("ij"); 11 | console.error(util_1.inspect(info.core, { depth: null, colors: true })); 12 | } 13 | finally { 14 | r2.quit(); 15 | } 16 | } 17 | main().catch(err => { console.error(err); }); 18 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/node/bugs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var r2pipe = require('../..'); 4 | var ts = require('..'); 5 | 6 | function testSync (fin) { 7 | try { 8 | var r2 = r2pipe.open('../b/ls'); // async open with no callback 9 | // var r2 = r2pipe.openSync('../b/ls'); // async open with no callback 10 | if (r2) { 11 | fin(r2.cmd('?e hello world')); 12 | r2.quit(); 13 | } 14 | } catch (e) { 15 | fin(e.toString()); 16 | } 17 | } 18 | 19 | ts.addTest('testSync', testSync, 'hello world\n', { 20 | broken: true 21 | }); 22 | 23 | ts.inSerial(); 24 | // ts.inParalel(); 25 | -------------------------------------------------------------------------------- /vala/main.vala: -------------------------------------------------------------------------------- 1 | 2 | var r2 = new R2Pipe.sync("/bin/ls"); 3 | stdout.printf ("%s\n", r2.cmd("x")); 4 | stdout.printf ("%s\n", r2.cmd("pd 20")); 5 | 6 | MainLoop loop = new MainLoop (); 7 | var r2p = new R2Pipe ("/bin/ls"); 8 | r2p.cmd ("pi 4", (x) => { 9 | stdout.printf ("DISASM((%s))\n", x); 10 | r2p.cmd ("ie", (x) => { 11 | stdout.printf ("entry((%s))\n", x); 12 | r2p.cmd ("q"); 13 | }); 14 | }); 15 | 16 | /* 17 | ChildWatch.add (r2p.child_pid, (pid, status) => { 18 | // Triggered when the child indicated by child_pid exits 19 | Process.close_pid (pid); 20 | loop.quit (); 21 | }); 22 | loop.run (); 23 | */ 24 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-co.js: -------------------------------------------------------------------------------- 1 | const r2promise = require('./'); 2 | const co = require('co'); 3 | 4 | function work (file) { 5 | return co(function * () { 6 | const r2 = yield r2promise.open(file); 7 | return [r2, yield r2.cmd('o')]; 8 | }); 9 | } 10 | 11 | co(function * () { 12 | try { 13 | const [r2, msg] = yield work('/bin/ls'); 14 | console.log('This is', msg); 15 | const [r3, msh] = yield work('/bin/cp'); 16 | console.log('This is', msh); 17 | yield r3.quit(); 18 | yield r2.quit(); 19 | } catch (e) { 20 | console.error('error', e); 21 | process.exit(1); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /c/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS+=$(shell pkg-config --cflags r_socket) 2 | LDFLAGS+=$(shell pkg-config --libs r_socket) 3 | 4 | TESTS=test-pipe test-pipe2 test-spawn 5 | 6 | all: $(TESTS) 7 | 8 | test-pipe: 9 | $(CC) -o test-pipe test-pipe.c $(CFLAGS) $(LDFLAGS) 10 | r2 -q -c '#!pipe ./test-pipe' /bin/ls 11 | 12 | test-pipe2: 13 | $(CC) -o test-pipe2 test-pipe2.c $(CFLAGS) $(LDFLAGS) 14 | #r2 -q -c '#!pipe ./test-pipe2' /bin/ls 15 | ./test-pipe2 16 | 17 | test-spawn: 18 | $(CC) -o test-spawn test-spawn.c $(CFLAGS) $(LDFLAGS) 19 | ./test-spawn 20 | 21 | clean: 22 | rm -f $(TESTS) 23 | rm -f a.out 24 | 25 | .PHONY: $(TESTS) 26 | 27 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-pipeSync.js: -------------------------------------------------------------------------------- 1 | /* Small tests for r2pipe */ 2 | // return true; 3 | 4 | var r2pipe = require('./../'); 5 | 6 | var r2 = r2pipe.pipeSync('/bin/ls'); 7 | var res = r2.cmd('pd 4'); 8 | var resj = r2.cmdj('pdj 4'); 9 | 10 | var sys = r2.syscmd('rabin2 -zz /bin/ls'); 11 | var sysj = r2.syscmdj('rabin2 -j -zz /bin/ls'); 12 | 13 | console.log('Normal output'); 14 | console.log(res); 15 | 16 | console.log('JSON output'); 17 | console.log(resj); 18 | 19 | console.log('\nSyscmd normal output'); 20 | console.log(sys); 21 | 22 | console.log('Syscmd JSON output'); 23 | console.log(sysj); 24 | 25 | r2.quit(); 26 | -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # r2pipe for Python 2 | 3 | Interact with radare2 using the #!pipe command or in standalone scripts 4 | that communicate with local or remote r2 via pipe, tcp or http. 5 | 6 | ## Installation 7 | 8 | ``` 9 | $ pip install r2pipe 10 | ``` 11 | 12 | or 13 | 14 | ``` 15 | $ pip3 install r2pipe 16 | ``` 17 | 18 | ## Usage example: 19 | 20 | ```python 21 | import r2pipe 22 | 23 | r2 = r2pipe.open("/bin/ls") 24 | r2.cmd('aa') 25 | print(r2.cmd("afl")) 26 | print(r2.cmdj("aflj")) # evaluates JSONs and returns an object 27 | print(r2.cmdj("ij").core.format) # shows file format 28 | r2.quit() 29 | ``` 30 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-pipe.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function assert (a, b) { 4 | if (a === b) { 5 | console.error('test passes ok'); 6 | } else { 7 | console.error('assert', a, b); 8 | process.exit(1); 9 | } 10 | } 11 | 12 | const r2p = require('../'); 13 | r2p.pipe('target-bin', ['-nw'], (error, r2) => { 14 | assert(error, null); 15 | r2.cmd('wx 90;p8 1', (error, result) => { 16 | assert(error, null); 17 | assert(result.trim(), '90'); 18 | r2.cmd('wx 90', (error, result) => { 19 | assert(error, null); 20 | r2.quit(); 21 | console.log('done'); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /zig/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.build.Builder) void { 4 | // Standard release options allow the person running `zig build` to select 5 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. 6 | const mode = b.standardReleaseOptions(); 7 | 8 | const lib = b.addStaticLibrary("zig", "src/lib.zig"); 9 | lib.setBuildMode(mode); 10 | lib.install(); 11 | 12 | const main_tests = b.addTest("src/lib.zig"); 13 | main_tests.setBuildMode(mode); 14 | 15 | const test_step = b.step("test", "Run library tests"); 16 | test_step.dependOn(&main_tests.step); 17 | } 18 | -------------------------------------------------------------------------------- /go/errside_test.go: -------------------------------------------------------------------------------- 1 | package r2pipe 2 | 3 | import "testing" 4 | import "fmt" 5 | import "time" 6 | 7 | func TestErrSide(t *testing.T) { 8 | r2p, err := NewPipe("malloc://256") 9 | if err != nil { 10 | t.Fatal(err) 11 | } 12 | r2p.Close() 13 | var res = false 14 | r2p.On("errmsg", res, func(p *Pipe, typ string, user interface{}, dat string) bool { 15 | fmt.Println("errmsg received") 16 | res = true 17 | return false 18 | // return true 19 | }) 20 | 21 | r2p.Cmd("aaa") 22 | time.Sleep(1) 23 | if res { 24 | fmt.Println("It works!") 25 | } 26 | defer r2p.Close() 27 | fmt.Println("[*] Testing r2pipe-side stderr message") 28 | } 29 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/promise.js: -------------------------------------------------------------------------------- 1 | const r2pipe = require('..'); 2 | const co = require('co'); 3 | 4 | r2pipe.open('/bin/ls', (err, r2) => { 5 | if (err) { 6 | throw err; 7 | } 8 | const r2p = r2.promisify(); 9 | co(function * () { 10 | try { 11 | const hello = yield r2p.cmd('?E Hello'); 12 | console.log(hello); 13 | const version = yield r2p.cmd('?V'); 14 | console.log('version', version); 15 | const info = yield r2p.cmdj('ij'); 16 | console.log('info', JSON.stringify(info, null, ' ')); 17 | } catch (err) { 18 | console.error(err); 19 | } 20 | yield r2p.quit(); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /lisp/main.lisp: -------------------------------------------------------------------------------- 1 | ;;; -*- encoding:utf-8 Mode: LISP; Syntax: COMMON-LISP; Base: 10 -*- --- 2 | ;; 3 | ;; Filename: main.lisp 4 | ;; Description: 5 | ;; Author: Jingtao Xu 6 | ;; Created: 2015.09.29 17:43:05(+0800) 7 | ;; Last-Updated: 2015.09.30 16:33:26(+0800) 8 | ;; Update #: 6 9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10 | ;; 11 | ;;; Commentary: 12 | ;; 13 | ;; 14 | ;;(load "r2pipe.lisp") 15 | (setf pipe (r2pipe "/bin/bash")) 16 | (format t "~s~%" (r2-cmd pipe "pi 5")) 17 | (format t "~s~%" (r2-json (r2-cmd pipe "pij 1"))) 18 | (format t "~s~%" (r2-cmd pipe "px 64")) 19 | (r2-quit pipe) 20 | -------------------------------------------------------------------------------- /nodejs/r2pipe/util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function cleanCmd (cmd) { 4 | cmd = cmd.trim(); 5 | 6 | /* Check for new lines / multiple cmds */ 7 | const pos = cmd.indexOf('\n'); 8 | if (pos !== -1) { 9 | cmd = cmd.replace('\n', '\\n'); 10 | throw new Error('Invalid character at pos: ' + pos + ' (' + cmd + ')'); 11 | } 12 | 13 | const ascii = /^[ -~]+$/; 14 | if (!ascii.test(cmd)) { 15 | /* Check for non printable characters */ 16 | const buff = new Buffer(cmd); 17 | throw new Error('Invalid character at cmd: ' + JSON.stringify(buff)); 18 | } 19 | 20 | return cmd; 21 | } 22 | 23 | module.exports.cleanCmd = cleanCmd; 24 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Look for the 'acr' tool here: https://github.com/radare/acr 4 | # Clone last version of ACR from here: 5 | # git clone https://github.com/radare/acr 6 | # 7 | # -- pancake 8 | 9 | r2pm -h >/dev/null 2>&1 10 | if [ $? = 0 ]; then 11 | echo "Installing the last version of 'acr'..." 12 | r2pm -i acr > /dev/null 13 | r2pm -r acr -h > /dev/null 2>&1 14 | if [ $? = 0 ]; then 15 | echo "Running 'acr -p'..." 16 | r2pm -r acr -p 17 | else 18 | echo "Cannot find 'acr' in PATH" 19 | fi 20 | else 21 | echo "Running acr..." 22 | acr -p 23 | fi 24 | if [ -n "$1" ]; then 25 | echo "./configure $*" 26 | ./configure $* 27 | fi 28 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-r2io-plugin.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | r2 r2pipe://"node test-r2io-plugin.js" 4 | 5 | */ 6 | 7 | var r2p = require('./../'); 8 | 9 | r2p.ioplugin(function (io, msg) { 10 | switch (msg.op) { 11 | case 'read': 12 | var obj = { 13 | result: msg.count, 14 | data: [1, 2, 3] 15 | }; 16 | io.send(obj); 17 | break; 18 | case 'write': 19 | /* not implemented */ 20 | io.writeObject(); 21 | break; 22 | case 'system': 23 | io.send({ 24 | result: 'Hello World' 25 | }); 26 | break; 27 | default: 28 | io.send(); 29 | break; 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-hang-bug.js: -------------------------------------------------------------------------------- 1 | const r2pipePromise = require('r2pipe-promise'); 2 | const r2pipe = require('r2pipe'); 3 | 4 | // Async hangs 5 | async function test () { 6 | const r2 = await r2pipePromise.open(); 7 | const msg = await r2.cmd('?E hello'); 8 | console.log(msg); 9 | await r2.quit(); 10 | } 11 | 12 | async function testSync () { 13 | const r2 = r2pipe.openSync(); 14 | const msg = r2.cmd('?E hello'); 15 | console.log(msg); 16 | r2.quit(); 17 | } 18 | 19 | // hangs 20 | test().then(console.log).catch(console.error); 21 | // works 22 | //testSync().then(console.log).catch(console.error); 23 | bare().then(console.log).catch(console.error); 24 | -------------------------------------------------------------------------------- /c/README.md: -------------------------------------------------------------------------------- 1 | The C r2pipe API 2 | ================ 3 | 4 | It's implemented in `libr_socket`, so it depends on r2 libraries. 5 | 6 | Here's a simple usage example: 7 | 8 | ```c 9 | #include 10 | 11 | static void r2cmd(R2Pipe *r2, const char *cmd) { 12 | char *msg = r2pipe_cmd (r2, cmd); 13 | if (msg) { 14 | printf ("%s\n", msg); 15 | free (msg); 16 | } 17 | } 18 | 19 | int main() { 20 | R2Pipe *r2 = r2pipe_open ("radare2 -q0 /bin/ls"); 21 | if (r2) { 22 | r2cmd (r2, "?e Hello World"); 23 | r2cmd (r2, "x"); 24 | r2cmd (r2, "?e Hello World"); 25 | r2cmd (r2, "pd 20"); 26 | r2pipe_close (r2); 27 | return 0; 28 | } 29 | return 1; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-channels.js: -------------------------------------------------------------------------------- 1 | /* Small tests for r2pipe */ 2 | 3 | var r2pipe = require('../'); 4 | 5 | function doSomeStuff (err, r2) { 6 | if (err) throw err; 7 | r2.cmdj('aij entry0+2', function (err, o) { 8 | if (err) throw err; 9 | console.log(o); 10 | }); 11 | 12 | r2.cmd('af @ entry0', function (err, o) { 13 | if (err) throw err; 14 | r2.cmd('pdf @ entry0', function (err, o) { 15 | if (err) throw err; 16 | console.log(o); 17 | r2.quit(); 18 | }); 19 | }); 20 | } 21 | 22 | r2pipe.pipe('/bin/ls', doSomeStuff); 23 | // r2pipe.launch('/bin/ls', doSomeStuff); 24 | // r2pipe.connect('http://cloud.rada.re/cmd/', doSomeStuff); 25 | -------------------------------------------------------------------------------- /crystal/core.cr: -------------------------------------------------------------------------------- 1 | class RCore 2 | @r2 : Void* 3 | def initialize # (@r2 : Void*) 4 | @r2 = RCoreC.new 5 | end 6 | def cmd(c : String) : String 7 | cres = RCoreC.cmd(@r2, c.to_unsafe) 8 | res = String.new(cres) 9 | RCoreC.libc_free(cres) 10 | return res 11 | end 12 | def finalize 13 | RCoreC.free(@r2) 14 | end 15 | end 16 | 17 | @[Link("r_core")] 18 | lib RCoreC 19 | fun new = r_core_new() : Void* 20 | fun cmd = r_core_cmd_str(core: Void*, cmd: LibC::Char*) : LibC::Char* 21 | fun free = r_core_free(core: Void*) 22 | fun libc_free = free(core: Void*) 23 | end 24 | 25 | r2 = RCore.new 26 | res = r2.cmd("?E Hello World") 27 | print(res) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/tgbot/README.md: -------------------------------------------------------------------------------- 1 | radare2 Telegram Bot 2 | ==================== 3 | 4 | This directory contains the sourcecode of the Telegram bot 5 | for radare2. The code can be easily modified to make any 6 | other bot for your own needs. But i'm just too lazy to split 7 | up the core functionality into a separate node module right 8 | now. I'll probably do someday if i have time :-) 9 | 10 | As always, just run `npm install` to get all the dependencies 11 | installed (actually, it's just r2pipe) 12 | 13 | $ npm install 14 | 15 | To run the bot you'll need to create a file named `TOKEN` 16 | with the Token provided by @botfather and type: 17 | 18 | $ npm run bot 19 | 20 | Enjoy! 21 | -------------------------------------------------------------------------------- /perl/t/readme_example.pl: -------------------------------------------------------------------------------- 1 | use Radare::r2pipe; 2 | use Data::Printer; 3 | 4 | my $r2 = Radare::r2pipe->new('/bin/ls'); 5 | print "Information about the /bin/ls binary:\n"; 6 | print $r2->cmd('iI'); 7 | print "Information about the /bin/ls binary in JSON: "; 8 | print $r2->cmd('ij') . "\n"; 9 | print "Information about the /bin/ls binary in a native Perl datastructure:\n"; 10 | p $r2->cmdj('ij'); 11 | $r2->quit(); 12 | 13 | # Other stuff 14 | print "Opening /bin/ls with -A (analyze) flag.\n"; 15 | $r2 = Radare::r2pipe->new(file => '/bin/ls', analyse => 1); # Opens r2 with -A option. 16 | print "Functions found in /bin/ls:\n"; 17 | print $r2->cmd('afl') . "\n"; 18 | $r2->close(); # Same as quit() 19 | -------------------------------------------------------------------------------- /erlang/README.md: -------------------------------------------------------------------------------- 1 | r2pipe for erlang 2 | ================= 3 | Works with r2 over the ports interface or by calling escript direclty from r2. 4 | 5 | Build: 6 | 7 | ``` 8 | $ rebar get-deps 9 | $ rebar co 10 | ``` 11 | 12 | Example pipe usage: 13 | 14 | ``` 15 | $ rebar sh 16 | erl> H = r2pipe:init(pipe, "/bin/ls"). 17 | erl> io:format("~s", [r2pipe:cmd(H, "i")]). 18 | erl> r2pipe:cmdj(H, "ij"). 19 | ``` 20 | 21 | See testr2pipe.erl as local pipe call example escript. Call it from r2 by using: 22 | ``` 23 | r2> #!pipe escript testr2pipe.erl 24 | ``` 25 | 26 | Or 27 | 28 | ``` 29 | $ chmod +x testr2pipe.erl 30 | ``` 31 | 32 | And then from r2: 33 | 34 | ``` 35 | r2> #!pipe testr2pipe.erl 36 | ``` -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/r2pipe-promise.d.ts: -------------------------------------------------------------------------------- 1 | 2 | export declare class R2Pipe { 3 | static open(target: string, options?: string[]): R2Pipe; 4 | cmd(command: string): Promise; 5 | cmdj(command: string): Promise; 6 | cmdAt(command: string, addr: number): Promise; 7 | call(command: string): Promise; 8 | callj(command: string): Promise; 9 | callAt(command: string, addr: number): Promise; 10 | plugin(string, string): boolean; 11 | unload(string, string): boolean; 12 | log(string); 13 | quit(): Promise; 14 | } 15 | 16 | export declare interface CommandResponse { 17 | [key: string]: any; 18 | } 19 | -------------------------------------------------------------------------------- /typescript/examples/hello/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-example-hello", 3 | "version": "0.0.1", 4 | "description": "example using the new r2pipe", 5 | "type": "module", 6 | "main": "./index.js", 7 | "types": "./index.d.js", 8 | "license": "LGPL-3.0", 9 | "module": "es2020", 10 | "engines": { 11 | "node": ">=14.16" 12 | }, 13 | "devDependencies": { 14 | "@frida/events": "^4.0.4", 15 | "@types/frida-gum": "^18.3.1", 16 | "@types/node": "^18.0.0", 17 | "@typescript-eslint/eslint-plugin": "^5.51.0", 18 | "@typescript-eslint/parser": "^5.51.0", 19 | "eslint": "^8.34.0", 20 | "frida-compile": "^16.1.5", 21 | "typescript": "^5.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Makefile.acr: -------------------------------------------------------------------------------- 1 | VERSION=@VERSION@ 2 | 3 | REMOTE=ocaml go rust erlang 4 | DISTDIR=radare2-r2pipe-$(VERSION) 5 | ORIGIN=$(shell cat "$@/ORIGIN" 2> /dev/null) 6 | 7 | all: 8 | @echo Nothing to do. 9 | 10 | clean: 11 | for a in */Makefile ; do $(MAKE) -C $$a ; done 12 | -rm -rf */node_modules 13 | 14 | dist: 15 | git clone . $(DISTDIR) 16 | $(MAKE) -C $(DISTDIR) rsync 17 | rm -rf $(DISTDIR)/.git 18 | tar czvf $(DISTDIR).tar.gz $(DISTDIR) 19 | rm -rf $(DISTDIR) 20 | 21 | $(REMOTE): 22 | git clone "$(ORIGIN)" "$@.git" 23 | mv "$@/ORIGIN" . 24 | rm -rf "$@/"* 25 | cp -rf "$@.git/"* "$@/" 26 | rm -rf $@.git 27 | mv ORIGIN "$@" 28 | 29 | sync: $(REMOTE) 30 | 31 | .PHONY: sync rsync clean all $(REMOTE) 32 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-connect.js: -------------------------------------------------------------------------------- 1 | /* Common-Javascript API for R2 --pancake 2014 */ 2 | 3 | /* This is a NodeJS program that uses the generic r2 api 4 | which is also compatible with the WebUI and Duktape. 5 | Enabling you to write Javascript extensions for r2 6 | that run in the shell, the web or inside r2 */ 7 | 8 | /* require the nodejs api */ 9 | var r2pipe = require('../'); 10 | 11 | function doSomeStuff (err, r2) { 12 | if (err) { 13 | return console.error(err.toString()); 14 | } 15 | r2.cmd('pd 4', function (err, res) { 16 | if (err) throw err; 17 | console.log(res); 18 | r2.quit(); 19 | }); 20 | } 21 | 22 | r2pipe.connect('http://cloud.rada.re/cmd/', doSomeStuff); 23 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-open.js: -------------------------------------------------------------------------------- 1 | /* 2 | Test open and openSync lpipe protocols 3 | */ 4 | 5 | var r2pipe = require('../'); 6 | 7 | const syncMode = process.argv[2] === '-s'; 8 | 9 | /* sync example */ 10 | try { 11 | if (syncMode) { 12 | const r2p = r2pipe.openSync(); 13 | console.log(r2p.cmdj('ij')); 14 | r2p.quit(); 15 | } else { 16 | r2pipe.open((err, r2p) => { 17 | if (err) { 18 | throw err; 19 | } 20 | r2p.cmdj('ij', (err, res) => { 21 | if (err) { 22 | throw err; 23 | } 24 | console.log(res); 25 | r2p.quit(); 26 | }); 27 | }); 28 | } 29 | } catch (e) { 30 | console.error(e); // .toString()); 31 | } 32 | -------------------------------------------------------------------------------- /haskell/r2pipe.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: >=1.10 2 | 3 | name: r2pipe 4 | version: 0.1.0.0 5 | synopsis: Pipe interface for radare2 6 | license-file: LICENSE 7 | author: radareorg 8 | build-type: Simple 9 | 10 | library 11 | exposed-modules: R2Pipe 12 | other-modules: 13 | build-depends: base >=4.12 && <5, 14 | HTTP, aeson, process, bytestring 15 | default-language: Haskell2010 16 | 17 | executable example 18 | main-is: example_r2pipe.hs 19 | other-modules: R2Pipe 20 | build-depends: base >= 4.12 && <5, 21 | r2pipe, HTTP, aeson, process, bytestring 22 | 23 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/promise2.js: -------------------------------------------------------------------------------- 1 | const r2pipe = require('..'); 2 | const co = require('co'); 3 | 4 | r2pipe.open('/bin/ls', (err, r2) => { 5 | if (err) { 6 | throw err; 7 | } 8 | r2pipe.open('/bin/cp', (err, r22) => { 9 | if (err) { 10 | throw err; 11 | } 12 | const r2p = r2.promisify(); 13 | const r22p = r22.promisify(); 14 | co(function * () { 15 | try { 16 | console.log(yield r2p.cmd('o')); 17 | console.log(yield r22p.cmd('o')); 18 | } catch (err) { 19 | console.error(err); 20 | } 21 | console.log('Should be done'); 22 | r22.quit(); 23 | r2.quit(); 24 | console.log('Should be done'); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /dotnet/DllExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using r2pipe; 3 | 4 | namespace DllExample 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | string osName = System.Environment.OSVersion.ToString().Split(' ')[0]; 11 | 12 | const string fileName = "r2pipe.dll"; 13 | 14 | using (IR2Pipe pipe = new DllR2Pipe()) 15 | { 16 | Console.WriteLine("Hello r2! " + pipe.RunCommand("?V")); 17 | 18 | pipe.RunCommand("o " + fileName); 19 | Console.WriteLine("Hello r2! " + pipe.RunCommand("pd 20")); 20 | /* no async support yet */ 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /php/poc.php: -------------------------------------------------------------------------------- 1 | array("pipe", "r"), // stdin 7 | 1 => array("pipe", "w"), // stdout 8 | 2 => array("pipe", "w") // stderr 9 | ); 10 | $proc = proc_open("radare2 -q0 /bin/ls", $descs, $pipes); 11 | if (is_resource($proc)) { 12 | $msg = fread($pipes[1], 1); 13 | } 14 | 15 | function r2cmd($cmd) { 16 | global $pipes; 17 | $rc = fwrite($pipes[0], "$cmd\n"); 18 | return trim(fread($pipes[1], 4096)); 19 | } 20 | 21 | function r2cmdj($cmd) { 22 | return json_decode (r2cmd ($cmd), true); 23 | } 24 | 25 | print_r(r2cmdj("ij")); 26 | print(r2cmd("?V")); 27 | print(r2cmd("pd 10")); 28 | 29 | $return_value = proc_close($proc); 30 | 31 | ?> 32 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/http/README.md: -------------------------------------------------------------------------------- 1 | Node.JS express based webserver 2 | =============================== 3 | 4 | Author : pancake 5 | 6 | Date: 2015-03-31 7 | 8 | Description 9 | ----------- 10 | 11 | This is the nodejs implementation of a websever 12 | for radare2. This script can be executed from 13 | inside r2 by using the following command: 14 | 15 | > #!pipe node . 16 | 17 | If you don't have any other .js handler (like duktape) 18 | you can run it directly like this: 19 | 20 | $ . index.js 21 | 22 | From the shell you can run the script like this: 23 | 24 | $ r2 -c '#!pipe node index.js' /bin/ls 25 | 26 | Or just run it from nodejs: 27 | 28 | $ node . 29 | 30 | Or specify a different file to open 31 | 32 | $ node . /bin/awk 33 | -------------------------------------------------------------------------------- /python/python-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # python wrapper trying to fix the python versioning hell 3 | # -- pancake 4 | 5 | PCS="${PYTHON_CONFIG} 6 | python3.12 7 | python3.11 8 | python3 9 | python39 10 | python3.9 11 | python-3.9 12 | python38 13 | python3.8 14 | python-3.8 15 | python37 16 | python3.7 17 | python-3.7 18 | python" 19 | PYCFG="" 20 | 21 | for a in ${PCS} ; do 22 | $a --help >/dev/null 2>&1 23 | if [ $? = 0 ]; then 24 | PYCFG="$a" 25 | PY3="`$a --version 2>&1 | grep 'Python 3'`" 26 | [ -n "${PY3}" ] && break 27 | fi 28 | done 29 | 30 | [ -z "${PYCFG}" ] && exit 1 31 | if [ "$1" = "-n" ]; then 32 | echo ${PYCFG} 33 | exit 0 34 | fi 35 | 36 | ${PYCFG} $@ | sed -e 's/-arch [^\s]*//g' | \ 37 | sed s,-Wstrict-prototypes,,g 2>/dev/null 38 | -------------------------------------------------------------------------------- /r2core-js/index.js: -------------------------------------------------------------------------------- 1 | /* pancake @ nopcode.org - 2017 */ 2 | const r2core = require("./r2core") 3 | 4 | // ffi 5 | const coreNew = r2core.cwrap('r2_asmjs_new', 'number', []); 6 | const coreFree = r2core.cwrap('r2_asmjs_free', 'void', ['number']); 7 | const coreCmd = r2core.cwrap('r2_asmjs_cmd', 'string', ['number', 'string']); 8 | const openurl = r2core.cwrap('r2_asmjs_openurl', 'void', ['number', 'string']); 9 | 10 | module.exports = function () { 11 | var r2i = coreNew(); 12 | return { 13 | open: function(url) { 14 | openurl(r2i, url); 15 | }, 16 | cmd: function(c) { 17 | return coreCmd(r2i, c); 18 | }, 19 | cmdj: function(c) { 20 | return JSON.parse(cmd(c)); 21 | }, 22 | free: function() { 23 | coreFree(r2i); 24 | r2i = 0; 25 | } 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /r2core-js/nodetest.js: -------------------------------------------------------------------------------- 1 | const r2 = require("./radare2") 2 | 3 | // ffi 4 | const coreNew = r2.cwrap('r2_asmjs_new', 'number', []); 5 | const coreFree = r2.cwrap('r2_asmjs_free', 'void', ['number']); 6 | const coreCmd = r2.cwrap('r2_asmjs_cmd', 'string', ['numnber', 'string']); 7 | const openurl = r2.cwrap('r2_asmjs_openurl', 'void', ['number', 'string']); 8 | 9 | function r2pipeAsmJS() { 10 | var r2i = coreNew(); 11 | return { 12 | cmd: function(c) { 13 | return coreCmd(r2i, c); 14 | }, 15 | free: function() { 16 | coreFree(r2i); 17 | r2i = 0; 18 | } 19 | }; 20 | } 21 | 22 | //r2.openurl("http://radare.org/r/index.html"); 23 | r2.cmd('o malloc://1024'); 24 | r2.cmd('w hello world'); 25 | console.log(r2.cmd('x 32')); 26 | console.log(r2.cmd('e asm.arch=?')); 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | name: r2pipe 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Install python 12 | run: sudo apt-get --assume-yes install python3-wheel python3-setuptools 13 | - name: Building Radare2 14 | run: git clone --depth=1 https://github.com/radareorg/radare2 r2 && r2/sys/install.sh /usr > /dev/null 15 | - name: Testing r2 16 | run: r2 -v; type r2 ; ls -l /usr/lib/libr_*.so 17 | - name: Testing r2pipe.py 18 | run: make -C python test 19 | - name: Testing r2pipe.ts 20 | run: | 21 | node --version 22 | tsc --version 23 | cd typescript 24 | mkdir node_modules && npm i 25 | make 26 | -------------------------------------------------------------------------------- /r2core-js/tuto/style.css: -------------------------------------------------------------------------------- 1 | .txt { 2 | background-color: #d0d0d0; 3 | padding:5px; 4 | border-radius: 5px; 5 | color:#202020; 6 | font-size: 0.8em; 7 | width: 80%; 8 | } 9 | 10 | .prompt { 11 | position: fixed; 12 | top: 0px; 13 | padding-top:5px; 14 | padding-left:10px; 15 | padding-bottom: 5px; 16 | left:0px; 17 | border:15px; 18 | width:100%; 19 | background-color: #303030; 20 | } 21 | .shell { 22 | margin-top: 7em; 23 | font-family: monospace !important; 24 | line-height: 90%; 25 | display: block !important; 26 | white-space: pre; 27 | background-color:black; 28 | color:white; 29 | } 30 | input { 31 | background-color:black; 32 | color:white; 33 | border: solid 1px gray; 34 | } 35 | body { 36 | font-family:Verdana; 37 | background-color:black; 38 | color:gray; 39 | } 40 | -------------------------------------------------------------------------------- /r2core-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2core", 3 | "version": "1.2.3", 4 | "description": "emscripten build of radare2 with an r2pipe api", 5 | "main": "index.js", 6 | "devDependencies": { 7 | "coffee-script": "^1.3.3", 8 | "closurecompiler": "^1.6.1", 9 | "uglify-js": "^2.4.24" 10 | }, 11 | "scripts": { 12 | "test": "node test.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/radareorg/radare2-r2pipe.git" 17 | }, 18 | "keywords": [ 19 | "radare2", 20 | "r2pipe", 21 | "emscripten" 22 | ], 23 | "author": "pancake ", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/radare2/radare2-r2pipe/issues" 27 | }, 28 | "homepage": "https://github.com/radare2/radare2-r2pipe#readme" 29 | } 30 | -------------------------------------------------------------------------------- /cxx-qt/r2pipe-api.cxx: -------------------------------------------------------------------------------- 1 | #include "r2pipe.h" 2 | #if HAVE_R2_API 3 | 4 | R2PipeAPI::R2PipeAPI(QString filepath) { 5 | this->core = r_core_new (); 6 | if (filepath != NULL) { 7 | this->cmd(QString("\"o %1\"").arg(filepath)); 8 | } 9 | } 10 | 11 | QString R2PipeAPI::cmd(const QString str) { 12 | std::string tmpstr = str.toStdString(); 13 | const char* cmd = tmpstr.c_str(); 14 | char *res = r_core_cmd_str (this->core, cmd); 15 | QString o = (res && *res)? QString::fromUtf8(res): QString(); 16 | free (res); 17 | return o; 18 | } 19 | 20 | /* Can be implemented in R2Pipe API */ 21 | QJsonObject R2PipeAPI::cmdj(QString x) { 22 | QString r = cmd(x); 23 | QJsonDocument d = QJsonDocument::fromJson(r.toUtf8()); 24 | return d.object(); 25 | } 26 | 27 | void R2PipeAPI::close() { 28 | r_core_free (this->core); 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /vim/README.md: -------------------------------------------------------------------------------- 1 | # r2pipe.vim 2 | 3 | This vim plugin allows you to run r2 commands into the current Vim buffer 4 | 5 | ## Installation 6 | 7 | Just type `make`. If you want to get rid of that run: `make uninstall` 8 | 9 | Note that the same code works with neovim. But it's not yet installed. Contribs are welcome 10 | 11 | ## How to use 12 | 13 | In one terminal start the r2 webserver 14 | 15 | In vim open 16 | 17 | ## Future 18 | 19 | Right now this is just a PoC, but there are a lot of things to be done to improve the integration between r2 and vim 20 | 21 | * [ ] Use r2p instead of `curl` (one less dependency, and support socket files, pipes..) 22 | * [ ] Make interactive buffers and use the right syntax highlighting for disasm, hexa, .. 23 | * [ ] Setup split layouts to navigate function list, disasm, etc 24 | * [ ] Improve apis 25 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/test-timeout.js: -------------------------------------------------------------------------------- 1 | const r2promise = require('./'); 2 | 3 | function testTimeout (ns, cb) { 4 | console.log('Testing for ' + ns); 5 | r2promise.open('-') 6 | .then(waitAndRun) 7 | .catch(cb); 8 | 9 | function waitAndRun (r2) { 10 | r2.cmd('!sleep 1') 11 | .timeout(ns) 12 | .then(res => { 13 | r2.quit() 14 | .then(_ => { cb(null, _); }) 15 | .catch(cb); 16 | }) 17 | .catch(err => { 18 | r2.quit(); 19 | cb(err); 20 | }); 21 | } 22 | } 23 | 24 | // XXX if we run the 200ms test first the second call will fail 25 | testTimeout(2000, err => { 26 | console.log('error must be null', err); 27 | console.log('2s will fail', err ? 'FAIL' : 'OK'); 28 | }); 29 | 30 | testTimeout(200, err => { 31 | console.log('error wins', err); 32 | console.log('200ms will fail', err ? 'OK' : 'FAIL'); 33 | }); 34 | -------------------------------------------------------------------------------- /r2core-js/Makefile: -------------------------------------------------------------------------------- 1 | FILES= Makefile README.md package.json index.js r2core.js test.js webtest.html 2 | 3 | all: r2core.js 4 | 5 | r2core.js: radare2.closure.ugly.js 6 | cp -f radare2.closure.ugly.js r2core.js 7 | 8 | radare2.closure.ugly.js: radare2.closure.js 9 | node --max-old-space-size=4096 node_modules/.bin/uglifyjs \ 10 | < radare2.closure.js > radare2.closure.ugly.js || rm -f radare2.closure.ugly.js 11 | 12 | radare2.closure.js: 13 | # we need at least 2GB of heap 14 | node_modules/.bin/ccjs radare2.js --xmx=4096m > radare2.closure.js 15 | 16 | clean: 17 | rm -f r2core.js 18 | rm -f radare2.closure.js 19 | rm -f radare2.closure.ugly.js 20 | 21 | pub: 22 | mkdir r2core 23 | cp $(FILES) r2core 24 | cd r2core ; npm publish 25 | rm -rf r2core 26 | 27 | dist: 28 | mkdir r2core 29 | cp $(FILES) r2core 30 | tar czvf r2core.tar.gz r2core 31 | rm -rf r2core 32 | -------------------------------------------------------------------------------- /dotnet/r2pipe/IR2Pipe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace r2pipe 8 | { 9 | public interface IR2Pipe : IDisposable 10 | { 11 | 12 | /// 13 | /// Executes given RunCommand in radare2 14 | /// 15 | /// The command to execute. 16 | /// Returns a string 17 | string RunCommand(string command); 18 | 19 | #if !OLDNETFX 20 | /// 21 | /// Executes given RunCommand in radare2 asynchronously 22 | /// 23 | /// The command to execute. 24 | /// 25 | /// Returns a string 26 | /// 27 | Task RunCommandAsync(string command); 28 | #endif 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /vala/Makefile: -------------------------------------------------------------------------------- 1 | include ../../config.mk 2 | 3 | all: 4 | valac -g -X -O3 main.vala r2pipe.vala 5 | valac -g -X -O3 --library=r2pipe -H r2pipe.h r2pipe.vala -X -fPIC -c 6 | rm -f libr2pipe.a 7 | ar q libr2pipe.a r2pipe.vala.o 8 | 9 | install: 10 | mkdir -p $(DESTDIR)/${PREFIX}/lib/pkgconfig 11 | cp -f r2pipe.pc $(DESTDIR)/${PREFIX}/lib/pkgconfig/r2pipe.pc 12 | mkdir -p $(DESTDIR)/${PREFIX}/share/vala/vapi 13 | cp -f r2pipe.vapi $(DESTDIR)/${PREFIX}/share/vala/vapi/r2pipe.vapi 14 | mkdir -p $(DESTDIR)/${PREFIX}/include/r2pipe 15 | cp -f r2pipe.h $(DESTDIR)/${PREFIX}/include/r2pipe/r2pipe.h 16 | mkdir -p $(DESTDIR)/${PREFIX}/lib 17 | cp -f libr2pipe.a $(DESTDIR)/${PREFIX}/lib/libr2pipe.a 18 | 19 | uninstall: 20 | rm -f $(DESTDIR)/${PREFIX}/lib/pkgconfig/r2pipe.pc 21 | rm -f $(DESTDIR)/${PREFIX}/share/vala/vapi/r2pipe.vapi 22 | rm -rf $(DESTDIR)/${PREFIX}/include/r2pipe 23 | rm -f $(DESTDIR)/${PREFIX}/lib/libr2pipe.a 24 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/r2co.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const co = require('co'); 4 | const r2pipe = require('r2pipe'); 5 | 6 | const r2launch = co.wrap(function * (fn) { 7 | return new Promise(function (resolve) { 8 | r2pipe.launch(fn, function (r2) { 9 | r2.__cmd = r2.cmd; 10 | r2.cmd = co.wrap(function * (cmd) { 11 | return new Promise(function (resolve) { 12 | r2.__cmd(cmd, resolve); 13 | }); 14 | }); 15 | resolve(r2); 16 | }); 17 | }); 18 | }); 19 | 20 | const identifyTarget = co.wrap(function * (bin) { 21 | return new Promise(function (resolve) { 22 | co(function * () { 23 | const r2 = yield r2launch(bin); 24 | console.log('->', yield r2.cmd('?V')); 25 | resolve(r2); 26 | }); 27 | }); 28 | }); 29 | 30 | co(function * () { 31 | let r = yield identifyTarget('/bin/ls'); 32 | console.log(yield r.cmd('pd 3')); 33 | r.quit(); 34 | }); 35 | -------------------------------------------------------------------------------- /python/examples/bug.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import r2pipe 3 | 4 | err = 0 5 | 6 | 7 | def test(msg, a, b): 8 | global err 9 | sys.stdout.write("%s " % (msg)) 10 | a = a.strip() 11 | b = b.strip() 12 | if a == b: 13 | print("ok") 14 | else: 15 | err = err + 1 16 | print("FAIL") 17 | 18 | 19 | def verify(title, cmd, expected): 20 | r2 = r2pipe.open("-") 21 | msg = r2.cmd(cmd) 22 | test(title, msg, expected) 23 | r2.quit() 24 | 25 | 26 | verify("Test #1", "?e hello", "hello") 27 | verify("Test #2", "?e hello\n", "hello") 28 | verify("Test #3", "?e hello\n?e world", "hello\nworld") 29 | verify("Test #4", "?e hello;?e world", "hello\nworld") 30 | verify("Test #5", "?e hello\n", "hello") 31 | verify("Test #6", "?e hello\n\n;\n\n?e world", "hello\nworld") # known to fail 32 | verify("Test #7", "?e hello\n", "hello") 33 | verify("Test #8", "?e hello;;;;;?e world", "hello\nworld") 34 | 35 | sys.exit(err) 36 | -------------------------------------------------------------------------------- /python/test/test_unit.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os 3 | 4 | import r2pipe 5 | from r2pipe.native import * 6 | import ctypes 7 | 8 | 9 | class TestR2PipeUnit(unittest.TestCase): 10 | 11 | @classmethod 12 | def setUpClass(cls): 13 | cls.curdir = os.path.dirname(os.path.realpath(__file__)) 14 | 15 | def test_version(self): 16 | self.assertEqual(r2pipe.version(), r2pipe.VERSION) 17 | 18 | def test_native_r2lib(self): 19 | lib = r2lib() 20 | if sys.platform.startswith("win"): 21 | self.assertIsInstance(lib, ctypes.WinDLL) 22 | else: 23 | self.assertIsInstance(lib, ctypes.CDLL) 24 | 25 | def test_race_io(self): 26 | os.system("sh race.sh"); 27 | 28 | def test_native_rcore(self): 29 | c = RCore() 30 | value = c.cmd_str("o %s/ls; s entry0;pi 1 @e:scr.color=0" % self.curdir).strip() 31 | c.free() 32 | self.assertEqual(value, 'push rbp') 33 | -------------------------------------------------------------------------------- /websocket/ws.py: -------------------------------------------------------------------------------- 1 | import signal, sys 2 | from SimpleWebSocketServer import WebSocket, SimpleWebSocketServer 3 | import r2pipe 4 | 5 | 6 | PORTNUM = 5678 7 | 8 | # Websocket class to echo received data 9 | class Echo(WebSocket): 10 | 11 | def handleMessage(self): 12 | res = self.r2.cmd(self.data) 13 | print("Run '%s'" % self.data) 14 | self.sendMessage(res) 15 | 16 | def handleConnected(self): 17 | self.r2 = r2pipe.open("--") 18 | print("Connected") 19 | 20 | def handleClose(self): 21 | self.r2.quit() 22 | self.r2 = None 23 | print("Disconnected") 24 | 25 | # Handle ctrl-C: close server 26 | def close_server(signal, frame): 27 | server.close() 28 | sys.exit() 29 | 30 | if __name__ == "__main__": 31 | print("Websocket server on port %s" % PORTNUM) 32 | server = SimpleWebSocketServer('', PORTNUM, Echo) 33 | signal.signal(signal.SIGINT, close_server) 34 | server.serveforever() 35 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/load-tcp.js: -------------------------------------------------------------------------------- 1 | /* pancake - 2016 - radare project */ 2 | 3 | const r2pipe = require('..'); 4 | const fs = require('fs'); 5 | 6 | const buf = fs.readFileSync('/bin/ls'); 7 | 8 | r2pipe.openBuffer(buf, (err, r2) => { 9 | if (err) { 10 | throw err; 11 | } 12 | r2.cmd('pd 20', (err, res) => { 13 | if (err) { 14 | throw err; 15 | } 16 | console.log(res); 17 | r2.quit(); 18 | }); 19 | }); 20 | 21 | /* 22 | 23 | PoC 24 | 25 | const net = require('net'); 26 | 27 | const server = net.createServer(client => { 28 | client.write(buf, null, _ => { 29 | client.destroy(); 30 | server.close(); 31 | }); 32 | }); 33 | 34 | server.listen(0, _ => { 35 | const port = server.address().port; 36 | r2pipe.open('tcp://127.0.0.1:' + port, (err, r2) => { 37 | if (err) { 38 | throw err; 39 | } 40 | r2.cmd('pd 20', (err, res) => { 41 | console.log(res); 42 | r2.quit(); 43 | }); 44 | }); 45 | }); 46 | */ 47 | -------------------------------------------------------------------------------- /prolog/r2pipe.pl: -------------------------------------------------------------------------------- 1 | % -*- Mode: Prolog -*- 2 | :- module(r2pipe, []). 3 | :- use_module(library(unix)). 4 | :- use_module(library(process)). 5 | :- use_module(library(http/json)). 6 | 7 | read_result(Out, Json) :- 8 | read_string(Out, "", "", _, String), 9 | atom_json_dict(String, Json, []). 10 | 11 | send_command(R, Command, Json) :- 12 | write(R.in, Command), 13 | nl(R.in), 14 | flush_output(R.in), 15 | read_result(R.out, Json). 16 | 17 | % create structure with pid and in/out pipes 18 | open_file(File, R) :- 19 | process_create(path(radare2), 20 | % r2 -2 -q0 file 21 | ["-2", "-q0", file(File)], 22 | [stdin(pipe(In)), 23 | stdout(pipe(Out)), 24 | process(Pid)]), 25 | dict_create(R, r2instance, [pid:Pid,in:In,out:Out]). 26 | 27 | % TODO: Make more graceful exit 28 | close_instance(R) :- 29 | close(R.in), 30 | close(R.out), 31 | process_kill(R.pid). 32 | 33 | with_command(File, Command, O) :- 34 | open_file(File, R), 35 | send_command(R, Command, O), 36 | close_instance(R). 37 | 38 | -------------------------------------------------------------------------------- /go/r2pipe_test.go: -------------------------------------------------------------------------------- 1 | // radare - LGPL - Copyright 2015 - nibble 2 | 3 | package r2pipe 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | ) 9 | 10 | type Offset struct { 11 | Offset uint 12 | Current bool 13 | } 14 | 15 | func TestCmd(t *testing.T) { 16 | fmt.Println("[*] Testing r2 spawn pipe") 17 | r2p, err := NewPipe("malloc://256") 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | defer r2p.Close() 22 | 23 | check := "Hello World" 24 | 25 | _, err = r2p.Cmd("w " + check) 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | buf, err := r2p.Cmd("ps") 30 | if err != nil { 31 | t.Fatal(err) 32 | } 33 | if buf != check { 34 | t.Errorf("buf=%v; want=%v", buf, check) 35 | } 36 | 37 | offset := Offset{} 38 | r2p.CmdjStruct("sj ~{0}", &offset) 39 | 40 | if !offset.Current { 41 | t.Errorf("CurrentOffset=%v; want=%v", offset.Current, true) 42 | } 43 | 44 | r2p.CmdjfStruct("sj ~{%d}", &offset, 0) 45 | if !offset.Current { 46 | t.Errorf("CurrentOffset=%v; want=%v", offset.Current, true) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /websocket/r2ws.js: -------------------------------------------------------------------------------- 1 | var queue = []; 2 | 3 | var ws = null; 4 | var r2ws = {}; 5 | 6 | r2ws.quit = function r2ws_quit (cb) { 7 | ws.close(); 8 | return cb(); 9 | }; 10 | 11 | r2ws.cmd = function r2ws_cmd (cmd, cb) { 12 | if (ws === null) { 13 | console.error('not connected'); 14 | return; 15 | } 16 | queue.push(cb); 17 | ws.send(cmd); 18 | }; 19 | 20 | r2ws.open = function r2ws_open (addr, file, cb) { 21 | ws = new WebSocket(addr); 22 | ws.onmessage = function (event) { 23 | if (queue.length === 0) { 24 | return; 25 | } 26 | first = queue[0]; 27 | queue = queue.slice(1); 28 | if (first) { 29 | first(event.data); 30 | } 31 | }; 32 | ws.onopen = function (event) { 33 | r2ws.cmd('o ' + file); 34 | if (cb) { 35 | cb(null, r2ws); 36 | } 37 | }; 38 | return { 39 | ws: ws, 40 | cmd: r2ws.cmd, 41 | quit: r2ws.quit 42 | }; 43 | }; 44 | 45 | r2ws.open('ws://127.0.0.1:5678', '/bin/ls', function (err, r2) { 46 | r2.cmd('x', console.log); 47 | }); 48 | -------------------------------------------------------------------------------- /erlang/src/r2pipe.erl: -------------------------------------------------------------------------------- 1 | -module(r2pipe). 2 | 3 | -author(dark_k3y). 4 | 5 | -ifdef(TEST). 6 | -include_lib("eunit/include/eunit.hrl"). 7 | -endif. 8 | 9 | -export([init/1, init/2, init/3, cmd/2, cmdj/2, quit/0]). 10 | 11 | init(pipe, File) -> 12 | init(pipe, File, "radare2"). 13 | 14 | init(pipe, File, R2Bin) -> 15 | Path = R2Bin ++ " -q0 " ++ File, 16 | r2pipe_handler:start(Path), 17 | {pipe, r2pipe_handler}. 18 | 19 | init(lpipe) -> 20 | r2pipe_handler:start(lpipe), 21 | timer:sleep(50), %% ugly sleep to let i/o initialize 22 | {pipe, r2pipe_handler}. 23 | 24 | cmd({pipe, _}, Cmd) -> 25 | {ok, Data} = r2pipe_handler:call(prepare_cmd(Cmd)), 26 | binary_to_list(Data). 27 | 28 | cmdj({pipe, _}, Cmd) -> 29 | {ok, Data} = r2pipe_handler:call(prepare_cmd(Cmd)), 30 | parse_json(Data). 31 | 32 | quit() -> 33 | r2pipe_handler:stop(). 34 | 35 | prepare_cmd(Cmd) -> 36 | Cmd ++ [10]. 37 | 38 | parse_json(Res) when is_binary(Res) -> 39 | Size = (byte_size(Res) - 2 ) * 8, 40 | <> = Res, 41 | jsx:decode(<>). 42 | -------------------------------------------------------------------------------- /typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-ts", 3 | "version": "0.2.0", 4 | "description": "TypeScript r2pipe API", 5 | "type": "commonjs", 6 | "main": "./dist/index.js", 7 | "types": "./dist/index.d.js", 8 | "license": "MIT", 9 | "engines": { 10 | "node": ">=18.0" 11 | }, 12 | "scripts": { 13 | "build": "tsc" 14 | }, 15 | "devDependencies": { 16 | "@types/node": "^20.11.28", 17 | "@typescript-eslint/eslint-plugin": "^7.2.0", 18 | "@typescript-eslint/parser": "^7.2.0", 19 | "eslint": "^8.34.0", 20 | "typescript": "^5.0.0" 21 | }, 22 | "files": [ 23 | "README.md", 24 | "package.json", 25 | "package-lock.json", 26 | "dist/base.js", 27 | "dist/index.js", 28 | "dist/http.js", 29 | "dist/queue.js", 30 | "dist/local.js", 31 | "dist/spawn.js" 32 | ], 33 | "keywords": [ 34 | "radare", 35 | "radare2", 36 | "r2", 37 | "reversing", 38 | "disassembler", 39 | "hexadecimal", 40 | "editor", 41 | "exploit", 42 | "exploiting" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /typescript/test-http.ts: -------------------------------------------------------------------------------- 1 | // tsc test-http.ts 2 | // node --insecure-http-parser test-http.js 3 | 4 | import * as r2pipe from "./dist/index.js"; 5 | import { R2PipeCmdInterface } from "./dist/base.js"; 6 | // import * as r2pipe from "r2pipe-ts"; 7 | 8 | const R2_SERVER_URL = process.env.R2_SERVER_URL || "http://127.0.0.1:9090"; 9 | 10 | async function main(): Promise { 11 | console.log("Hello R2Pipe for TypeScript"); 12 | let r2: R2PipeCmdInterface | null = null; 13 | 14 | try { 15 | r2 = await r2pipe.open(R2_SERVER_URL); 16 | const res: string = await r2.cmd("?E Hello TypeScript"); 17 | console.log(res); 18 | return "Done"; 19 | } catch (error) { 20 | if (error instanceof Error) { 21 | console.error(`Error connecting to radare2 server at ${R2_SERVER_URL}:`, error.message); 22 | } else { 23 | console.error("Unknown error occurred:", error); 24 | } 25 | throw error; 26 | } finally { 27 | if (r2) { 28 | await r2.quit(); 29 | } 30 | } 31 | } 32 | 33 | main().catch(console.error); 34 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/node/cloud.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var r2p = require('../..'); 4 | var ts = require('..'); 5 | 6 | function testCloud (fin) { 7 | try { 8 | r2p.connect('http://cloud.radare.org/cmd/', (err, r2) => { 9 | if (err) throw err; 10 | r2.cmd('?e hello world', function (err, res) { 11 | if (err) throw err; 12 | fin(res); 13 | r2.quit(); 14 | }); 15 | }); 16 | } catch (e) { 17 | fin(e.toString()); 18 | } 19 | } 20 | 21 | function testCloudOK (fin) { 22 | try { 23 | r2p.connect('http://cloud.rada.re/cmd/', function (err, r2) { 24 | if (err) throw err; 25 | r2.cmd('?e hello world', function (err, res) { 26 | if (err) throw err; 27 | fin(res); 28 | r2.quit(); 29 | }); 30 | }); 31 | } catch (e) { 32 | fin(e.toString()); 33 | } 34 | } 35 | 36 | ts.addTest('testCloud', testCloud, 'hello world\n', { 37 | broken: true 38 | }); 39 | ts.addTest('testCloudOK', testCloudOK, 'hello world\n'); 40 | 41 | // ts.inSerial(); 42 | ts.inParalel(); 43 | -------------------------------------------------------------------------------- /rust/README.md: -------------------------------------------------------------------------------- 1 | r2pipe.rs 2 | ========= 3 | 4 | | **TravisCI** | [![Build Status](https://travis-ci.org/radare/r2pipe.rs.svg?branch=master)](https://travis-ci.org/radare/r2pipe.rs)| 5 | 6 | The Rust Crate to interact with radare2. 7 | Please check [Documentation](https://radare.github.io/r2pipe.rs) to get 8 | started. 9 | 10 | 11 | TODO 12 | ---- 13 | * Support async API 14 | * Support HTTP connectivity 15 | * Add custom r2 start flags for spawn method 16 | * Add plain TCP api 17 | * Better error handling 18 | 19 | ## License 20 | 21 | Licensed under either of 22 | 23 | * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 24 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) 25 | 26 | at your option. 27 | 28 | ### Contribution 29 | 30 | Unless you explicitly state otherwise, any contribution intentionally submitted 31 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. 32 | -------------------------------------------------------------------------------- /dotnet/HttpExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using r2pipe; 7 | 8 | namespace HttpExample 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | using(IR2Pipe pipe = new HttpR2Pipe("http://cloud.rada.re/cmd/")) 15 | { 16 | Console.WriteLine(pipe.RunCommand("p8 32")); 17 | 18 | // you can use the queue here too: 19 | QueuedR2Pipe qr2 = new QueuedR2Pipe(pipe); 20 | 21 | qr2.Enqueue(new R2Command("?V", (string result) => { 22 | Console.WriteLine("Version: {0}", result); 23 | })); 24 | 25 | qr2.Enqueue(new R2Command("pdf @ entry0", (string result) => 26 | { 27 | Console.WriteLine("Entrypoint: \n{0}", result); 28 | })); 29 | 30 | qr2.ExecuteCommands(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /clojure/src/r2pipe/spawn.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe.spawn 2 | (:require [r2pipe.proto :as r2p] 3 | 4 | [me.raynes.conch.low-level :as sh])) 5 | 6 | (def cmd-delim (char 0)) 7 | 8 | (deftype R2Spawn [proc] 9 | r2p/R2Proto 10 | (r2-read [this] 11 | "Read from the r2 process" 12 | (apply str 13 | (take-while 14 | (fn [c] (not (= c (str cmd-delim)))) 15 | (repeatedly 16 | #(-> proc :out .read char str))))) 17 | 18 | (r2-write [this input] 19 | "Write to the r2 process" 20 | (.write (:in proc) (.getBytes (str input "\n"))) 21 | (.flush (:in proc))) 22 | 23 | (close [this] 24 | "Close r2 process" 25 | (-> proc :process .destroy) 26 | (:process proc))) 27 | 28 | (defn r2open 29 | "Opens a file in r2 and starts a process instance" 30 | [filename r2-path] 31 | (let [proc (sh/proc r2-path 32 | "-q0" "-e" "scr.utf8=false" 33 | (str filename)) 34 | p (R2Spawn. proc)] 35 | (.r2-read p) ;; first prompt must go 36 | p)) 37 | -------------------------------------------------------------------------------- /dart/r2pipe-r2js.dart: -------------------------------------------------------------------------------- 1 | library r2pipe.js; 2 | 3 | import 'dart:convert'; 4 | import 'dart:js' as js; 5 | 6 | String r2cmd(String cmd) { 7 | return js.context.callMethod ("r2cmd", [cmd]); 8 | } 9 | dynamic r2cmdj(String cmd) { 10 | return jsonDecode(r2cmd(cmd)); 11 | } 12 | void main() { 13 | print("Hello Radare2" + r2cmd("pd 10")); 14 | print("FileName: " + r2cmdj("ij")["core"]["file"]); 15 | } 16 | 17 | /* 18 | import 'package:js/js.dart'; 19 | // import 'dart:js' as js; 20 | 21 | // external JsAny r2; // 22 | @JS('r2cmd') 23 | external String r2cmd(String input); 24 | 25 | @JS('r2') 26 | abstract class r2 { 27 | external static String cmd(String); 28 | external static Object cmdj(String); 29 | } 30 | 31 | void main() { 32 | // final js.JsFunction r2cmd = js.context['r2cmd']; 33 | print("Hello Radare2" + r2.cmd("x")); 34 | // print("Hello Radare2" + r2cmd("x")); 35 | // print("Hello Radare2" + js.context.callMethod("r2cmd", ["x"])); 36 | // print("Hello Radare2" + js.context.callMethod(r2cmd, ["x"])); // r2cmd("x")); // js.context.callMethod('r2.cmd', ["x"])); 37 | } 38 | */ 39 | -------------------------------------------------------------------------------- /r2core-js/tuto/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | r2core.js shell 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 26 | > 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 |
37 | 38 |
39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /cxx-qt/r2pipe.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define HAVE_R2_API 1 6 | 7 | /* interface must be R2Pipe */ 8 | 9 | class R2Pipe { 10 | private: 11 | QObject *parent; 12 | QProcess *proc; 13 | int r2p_fd[2]; 14 | 15 | QString Read() { 16 | QString r = QString(); 17 | char ch; 18 | if (r2p_fd[0] == -1) { 19 | return NULL; 20 | } 21 | while (read (r2p_fd[0], &ch, 1) == 1) { 22 | if (ch == 0) break; 23 | r += ch; 24 | } 25 | return r; 26 | } 27 | 28 | bool Write(QString cmd) { 29 | const char *str = (const char *)cmd.toLatin1(); 30 | const int len = strlen (str); 31 | return write (r2p_fd[1], str, len + 1) != -1; 32 | } 33 | public: 34 | R2Pipe(QString filepath = NULL); 35 | QString cmd(QString x); 36 | QJsonObject cmdj(QString x); 37 | void close(); 38 | }; 39 | 40 | #if HAVE_R2_API 41 | #include 42 | 43 | class R2PipeAPI { 44 | private: 45 | void *core; 46 | public: 47 | R2PipeAPI(QString filepath = NULL); 48 | QString cmd(QString x); 49 | QJsonObject cmdj(QString x); 50 | void close(); 51 | }; 52 | #endif 53 | -------------------------------------------------------------------------------- /shell/r2cmd.c: -------------------------------------------------------------------------------- 1 | /* Simple r2pipe implementation in C for writing r2pipe shellscripts */ 2 | /* Copyleft -- pancake 2019 */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | static void r2cmd(int in, int out, const char *cmd) { 10 | write (out, cmd, strlen (cmd) + 1); 11 | write (out, "\n", 1); 12 | int n; 13 | int bufsz = (1024 * 1024 * 2); 14 | unsigned char *buf = malloc (bufsz); 15 | if (!buf) { 16 | return; 17 | } 18 | while (1) { 19 | int n = read (in, buf, bufsz); 20 | int len = strlen ((const char *)buf); 21 | n = len; 22 | if (n < 1) { 23 | break; 24 | } 25 | write (1, buf, n); 26 | if (n != sizeof (buf)) { 27 | break; 28 | } 29 | } 30 | free (buf); 31 | write(1, "\n", 1); 32 | } 33 | 34 | int main(int argc, char **argv) { 35 | int i; 36 | char *_in = getenv ("R2PIPE_IN"); 37 | char *_out = getenv ("R2PIPE_OUT"); 38 | if (!_in || !_out) { 39 | return 1; 40 | } 41 | int in = atoi (_in); 42 | int out = atoi (_out); 43 | for (i = 1; i < argc; i++) { 44 | r2cmd (in, out, argv[i]); 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /nodejs/r2pipe-promise/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-promise", 3 | "version": "1.6.4", 4 | "description": "promisified r2pipe api", 5 | "types": "r2pipe-promise.d.ts", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "semistandard", 9 | "fix": "semistandard --fix" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/radareorg/radare2-r2pipe.git" 14 | }, 15 | "files": [ 16 | "index.js", 17 | "r2pipe-promise.d.ts" 18 | ], 19 | "keywords": [ 20 | "radare", 21 | "radare2", 22 | "r2", 23 | "r2pipe", 24 | "reversing", 25 | "disassembler", 26 | "hexadecimal", 27 | "editor", 28 | "exploit", 29 | "exploiting" 30 | ], 31 | "author": { 32 | "name": "pancake", 33 | "email": "pancake@nopcode.org" 34 | }, 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/radareorg/radare2-r2pipe/issues" 38 | }, 39 | "homepage": "http://www.radare.org", 40 | "devDependencies": { 41 | "semistandard": "^17.0.0" 42 | }, 43 | "dependencies": { 44 | "r2pipe": "^2.8.5" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | schedule: 9 | - cron: "35 1 * * 6" 10 | 11 | jobs: 12 | analyze: 13 | name: Analyze 14 | runs-on: ubuntu-latest 15 | permissions: 16 | actions: read 17 | contents: read 18 | security-events: write 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | language: [ javascript, python ] 24 | 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v3 28 | 29 | - name: Initialize CodeQL 30 | uses: github/codeql-action/init@v2 31 | with: 32 | languages: ${{ matrix.language }} 33 | queries: +security-and-quality 34 | 35 | - name: Autobuild 36 | uses: github/codeql-action/autobuild@v2 37 | if: ${{ matrix.language == 'javascript' || matrix.language == 'python' }} 38 | 39 | - name: Perform CodeQL Analysis 40 | uses: github/codeql-action/analyze@v2 41 | with: 42 | category: "/language:${{ matrix.language }}" 43 | -------------------------------------------------------------------------------- /java/src/main/java/org/radare/r2pipe/R2PipeJNI.java: -------------------------------------------------------------------------------- 1 | package org.radare.r2pipe; 2 | 3 | import java.io.*; 4 | import java.net.*; 5 | 6 | public class R2PipeJNI { 7 | static { 8 | try { 9 | System.loadLibrary("r2pipe-jni"); 10 | } catch (UnsatisfiedLinkError e) { 11 | /* do nothing here */ 12 | } 13 | } 14 | 15 | private static native long r2pipeNew(); 16 | private static native String r2pipeCmd(long core, String cmd); 17 | private static native void r2pipeFree(long core); 18 | 19 | private long core = 0; 20 | 21 | public R2PipeJNI() throws Exception { 22 | this.core = r2pipeNew(); 23 | if (this.core == 0) { 24 | throw new Exception("Cannot initialize r2pipe-jni"); 25 | } 26 | } 27 | 28 | public R2PipeJNI(String file) throws Exception { 29 | this(); 30 | this.cmd("o " + file); 31 | } 32 | 33 | public String cmd(String str) throws Exception { 34 | return r2pipeCmd(this.core, str); 35 | } 36 | 37 | /* 38 | protected void finalize() throws Throwable { 39 | quit(); 40 | } 41 | */ 42 | 43 | public void quit() throws Exception { 44 | r2pipeFree(this.core); 45 | this.core = 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /java/jni/Makefile: -------------------------------------------------------------------------------- 1 | EXT_SO=$(shell r2 -H R2_LIBEXT) 2 | OUT=libr2pipe-jni.$(EXT_SO) 3 | JVH=org_radare_r2pipe_R2PipeJNI.h 4 | 5 | JAVA_HOME?=$(shell /usr/libexec/java_home) 6 | ifeq ($(JAVA_HOME),) 7 | JAVA_HOME ?= $(shell dirname $(shell dirname $(shell readlink -f $(shell which javac)))) 8 | endif 9 | JNI_INCLUDE = -I$(JAVA_HOME)/include 10 | ifeq ($(shell uname),Darwin) 11 | JNI_INCLUDE+= -I$(JAVA_HOME)/include/darwin 12 | else 13 | JNI_INCLUDE+= -I$(JAVA_HOME)/include/linux 14 | endif 15 | 16 | JNIFLAGS+=$(JNI_INCLUDE) 17 | # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/JavaVM.framework/Headers/ 18 | # JNIFLAGS+=-I /System/Library/Frameworks/JavaVM.framework/Headers/ 19 | 20 | all: $(JVH) 21 | $(CC) -o $(OUT) -dynamiclib -fPIC $(JNIFLAGS) r2pipe-jni.c 22 | # -framework JavaVM 23 | 24 | $(JVH): ../src/main/java/org/radare/r2pipe/R2PipeJNI.class 25 | javac -h . -d . ../src/main/java/org/radare/r2pipe/R2PipeJNI.java 26 | #javac -h . org.radare.r2pipe.R2PipeJNI 27 | # javah -cp ../r2pipe.jar -d . org.radare.r2pipe.R2PipeJNI 28 | 29 | clean: 30 | rm -f $(JVH) $(OUT) 31 | -------------------------------------------------------------------------------- /cxx-qt/r2pipe.cxx: -------------------------------------------------------------------------------- 1 | #include "r2pipe.h" 2 | 3 | R2Pipe::R2Pipe(QString filepath) { 4 | parent = NULL; 5 | r2p_fd[0] = r2p_fd[1] = -1; 6 | if (filepath.isEmpty()) { 7 | QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 8 | proc = NULL; 9 | QString r2p_in = env.value("R2PIPE_IN"); 10 | QString r2p_out = env.value("R2PIPE_OUT"); 11 | if (r2p_in.isEmpty() || r2p_out.isEmpty()) { 12 | throw QString("Cannot find R2PIPE_IN or R2PIPE_OUT environment"); 13 | } 14 | r2p_fd[0] = r2p_in.toInt(); 15 | r2p_fd[1] = r2p_out.toInt(); 16 | // Check R2PIPE_IN and R2PIPE_OUT env vars 17 | } else { 18 | proc = new QProcess(parent); 19 | QStringList args; 20 | args << "-q0" << filepath; 21 | proc->start("/usr/bin/r2", args); 22 | // TODO: support spawn method 23 | } 24 | } 25 | 26 | QString R2Pipe::cmd(QString x) { 27 | Write (x + "\n"); 28 | return Read(); 29 | } 30 | 31 | QJsonObject R2Pipe::cmdj(QString x) { 32 | QString r = cmd(x); 33 | QJsonDocument d = QJsonDocument::fromJson(r.toUtf8()); 34 | return d.object(); 35 | } 36 | 37 | void R2Pipe::close() { 38 | if (proc != NULL) { 39 | proc->terminate(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /go/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 radare 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | 24 | -------------------------------------------------------------------------------- /haskell/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 radareorg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /python/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 pancake 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /dotnet/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 radare project 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('colors'); 4 | 5 | var stack = []; 6 | function queue (cb) { 7 | stack.push(cb); 8 | } 9 | 10 | function next () { 11 | if (stack.length > 0) { 12 | var cb = stack.pop(); 13 | try { 14 | cb(); 15 | } catch (e) { 16 | console.error(e); 17 | } 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | module.exports.inSerial = function () { 24 | next(); 25 | }; 26 | 27 | module.exports.inParalel = function () { 28 | while (next()); 29 | }; 30 | 31 | module.exports.addTest = function (n, a, b, opt) { 32 | queue(() => { 33 | let msg = ' node '.yellow + n; 34 | process.stdout.write('[ ]' + msg); 35 | a((c) => { 36 | process.stdout.write('\x1b[2K'); 37 | if (c === b) { 38 | console.log('\r[OK]'.green + msg); 39 | } else { 40 | if (opt && opt.broken) { 41 | console.log('\r[BR]'.blue + msg); 42 | } else { 43 | console.log('\r[XX]'.red + msg); 44 | } 45 | console.log('((' + c + '))'); 46 | } 47 | next(); 48 | }); 49 | }); 50 | return module.exports; 51 | }; 52 | -------------------------------------------------------------------------------- /go/api.go: -------------------------------------------------------------------------------- 1 | // radare - LGPL - Copyright 2021 - pancake 2 | 3 | package r2pipe 4 | 5 | // #cgo CFLAGS: -I/usr/local/include/libr 6 | // #cgo CFLAGS: -I/usr/local/include/libr/sdb 7 | // #cgo LDFLAGS: -L/usr/local/lib -lr_core 8 | // #include 9 | // #include 10 | // extern void r_core_free(void *); 11 | // extern void *r_core_new(void); 12 | // extern char *r_core_cmd_str(void*, const char *); 13 | // 14 | import "C" 15 | 16 | import ( 17 | "unsafe" 18 | ) 19 | 20 | func (r2p *Pipe) ApiCmd(cmd string) (string, error) { 21 | res := C.r_core_cmd_str(r2p.Core, C.CString(cmd)) 22 | return C.GoString(res), nil 23 | } 24 | 25 | func (r2p *Pipe) ApiClose() error { 26 | C.r_core_free(unsafe.Pointer(r2p.Core)) 27 | r2p.Core = nil 28 | return nil 29 | } 30 | 31 | func NewApiPipe(file string) (*Pipe, error) { 32 | r2 := C.r_core_new() 33 | r2p := &Pipe{ 34 | File: file, 35 | Core: r2, 36 | cmd: func(r2p *Pipe, cmd string) (string, error) { 37 | return r2p.ApiCmd(cmd) 38 | }, 39 | close: func(r2p *Pipe) error { 40 | return r2p.ApiClose() 41 | }, 42 | } 43 | if file != "" { 44 | r2p.ApiCmd("o " + file) 45 | } 46 | return r2p, nil 47 | } 48 | -------------------------------------------------------------------------------- /dotnet/r2pipe.csproj.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | r2pipe 5 | 1.1.0 6 | radare2 7 | radare2 8 | https://github.com/radareorg/radare2-bindings/blob/master/COPYING 9 | https://github.com/radareorg/radare2-bindings 10 | true 11 | r2pipe 12 | 13 | Copyright 2015-2020 14 | radare2 r2pipe 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /dotnet/r2pipe/OldApi/HttpR2Pipe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace r2pipe.OldApi 9 | { 10 | [Obsolete("Please use the newer HttpR2Pipe Class.")] 11 | public class R2PipeHttp : HttpR2Pipe 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The URI. 17 | /// URI must be HTTP(S) 18 | public R2PipeHttp(string uri) : base(new Uri(uri + "/")) 19 | { } 20 | 21 | [Obsolete("Please use QueuedR2Pipe, which supports Callbacks or the async method which does not need one.")] 22 | public void Cmd(string cmd, Action cb) 23 | { 24 | cb(this.RunCommand(cmd)); 25 | } 26 | 27 | [Obsolete("Please use the interface Member Command() instead.")] 28 | public string CmdSync(string cmd) 29 | { 30 | return this.RunCommand(cmd); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /erlang/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 by Alexander 'dark_k3y' Bolshev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | 24 | -------------------------------------------------------------------------------- /typescript/r2pipe/base.ts: -------------------------------------------------------------------------------- 1 | export abstract class R2PipeBase implements R2PipeCmdInterface { 2 | abstract cmd(command: string): Promise; 3 | abstract quit(): Promise; 4 | 5 | async cmdj(command: string): Promise { 6 | const output = await this.cmd(command); 7 | try { 8 | return JSON.parse(output); 9 | } catch (e) { 10 | throw new Error("Failed to parse JSON output from radare2 command."); 11 | } 12 | } 13 | } 14 | 15 | export interface R2PipeCmdInterface { 16 | /** 17 | * Executes a radare2 command and returns the output as a string. 18 | * @param command The radare2 command to execute. 19 | * @returns A promise that resolves with the command output as a string. 20 | */ 21 | cmd(command: string): Promise; 22 | 23 | /** 24 | * Executes a radare2 command that expects a JSON response. 25 | * @param command The radare2 command to execute. 26 | * @returns A promise that resolves with the parsed JSON output. 27 | */ 28 | cmdj(command: string): Promise; 29 | 30 | /** 31 | * Quits and destroys the given instance 32 | * @returns async nothing 33 | */ 34 | quit(): Promise; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/test-r2.js: -------------------------------------------------------------------------------- 1 | /* Common-Javascript API for R2 --pancake 2014 */ 2 | 3 | /* This is a NodeJS program that uses the generic r2 api 4 | which is also compatible with the WebUI and Duktape. 5 | Enabling you to write Javascript extensions for r2 6 | that run in the shell, the web or inside r2 */ 7 | 8 | /* require the nodejs api */ 9 | var r2jsapi = './r2.js'; 10 | var r2node = require('../'); 11 | 12 | function doSomeStuff (r) { 13 | var r2 = require(r2jsapi)(r); 14 | r2.analOp('entry0', function (op) { 15 | console.log(op.size, op.opcode, op.esil); 16 | }); 17 | r2.cmd('af @ entry0', function (o) { 18 | r2.cmd('pdf @ entry0', function (o) { 19 | console.log(o); 20 | r.quit(); 21 | }); 22 | }); 23 | r2.cmdj('aij entry0+2', function (o) { 24 | console.log(o); 25 | }); 26 | } 27 | 28 | r2node.pipe('/bin/ls', doSomeStuff); 29 | r2node.launch('/bin/ls', doSomeStuff); 30 | /* 31 | r2node.connect ("http://cloud.rada.re/cmd/", doSomeStuff); 32 | r2node.launch ("/bin/ls", function (r) { 33 | var r2 = require (r2jsapi)(r); 34 | r2.cmd (["?v $s", "p8 10", "pi 3"], function(res) { 35 | console.log (res); 36 | r.quit (); 37 | }); 38 | }); 39 | */ 40 | -------------------------------------------------------------------------------- /python/Makefile: -------------------------------------------------------------------------------- 1 | PWD=$(shell pwd) 2 | PYTHON?=`pwd`/python-wrapper 3 | PYTHON_VERSION?=`${PYTHON} --version 2>&1 | cut -d ' ' -f 2 | cut -d . -f 1,2` 4 | PYTHON_PKGDIR=$(shell ${PYTHON} ../../mp.py) 5 | PYTHON_INSTALL_DIR=${DESTDIR}/${PYTHON_PKGDIR}/r2pipe 6 | 7 | PYTHON2=python 8 | PYTHON3=python3 9 | 10 | all: 11 | $(PYTHON) setup.py build sdist 12 | 13 | install: uninstall 14 | $(PYTHON) setup.py install 15 | 16 | clean: 17 | $(PYTHON) setup.py clean 18 | rm -rf dist 19 | 20 | symstall: uninstall 21 | ln -fs $(PWD)/r2pipe "$(PYTHON_INSTALL_DIR)" 22 | 23 | twine: 24 | sudo pip install -U twine 25 | 26 | test: testpy2 testpy3 test-examples 27 | 28 | testpy2: 29 | @echo "Testing $(PYTHON)" 30 | PYTHONPATH=$$PWD $(PYTHON) -m pip install coverage pytest 31 | PYTHONPATH=$$PWD $(PYTHON) -m coverage run --omit="*.local*" -m pytest -k "test_" test 32 | PYTHONPATH=$$PWD $(PYTHON) -m coverage report 33 | -pylint r2pipe/*.py 34 | 35 | test-examples: 36 | $(PYTHON) examples/test.py 37 | $(PYTHON) examples/test2.py 38 | 39 | testpy3: 40 | @$(MAKE) testpy2 PYTHON=$(PYTHON3) 41 | 42 | uninstall: 43 | rm -rf "$(PYTHON_INSTALL_DIR)" 44 | 45 | .PHONY: twine 46 | 47 | pub publish: all 48 | twine upload -u __token__ --repository-url https://upload.pypi.org/legacy/ --verbose dist/* 49 | -------------------------------------------------------------------------------- /clojure/src/r2pipe/proto.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe.proto 2 | (:require [clojure.string :as string] 3 | [cheshire.core :refer :all])) 4 | 5 | (def deny-inquiry true) 6 | 7 | (defn set-deny-inquiry 8 | [deny] 9 | (def deny-inquiry deny)) 10 | 11 | (defprotocol R2Proto 12 | (r2-read [this]) 13 | (r2-write [this input]) ; will specific serialization be required? 14 | (close [this])) 15 | 16 | (defn cmd [this & cmds] 17 | "Generic function to send to an R2 pipe a command" 18 | (let [cmd (first (string/split (first cmds) #"\s+")) 19 | msg (string/join " " cmds)] 20 | (if (and deny-inquiry (string/includes? cmd "?")) 21 | (throw (ex-info "inquiry command" {:cmd cmd :cmds cmds}))) 22 | (.r2-write this msg) 23 | (.r2-read this))) 24 | 25 | (defn cmdj [this & cmds] 26 | "Generic function to send to an R2 pipe a command and receive a JSON" 27 | (let [cmd (first (string/split (first cmds) #"\s+")) 28 | msg (string/join " " cmds)] 29 | (if (and deny-inquiry (string/includes? cmd "?")) 30 | (throw (ex-info "inquiry command" {:cmd cmd :cmds cmds}))) 31 | (if (not (string/ends-with? cmd "j")) 32 | (throw (ex-info "not a json command" {:cmd cmd :cmds cmds}))) 33 | (.r2-write this msg) 34 | (parse-string (.r2-read this) true))) 35 | -------------------------------------------------------------------------------- /dotnet/r2pipe-portable/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // Allgemeine Informationen über eine Assembly werden über folgende 7 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 8 | // die einer Assembly zugeordnet sind. 9 | [assembly: AssemblyTitle("r2pipe-portable")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("r2pipe-portable")] 14 | [assembly: AssemblyCopyright("Copyright © 2016-2023")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en-150")] 18 | 19 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 20 | // 21 | // Hauptversion 22 | // Nebenversion 23 | // Buildnummer 24 | // Revision 25 | // 26 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 27 | // übernehmen, indem Sie "*" eingeben: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /java/examples/TestJSON.java: -------------------------------------------------------------------------------- 1 | import org.radare.r2pipe.R2Pipe; 2 | import java.util.Map; 3 | import java.util.HashMap; 4 | import javax.json.*; 5 | import javax.json.stream.*; 6 | import java.io.StringWriter; 7 | 8 | public class TestJSON { 9 | public static String jsonStringify(JsonObject obj) { 10 | Map config = new HashMap<>(); 11 | config.put(JsonGenerator.PRETTY_PRINTING, true); 12 | JsonWriterFactory jwf = Json.createWriterFactory(config); 13 | StringWriter sw = new StringWriter(); 14 | try (JsonWriter jsonWriter = jwf.createWriter(sw)) { 15 | jsonWriter.writeObject(obj); 16 | } 17 | return sw.toString(); 18 | } 19 | 20 | public static void main (String[] args) { 21 | try { 22 | R2Pipe r2p = new R2Pipe ("/bin/ls"); 23 | //R2Pipe r2p = new R2Pipe ("http://cloud.rada.re/cmd/", true); 24 | System.out.println (r2p.cmd ("pd 10")); 25 | System.out.println ("=============="); 26 | System.out.println (r2p.cmd ("px 32")); 27 | JsonObject obj = r2p.cmdj ("ij"); 28 | String intrp = obj.getJsonObject("bin").getString("intrp"); 29 | String pretty = jsonStringify(obj); 30 | System.out.println (pretty); 31 | System.out.println (intrp); 32 | r2p.quit(); 33 | } catch (Exception e) { 34 | System.err.println (e); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /dlang/r2pipe.d: -------------------------------------------------------------------------------- 1 | module r2pipe; 2 | 3 | import std.conv; 4 | import std.json; 5 | import std.stdio; 6 | import std.string; 7 | import std.process; 8 | import core.sys.posix.unistd; 9 | 10 | class R2Pipe { 11 | private alias sysread = core.sys.posix.unistd.read; 12 | private alias syswrite = core.sys.posix.unistd.write; 13 | 14 | private int fdIn; 15 | private int fdOut; 16 | 17 | this() { 18 | fdIn = to!int(environment["R2PIPE_IN"]); 19 | fdOut = to!int(environment["R2PIPE_OUT"]); 20 | } 21 | 22 | public string cmd(string c) { 23 | char[] cbuf = (c~"\n").dup; 24 | syswrite(fdOut, cast(void*)cbuf, cbuf.length); 25 | string res = ""; 26 | while (true) { 27 | byte[1] buf; 28 | auto n = sysread(fdIn, &buf, 1); 29 | if (buf[0] == '\0') { 30 | break; 31 | } 32 | res ~= buf[0]; 33 | } 34 | return res.chomp(); 35 | } 36 | public JSONValue cmdj(string s) { 37 | return parseJSON(cmd(s)); 38 | } 39 | } 40 | 41 | public static R2Pipe open() { 42 | return new R2Pipe(); 43 | } 44 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe-testsuite", 3 | "version": "0.1.0", 4 | "description": "testsuite for the r2pipe bindings for radare2", 5 | "main": "index.js", 6 | "scripts": { 7 | "tests": "(cd node ; for a in * ; do node $a ; done);(cd r2 ; for a in * ; do r2 -qi $a ../b/ls ; done )", 8 | "indent": "$(npm bin)/jsfmt -w *.js testsuite/*.js testsuite/r2/*.js testsuite/node/*.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/radareorg/radare2-bindings.git" 13 | }, 14 | "files": [ 15 | "README.md", 16 | "index.js", 17 | "test.js" 18 | ], 19 | "keywords": [ 20 | "radare", 21 | "radare2", 22 | "r2", 23 | "reversing", 24 | "disassembler", 25 | "hexadecimal", 26 | "editor", 27 | "exploit", 28 | "exploiting" 29 | ], 30 | "author": { 31 | "name": "pancake", 32 | "email": "pancake@nopcode.org" 33 | }, 34 | "contributors": [ 35 | { 36 | "name": "Jaime Peñalba", 37 | "email": "jpenalbae@gmail.com" 38 | } 39 | ], 40 | "license": "LGPL-3.0", 41 | "bugs": { 42 | "url": "https://github.com/radareorg/radare2-bindings/issues" 43 | }, 44 | "homepage": "http://www.radare.org", 45 | "dependencies": { 46 | "colors": "^1.4.0", 47 | "jsfmt": "*" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /python/examples/test-backends.py: -------------------------------------------------------------------------------- 1 | # /usr/bin/env python 2 | 3 | import r2pipe 4 | from os import system 5 | import time 6 | 7 | if __name__ == "__main__": 8 | print("[+] Spawning r2 tcp and http servers") 9 | system("pkill r2") 10 | system("radare2 -qc.:9080 /bin/ls &") 11 | system("radare2 -qc=h /bin/ls &") 12 | time.sleep(1) 13 | 14 | # Test r2pipe with local process 15 | print("[+] Testing python r2pipe local") 16 | rlocal = r2pipe.open("/bin/ls") 17 | print(rlocal.cmd("pi 5")) 18 | # print rlocal.cmd("pn") 19 | info = rlocal.cmdj("ij") 20 | print("Architecture: " + info["bin"]["machine"]) 21 | 22 | # Test r2pipe with remote tcp process (launch it with "radare2 -qc.:9080 myfile") 23 | print("[+] Testing python r2pipe tcp://") 24 | rremote = r2pipe.open("tcp://127.0.0.1:9080") 25 | disas = rremote.cmd("pi 5") 26 | if not disas: 27 | print("Error with remote tcp conection") 28 | else: 29 | print(disas) 30 | 31 | # Test r2pipe with remote http process (launch it with "radare2 -qc=H myfile") 32 | print("[+] Testing python r2pipe http://") 33 | rremote = r2pipe.open("http://127.0.0.1:9090") 34 | disas = rremote.cmd("pi 5") 35 | if not disas: 36 | print("Error with remote http conection") 37 | else: 38 | print(disas) 39 | system("pkill -INT r2") 40 | -------------------------------------------------------------------------------- /nim/r2pipe.nim: -------------------------------------------------------------------------------- 1 | import sockets, strutils 2 | import httpclient 3 | import asyncdispatch 4 | import sequtils 5 | import json 6 | 7 | type 8 | R2PipeHttp = ref object 9 | url*:string 10 | 11 | proc cmd*(r: R2PipeHttp, c: string):Future[string] {.async.} = 12 | var client = newAsyncHttpClient() 13 | var resp = await client.request(r.url & "/cmd/" & c) 14 | return resp.body; 15 | 16 | proc cmdj*(r: R2PipeHttp, c: string):Future[JsonNode] {.async.} = 17 | return parseJson(await cmd(r, c)) 18 | 19 | # dll api 20 | 21 | proc r_core_new(): pointer {.importc, dynlib: "libr_core.dylib".} 22 | proc r_core_cmd_str(c: pointer, cmd: cstring): cstring {.importc, dynlib: "libr_core.dylib".} 23 | # proc r_core_free(c: pointer): void {.importc, dynlib: "libr_core.dyilb".} 24 | 25 | proc toString(str: seq[char]): string = 26 | result = newStringOfCap(len(str)) 27 | for ch in str: 28 | add(result, ch) 29 | return result 30 | 31 | proc fromString(str: string): seq[char] = 32 | return toSeq(str.items) 33 | 34 | type R2PipeApi = ref object 35 | lib: pointer 36 | 37 | # proc construct(this: R2PipeAPI) = 38 | # this.lib = r_core_new(); 39 | 40 | proc cmd*(this: R2PipeApi, c: string): string = 41 | if this.lib == nil: 42 | this.lib = r_core_new() 43 | return $r_core_cmd_str(this.lib, c) 44 | 45 | proc cmdj*(r: R2PipeApi , c: string):JsonNode = 46 | return parseJson(cmd(r, c)) 47 | -------------------------------------------------------------------------------- /swift/r2plugin/r2.h: -------------------------------------------------------------------------------- 1 | extern int r2swift_cmd(void *core, const char *cmd); 2 | typedef struct r_lib_struct_t { 3 | int type; 4 | void *data; /* pointer to data handled by plugin handler */ 5 | const char *version; /* r2 version */ 6 | void (*free)(void *data); 7 | const char *pkgname; /* pkgname associated to this plugin */ 8 | } RLibStruct; 9 | typedef enum r_plugin_status_t { 10 | R_PLUGIN_STATUS_BROKEN = 0, 11 | R_PLUGIN_STATUS_INCOMPLETE = 1, 12 | R_PLUGIN_STATUS_BASIC = 2, 13 | R_PLUGIN_STATUS_OK = 3, 14 | R_PLUGIN_STATUS_GOOD= 4, 15 | R_PLUGIN_STATUS_COMPLETE = 5, 16 | } RPluginStatus; 17 | typedef struct r_plugin_meta_t { 18 | char *name; 19 | char *desc; 20 | char *author; 21 | char *version; 22 | char *license; 23 | RPluginStatus status; 24 | } RPluginMeta; 25 | 26 | typedef int (*RCmdCb) (void *user, const char *input); 27 | typedef struct r_core_plugin_t { 28 | RPluginMeta meta; 29 | RCmdCb call; // returns true if command was handled, false otherwise. 30 | RCmdCb init; 31 | RCmdCb fini; 32 | } RCorePlugin; 33 | 34 | // PLUGIN Definition Info 35 | RCorePlugin swift_plugin = { 36 | .meta = { 37 | .name = "a2f", 38 | .desc = "The reworked analysis from scratch thing", 39 | .license = "LGPL3", 40 | }, 41 | .call = r2swift_cmd, 42 | }; 43 | 44 | #define R2_VERSION "5.8.9" 45 | #define R_LIB_TYPE_CORE 13 46 | #define R_API __attribute__((__visibility__("default"))) 47 | 48 | -------------------------------------------------------------------------------- /python/examples/010-to-r2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # TODO: add structs in pf 3 | # TODO: specify flag sizes acordingly 4 | # TODO: walk the dom using the api 5 | 6 | import pfp 7 | import sys 8 | import os 9 | 10 | if len(sys.argv) > 1: 11 | template = sys.argv[1] 12 | try: 13 | binfile = os.environ["FILE"] 14 | except: 15 | try: 16 | binfile = sys.argv[2] 17 | except: 18 | print "Missing file to parse" 19 | sys.exit(1) 20 | else: 21 | print "Usage: 010-to-r2.py [template.bt] ([file])" 22 | print "> .!python 010-to-r2.py JPEGTemplate.bt" 23 | sys.exit(1) 24 | 25 | # XXX pfp.parse show noisy messages 26 | dom = pfp.parse(data_file=binfile, template_file=template) 27 | 28 | 29 | def filterFlagName(x): 30 | x = x.replace("[", "_") 31 | x = x.replace("]", "_") 32 | return x 33 | 34 | 35 | rows = dom._pfp__show(include_offset=True) 36 | structName = "" 37 | for line in rows.split("\n"): 38 | isStruct = line.find("struct") != -1 39 | line = line.strip() 40 | line = line.split("=")[0] 41 | if line[0] == "}": 42 | continue 43 | line = "0x" + line 44 | cols = line.split(" ") 45 | if isStruct: 46 | structName = cols[1] 47 | else: 48 | fn = structName + "." + cols[1] 49 | flagName = "struct." + filterFlagName(fn) 50 | print "f " + flagName + " = " + cols[0] 51 | -------------------------------------------------------------------------------- /zig/src/r2pipe.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const print = @import("std").debug.print; 3 | 4 | pub const R2PipeMode = enum { 5 | env, 6 | api, 7 | // http, 8 | }; 9 | 10 | pub const R2Pipe = struct { 11 | fd_in: i32 = -1, 12 | fd_out: i32 = -1, 13 | 14 | pub fn deinit(r2: *R2Pipe) void { 15 | r2.arena.deinit(); 16 | } 17 | pub fn cmd(r2: R2Pipe, s: []const u8) ![]const u8 { 18 | var foo: [4096]u8 = undefined; 19 | if (r2.fd_in != -1 and r2.fd_out != -1) { 20 | _ = try std.os.write(r2.fd_out, s); 21 | _ = try std.os.write(r2.fd_out, "\n"); 22 | const res = try std.os.read(r2.fd_in, &foo); 23 | if (res > 0) { 24 | return foo[0..res]; 25 | } 26 | } 27 | return ""; 28 | } 29 | 30 | pub fn quit(r2: R2Pipe) !void { 31 | _ = r2.cmd("q!!"); 32 | } 33 | }; 34 | 35 | pub fn open(file: []const u8) !R2Pipe { 36 | var r2 = R2Pipe{}; 37 | if (std.mem.eql(u8, file, "")) { 38 | var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); 39 | const env_map = try std.process.getEnvMap(arena.allocator()); 40 | r2.fd_in = try std.fmt.parseInt(i32, env_map.get("R2PIPE_IN") orelse "-1", 10); 41 | r2.fd_out = try std.fmt.parseInt(i32, env_map.get("R2PIPE_OUT") orelse "-1", 10); 42 | arena.deinit(); 43 | } 44 | return r2; 45 | } 46 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/http/index.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | Author : pancake 5 | 6 | Date: 2015-03-31 7 | 8 | From inside r2 9 | 10 | r2 -c '#!pipe node index.js' /bin/ls 11 | 12 | Or from the shell: 13 | 14 | node . 15 | 16 | */ 17 | 18 | var r2p = require ("r2pipe") 19 | var http = require('http'); 20 | var express = require('express'); 21 | 22 | function runWebServer(r) { 23 | r.cmd ("e http.root", function(wwwroot) { 24 | wwwroot = wwwroot.trim (); 25 | r.cmd ("e http.port", function(port) { 26 | port = +port.trim (); 27 | r.cmd ("e scr.color=0", function() {}); 28 | r.cmd ("e scr.interactive=false", function() {}); 29 | r.cmd ("e scr.html=true", function(){}); 30 | var app = express(); 31 | app.all('/cmd/*', function(req,res) { 32 | var cmd = unescape (req.url.substring (5)); 33 | console.log ("cmd:", cmd); 34 | r.cmd (cmd, function (data) { 35 | res.send(data); 36 | }); 37 | }); 38 | app.use(express.static(wwwroot)); 39 | r.cmd ("?e http://localhost:`e http.port`/p", function (data) { 40 | console.log (data.replace(' ','').trim()); 41 | }) 42 | app.listen (port); 43 | }); 44 | }); 45 | } 46 | 47 | if (process.env.R2PIPE_IN) { 48 | var r = r2p.rlangpipe(runWebServer); 49 | } else { 50 | var targetfile = "/bin/ls"; 51 | if (process.argv.length>2) { 52 | targetfile = process.argv[2]; 53 | } 54 | var r = r2p.pipe (targetfile, runWebServer); 55 | } 56 | -------------------------------------------------------------------------------- /r2core-js/tuto/engine.js: -------------------------------------------------------------------------------- 1 | var level = 0; 2 | /* 3 | const tutorial = [ 4 | { 5 | "title": "To start we must learn the '?' Command that will show the list of root commands.", 6 | "expect": { 7 | "input": "?" 8 | } 9 | },{ 10 | "title": "Some commands are used to interact with the user like the echo. Try ?e hello", 11 | "expect": { 12 | "output": "hello" 13 | } 14 | },{ 15 | "title": "We can get the help and list of subcommands by appending the question mark at the end of any command.", 16 | "expect": { 17 | "inputEndsWith": "?" 18 | } 19 | } 20 | ]; 21 | */ 22 | 23 | String.prototype.endsWith = String.prototype.endsWith || function(suffix) { 24 | return this.indexOf(suffix, this.length - suffix.length) >= 0; 25 | }; 26 | 27 | function checkLevel(inp, out) { 28 | var e = tutorial[level].expect; 29 | if (e.input) { 30 | return inp.trim() == e.input; 31 | } 32 | if (e.inputEndsWith) { 33 | if (inp.trim() !== e.inputEndsWith) { 34 | return inp.trim().endsWith(e.inputEndsWith); 35 | } 36 | } 37 | if (e.output) { 38 | return out.trim() == e.output; 39 | } 40 | return false; 41 | } 42 | 43 | function levelMessage() { 44 | return tutorial[level].title; 45 | } 46 | 47 | function winLevel() { 48 | level ++; 49 | if (!tutorial[level]) { 50 | alert ('The tutorial is over!'); 51 | level = 0; 52 | } else { 53 | alert("Good!"); 54 | } 55 | } 56 | 57 | function startTutorial() { 58 | evalTutorial 59 | } 60 | -------------------------------------------------------------------------------- /r2core-js/tuto/tuto01.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # This is a config file for a tutorial for r2core.js 4 | # 5 | # 6 | - title: Welcome to the radare2 web tutorial! Press 'enter' in the input box to open the crackme 7 | expect: 8 | input: o crackme 9 | - title: To start we must learn the question mark ('?') Command that will show the list of root commands. 10 | expect: 11 | input: ? 12 | - title: Some commands are used to interact with the user like the echo. Try ?e hello 13 | expect: 14 | output: hello 15 | - title: We can get the help and list of subcommands by appending the question mark at the end of any command. 16 | expect: 17 | inputEndsWith: ? 18 | - title: r2 is a block based hexadecimal editor. This means that you will only see a portion of the data. Use the 'b' comamnd to change the block size and run 'px' to print the block. 19 | expect: 20 | input: px 21 | - title: You can also specify the block size as an argument to 'px'. As long as 'px' is too long, r2 provides a short for it: 'x' 22 | expect: 23 | input: x 24 | - title: Numeric arguments in r2 can be complex math expressions using numbers in any base. Let's try to evaluate a math expression that computes to 6 using the ?v command. 25 | expect: 26 | output: 0x6 27 | - title: Thanks for playing! This is a very early implementation. Feel free to submit PRs to extend the tutorials 28 | expect: 29 | input: restart 30 | -------------------------------------------------------------------------------- /nodejs/r2pipe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r2pipe", 3 | "version": "2.8.6", 4 | "description": "NodeJS r2pipe API for radare2", 5 | "main": "index.js", 6 | "types": "r2pipe.d.ts", 7 | "scripts": { 8 | "test": "node examples/test-channels.js", 9 | "semi": "semistandard", 10 | "fix": "semistandard --fix" 11 | }, 12 | "engineStrict": true, 13 | "engines": { 14 | "node": ">= 4.2.0", 15 | "iojs": ">= 1.0.0" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/radareorg/radare2-r2pipe.git" 20 | }, 21 | "files": [ 22 | "README.md", 23 | "r2pipe.d.ts", 24 | "index.js", 25 | "promise.js", 26 | "sync.js", 27 | "util.js" 28 | ], 29 | "keywords": [ 30 | "radare", 31 | "radare2", 32 | "r2", 33 | "reversing", 34 | "disassembler", 35 | "hexadecimal", 36 | "editor", 37 | "exploit", 38 | "exploiting" 39 | ], 40 | "author": { 41 | "name": "pancake", 42 | "email": "pancake@nopcode.org" 43 | }, 44 | "contributors": [ 45 | { 46 | "name": "Jaime Peñalba", 47 | "email": "jpenalbae@gmail.com" 48 | } 49 | ], 50 | "license": "MIT", 51 | "bugs": { 52 | "url": "https://github.com/radareorg/radare2-r2pipe/issues" 53 | }, 54 | "homepage": "http://www.radare.org", 55 | "devDependencies": { 56 | "semistandard": "^14.2.0" 57 | }, 58 | "dependencies": { 59 | "tern": "^0.24.2" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /nodejs/r2pipe/r2pipe.d.ts: -------------------------------------------------------------------------------- 1 | // const r2pipe = r2pipe.open('/bin/ls') 2 | 3 | export class R2Pipe { 4 | cmd(string): string; 5 | cmdj(string): any; 6 | cmdAt(string, string|number): any; 7 | call(string): string; 8 | callj(string): any; 9 | callAt(string, string|number): any; 10 | plugin(string, any): boolean; 11 | unload(string, string): boolean; 12 | log(string); 13 | } 14 | 15 | export default class r2pipe { 16 | static open(): R2Pipe; 17 | } 18 | // export default r2pipe; 19 | 20 | /* 21 | export const options: any[]; 22 | export const r2bin: string; 23 | export function connect(uri: any, cb: any): void; 24 | 25 | export function ioplugin(cb: any): void; 26 | 27 | export function jsonParse(p0: any, p1: any): any; 28 | 29 | export function launch(file: any, opts: any, cb: any): void; 30 | 31 | export function listen(file: any, cb: any): void; 32 | 33 | export function lpipe(cb: any): void; 34 | 35 | export function lpipeSync(): any; 36 | 37 | export function open(...args: any[]): any; 38 | 39 | export function openBuffer(buf: any, cb: any): void; 40 | 41 | export function openSync(...args: any[]): any; 42 | 43 | export function pipe(file: any, opts: any, cb: any): void; 44 | 45 | export function pipeSync(file: any, opts: any): any; 46 | 47 | export function syscmd(command: any, childOpts: any, cb: any): void; 48 | 49 | export function syscmdj(command: any, cb2: any): void; 50 | 51 | */ 52 | -------------------------------------------------------------------------------- /dotnet/Makefile: -------------------------------------------------------------------------------- 1 | R2P_LIB=r2pipe.dll 2 | MCS=mcs 3 | MONO=mono 4 | XBUILD=xbuild /p:Configuration=Release 5 | NUGET=nuget 6 | # See http://sourceforge.net/projects/narrange/files/narrange/NArrange%20Beta%20Version%200.2.9/NArrange-0.2.9-net-2.0.zip/download 7 | NARRANGE_WD=~/Downloads/NArrange/bin 8 | NARRANGE=$(NARRANGE_WD)/narrange-console.exe 9 | MCS_LIB=$(MCS) -optimize -target:library -out:$(R2P_LIB) 10 | MCS_LINK=$(MCS) -optimize -reference:$(R2P_LIB) 11 | 12 | ifneq ($(KEYFILE),) 13 | MCS_LIB+=-keyfile:$(KEYFILE) 14 | MCS_LINK+=-keyfile:$(KEYFILE) 15 | endif 16 | 17 | all: $(R2P_LIB) examples 18 | ln -fs r2pipe/bin/Release/r2pipe.dll r2pipe.dll 19 | ln -fs r2pipe/bin/Debug/r2pipe.dll r2pipeDebug.dll 20 | 21 | $(R2P_LIB): 22 | ifneq ($(KEYFILE),) 23 | $(XBUILD) /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=$(KEYFILE) r2pipe/r2pipe.csproj 24 | else 25 | $(XBUILD) r2pipe/r2pipe.csproj 26 | endif 27 | 28 | examples: 29 | $(XBUILD) LocalExample/LocalExample.csproj 30 | $(XBUILD) HttpExample/HttpExample.csproj 31 | 32 | run: 33 | $(MONO) LocalExample/bin/Release/LocalExample.exe 34 | 35 | clean: 36 | rm -f main.exe http.exe $(R2P_LIB) 37 | rm -rf r2pipe/obj r2pipe/bin 38 | rm -rf HttpExample/obj HttpExample/bin 39 | rm -rf LocalExample/obj LocalExample/bin 40 | 41 | nuget: 42 | $(NUGET) pack r2pipe/r2pipe.csproj.nuspec 43 | 44 | indent: 45 | for a in *.cs ; do $(MONO) $(NARRANGE) $$a ; done 46 | 47 | .PHONY: run all clean indent examples $(R2P_LIB) 48 | -------------------------------------------------------------------------------- /ruby/r2pipe.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # author pancake@nopcode.org 4 | 5 | require 'open3' 6 | require 'json' 7 | require 'shellwords' 8 | 9 | # R2Pipe is an easy way to communicate with an r2 core through ruby 10 | class R2Pipe 11 | def initialize(file = nil) 12 | @file = file 13 | if file.nil? 14 | fd_in, fd_out = getfds 15 | @read = IO.new(fd_in, 'r') 16 | @write = IO.new(fd_out, 'w') 17 | @pid = -1 18 | else 19 | execute file 20 | end 21 | end 22 | 23 | def cmd(str) 24 | @write.print "#{str}\n" 25 | @write.flush 26 | @read.gets("\0")[0..-2] 27 | end 28 | 29 | def cmdj(str) 30 | json(cmd(str)) 31 | end 32 | 33 | def quit 34 | cmd('q!') 35 | @read.close 36 | @write.close 37 | return if @pid == -1 38 | 39 | ::Process.wait @pid 40 | end 41 | 42 | def json(str) 43 | return if str.nil? 44 | 45 | JSON.parse str.sub("\n", '').sub("\r", '') 46 | end 47 | 48 | private 49 | 50 | def getfds 51 | fd_in = ENV['R2PIPE_IN'].to_i 52 | fd_out = ENV['R2PIPE_OUT'].to_i 53 | if fd_in < 1 || fd_out < 1 54 | raise 'Cannot find R2PIPE_IN and R2PIPE_OUT environment variables' 55 | end 56 | 57 | [fd_in, fd_out] 58 | end 59 | 60 | def execute(file) 61 | exec = "radare2 -q0 #{Shellwords.shellescape file} 2>/dev/null" 62 | write, read, wait_thr = Open3.popen2(exec) 63 | @read = read 64 | @write = write 65 | @pid = wait_thr.pid 66 | @read.gets("\0") 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /erlang/src/r2pipe_handler.erl: -------------------------------------------------------------------------------- 1 | -module(r2pipe_handler). 2 | 3 | %% standard port handler interface 4 | 5 | -export([start/1, stop/0, init/1, call/1]). 6 | 7 | start(R2Path) -> 8 | spawn(?MODULE, init, [R2Path]). 9 | stop() -> 10 | r2pipe_handler ! stop. 11 | 12 | init_port(lpipe) -> 13 | open_port({fd, list_to_integer(os:getenv("R2PIPE_IN")), list_to_integer(os:getenv("R2PIPE_OUT"))}, [stream, binary]); 14 | init_port(R2Path) -> 15 | open_port({spawn, R2Path}, [stream, binary]). 16 | 17 | init(Mode) -> 18 | register(r2pipe_handler, self()), 19 | process_flag(trap_exit, true), 20 | Port = init_port(Mode), 21 | loop(Port). 22 | 23 | call(Msg) -> 24 | r2pipe_handler ! {call, self(), Msg}, 25 | receive 26 | {r2pipe_handler, Result} -> 27 | Result 28 | end. 29 | 30 | %% TODO: Dirty code: timeout should be externally configurable 31 | get_timeout() -> 32 | 10000. 33 | 34 | loop(Port) -> 35 | receive 36 | {Port, {data, _Data}} -> 37 | %% data without query, do nothing 38 | loop(Port); 39 | {call, Caller, Msg} -> 40 | Port ! {self(), {command, Msg}}, 41 | receive 42 | {Port, {data, Data}} -> 43 | Caller ! {r2pipe_handler, {ok, Data}} 44 | after get_timeout() -> 45 | Caller ! {r2pipe_handler, {fail, expired}} 46 | end, 47 | loop(Port); 48 | stop -> 49 | Port ! {self(), close}, 50 | receive 51 | {Port, closed} -> 52 | exit(normal) 53 | end; 54 | {'EXIT', Port, _Reason} -> 55 | exit(port_terminated) 56 | end. 57 | 58 | -------------------------------------------------------------------------------- /python/examples/libgraph.py: -------------------------------------------------------------------------------- 1 | import r2pipe 2 | import sys 3 | import os 4 | 5 | r2 = r2pipe.open("/bin/ls") 6 | libpath = ["", ".", "/lib", "/usr/lib"] 7 | output = "aa" 8 | # output = 'dot' 9 | 10 | done = {} 11 | 12 | 13 | def findlib(lib): 14 | if os.path.isfile(lib): 15 | return lib 16 | for a in libpath: 17 | if os.path.isfile("%s/%s" % (a, lib)): 18 | return "%s/%s" % (a, lib) 19 | return [] 20 | 21 | 22 | def getlibs(lib): 23 | return r2.syscmdj("rabin2 -lj %s" % (lib))["libs"] 24 | 25 | 26 | def filter(s): 27 | return s.replace("-", "_").replace("+", "x") 28 | 29 | 30 | def makeNode(name): 31 | r2.cmd("agn %s" % (filter(name))) 32 | 33 | 34 | def makeEdge(f, t): 35 | r2.cmd("age %s %s" % (filter(f), filter(t))) 36 | 37 | 38 | def graphlibs(src, root): 39 | hs = src.replace("/", "_") 40 | hs = hs.replace("-", "_") 41 | hs = hs.replace("+", "x") 42 | try: 43 | if done[hs]: 44 | return 45 | except: 46 | done[hs] = True 47 | src = findlib(src) 48 | makeNode(src) 49 | for lib in getlibs(src): 50 | lib = findlib(lib) 51 | makeNode(lib) 52 | makeEdge(src, lib) 53 | graphlibs(lib, src) 54 | 55 | 56 | if len(sys.argv) > 1: 57 | path = sys.argv[1] 58 | graphlibs(path, None) 59 | if output == "dot": 60 | print r2.cmd("aggd") 61 | else: 62 | print r2.cmd("e scr.color=true;agg") 63 | r2.quit() 64 | else: 65 | print "Usage: libgraph.py [path-to-bin]" 66 | sys.exit(1) 67 | -------------------------------------------------------------------------------- /java/jni/r2pipe-jni.c: -------------------------------------------------------------------------------- 1 | /* jni interface for r2pipe -- pancake 2016-2024 */ 2 | 3 | #include "org_radare_r2pipe_R2PipeJNI.h" 4 | #include 5 | #include 6 | #include 7 | 8 | static void* (*r_core_new)(void) = NULL; 9 | static void (*r_core_free)(void *core); 10 | static char* (*r_core_cmd_str)(void *core, const char *cmd); 11 | 12 | static bool initLibrary() { 13 | if (r_core_new) { 14 | return true; 15 | } 16 | void *rCore = dlopen ("/usr/local/lib/libr_core.dylib", RTLD_LAZY); 17 | if (!rCore) { 18 | perror ("dlopen"); 19 | return false; 20 | } 21 | r_core_new = dlsym (rCore, "r_core_new"); 22 | r_core_free = dlsym (rCore, "r_core_free"); 23 | r_core_cmd_str = dlsym (rCore, "r_core_cmd_str"); 24 | return r_core_new != NULL; 25 | } 26 | 27 | JNIEXPORT jlong JNICALL Java_org_radare_r2pipe_R2PipeJNI_r2pipeNew (JNIEnv *env, jobject thiz) { 28 | if (initLibrary ()) { 29 | return (jlong) (size_t) r_core_new (); 30 | } 31 | return 0; 32 | } 33 | 34 | JNIEXPORT jstring JNICALL Java_org_radare_r2pipe_R2PipeJNI_r2pipeCmd 35 | (JNIEnv *env, jobject thiz, jlong core, jstring cmd) { 36 | if (core) { 37 | void *cCore = (void*) (size_t) core; 38 | const char *cCmd = (*env)->GetStringUTFChars(env, cmd, NULL); 39 | return (*env)->NewStringUTF(env, r_core_cmd_str (cCore, cCmd)); 40 | } 41 | return (*env)->NewStringUTF(env, ""); 42 | } 43 | 44 | JNIEXPORT void JNICALL Java_org_radare_r2pipe_R2PipeJNI_r2pipeFree(JNIEnv *env, jobject thiz, jlong core) { 45 | if (core) { 46 | void *c = (void*) (size_t) core; 47 | r_core_free (c); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lisp/r2pipe.lisp: -------------------------------------------------------------------------------- 1 | ;;; -*- encoding:utf-8 Mode: LISP; Syntax: COMMON-LISP; Base: 10 -*- --- 2 | ;; 3 | ;; Filename: r2pipe.lisp 4 | ;; Description: 5 | ;; Author: Jingtao Xu 6 | ;; Created: 2015.09.29 17:42:43(+0800) 7 | ;; Last-Updated: 2015.09.30 16:30:25(+0800) 8 | ;; Update #: 38 9 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10 | ;; 11 | ;;; Commentary: 12 | ;; 13 | ;; 14 | (in-package :cl-user) 15 | 16 | (asdf:oos 'asdf:load-op :cl-json) 17 | 18 | (defvar *r2-bin-path* "/usr/bin/r2") 19 | (defun r2-read-pipe (pipe) 20 | (with-output-to-string (stream) 21 | (loop for c = (read-char pipe) 22 | until (= 0 (char-code c)) 23 | do (write-char c stream)))) 24 | 25 | (defun r2pipe (file) 26 | (let ((pipe #-lispworks(error "r2pipe is not implemented for current lisp platform.") 27 | #+lispworks(sys:open-pipe `(,*r2-bin-path* "-q" "-0" ,file) :direction :io))) 28 | (values pipe (r2-read-pipe pipe)))) 29 | 30 | (defun r2-cmd (pipe cmd) 31 | (write-line (format nil "~a" cmd) pipe) 32 | (finish-output pipe) 33 | (r2-read-pipe pipe)) 34 | 35 | (defun r2-quit (pipe) 36 | (r2-cmd pipe "q!")) 37 | 38 | (defun r2-json (str) 39 | (json:decode-json-from-string 40 | (with-output-to-string (*standard-output*) 41 | (with-input-from-string (*standard-input* str) 42 | (loop for c = (read-char *standard-input* nil nil) then (read-char *standard-input* nil nil) 43 | until (null c) 44 | unless (find c '(#\Newline #\Return)) 45 | do (write-char c)))))) 46 | -------------------------------------------------------------------------------- /dotnet/r2pipe/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("r2pipe")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("r2pipe")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("4690d592-f09f-4331-afba-87e023576cfc")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /swift/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=ios 2 | TARGET=osx 3 | 4 | SDKROOT=SDKROOT="$(shell xcrun --show-sdk-path --sdk ${SDK})" 5 | SC=$(SDKROOT) xcrun -sdk $(SDK) swiftc 6 | SFILES=Sources/r2pipe/r2pipe.swift 7 | 8 | USE_SPAWN=1 9 | USE_CCALL=1 10 | USE_NSURL_SESSION=1 11 | USE_ENV_PIPE=1 12 | 13 | ifeq ($(TARGET),ios) 14 | SDK=iphoneos 15 | CPU=arm64 16 | IOS=9.2 17 | # IOS=9.0 # deprecates Sync methods? Use Just library? 18 | SC+=-target $(CPU)-apple-ios$(IOS) 19 | USE_NSURL_SESSION=1 20 | else 21 | SDK=macosx 22 | endif 23 | 24 | SFLAGS= 25 | ifeq ($(USE_CCALL),1) 26 | SFLAGS+=-D USE_CCALL 27 | SFLAGS+=-Iccall 28 | SFLAGS+=-L/usr/local/lib 29 | endif 30 | ifeq ($(USE_ENV_PIPE),1) 31 | SFLAGS+=-D USE_ENV_PIPE 32 | endif 33 | ifeq ($(USE_SPAWN),1) 34 | SFLAGS+=-D USE_SPAWN 35 | SFILES+=Sources/r2pipe/r2pipeNative.swift 36 | endif 37 | ifeq ($(USE_NSURL_SESSION),1) 38 | SFLAGS+=-D USE_NSURL_SESSION 39 | endif 40 | 41 | all: 42 | $(SC) $(SFLAGS) main.swift $(SFILES) 43 | 44 | repl: lib 45 | @echo 46 | @echo 47 | @echo "import R2Pipe;" 48 | @echo "/* let r2p = R2Pipe(url:\"/bin/ls\")!; */" 49 | @echo "let r2p = R2Pipe(url:\"http://cloud.radare.org/cmd/\")!;" 50 | @echo "print(r2p.cmdSync(\"x\")!);" 51 | @echo 52 | @echo 53 | swift -I . -L . -lR2Pipe -module-link-name R2Pipe 54 | 55 | lib: 56 | swiftc -emit-library -emit-object -module-name R2Pipe $(SFLAGS) $(SFILES) 57 | ar rcs libR2Pipe.a r2pipe.o r2pipeNative.o 58 | swiftc -emit-library -emit-module -module-name R2Pipe $(SFLAGS) $(SFILES) 59 | 60 | xcode: 61 | open -a xcode . 62 | 63 | fmt: 64 | swiftformat . 65 | 66 | clean: 67 | rm -f main 68 | rm -rf main.dSYM 69 | 70 | .PHONY: lib repl all clean 71 | -------------------------------------------------------------------------------- /dotnet/JsonExample/main.cs: -------------------------------------------------------------------------------- 1 | using r2pipe; 2 | using System; 3 | 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Linq; 6 | 7 | namespace R2Net { 8 | public class Rasm2 { 9 | private IR2Pipe r2 = null; 10 | 11 | public string GetVersion() { 12 | return Cmd("?V").Trim(); 13 | } 14 | 15 | public JObject CmdJ(string cmd) { 16 | string result = Cmd(cmd); 17 | return JObject.Parse(result); 18 | } 19 | 20 | public JArray CmdA(string cmd) { 21 | string result = Cmd(cmd); 22 | return JArray.Parse(result); 23 | } 24 | 25 | public string Cmd(string cmd) { 26 | if (r2 != null) { 27 | return r2.RunCommand(cmd); 28 | } 29 | return ""; 30 | } 31 | 32 | public string GetInfo() { 33 | var info = CmdJ("ij"); 34 | var a = info["core"]["type"]; 35 | return info.ToString();; 36 | } 37 | 38 | public JArray Disasm() { 39 | return CmdA("pdj 4"); 40 | } 41 | 42 | public void Kill() { 43 | this.r2 = null; 44 | } 45 | 46 | public Rasm2(string file) { 47 | this.r2 = new R2Pipe(file); 48 | } 49 | 50 | public static void Main(string[] args) { 51 | try { 52 | Rasm2 e = new Rasm2(args[0]); 53 | Console.WriteLine("r2 version: "+ e.GetVersion()); 54 | Console.WriteLine("--> " + e.GetInfo()); 55 | Console.WriteLine("--> " + e.Disasm().ToString()); 56 | do { 57 | Console.Write("> "); 58 | var line = Console.ReadLine(); 59 | if (line == "q") { 60 | break; 61 | } 62 | Console.WriteLine(e.Cmd(line)); 63 | } while (true); 64 | 65 | e.Kill(); 66 | } catch (Exception e) { 67 | Console.WriteLine(e.ToString()); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /dotnet/HttpExample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("HttpExample")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("HttpExample")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("fcf43cea-8e09-47e3-88fe-d60381c7d120")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dotnet/LocalExample/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die mit einer Assembly verknüpft sind. 8 | [assembly: AssemblyTitle("LocalExample")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LocalExample")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("5db0b7da-8cfa-4e7b-988d-8b7bdffd1858")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dotnet/LocalExample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using r2pipe; 8 | 9 | namespace LocalExample 10 | { 11 | class Program 12 | { 13 | static void Main(string[] args) 14 | { 15 | 16 | #if __MonoCS__ 17 | using (IR2Pipe pipe = new R2Pipe("/bin/ls")) 18 | #else 19 | using (IR2Pipe pipe = new R2Pipe(@"C:\Windows\notepad.exe", @"C:\radare2\radare2.exe")) 20 | #endif 21 | { 22 | Console.WriteLine("Hello r2! " + pipe.RunCommand("?V")); 23 | 24 | Task async = pipe.RunCommandAsync("?V"); 25 | 26 | // To use non-blocking async stuff in console applications, you need an async context. Google helps you. 27 | 28 | // calling Result will block ulitmately. 29 | Console.WriteLine("Hello async r2!" + async.Result); 30 | 31 | // We can also issue multiple command sequentially, using a QueuedR2Pipe. 32 | // Note however that if we supply the pipe to use we must not call dispose on the pipe. 33 | 34 | QueuedR2Pipe qr2 = new QueuedR2Pipe(pipe); 35 | 36 | qr2.Enqueue(new R2Command("x", (string result) => { Console.WriteLine("Result of x:\n {0}", result); })); 37 | qr2.Enqueue(new R2Command("pi 10", (string result) => { Console.WriteLine("Result of pi 10:\n {0}", result); })); 38 | 39 | // note that this can also be done asynchronously via qr2.ExecuteCommandsAsync(); 40 | qr2.ExecuteCommands(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /dotnet/r2pipe/CmdQueue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace r2pipe 8 | { 9 | public class R2Command 10 | { 11 | #region Fields 12 | 13 | /// 14 | /// Gets or sets the callback. 15 | /// 16 | /// 17 | /// The callback. 18 | /// 19 | public Action Callback { get; set; } 20 | 21 | /// 22 | /// Gets or sets the command. 23 | /// 24 | /// 25 | /// The command. 26 | /// 27 | public string Command { get; set; } 28 | 29 | #endregion Fields 30 | 31 | #region Constructors 32 | 33 | /// 34 | /// Initializes a new instance of the class. 35 | /// 36 | /// The command. 37 | /// The cb. 38 | public R2Command(string cmd, Action cb) 39 | { 40 | this.Command = cmd; 41 | this.Callback = cb; 42 | } 43 | 44 | #endregion Constructors 45 | 46 | #region Methods 47 | 48 | /// 49 | /// Returns a that represents this instance. 50 | /// 51 | /// 52 | /// A that represents this instance. 53 | /// 54 | public override string ToString() 55 | { 56 | return Command; 57 | } 58 | 59 | #endregion Methods 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /nodejs/r2pipe/examples/syscall/int.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var r2pipe = require('r2pipe'); 3 | var sn = +process.argv[2]; 4 | 5 | // runs some code emulating each syscall 6 | console.log('Running NodeJS powered syscall handler', sn); 7 | 8 | function syscallLinuxX8632 (r2p, regs) { 9 | console.log('REGS', regs); 10 | switch (regs.eax) { 11 | case 1: // exit() syscall 12 | console.log('[SYSCALL] exit code ', regs.ebx); 13 | break; 14 | case 4: // write() syscall, 15 | const a0 = regs.ebx; // fd 16 | const a1 = regs.ecx; // data 17 | const a2 = regs.edx; // len 18 | console.log('[SYSCALL] write fd:', a0); 19 | console.log('[SYSCALL] write data:', a1); 20 | console.log('[SYSCALL] write len:', a2); 21 | r2p.cmd('psz ' + a2 + '@' + a1, function (out) { 22 | console.log(out); 23 | process.exit(0); 24 | }); 25 | break; 26 | default: // etc... 27 | console.log('[SYSCALL] reg:', regs.eax); 28 | } 29 | } 30 | 31 | // it works using r2pipe, connecting to r2 session 32 | r2pipe.lpipe(function (err, r2p) { 33 | if (err) { 34 | throw err; 35 | } 36 | const syscall = syscallLinuxX8632; 37 | switch (sn) { 38 | case 3: // same as INT3 39 | console.error('[INT3] Breakpoint trap'); 40 | process.exit(0); 41 | break; 42 | case 128: 43 | case 0x80: // INT 0x80 44 | /* linux */ 45 | console.error('[SYSCALL] number:', sn); 46 | r2p.cmdj('arj', function (err, regs) { 47 | if (err) throw err; 48 | if (syscall(r2p, regs)) { 49 | process.exit(0); 50 | } 51 | }); 52 | break; 53 | default: 54 | process.exit(0); 55 | break; 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /nodejs/r2pipe/testsuite/node/async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var r2pipe = require('../..'); 4 | var TestSuite = require('..'); 5 | 6 | function testAsync5 (fin) { 7 | let result = ''; 8 | try { 9 | var count = 5; 10 | r2pipe.open('../b/ls', function (err, r2) { 11 | if (err) { 12 | throw err; 13 | } 14 | var intrv = setInterval(function () { 15 | if (count === 0) { 16 | r2.quit(); 17 | } else { 18 | r2.cmd('?e a', (err, x) => { 19 | if (err) { 20 | throw err; 21 | } 22 | result += x; 23 | count--; 24 | if (count === 0) { 25 | clearInterval(intrv); 26 | r2.quit(); 27 | fin(result); 28 | } 29 | }); 30 | } 31 | }, 10); 32 | }); 33 | } catch (e) { 34 | console.error('XXX', e); 35 | } 36 | return result; 37 | } 38 | 39 | function testAsyncFor5 (fin) { 40 | let result = ''; 41 | try { 42 | var count = 5; 43 | r2pipe.open('../b/ls', function (err, r2) { 44 | if (err) { 45 | throw err; 46 | } 47 | for (let i = 0; i < 5; i++) { 48 | if (count === 0) { 49 | r2.quit(); 50 | } else { 51 | r2.cmd('?e a', (err, x) => { 52 | if (err) throw err; 53 | result += x; 54 | count--; 55 | if (count === 0) { 56 | r2.quit(); 57 | fin(result); 58 | } 59 | }); 60 | } 61 | } 62 | }); 63 | } catch (e) { 64 | console.error('error', e); 65 | } 66 | return result; 67 | } 68 | 69 | TestSuite 70 | .addTest('testAsync5', testAsync5, 'a\na\na\na\na\n') 71 | .addTest('testAsyncFor5', testAsyncFor5, 'a\na\na\na\na\n') 72 | .inParalel(); 73 | -------------------------------------------------------------------------------- /clojure/src/r2pipe/core.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe.core 2 | (:require [r2pipe.proto :as proto] 3 | [r2pipe.spawn :as spawn] 4 | [r2pipe.tcp :as tcp] 5 | [r2pipe.http :as http] 6 | 7 | [clojure.string :as string]) 8 | (:import [java.net URI])) 9 | 10 | ;; Define the default path for r2 to load. 11 | (def r2-path "/usr/bin/r2") 12 | 13 | ;; Define core instance 14 | (def r2-instance nil) 15 | 16 | (defn configure-path 17 | "Configure the r2 path." 18 | [path] 19 | (def r2-path path)) 20 | 21 | (defn parse-r2pipe-url 22 | "Parse r2pipe URL" 23 | [url] 24 | (let [url-parsed (URI. url)] 25 | {:url url 26 | :scheme (keyword (.getScheme url-parsed)) 27 | :server-name (.getHost url-parsed) 28 | :server-port (.getPort url-parsed) 29 | :uri (.getPath url-parsed) 30 | :user-info (.getUserInfo url-parsed) 31 | :query-string (.getRawQuery url-parsed)})) 32 | 33 | (defn r2open 34 | "Open instance, according to url. 35 | 36 | Example urls: 37 | spawn:///./program.bin 38 | tcp://127.0.0.1:9090 39 | http://127.0.0.1:9090/cmd 40 | " 41 | [url] 42 | (let [parsed-url (parse-r2pipe-url url)] 43 | (def r2-instance 44 | (case (:scheme parsed-url) 45 | :spawn 46 | (spawn/r2open (string/replace-first (:uri parsed-url) "/" "") r2-path) 47 | :tcp 48 | (tcp/r2open (:server-name parsed-url) (:server-port parsed-url)) 49 | :http 50 | (http/r2open (:url parsed-url)) 51 | ;; default 52 | (ex-info "unsupported url" {:url url}))))) 53 | 54 | (defn cmd 55 | "Send command to the default r2 instance" 56 | [& cmds] 57 | (apply proto/cmd r2-instance cmds)) 58 | 59 | (defn cmdj 60 | "Send JSON command to the default r2 instance" 61 | [& cmds] 62 | (apply proto/cmdj r2-instance cmds)) 63 | 64 | (defn close 65 | "Closes default r2 pipe instance" 66 | [] 67 | (.close r2-instance) 68 | (def r2-instance nil)) 69 | -------------------------------------------------------------------------------- /perl/README.md: -------------------------------------------------------------------------------- 1 | # Radare::r2pipe 2 | 3 | ```perl 4 | use Radare::r2pipe; 5 | 6 | my $r2 = Radare::r2pipe->new('/bin/ls'); 7 | my $result = $r2->cmd('iI'); 8 | my $ds = $r2->cmdj('ij'); 9 | print "Architecture: " . $ds->{bin}->{machine} . "\n"; 10 | $r2->quit(); 11 | 12 | # Other stuff 13 | $r2 = Radare::r2pipe->new; 14 | $r2->open('http://localhost:9090'); 15 | $r2->cmd('pi 5'); 16 | $r2->close(); # Same as quit() 17 | ``` 18 | 19 | ## Description 20 | 21 | The r2pipe APIs are based on a single r2 primitive found behind `r_core_cmd_str()` which is a function that accepts a string parameter describing the r2 command to run and returns a string with the result. 22 | 23 | The decision behind this design comes from a series of benchmarks with different libffi implementations and resulted that using the native API is more complex and slower than just using raw command strings and parsing the output. 24 | 25 | As long as the output can be tricky to parse, it's recommended to use the JSON output and deserializing them into native language objects which results much more handy than handling and maintaining internal data structures and pointers. 26 | 27 | Also, memory management results into a much simpler thing because you only have to care about freeing the resulting string. 28 | 29 | ## METHODS 30 | 31 | ### new($file) 32 | 33 | The new constructor initializes r2 and optionally loads a file into r2. 34 | 35 | ### open($file) 36 | 37 | Opens the file in radare2. It also supports radare2 over TCP sockets (`$r2pipe->open("tcp://127.0.0.1:9080")`) and HTTP (`$r2pipe->open("http://127.0.0.1:9090")`). 38 | 39 | ### cmd($command) 40 | 41 | Executes the command in radare2. 42 | 43 | ### cmdj($command) 44 | 45 | Executes the command in radare2 and JSON decodes the result into a Perl datastructure. 46 | 47 | ### close 48 | 49 | Closes the connection to radare2. 50 | 51 | ### quit 52 | 53 | Closes the connection to radare2. This is exactly the same as the close method. 54 | -------------------------------------------------------------------------------- /haskell/R2Pipe.hs: -------------------------------------------------------------------------------- 1 | module R2Pipe (R2Context(), open, cmd, cmdj) where 2 | import Data.Char 3 | import Data.Word 4 | import Network.HTTP 5 | import System.IO 6 | import System.Process 7 | import System.Environment (getEnv) 8 | import GHC.IO.Handle.FD 9 | import System.Posix.Internals (FD) 10 | import qualified Data.Aeson as JSON 11 | import qualified Data.ByteString.Lazy as L 12 | 13 | withPipes p = p { std_in = CreatePipe, std_out = CreatePipe, std_err = CreatePipe } 14 | 15 | createProcess' args = fmap f $ createProcess (withPipes args) where 16 | f (Just i, Just o, Just e, h) = (i, o, e, h) 17 | f _ = error "createProcess': Failed to open pipes to the subprocess." 18 | 19 | stringToLBS = L.pack . map (fromIntegral . ord) 20 | 21 | lHTakeWhile :: (Word8 -> Bool) -> Handle -> IO L.ByteString 22 | lHTakeWhile p h = do 23 | c <- fmap L.uncons $ L.hGet h 1 24 | case c of 25 | Just (j, _) | p j -> fmap (j `L.cons`) $ lHTakeWhile p h 26 | _ -> return L.empty 27 | 28 | data R2Context = HttpCtx String 29 | | PipeCtx Handle Handle 30 | 31 | open :: Maybe String -> IO R2Context 32 | open (Just url@('h':'t':'t':'p':_)) = return $ HttpCtx (url ++ "/cmd/") 33 | open (Just filename) = do 34 | (hIn, hOut, _, _) <- createProcess' $ proc "radare2" ["-q0", filename] 35 | lHTakeWhile (/= 0) hOut -- drop the inital null that r2 emits 36 | return $ PipeCtx hIn hOut 37 | open Nothing = do 38 | hIn <- fdToHandle =<< (read::(String -> FD)) <$> getEnv "R2PIPE_OUT" 39 | hOut <- fdToHandle =<< (read::(String -> FD)) <$> getEnv "R2PIPE_IN" 40 | return $ PipeCtx hIn hOut 41 | 42 | cmd :: R2Context -> String -> IO L.ByteString 43 | cmd (HttpCtx url) cmd = fmap stringToLBS $ getResponseBody =<< simpleHTTP (getRequest (url ++ urlEncode cmd)) 44 | cmd (PipeCtx hIn hOut) cmd = hPutStrLn hIn cmd >> hFlush hIn >> lHTakeWhile (/= 0) hOut 45 | 46 | cmdj :: JSON.FromJSON a => R2Context -> String -> IO (Maybe a) 47 | cmdj = (fmap JSON.decode .) . cmd 48 | -------------------------------------------------------------------------------- /swift/README.md: -------------------------------------------------------------------------------- 1 | R2PIPE.SWIFT 2 | ============ 3 | 4 | Swift 2.0 API to communicate with a radare2 session using r2pipe. 5 | 6 | Author: pancake 7 | 8 | Description 9 | ----------- 10 | This API provides support to run commands in r2 using different channels: 11 | 12 | * http 13 | * spawn 14 | * pipe 15 | 16 | And can be accessed: 17 | 18 | * sync 19 | * async 20 | 21 | And optionally supports to parse JSON 22 | 23 | Example 24 | ------- 25 | 26 | This example shows how to use the sync and async APIs for HTTP: 27 | 28 | ```swift 29 | if let r2p = R2Pipe("http://cloud.radare.org/cmd/") { 30 | if let str = r2p.cmdSync ("?V") { 31 | print ("Version: \(str)"); 32 | } else { 33 | print ("ERROR: HTTP Sync Call failed"); 34 | } 35 | r2p.cmd("pi 5 @ entry0", closure:{ 36 | (str:String)->() in 37 | print ("Disasm:\n\(str)"); 38 | }); 39 | } 40 | ``` 41 | 42 | But Swift also supports the R2Pipe Env interface: 43 | 44 | ```swift 45 | if let r2p = R2Pipe("#!pipe") { 46 | r2p.cmd ("?V", closure:{ 47 | (str:String) in 48 | print ("R2PIPE.SWIFT: \(str)"); 49 | exit (0); 50 | }); 51 | NSRunLoop.currentRunLoop().run(); 52 | } else { 53 | print ("Invalid R2PIPE_{IN|OUT} environment") 54 | } 55 | ``` 56 | 57 | Which can be executed from inside r2: 58 | 59 | ``` 60 | $ r2 -qc '#!pipe ./main' - 61 | Hello r2pipe.swift! 62 | R2PIPE.SWIFT: 0.10.0-git aka 0.9.9-790-gccd2e51 commit 8899 63 | ``` 64 | 65 | Compilation 66 | ----------- 67 | Use `make` with the following options: 68 | 69 | * HAVE_SPAWN=1 # or 0 70 | * USE_NSURL_SESSION=0 # or 1 - required for iOS9 71 | * TARGET=ios # select ios as target 72 | * IOS=8.4 # specify iOS SDK version 73 | 74 | TODO 75 | ---- 76 | * Add support for `#!pipe` 77 | * Better support for JSON 78 | 79 | JSON Support 80 | ------------ 81 | Use or integrate one of the following libraries: 82 | 83 | * https://github.com/SwiftyJSON/SwiftyJSON 84 | * https://github.com/dankogai/swift-json/ 85 | -------------------------------------------------------------------------------- /clojure/src/r2pipe/tcp.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe.tcp 2 | (:refer-clojure :exclude [read-string]) 3 | (:require [r2pipe.proto :as r2p]) 4 | (:import [java.net Socket])) 5 | 6 | (def cmd-delim -1) 7 | 8 | (defrecord TCPClient [host port socket]) 9 | 10 | (defn- is-connected? [^TCPClient client] (-> client :socket nil? not)) 11 | 12 | ;; this would be nice to async ;) todo: create a pool 13 | (defn- connect [^TCPClient client] 14 | "Connect the client to a new TCP stream" 15 | (if (is-connected? client) 16 | (do 17 | (ex-info "connection already in progress" {:client client}) 18 | client) 19 | (assoc client :socket (Socket. (:host client) (:port client))))) 20 | 21 | (defn- disconnect [^TCPClient client] 22 | "Disconnect the client from the TCP stream" 23 | (if (-> client :socket nil? not) 24 | (do 25 | (-> client :socket .close) 26 | (assoc client :socket nil)) 27 | client)) 28 | 29 | (deftype R2TCP [^TCPClient ^:volatile-mutable client] 30 | r2p/R2Proto 31 | (r2-read [this] 32 | "Read from the r2 TCP stream" 33 | (if (is-connected? client) 34 | (let [s-out (-> client :socket .getInputStream) 35 | output 36 | (apply 37 | str 38 | (map (fn [c] (char c)) 39 | (take-while 40 | (fn [c] (not (= c cmd-delim))) 41 | (repeatedly 42 | #(-> s-out .read)))))] 43 | (.close this) 44 | output) 45 | nil)) 46 | 47 | (r2-write [this input] 48 | "Write to the r2 TCP stream" 49 | (set! client (connect client)) 50 | (let [s-in (-> client :socket .getOutputStream)] 51 | (.write s-in (.getBytes (str input "\n"))) 52 | (.flush s-in))) 53 | 54 | (close [this] 55 | "Close r2 TCP connection, if possible" 56 | (set! client (disconnect client)))) 57 | 58 | (defn r2open 59 | "Creates the TCP connection client" 60 | [host port] 61 | (R2TCP. (->TCPClient host port nil))) 62 | -------------------------------------------------------------------------------- /clojure/src/r2pipe/http.clj: -------------------------------------------------------------------------------- 1 | (ns r2pipe.http 2 | (:refer-clojure :exclude [read-string]) 3 | (:require [r2pipe.proto :as r2p] 4 | [clojure.string :as string] 5 | [clj-http.client :as client])) 6 | 7 | (defrecord HTTPClientData [scheme server port base-uri last-response]) 8 | 9 | (deftype R2HTTP [^HTTPClientData ^:volatile-mutable client-data] 10 | r2p/R2Proto 11 | (r2-read [this] 12 | "Read last response of r2 HTTP server" 13 | (let [response (:last-response client-data)] 14 | (.close this) 15 | response)) 16 | 17 | (r2-write [this input] 18 | "Write request r2 HTTP server" 19 | (let [full-uri 20 | (string/join `(~(:base-uri client-data) 21 | ~(if (string/ends-with? (:base-uri client-data) "/") "" "/") 22 | ~(client/url-encode-illegal-characters input))) 23 | full-url (client/unparse-url 24 | {:scheme (:scheme client-data) 25 | :server-name (:server client-data) 26 | :server-port (:port client-data) 27 | :uri full-uri}) 28 | response (client/get full-url)] 29 | (if (not (= 200 (:status response))) 30 | (ex-info "request in error" 31 | {:status (:status response) 32 | :input input :url full-url 33 | :response response})) 34 | (set! client-data (assoc client-data :last-response (:body response))) 35 | nil)) 36 | 37 | (close [this] 38 | "Closes r2 HTTP client (does nothing really)" 39 | (set! client-data (assoc client-data :last-response nil)))) 40 | 41 | (defn r2open 42 | "Creates the HTTP connection client" 43 | [url] 44 | (let [parsed-url (client/parse-url url)] 45 | (R2HTTP. (->HTTPClientData 46 | (:scheme parsed-url) 47 | (:server-name parsed-url) 48 | (:server-port parsed-url) 49 | (:uri parsed-url) 50 | nil)))) 51 | -------------------------------------------------------------------------------- /dotnet/r2pipe/DllR2Pipe.cs: -------------------------------------------------------------------------------- 1 | /* --pancake */ 2 | using System; 3 | using System.Runtime.InteropServices; 4 | using System.Collections.Generic; 5 | using System.Threading.Tasks; 6 | 7 | namespace r2pipe 8 | { 9 | public class DllR2Pipe : IR2Pipe 10 | { 11 | [DllImport("libr_core")] 12 | private static extern UIntPtr r_core_new(); 13 | [DllImport("libr_core")] 14 | private static extern string r_core_cmd_str(UIntPtr core, string cmd); 15 | [DllImport("libr_core")] 16 | private static extern void r_core_free(UIntPtr core); 17 | 18 | /// 19 | /// The URI 20 | /// 21 | internal UIntPtr core; 22 | 23 | /// 24 | /// Initializes a new instance of the class. 25 | /// 26 | public DllR2Pipe() 27 | { 28 | this.core = r_core_new(); 29 | } 30 | 31 | /// 32 | /// Executes given RunCommand in radare2 33 | /// 34 | /// The command to execute. 35 | /// 36 | /// Returns a string 37 | /// 38 | public string RunCommand(string command) 39 | { 40 | return r_core_cmd_str(this.core, command); 41 | } 42 | 43 | #if !OLDNETFX 44 | /// 45 | /// Executes given RunCommand in radare2 asynchronously 46 | /// 47 | /// The command to execute. 48 | /// 49 | /// Returns a string 50 | /// 51 | public async Task RunCommandAsync(string command) 52 | { 53 | // this is not async at all. use threads? :D 54 | return r_core_cmd_str(this.core, command); 55 | } 56 | #endif 57 | 58 | public void Dispose() 59 | { 60 | r_core_free(this.core); 61 | this.core = new UIntPtr(0); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /r2core-js/README.md: -------------------------------------------------------------------------------- 1 | r2core.js 2 | ========= 3 | 4 | This is the NodeJS module and Browser ready emscripten builds of radare2. 5 | 6 | $ npm install r2core 7 | 8 | And now you can run things like that: 9 | 10 | $ node -e "console.log(new require('r2core')().cmd('?E Hello World'))" 11 | .--. .-------------. 12 | | _| | | 13 | | O O < Hello World | 14 | | | | | | 15 | || | / `-------------' 16 | |`-'| 17 | `---' 18 | 19 | API 20 | --- 21 | The API provided is similar to the r2pipe one, so you can reuse the same scripts. 22 | 23 | * .open() - opens a file from an external resource (vfs/net) 24 | * .cmd() - run a command in r2 and return the string 25 | * .cmdj() - same as above but parsing the output as JSON 26 | * .free() - destroy the instance 27 | 28 | Example 29 | ------- 30 | 31 | You can create multiple instances of RCore and you can open external resources too: 32 | 33 | ```js 34 | const R2Core = require('r2core'); 35 | const c = new R2Core(); 36 | const c2 = new R2Core(); 37 | console.log(c.cmd('wv 123')); 38 | console.log(c2.cmd('p8 4')); 39 | ``` 40 | 41 | Testing 42 | ------- 43 | 44 | To get the latest version of r2core.js download it from npm or [http://cloud.rada.re/asmjs/r2core.js](http://cloud.rada.re/asmjs/r2core.js). 45 | 46 | Building 47 | -------- 48 | 49 | If you are not satisfied by downloading precompiled programs you can also build it yourself by using the `radare2-release` tool that is available via `r2pm`: 50 | 51 | ```sh 52 | $ r2pm -r r2rls docker_asmjs 53 | ``` 54 | 55 | Now you may run `make` to minify the radare2.js and generating r2core.js. 56 | This process is using uglifyjs and closurejs and requires at least 2GB of RAM. 57 | 58 | You can now use this file from nodejs or the browser 59 | 60 | * open webtest.html 61 | * node test.js 62 | 63 | Future 64 | ------ 65 | 66 | * Integration with brotli (Compression goes from 16MB to 1.8MB) 67 | * Open Buffers instead of fs/network resources 68 | 69 | Author 70 | ------ 71 | 72 | * pancake 73 | -------------------------------------------------------------------------------- /typescript/README.md: -------------------------------------------------------------------------------- 1 | # r2pipe API for radare2 2 | 3 | ![r2pipe logo](http://lolcathost.org/b/r2pipe.png) 4 | 5 | This is a reimplementation in TypeScript of the original `r2pipe` and `r2pipe-promise` modules for NodeJS. 6 | 7 | ## Usage 8 | 9 | If you are using r2skel (`r2pm -ci r2skel`) you can get a hello world to use this module with the following line: 10 | 11 | ``` 12 | r2pm -r r2skel r2-script-r2pipe-ts hello-ts 13 | make -C hello-ts 14 | ``` 15 | 16 | ## Basics 17 | 18 | The basic fundamentals of r2pipe is that you the API provides the most basic communication channel with r2, this is a single function called `cmd` that takes the command to be executed and returns the output of the command as a string. 19 | 20 | As long as many commands in r2 return JSON, it is ideal for working with TS/JS, because using `cmdj()` the API will convert the output into an object. 21 | 22 | In order to provide compatibility with all kind of backends, the whole api has been made asynchronous, this allows the developer to change the backend by only changing one line. 23 | 24 | Note that stderr events are not handled by this API, process stdin/stdout is also not handled by r2pipe, but there are ways to manage it if needed. 25 | 26 | ## Supported r2pipe methods 27 | 28 | * http (since node 18, plaintext http networking is not allowed unless you use the `--insecure-http-parser` flag) 29 | * spawn (launch a new radare2 process and communicate with it sending async commands to collect the response) 30 | * local (the local pipe is used when launching scripts from `r2 -i too.ts` or `> . too.ts` 31 | 32 | ## r2Frida-Compile 33 | 34 | radare2 also supports the esm modules generated by frida-compile. But it is worth to mention that r2frida comes with a C reimplementation of frida-compile (python). Which ships a typescript compiler and is able to pack multiple ts/js files into a single file. 35 | 36 | ## Runtime 37 | 38 | This module is suposed to run with NodeJS, under some circunstancies, it may also with with r2js, bun or deno. 39 | 40 | ## Author 41 | 42 | --pancake <@nopcode.org> 43 | -------------------------------------------------------------------------------- /nodejs/r2pipe/sync.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const util = require('./util'); 4 | const fs = require('fs'); 5 | const proc = require('child_process'); 6 | 7 | const BUFLEN = 1024; 8 | 9 | function runCmdSync (ls, cmd) { 10 | let result = ''; 11 | let buf = new Buffer(BUFLEN); 12 | let bread = 0; 13 | /* 14 | if (typeof ls.syncStdin !== 'number' || isNaN(ls.syncStdin)) { 15 | throw new Error('This must run from inside radare2.'); 16 | } 17 | */ 18 | fs.writeSync(ls.syncStdin, cmd + '\n'); 19 | while ((bread = fs.readSync(ls.syncStdout, buf, 0, BUFLEN, null)) > 0) { 20 | /* check for cmd end */ 21 | if (buf[bread - 1] !== 0x00) { 22 | result += buf.slice(0, bread).toString(); 23 | } else { 24 | result += buf.slice(0, bread - 1).toString(); 25 | break; 26 | } 27 | } 28 | 29 | return result; 30 | } 31 | 32 | function parseJSON (func, cmd) { 33 | const res = func(cmd); 34 | if (res === null) { 35 | return res; 36 | } 37 | try { 38 | return JSON.parse(res); 39 | } catch (e) { 40 | return null; 41 | } 42 | } 43 | 44 | function r2bind (ls, r2cmd) { 45 | const buf = new Buffer(1024); 46 | 47 | /* Wait for radare2 to start */ 48 | if (r2cmd === 'pipe') { 49 | fs.readSync(ls.syncStdout, buf, 0, 1024, null); 50 | } 51 | 52 | const r2 = { 53 | /* Run R2 cmd */ 54 | cmd: function (cmd) { 55 | return runCmdSync(ls, util.cleanCmd(cmd)); 56 | }, 57 | 58 | /* Run cmd and return JSON output */ 59 | cmdj: function (cmd) { 60 | return parseJSON(r2.cmd, util.cleanCmd(cmd)); 61 | }, 62 | 63 | /* Run system cmd */ 64 | syscmd: function (command, cb2) { 65 | return proc.execSync(command).toString(); 66 | }, 67 | 68 | syscmdj: function (cmd) { 69 | return parseJSON(r2.syscmd, cmd); 70 | }, 71 | 72 | /* Quit CMD */ 73 | quit: function () { 74 | if (ls.stdin && ls.stdin.end) { 75 | ls.stdin.end(); 76 | } 77 | ls.kill('SIGINT'); 78 | } 79 | }; 80 | 81 | return r2; 82 | } 83 | 84 | module.exports.r2bind = r2bind; 85 | -------------------------------------------------------------------------------- /typescript/r2pipe/http.ts: -------------------------------------------------------------------------------- 1 | import * as http from "http"; 2 | import { R2PipeBase } from "./base.js"; 3 | 4 | /** 5 | * Extends the `R2PipeBase` class to provide an HTTP-based implementation of the r2pipe protocol. 6 | */ 7 | export class R2PipeHttp extends R2PipeBase { 8 | private baseUrl: string; 9 | 10 | /** 11 | * Initializes a new instance of the `R2PipeHttp` class with the specified base URL. 12 | * @param url - The base URL for the HTTP-based r2pipe protocol. f.ex: `http://host:port` 13 | */ 14 | constructor(baseUrl: string) { 15 | super(); 16 | this.baseUrl = baseUrl; 17 | } 18 | 19 | /** 20 | * Executes the given r2 command and returns the response as a string. 21 | * @param command - The r2 command to execute. 22 | * @returns The response from the r2 command as a string. 23 | */ 24 | async cmd(command: string): Promise { 25 | return this.httpCmd(this.baseUrl, command); 26 | } 27 | 28 | /** 29 | * Closes the connection to the r2 process and returns a boolean indicating whether the operation was successful. 30 | * @returns `true` if the connection was closed successfully, `false` otherwise. 31 | */ 32 | async quit(): Promise { 33 | // do nothing 34 | return true; 35 | } 36 | 37 | private async httpCmd(uri: string, cmd: string): Promise { 38 | return new Promise((resolve, reject) => { 39 | const url = `${uri}/cmd/${cmd}`; 40 | http.get(url, (res: http.IncomingMessage) => { 41 | if (res.statusCode !== 200) { 42 | reject(new Error(`Request Failed. Status Code: ${res.statusCode}`)); 43 | res.resume(); // Consume response data to free up memory 44 | return; 45 | } 46 | res.setEncoding('utf8'); 47 | let rawData = ''; 48 | res.on('data', (chunk: string) => { rawData += chunk; }); 49 | res.on('end', () => { 50 | resolve(rawData); 51 | }); 52 | }).on('error', (e: Error) => { 53 | reject(new Error(`Error making HTTP request: ${e.message}`)); 54 | }); 55 | }); 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /typescript/r2pipe/local.ts: -------------------------------------------------------------------------------- 1 | import { R2PipeBase } from "./base.js"; 2 | import { R2PipeQueue } from "./queue.js"; 3 | import * as fs from "fs"; 4 | import * as os from "os"; 5 | import * as net from "net"; 6 | 7 | export class R2PipeLocal extends R2PipeBase { 8 | private stream: R2PipeQueue; 9 | 10 | constructor() { 11 | super(); 12 | if (os.platform() === 'win32') { 13 | const R2PIPE_PATH = process.env.R2PIPE_PATH; 14 | const client = net.connect('\\\\.\\pipe\\' + R2PIPE_PATH) as any; 15 | // TODO: we just need the read and write methods, but net.Socket doesnt have path or close() 16 | this.stream = new R2PipeQueue(client, client); 17 | } else { 18 | const envIn = process.env.R2PIPE_IN; 19 | const envOut = process.env.R2PIPE_OUT; 20 | if (!envIn || !envOut) { 21 | throw new Error('This script must be executed from r2 -c "#!pipe node foo.js"'); 22 | } 23 | const IN = parseInt(envIn); 24 | const OUT = parseInt(envOut); 25 | if (!IN || !OUT) { 26 | throw new Error('This script must be executed from r2 -c "#!pipe node foo.js"'); 27 | } 28 | const input = fs.createWriteStream(null, { fd: OUT }); 29 | const output = fs.createReadStream(null, { fd: IN }); 30 | this.stream = new R2PipeQueue(input, output); 31 | } 32 | } 33 | 34 | /** 35 | * Executes a command in the radare2 pipe and returns the output as a Promise. 36 | * 37 | * @param command - The command to execute in the radare2 pipe. 38 | * @returns A Promise that resolves with the output of the command, or rejects with an error. 39 | */ 40 | async cmd(command: string): Promise { 41 | return new Promise((resolve, reject) => { 42 | this.stream.cmd(command, (error, res) => { 43 | if (error) { 44 | reject(error); 45 | } else { 46 | resolve(res); 47 | } 48 | }); 49 | }); 50 | } 51 | 52 | async quit(): Promise { 53 | this.stream.dispose(); 54 | this.stream = null; 55 | process.kill(process.pid, 'SIGINT'); 56 | return true; 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /dart/r2pipe-ffi.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ffi' as ffi; 2 | import 'dart:convert' show utf8; 3 | /* doesnt exist 4 | 5 | import "package:ffi/ffi.dart"; 6 | 7 | typedef RCoreCmdStrFunc = ffi.Pointer Function(ffi.Pointer, ffi.Pointer); 8 | typedef RCoreCmdStr = String Function(ffi.Pointer, String); 9 | */ 10 | 11 | typedef RCoreNewFunc = ffi.Pointer Function(); 12 | typedef RCoreNew = ffi.Pointer Function(); 13 | 14 | typedef RCoreFreeFunc = ffi.Void Function(ffi.Pointer); 15 | typedef RCoreFree = void Function(ffi.Pointer); 16 | 17 | /* 18 | https://pub.dev/packages/ffi/example 19 | ------------------------------------ 20 | 21 | import 'dart:ffi'; 22 | import 'package:ffi/ffi.dart'; 23 | 24 | void main() { 25 | // Allocate and free some native memory with calloc and free. 26 | final pointer = calloc(); 27 | pointer.value = 3; 28 | print(pointer.value); 29 | calloc.free(pointer); 30 | 31 | // Use the Utf8 helper to encode zero-terminated UTF-8 strings in native memory. 32 | final String myString = '😎👿💬'; 33 | final Pointer charPointer = myString.toNativeUtf8(); 34 | print('First byte is: ${charPointer.cast().value}'); 35 | print(charPointer.toDartString()); 36 | calloc.free(charPointer); 37 | } 38 | 39 | */ 40 | 41 | void main() { 42 | print('Hello Radare2 from Dart!'); 43 | 44 | var libraryPath = '/usr/local/lib/libr_core.dylib'; 45 | 46 | final dylib = ffi.DynamicLibrary.open(libraryPath); 47 | final RCoreNew r_core_new = dylib 48 | .lookup>('r_core_new') 49 | .asFunction(); 50 | final RCoreFree r_core_free = dylib 51 | .lookup>('r_core_free') 52 | .asFunction(); 53 | // Call the function 54 | var a = r_core_new(); 55 | /* 56 | final pathC = Utf8.toUtf8(path); 57 | final RCoreCmdStr r_core_cmd_str = dylib 58 | .lookup>('r_core_cmd_str') 59 | .asFunction(); 60 | 61 | // var cmd = utf8.encode("?E Hello"); 62 | // var r = r_core_cmd_str (a, cmd); 63 | */ 64 | print(a); 65 | r_core_free (a); 66 | // r_core_cmd(); 67 | } 68 | -------------------------------------------------------------------------------- /python/examples/sync/talkto.py: -------------------------------------------------------------------------------- 1 | # 2 | # Author: 3 | # - Sergi Alvarez 4 | # - pancake@nopcode.org 5 | # 6 | # Requires: 7 | # - r2 from git 8 | # - r2pipe 0.9.0 9 | # - r2pm -i lang-python 10 | # - Python 2 or 3 11 | # 12 | # HowTo: 13 | # - Run r2 -c=h /bin/ls 14 | # - Run r2 -C http://localhost:9090/cmd/ 15 | # - Run r2 -i talkto.py /bin/ls 16 | # 17 | 18 | import r2pipe 19 | 20 | try: 21 | r2 = r2pipe.open() 22 | r2.cmd("e cfg.user=pancake") 23 | r2.cmd("e cfg.log=true") 24 | 25 | r2.cmd("T this is me") 26 | r2.cmd("CC hello world") 27 | logs = r2.cmd("T") 28 | print (logs) 29 | except: 30 | print ("You need r2pm -i lang-python") 31 | pass 32 | 33 | last = "" 34 | last2 = "" 35 | r2r = r2pipe.open("http://localhost:9090") 36 | r2r.cmd("e cfg.log=true") 37 | print r2r.cmd("o") 38 | 39 | 40 | def pull(): 41 | global last2 42 | print "PULL" 43 | items = r2r.cmdj("Tj%s" % (last2)) 44 | print "Syncing %s" % (last2) 45 | if len(items) > 0: 46 | print "ITEMS" 47 | for (id, msg) in items: 48 | print ("MUST RUN IN LOCAL %s" % (msg)) 49 | r2.cmd("e cfg.log=0") 50 | r2.cmd(msg[1:]) 51 | r2.cmd("e cfg.log=1") 52 | if id > last2 or last2 == "": 53 | last2 = id 54 | last2 = last2 + 1 55 | 56 | 57 | def runmsg(msg): 58 | if msg[0] == ":": 59 | print ("RUN REMOTE %s" % (msg)) 60 | r2r.cmd(msg[1:]) 61 | elif msg[0] == "<": 62 | print ("CHAT %s" % (msg)) 63 | else: 64 | print ("UNK %s" % (msg)) 65 | 66 | 67 | def sync(): 68 | global last 69 | print "Syncing %s" % (last) 70 | items = r2.cmdj("Tj%s" % (last)) 71 | if len(items) > 0: 72 | print "ITEMS" 73 | for (id, msg) in items: 74 | runmsg(msg) 75 | if id > last or last == "": 76 | last = id 77 | last = last + 1 78 | print ("LAST %s" % (last)) 79 | pull() 80 | 81 | 82 | # initialize 83 | r2.cmd('"e cmd.log=#!python -e sync()"') 84 | r2.cmd('"e cmd.prompt=#!python -e sync()"') 85 | r2.cmd('"e cmd.vprompt=#!python -e sync()"') 86 | -------------------------------------------------------------------------------- /typescript/r2pipe/queue.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | 3 | interface R2PipeQueueItem { 4 | cmd: string; 5 | result: string; 6 | cb: any; 7 | error: Error; 8 | } 9 | 10 | /** 11 | * Manages a queue of R2Pipe commands and their corresponding results. 12 | * 13 | * The `R2PipeQueue` class is responsible for sending commands to the 14 | * R2Pipe input stream and handling the responses from the output stream. 15 | * 16 | * It maintains a queue of pending commands and their associated callbacks, 17 | * and processes the responses in the order they were sent. 18 | */ 19 | export class R2PipeQueue { 20 | private pipeQueue: R2PipeQueueItem[]; 21 | private output: fs.ReadStream; 22 | private input: fs.WriteStream; 23 | 24 | constructor(input: fs.WriteStream, output: fs.ReadStream) { 25 | this.pipeQueue = []; 26 | this.input = input; 27 | this.output = output; 28 | this.output.on('data', (data: Buffer) => { 29 | this.onData(data); 30 | }); 31 | } 32 | dispose(): void { 33 | this.input.destroy(); 34 | this.output.destroy(); 35 | } 36 | cmd(cmd: string, cb: any) { 37 | this.pipeQueue.push({ 38 | cmd: cmd, 39 | cb: cb, 40 | result: '', 41 | error: null 42 | }); 43 | if (this.pipeQueue.length === 1) { 44 | this.input.write(cmd + '\n'); 45 | } 46 | } 47 | onData(data: Buffer) { 48 | let len = data.length; 49 | if (this.pipeQueue.length < 1) { 50 | return new Error('r2pipe error: No pending commands for incomming data'); 51 | } 52 | 53 | const pq0 = this.pipeQueue[0]; 54 | if (len > 0 && data[len - 1] !== 0x00) { 55 | pq0.result += data.toString(); 56 | return pq0.result; 57 | } 58 | 59 | while (len > 0 && data[len - 1] == 0x00) { 60 | len--; 61 | } 62 | 63 | pq0.result += data.slice(0, len).toString(); 64 | pq0.cb(pq0.error, pq0.result); 65 | this.pipeQueue.splice(0, 1); 66 | 67 | if (this.pipeQueue.length > 0) { 68 | try { 69 | this.input.write(this.pipeQueue[0].cmd + '\n'); 70 | } catch (e) { 71 | console.error(e); 72 | } 73 | } 74 | } 75 | } 76 | 77 | 78 | --------------------------------------------------------------------------------