npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

r2pipe

v2.8.6

Published

NodeJS r2pipe API for radare2

Downloads

233

Readme

Pipe bindings for radare2 (r2pipe)

r2pipe logo

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.

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.

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.

Also, memory management results into a much simpler thing because you only have to care about freeing the resulting string.

Getting Started

This plugin requires radare >= 0.9.8 (some features such as lpipe require git version)

Once radare2 is installed, you may install this plugin using this command:

npm install r2pipe

Once the plugin has been installed, you can load it with this line of JavaScript:

var r2pipe = require('r2pipe');

Spawn options

The r2pipe.options array is used to specify the extra arguments passed to r2 when using any spawn method like .launch() or .pipe() and their *Sync versions.

var r2pipe = require('r2pipe');
r2pipe.options = ['-n'];
var r2 = r2pipe.open('/bin/ls');
console.log (r2.cmd('x'));
r2.quit();

Promises

In order to use promises, async, co, .. with r2pipe, checkout the r2pipe-promise module.

Access methods

There are multiple ways to interact with a radare2 session

open ([uri], [callback])

Runs different connection methods depending on the uri and the number of arguments

var r2pipe = require('r2pipe');

function doStuff (err, r2p) {
  if (!err) {
    console.log (r2p.cmdj('ij'));
  } else  {
    console.log(`Error: ${err.message}`)
  }
  r2p.quit();
}

/* rlang r2pipe script ( r2 -qi foo.js /bin/ls ) */
r2pipe.open (doStuff);

r2pipe.open ('/bin/ls', doStuff);

r2pipe.open ('http://cloud.radare.org/cmd/', doStuff);

This method can be also used when running node scripts from r2 like this:

$ cat test.js
var r2 = require('r2pipe').open();
console.log(r2.cmd('x'));
r2.quit();
$ r2 -qi test.js /bin/ls

As long as open() gets no parameters, the r2pipe api asumes you are performing a sync lpipe connection. This is the same as calling openSync().

openSync ([uri])

Runs different synchronous connection methods depending on the uri and the number of arguments

NOTE: only lang and pipe methods supported, no http or so

var r2pipe = require('r2pipe');

/* sync rlang script */
try {
  var r2p = r2pipe.openSync ();
  console.log (r2p.cmdj('ij'));
  r2p.quit();
} catch (e) {
  console.error (e.message);
}

/* sync file open */
var r2p = r2pipe.openSync ('/bin/ls');
...

pipe (binfile, callback)

Spawns a new process and comunicate with it through standard stdin, stdout, stderr file descriptors

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   ...
}

r2pipe.pipe ("/bin/ls", doSomeStuff);

lpipe (callback)

This method is intended to be used while running scripts from the r2 console

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   ...
}

r2pipe.lpipe (doSomeStuff);

Execute the script from r2 command prompt

$ r2 binfile.elf
[0x080480a0]> #!pipe node /tmp/yourscript.js
Analizing file
Analysis finished
Searching for syscalls
 - found Syscall: write
 - found Syscall: close
 - found Syscall: read
 - found Syscall: write
 - found Syscall: exit
 - found Syscall: write
 - found Syscall: munmap
 - found Syscall: mmap
[0x080480a0]>

launch (binfile, callback)

Launch radare2 and listen for cmds through a tcp port

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   ...
}

r2pipe.launch ("/bin/ls", doSomeStuff);

ioplugin(callback)

Callback for the libr/io/r2pipe plugin interface to write IO plugins using the r2pipe api.

var r2pipe = require('r2pipe');

r2pipe.ioplugin(function (err, io, msg) {
  switch (msg.op) {
    case 'read':
      var obj = {
        result: msg.count,
        data: [1, 2, 3]
      };
      io.send(obj);
      break;
    /* ... */
    default:
      io.send();
      break;
  }
});

connect (url, callback)

Connect to an already running radare2 instance running an http listener

~$ r2 -
 -- Trust no one, nor a zero. Both lie.
[0x00000000]> =h 8182
Starting http server...
open http://localhost:8182/
r2 -C http://localhost:8182/cmd/
var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   ...
}

r2pipe.connect ("http://localhost:8182/cmd/", doSomeStuff);

API

r2pipes provides six basic commands

cmd (r2cmd, [callback])

Runs a radare2 command

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   r2.cmd ("iS", function(err, output) {
    console.log (output);
  });
}

r2pipe.launch ("/bin/ls", doSomeStuff);

cmdj (r2cmd, [callback])

Runs a radare2 command and tries to convert the output into an object.

Note that this will only work with commands producing JSON output.

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   r2.cmdj ("iSj", function(err, output) {
    if (output !== null)
       console.log (output);
    else
       console.log("An error has occurred");
  });
}

r2pipe.launch ("/bin/ls", doSomeStuff);

In case of error "null" will be passed as argument to the callback instead of an valid object

syscmd (oscmd, [callback])

Runs a system command, used mainly to access radare companion tools such as rabin2, raddif2, etc...

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   r2.syscmd ("rabin2 -S /bin/true", function(err, output) {
    console.log (output);
  });
}

r2pipe.launch ("/bin/ls", doSomeStuff);

syscmdj (oscmd, [callback])

Runs a system command and tries to convert the output into an object.

Note that this will only work with commands producing JSON output.

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   r2.syscmdj ("rabin2 -j -S /bin/true", function(err, output) {
    console.log (output);
  });
}
t
r2pipe.launch ("/bin/ls", doSomeStuff);

In case of error "null" will be passed as argument to the callback instead of an valid object

quit ()

Close the connection, kill the radare spawned process or terminate the lpipe script execution

var r2pipe = require('r2pipe');

function doSomeStuff(err, r2) {
   r2.quit();
}

r2pipe.launch ("/bin/ls", doSomeStuff);

Example

This is a small example using the pipe connection method for standalone scripts.

var r2pipe = require ("r2pipe");

function doSomeStuff(err, r2) {

  r2.cmdj ("aij entry0+2", function(err, o) {
    console.log (o);
  });

  r2.cmd ('af @ entry0', function(err, o) {
    r2.cmd ("pdf @ entry0", function(err, o) {
      console.log (o);
      r2.quit ()
    });
  });

}

r2pipe.pipe ("/bin/ls", doSomeStuff);
r2pipe.launch ("/bin/ls", doSomeStuff);
r2pipe.connect ("http://cloud.rada.re/cmd/", doSomeStuff);