Javascript in r2

May 13, 2014

One of the most prominent scripting languages right now is Javascript. Browsers rule the Internet and they all can execute code in this language, in addition, several other programming languages like C, C++, Go, Wisp, CoffeeScript, TypeScript, LUA, Python, Perl, Dart, Java, … can be transpiled into JS.

For those reasons r2 implements several ways to run Javascript and interact with the core APIs and commands.

  • Embedded WebServer (using AJAX from client side)
  • Duktape RLang plugin (#!duktape)
  • NodeJS (node-ffi API bindings)

To run the r2 web server type the following command:

$ r2 -c=H /bin/ls

Note that =H command starts the webserver and opens the webbrowser, use =h to not start the client’s browser.

The website it’s served by default can be tested in http://cloud.rada.re and it’s source is available at shlr/www (see http.root eval var). All the contents of that website are generated by Javascript by using the r2.js script.

This script can be reusable by any other implementation of Javascript (in web browser or commandline). It provides a work-in-progress API to interact with r2 by running r2 commands and parsing the output and returning JSON objects.

Recent versions of r2 feature a j suffix on some commands to display the output in JSON format. This is very helpful for the JS bindings because it’s used as a native data serialization method.

This is an example:

r2.getInfo = function(cb) {
  r2.cmd ("ij", function (o) {
    cb (JSON.parse (o));
  });
}
r2.getInfo (function(i) {
  print (i.type);
}

As you may see, the API sports an asynchronous methodology, but in commandline version you can pass only one parameter to ‘r2.cmd()’ and get the result in return.

[0x10004503]> #!duktape
duktape> print (r2.cmd ("pd 10"))

The easiest (and smaller) way to run JS in the r2 shell is by building the libr/lang/p/duktape plugin:

$ git clone git://github.com/radare/radare2-bindings
$ cd radare2-bindings/libr/lang/p
$ make
$ mkdir -p ~/.config/radare2/plugins
$ cp -f lang_duktape.so ~/.config/radare2/plugins/

After running those commands spawn a new r2 - shell and type #! to list all the supported hashbangs, which are the scripting languages available.

[0x1000010f8]> #!
 c: C language extension
 vala: VALA language extension
 duktape: JavaScript extension language using DukTape

And finally, we may meet the NodeJS bindings, which can be installed from radare2-bindings/node-ffi directory or by using npm:

$ npm install radare2.js

You may find in radare2-bindings/node-ffi-examples directory some scripts for the NodeJS API. Which is generated by valabind and therefor supports all the native library functions that are defined in the .vapi files.

var r2 = require('r_asm');

function Assembler(arch, bits) {
  var $this = new r2.RAsm();
  $this.use(arch);
  $this.set_bits(bits);
  this.assemble = function(x) {
    return $this.massemble(x).buf_hex;
  };
  this.disassemble = function(x) {
    return $this.mdisassemble_hexstr(x).buf_asm;
  };
}

var asm = new Assembler('x86', 32);
console.log(asm.assemble('int 0x80; mov eax, 33; ret'));
console.log(asm.disassemble('909090'));

Those are just the initial comments in order to extend or automate r2 using Javascript, now it’s your turn. Enjoy!