Using RAsm
April 26, 2016
RAsm
Recently I have noticed that many people gets saturated by the amount of stuff r2 can do and most users end up not learning anything.
So that’s why I am going to start writing a series of blog posts showing one feature at a time, making it as simple as possible.
What’s rasm?
The ‘r’ in r_asm
stands for radare, and it’s one of the several libraries shipped with radare2.
As long as it’s been designed with modularity in mind, you can use any of the r2 libraries by separate without having to ship or link with the entire framework.
The RAsm API is described in the vapi docs but you may find the real one in the .h file
Pluggable
Thanks to the modular design, every library shipped in r2 can be extended with plugins.
The plugins can be statically linked inside the library at compile time or loaded from separate shared libraries (dll, dylib, so) when placed in some directories or loaded with the r2 plugin API.
We will not go that far for now, but we must learn that every program in r2 handles the -L
flag in order to enumerate all the related plugins:
- r2 -L : list IO plugins
- rasm2 -L : list ASM/ANAL plugins
- rabin2 -L : list RBIN plugins
- rahash2 -L : list CRYPTO/HASH plugins
- …
Here’s the current output for rasm2 -L
, which shows the following:
- a : capable to assemble (ollyasm, custom, ..)
- d : disassemble (using capstone, gnu, custom, ..)
- A : analyze (associated r_anal plugin)
- e : emulate (provides ESIL)
$ rasm2 -L
_dAe 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU
_dA_ 8 8051 PD 8051 Intel CPU
_dA_ 16 32 arc GPL3 Argonaut RISC Core
a___ 16 32 64 arm.as LGPL3 as ARM Assembler (use ARM_AS environment)
adAe 16 32 64 arm BSD Capstone ARM disassembler
_dA_ 16 32 64 arm.gnu GPL3 Acorn RISC Machine CPU
_d__ 16 32 arm.winedbg LGPL2 WineDBG's ARM disassembler
adAe 8 16 avr GPL AVR Atmel
adAe 16 32 64 bf LGPL3 Brainfuck
_dA_ 16 cr16 LGPL3 cr16 disassembly plugin
_dA_ 32 cris GPL3 Axis Communications 32-bit embedded processor
_dA_ 16 csr PD Cambridge Silicon Radio (CSR)
adA_ 32 64 dalvik LGPL3 AndroidVM Dalvik
ad__ 16 dcpu16 PD Mojang's DCPU-16
_dA_ 32 64 ebc LGPL3 EFI Bytecode
adAe 16 gb LGPL3 GameBoy(TM) (z80-like)
_dAe 16 h8300 LGPL3 H8/300 disassembly plugin
_d__ 32 hppa GPL3 HP PA-RISC
_dAe i4004 LGPL3 Intel 4004 microprocessor
_dA_ 8 i8080 BSD Intel 8080 CPU
adA_ 32 java Apache Java bytecode
_d__ 32 lanai GPL3 LANAI
_d__ 8 lh5801 LGPL3 SHARP LH5801 disassembler
_d__ 32 lm32 BSD disassembly plugin for Lattice Micro 32 ISA
_dA_ 16 32 m68k BSD Motorola 68000
_dA_ 32 m68k.cs BSD Capstone M68K disassembler
_dA_ 32 malbolge LGPL3 Malbolge Ternary VM
_d__ 16 mcs96 LGPL3 condrets car
adAe 16 32 64 mips BSD Capstone MIPS disassembler
adAe 32 64 mips.gnu GPL3 MIPS CPU
_dA_ 16 msp430 LGPL3 msp430 disassembly plugin
_dA_ 32 nios2 GPL3 NIOS II Embedded Processor
_dAe 8 pic18c LGPL3 pic18c disassembler
_dA_ 32 64 ppc BSD Capstone PowerPC disassembler
_dA_ 32 64 ppc.gnu GPL3 PowerPC
ad__ rar LGPL3 RAR VM
_dA_ 32 64 riscv GPL RISC-V
_dA_ 32 sh GPL3 SuperH-4 CPU
_dA_ 8 16 snes LGPL3 SuperNES CPU
_dAe 32 64 sparc BSD Capstone SPARC disassembler
_dA_ 32 64 sparc.gnu GPL3 Scalable Processor Architecture
_d__ 16 spc700 LGPL3 spc700, snes' sound-chip
_d__ 32 sysz BSD SystemZ CPU disassembler
_dA_ 32 tms320 LGPLv3 TMS320 DSP family
_d__ 32 tricore GPL3 Siemens TriCore CPU
_dAe 32 v810 LGPL3 V810 disassembly plugin
_dA_ 32 v850 LGPL3 v850 disassembly plugin
_dAe 8 32 vax GPL VAX
_dA_ 32 ws LGPL3 Whitespace esotheric VM
a___ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler
_dAe 16 32 64 x86 BSD Capstone X86 disassembler
a___ 16 32 64 x86.nasm LGPL3 X86 nasm assembler
a___ 16 32 64 x86.nz LGPL3 x86 handmade assembler
ad__ 32 x86.olly GPL2 OllyDBG X86 disassembler
a___ 32 x86.tab LGPL3 x86 table lookup assembler
_dAe 16 32 64 x86.udis BSD udis86 x86-16,32,64
_dA_ 32 xcore BSD Capstone XCore disassembler
_dAe 32 xtensa GPL3 XTensa CPU
adA_ 8 z80 NC-GPL2 Zilog Z80
_d__ 8 z80.cr LGPL Zilog Z80
_d__ 32 swf LGPL3 SWF
_d__ 32 propeller LGPL3 propeller disassembly plugin
What can RAsm do for me?
Using rasm2
we can directly use that functionality and be able to assemble and disassemble code from the commandline.
We can provide different options to it, which defaults to the current system ones:
- -a : specify plugin arch name (arm, x86, mips, …)
- -b : specify bits (16, 32, 64) (arm-16 is thumb)
- -o : offset where this instruction is
- -s : change syntax for ATT, MASM, INTEL, ..
- -e : swap endian (for bi-endian archs)
By default rasm2
will assemble the argument passed, but using the -d switch it will expect an hexpair and give back the disassembled instruction for the selected architecture.
Rasm2 is not just an instruction assembler/disassembler. It can also handle source files like nasm
or gas
do. As well as disassemble raw files without parsing binary headers using the -f option.
Commandline
Let’s see how this thing works:
$ rasm2 -a x86 -b 32 "mov eax, 33"
b821000000
$ rasm2 -a x86 -b 32 -d b821000000
mov eax, 33
In case the default assembler doesn’t supports a specific instruction we can switch to another one:
$ rasm2 -L | grep x86 | grep ^a
a___ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler
a___ 16 32 64 x86.nasm LGPL3 X86 nasm assembler
a___ 16 32 64 x86.nz LGPL3 x86 handmade assembler
ad__ 32 x86.olly GPL2 OllyDBG X86 disassembler
a___ 32 x86.tab LGPL3 x86 table lookup assembler
like this:
$ rasm2 -a x86 -b32 'jbe 33'
Cannot assemble 'jbe 33' at line 3
$ rasm2 -a x86.nasm -b32 'jbe 33'
0f861b000000
Using the API
As long as this functionality is implemented in a library we can just use the API from C, C++, or any of the languages supported by radare2-bindings:
#include <r_asm.h>
int main() {
RAsmOp op = {0};
RAsm *a = r_asm_new ();
r_asm_use (a, "x86");
r_asm_set_bits (a, 32);
r_asm_set_pc (a, 0x80000);
r_asm_disassemble (a, &op, "\x90", 1);
printf ("%s\n", op.buf_asm);
r_asm_free (a);
return 0;
}
The latest version of r2 supports a simplified API which can be used like this:
#include <r_asm.h>
int main() {
RAsm *a = r_asm_new ();
r_asm_set_arch (a, "x86", 32);
/* assemble */
int i, buflen;
ut8 *buf = r_asm_from_string (a, 0x4000, "nop", &buflen);
if (buf) {
for (i = 0; i < buflen; i++) {
printf ("%02x", buf[i]);
}
printf ("\n");
}
/* disassemble */
char *code = r_asm_to_string (a, 0x4000, "\x90\x90", 2);
if (code) {
printf ("%s\n", code);
free (code);
}
r_asm_free (a);
}
Scripting
The radare2-bindings repository provides several bindings for a long list of programming languages.
Those bindings are automatically generated by valabind, which parses the VAPI api description files and generates the wrapper code for Python, NodeJS, Ruby, C#, …
Check out the examples under the t/
subdirectories to find out examples like this Python one:
from r2.r_asm import *
def ass(a, arch, op):
print "OPCODE: %s"%op
a.use (arch)
print "ARCH: %s"%arch
code = a.massemble (op)
if code is None:
print "HEX: Cannot assemble opcode"
else:
print "HEX: %s"%code.buf_hex
a = RAsm()
ass (a, 'x86.olly', 'mov eax, 33')
ass (a, 'java', 'bipush 33')
R2Pipe
R2Pipe provides a simple command
-> result
interface to talk to radare2, this eases the integration of radare2 into several other programs, without depending on a local installation of r2 because r2pipe can speak to http
, pipes
and other channels.
For this we must use the proper r2 commands:
- pa assemble code inline
- pad disassemble code inline
[0x00000000]> pa nop
90
[0x00000000]> pad 90
nop
We can also temporary change the arch/bits setup using the @
operator like this (see ?@?
output for more help):
[0x00000000]> pad 0d20a0e3 @a:arm:16
movs r0, 0xd
b 0x746
And merge this stuff into something like this nodejs script:
'use strict';
const r2pipe = require('r2pipe')
r2pipe.connect('http://cloud.radare.org/cmd', (r2p) {
r2p.cmd("pad 90@a:x86:32", (res)=> {
console.log('0x90 for x86:32 means:', res);
})
})
Conclusions
Radare2 provides multiple functionalities splitted into separate libraries, which at the same time are extended by plugins (for r_asm using capstone, keystone, nasm, GNU binutils, ..).
This functionality is accessible thru the r2 commandline, the rasm2 program and using the C API.