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

: list plugins rasm2 -L : list ASM/ANAL plugins

: list plugins rabin2 -L : list RBIN plugins

: list plugins rahash2 -L : list CRYPTO/HASH plugins

: list plugins …

Here’s the current output for rasm2 -L , which shows the following:

a : capable to assemble (ollyasm, custom, ..)

: capable to assemble (ollyasm, custom, ..) d : disassemble (using capstone, gnu, custom, ..)

: disassemble (using capstone, gnu, custom, ..) A : analyze (associated r_anal plugin)

: 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, …)

: specify plugin arch name (arm, x86, mips, …) -b : specify bits (16, 32, 64) (arm-16 is thumb)

: specify bits (16, 32, 64) (arm-16 is thumb) -o : offset where this instruction is

: offset where this instruction is -s : change syntax for ATT, MASM, INTEL, ..

: 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

" , 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 ( "

" ); } /* disassemble */ char * code = r_asm_to_string (a, 0x4000 , " \x90\x90 " , 2 ); if (code) { printf ( "%s

" , 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

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.

–pancake