table of contents
- unstable 6.0.4+dfsg-1
R_ASM(3) | Library Functions Manual | R_ASM(3) |
NAME¶
r_asm
— Assembler
and disassembler library for radare2
SYNOPSIS¶
#include
<r_asm.h>
DESCRIPTION¶
The r_asm
API exposes radare2's high level
assembler and disassembler primitives and the glue between them.
It is implemented as a frontend for the r_arch api that provides the architecture logic to encode and decode instructions. But offers support for multiline assembler with directive handling and pseudo disassembling and parsing plugins. Routines operate on the RAsm context which holds architecture configuration, current program counter and parser state. Results for multi-instruction operations are returned in RAsmCode objects which contain raw bytes, the disassembly text and per-assembly metadata.
INITIALIZATION¶
Before assembling or disassembling you must create and configure
an RAsm r2
RAsm
r_asm_set_user_ptr
(())
RCore
/* Initialization API (prototypes) */ RParse *r_parse_new (void); void r_parse_free (RParse *p); RAsm *r_asm_new (void); void r_asm_free (RAsm *a); void r_asm_set_user_ptr (RAsm *a, void *user); bool r_asm_use (RAsm *a, const char *name); int r_asm_set_bits (RAsm *a, int bits); int r_asm_set_pc (RAsm *a, ut64 pc);
RAsm *a = r_asm_new(); /* choose architecture and word size */ r_asm_use (a, "x86"); r_asm_set_bits (a, 64); /* set current location for relative operands and disassembly helpers */ r_asm_set_pc (a, 0x1000); /* when embedding in r2: r_asm_set_user_ptr (a, core); */ r_asm_free (a);
ASSEMBLY¶
The assembler API provides two levels of convenience. Use
r_asm_massemble
(())
when you need multi-line assembly, directive handling or want a
RAsmCode result with both bytes and the produced
assembly text. For single-line or binding-specific assembly callbacks use
r_asm_rasm_assemble
(())
or the lower-level encode callbacks that plugins expose. If you only need a
raw buffer of bytes from a textual instruction, the utility
r_asm_from_string
(())
/* Assembly API (prototypes) */ RAsmCode* r_asm_massemble (RAsm *a, const char *buf); RAsmCode* r_asm_rasm_assemble (RAsm *a, const char *buf, bool use_spp); ut8 *r_asm_from_string (RAsm *a, ut64 addr, const char *b, int *l); void r_asm_code_free (RAsm *acode);
/* assemble several instructions and inspect bytes */ RAsmCode *code = r_asm_massemble (a, "mov rax, 420op"); if (code) { for (int i = 0; i < code->len; i++) { printf ("%02x ", code->bytes[i]); } printf ("%s0, code->assembly); r_asm_code_free (code); } /* get a plain buffer (useful for embedding into other APIs) */ int len; ut8 *buf = r_asm_from_string (a, 0x1000, "add eax, 1", &len); if (buf) { free (buf); }
DISASSEMBLY¶
There are two complementary disassembly APIs. The low-level
r_asm_disassemble
(())
RAnalOp
r_asm_mdisassemble
(())
RAsmCode
/* Disassembly API (prototypes) */ int r_asm_disassemble (RAsm *a, RAnalOp *op, const ut8 *buf, int len); RAsmCode* r_asm_mdisassemble (RAsm *a, const ut8 *buf, int len); char *r_asm_tostring (RAsm *a, ut64 addr, const ut8 *b, int l); RAsmCode* r_asm_mdisassemble_hexstr (RAsm *a, RParse *p, const char *hexstr); void r_asm_op_init (RAnalOp *op); void r_asm_op_fini (RAnalOp *op);
rasm2
and other tools
calls
r_asm_disassemble
(())
repeatedly, updates the PC via
r_asm_set_pc
((),)
and finalizes each RAnalOp with
r_asm_op_fini
(().)
/* decode a buffer instruction-by-instruction */ RAnalOp op; int off = 0; while (off < buflen) { r_asm_op_init (&op); r_asm_set_pc (a, base_addr + off); int sz = r_asm_disassemble (a, &op, buf + off, buflen - off); if (sz <= 0) { break; } printf ("%s0, op.mnemonic); off += op.size; r_asm_op_fini (&op); }
For quick textual conversion of a byte buffer use
r_asm_tostring
(())
or r_asm_mdisassemble
(()) ; to
parse a hex string and optionally run the pseudo-assembly parser pass use
r_asm_mdisassemble_hexstr
(().)
PARSING¶
The assembler includes a lightweight parse/filter layer used to
transform or annotate the produced assembly. The
RParse
r_asm_use_parser
(().)
/* Parsing API (prototypes) */ RParse *r_parse_new (void); void r_parse_free (RParse *p); bool r_asm_use_parser (RAsm *a, const char *name); char *r_asm_parse_pseudo (RAsm *a, const char *data);
r_asm_mdisassemble_hexstr
(())
with an RParse instance to post-process a hex string, or
call
r_asm_parse_pseudo
(())
on a previously decoded mnemonic to get a human-friendly representation (for
example replacing memory operands with symbolic names). Example:
RParse *p = r_parse_new(); p->pseudo = true; /* enable pseudo transformations */ RAsmCode *c = r_asm_mdisassemble_hexstr (a, p, "4868 2a000000"); if (c) { printf ("%s0, c->assembly); r_asm_code_free (c); } r_parse_free (p);
EXAMPLES¶
Below are short examples that mirror patterns used across the codebase (see (libr/main/rasm2.c) and (libr/core/cmd_print.inc.c) for complete usages).
Assemble multiple lines and print the encoded bytes:
RAsmCode *ac = r_asm_massemble (a, ".bits 640ov rax, 420op"); if (ac) { for (int i = 0; i < ac->len; i++) printf ("%02x", ac->bytes[i]); r_asm_code_free (ac); }
Assemble and analyze instructions producing ESIL (pattern used by
the r2
commands that print analysis):
RAsmCode *acode = r_asm_massemble (a, "mov rax, 420dd rax, 1"); if (acode) { RAnalOp aop = {0}; int printed = 0; while (printed < acode->len) { aop.size = 0; if (r_anal_op (anal, &aop, base_addr, acode->bytes + printed, acode->len - printed, R_ARCH_OP_MASK_ESIL) > 0) { printf ("%s0, R_STRBUF_SAFEGET (&aop.esil)); } printed += aop.size; r_anal_op_fini (&aop); } r_asm_code_free (acode); }
Disassemble a hex string and run the pseudo-parser (as used by the print command):
RParse *p = r_parse_new(); p->pseudo = true; RAsmCode *c = r_asm_mdisassemble_hexstr (a, p, "4868 2a000000"); if (c) { puts (c->assembly); r_asm_code_free (c); } r_parse_free (p);
SEE ALSO¶
September 21, 2025 | Debian |