Migrate the brainfuck ##arch

This commit is contained in:
Luc Tielen 2023-03-27 19:43:21 +02:00 committed by pancake
parent 96db5a7c5e
commit 58cc69f0dd
30 changed files with 152 additions and 111 deletions

View File

@ -1,7 +1,7 @@
STATIC="
arch.arm
arch.x86_nz
anal.bf
arch.bf
anal.avr
anal.null
anal.x86_cs

View File

@ -22,7 +22,7 @@ anal.8051
arch.arc
anal.arm_cs
anal.avr
anal.bf
arch.bf
anal.dalvik
anal.i8080
anal.java

View File

@ -8,7 +8,7 @@ anal.arm_cs
anal.arm_gnu
arch.arm_v35
anal.avr
anal.bf
arch.bf
arch.bpf
arch.bpf_cs
anal.chip8

View File

@ -66,7 +66,7 @@ anal.sparc
anal.8051
anal.i8080
arch.arc
anal.bf
arch.bf
arch.z80
arch.xap
anal.tms320

View File

@ -1,7 +1,7 @@
STATIC="
arch.arm
arch.x86_nz
anal.bf
arch.bf
anal.null
anal.x86_cs
anal.arm_cs

View File

@ -2,7 +2,7 @@ STATIC="
asm.null
arch.arm
arch.x86_nz
anal.bf
arch.bf
anal.null
anal.x86_cs
anal.arm_cs

View File

@ -5,7 +5,7 @@ arch.arc
anal.arm_cs
anal.arm_gnu
anal.avr
anal.bf
arch.bf
anal.chip8
arch.lanai
arch.cris

View File

@ -3,7 +3,7 @@ arch.arc
anal.arm_gnu
arch.arm_v35
anal.avr
anal.bf
arch.bf
anal.chip8
arch.cris
arch.cr16

View File

@ -1,7 +1,7 @@
STATIC="anal.8051
arch.arc
anal.arm_cs
anal.bf
arch.bf
arch.cr16
arch.xap
anal.dalvik

View File

@ -4,7 +4,7 @@ STATIC="anal.8051
arch.arc
anal.arm_cs
anal.arm_gnu
anal.bf
arch.bf
anal.chip8
arch.cris
anal.dalvik

View File

@ -1,7 +1,7 @@
STATIC="anal.8051
arch.arc
anal.arm_cs
anal.bf
arch.bf
anal.chip8
arch.cris
anal.dalvik

View File

@ -2,7 +2,7 @@ STATIC="anal.8051
anal.arm_cs
anal.arm_gnu
anal.avr
anal.bf
arch.bf
anal.dalvik
anal.gb
anal.java

View File

@ -4,7 +4,7 @@ arch.arm
anal.dalvik
arch.wasm
arch.pyc
anal.bf
arch.bf
arch.bpf
arch.riscv
anal.ppc_gnu

View File

@ -4,7 +4,7 @@ Brainfuck support for r2
Plugins for brainfuck:
- `asm.bf` - brainfuck assembler and disassembler
- `debug.bf` - debugger using bfvm
- `anal.bf` - code analysis for brainfuck
- `arch.bf` - code analysis for brainfuck
- `bp.bf` - breakpoints support (experimental)
To debug a brainfuck program:

View File

@ -51,7 +51,6 @@ r_anal_sources = [
'p/anal_arm_cs.c',
'p/anal_arm_gnu.c',
'p/anal_avr.c',
'p/anal_bf.c',
'p/anal_chip8.c',
'p/anal_dalvik.c',
'../arch/p/ebc/plugin.c',

View File

@ -1,9 +0,0 @@
OBJ_BF=anal_bf.o
STATIC_OBJ+=${OBJ_BF}
TARGET_BF=anal_bf.${EXT_SO}
ALL_TARGETS+=${TARGET_BF}
${TARGET_BF}: ${OBJ_BF}
${CC} $(call libname,anal_bf) ${LDFLAGS} ${CFLAGS} -o anal_bf.${EXT_SO} ${OBJ_BF}

View File

@ -4,9 +4,6 @@
R_API RArchSession *r_arch_session(RArch *arch, RArchConfig *cfg, RArchPlugin *ap) {
RArchSession *ai = R_NEW0 (RArchSession);
if (!ai) {
return NULL;
}
if (ai) {
ai->arch = arch;
ai->config = cfg;
@ -20,7 +17,6 @@ R_API RArchSession *r_arch_session(RArch *arch, RArchConfig *cfg, RArchPlugin *a
}
}
}
// resolve and instantiate plugin by name (
return ai;
}

View File

@ -6,6 +6,7 @@ r_arch_sources = [
'arch_session.c',
'arch_cond.c',
'arch_value.c',
'p/bf/plugin.c',
'p/pic/plugin.c',
'p/pic/pic_midrange.c',
'p/pic/pic_baseline.c',

9
libr/arch/p/bf.mk Normal file
View File

@ -0,0 +1,9 @@
OBJ_BF=p/bf/plugin.o
STATIC_OBJ+=${OBJ_BF}
TARGET_BF=bf.${EXT_SO}
ALL_TARGETS+=${TARGET_BF}
${TARGET_BF}: ${OBJ_BF}
${CC} $(call libname,bf) ${LDFLAGS} ${CFLAGS} -o bf.${EXT_SO} ${OBJ_BF}

View File

@ -1,13 +1,9 @@
/* radare2 - LGPL - Copyright 2011-2022 - pancake */
/* radare2 - LGPL - Copyright 2011-2023 - pancake */
#include <string.h>
#include <r_types.h>
#include <r_lib.h>
#include <r_asm.h>
#include <r_anal.h>
#include <r_arch.h>
static size_t countChar(const ut8 *buf, int len, char ch) {
int i;
size_t i;
for (i = 0; i < len; i++) {
if (buf[i] != ch) {
break;
@ -79,63 +75,73 @@ static int disassemble(RAnalOp *op, const ut8 *buf, int len) {
return rep;
}
static bool _write_asm(ut8 *outbuf, int outbufsz, int value, int n) {
static void _write_asm(ut8 *outbuf, size_t outbufsz, int value, int n) {
memset (outbuf, value, R_MIN (n, outbufsz));
return n > outbufsz;
}
static int assemble(const char *buf, ut8 *outbuf, int outbufsz) {
static int assemble(const char *buf, ut8 **outbuf) {
int n = 0;
if (buf[0] && buf[1] == ' ') {
buf += 2;
}
const char *arg = strchr (buf, ',');
const char *ref = strchr (buf, '[');
bool write_err = false;
if (arg) {
n = atoi (arg + 1);
} else {
n = 1;
}
size_t outbufsz = n;
*outbuf = malloc (outbufsz);
if (!(*outbuf)) {
return 0;
}
if (r_str_startswith (buf, "trap")) {
write_err = _write_asm (outbuf, outbufsz, 0xcc, n);
_write_asm (*outbuf, outbufsz, 0xcc, n);
} else if (r_str_startswith (buf, "nop")) {
write_err = _write_asm (outbuf, outbufsz, 0x90, n);
_write_asm (*outbuf, outbufsz, 0x90, n);
} else if (r_str_startswith (buf, "inc")) {
char ch = ref? '+': '>';
n = 1;
write_err = _write_asm (outbuf, outbufsz, ch, n);
_write_asm (*outbuf, outbufsz, ch, n);
} else if (r_str_startswith (buf, "dec")) {
char ch = ref? '-': '<';
n = 1;
write_err = _write_asm (outbuf, outbufsz, ch, n);
_write_asm (*outbuf, outbufsz, ch, n);
} else if (r_str_startswith (buf, "sub")) {
char ch = ref? '-': '<';
write_err = _write_asm (outbuf, outbufsz, ch, n);
_write_asm (*outbuf, outbufsz, ch, n);
} else if (r_str_startswith (buf, "add")) {
char ch = ref? '+': '>';
write_err = _write_asm (outbuf, outbufsz, ch, n);
_write_asm (*outbuf, outbufsz, ch, n);
} else if (r_str_startswith (buf, "while")) {
n = 1;
write_err = _write_asm (outbuf, outbufsz, '[', 1);
_write_asm (*outbuf, outbufsz, '[', 1);
} else if (r_str_startswith (buf, "loop")) {
n = 1;
write_err = _write_asm (outbuf, outbufsz, ']', 1);
_write_asm (*outbuf, outbufsz, ']', 1);
} else if (r_str_startswith (buf, "in")) {
write_err = _write_asm (outbuf, outbufsz, ',', n);
_write_asm (*outbuf, outbufsz, ',', n);
} else if (r_str_startswith (buf, "out")) {
write_err = _write_asm (outbuf, outbufsz, '.', n);
_write_asm (*outbuf, outbufsz, '.', n);
} else {
R_FREE (*outbuf);
n = 0;
}
if (write_err) {
return 0;
}
return n;
}
#define BUFSIZE_INC 32
static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *_buf, int len, RAnalOpMask mask) {
static bool decode(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
int len = op->size;
const ut8 *_buf = op->bytes;
const ut64 addr = op->addr;
if (len < 1) {
return false;
}
ut8 *buf = (ut8*)_buf; // XXX
ut64 dst = 0LL;
if (!op) {
@ -178,12 +184,12 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *_buf, int len,
op->type = R_ANAL_OP_TYPE_ILL;
goto beach;
}
if (i == len - 1 && anal->read_at) {
if (i == len - 1) {
int new_buf_len = len + 1 + BUFSIZE_INC;
ut8 *new_buf = calloc (new_buf_len, 1);
if (new_buf) {
free (buf);
(void)anal->read_at (anal, addr, new_buf, new_buf_len);
memcpy (new_buf, op->bytes, new_buf_len);
buf = new_buf;
p = buf + i;
len += BUFSIZE_INC;
@ -196,7 +202,8 @@ static int bf_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *_buf, int len,
beach:
free (buf);
break;
case ']': op->type = R_ANAL_OP_TYPE_UJMP;
case ']':
op->type = R_ANAL_OP_TYPE_UJMP;
// XXX This is wrong esil
r_strbuf_set (&op->esil, "brk,--=,brk,[1],pc,=");
break;
@ -241,7 +248,7 @@ beach:
return op->size;
}
static char *get_reg_profile(RAnal *anal) {
static char *get_reg_profile(RArchSession *as) {
return strdup (
"=PC pc\n"
"=BP brk\n"
@ -258,27 +265,40 @@ static char *get_reg_profile(RAnal *anal) {
);
}
static int bf_opasm(RAnal *a, ut64 addr, const char *str, ut8 *outbuf, int outsize) {
return assemble (str, outbuf, outsize);
static bool encode(RArchSession *as, RAnalOp *op, RArchEncodeMask mask) {
ut8 *outbuf = NULL;
int size = assemble (op->mnemonic, &outbuf);
free (op->bytes);
op->bytes = outbuf;
op->size = size;
return size > 0;
}
RAnalPlugin r_anal_plugin_bf = {
static int archinfo(RArchSession *as, ut32 q) {
switch (q) {
case R_ANAL_ARCHINFO_MAX_OP_SIZE:
return 32;
}
return 1;
}
RArchPlugin r_arch_plugin_bf = {
.name = "bf",
.desc = "brainfuck code analysis plugin",
.license = "LGPL3",
.arch = "bf",
.bits = 8,
.bits = R_SYS_BITS_PACK2 (8, 32),
.endian = R_SYS_ENDIAN_NONE,
.esil = true,
.op = &bf_op,
.opasm = &bf_opasm,
.get_reg_profile = get_reg_profile,
.decode = &decode,
.encode = &encode,
.regs = get_reg_profile,
.info = &archinfo
};
#ifndef R2_PLUGIN_INCORE
R_API RLibStruct radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_bf,
.type = R_LIB_TYPE_ARCH,
.data = &r_arch_plugin_bf,
.version = R2_VERSION
};
#endif

View File

@ -1,14 +1,26 @@
/* radare - LGPL - Copyright 2022 - pancake */
/* radare - LGPL - Copyright 2022-2023 - pancake */
#include <r_arch.h>
#include <r_util.h>
static char* regs(RArchSession *as) {
const char* profile =
"=PC null0\n"
"=SP null1\n"
"=SN null0\n"
"=A0 null0\n"
"gpr null0 .32 ?0 0\n"
"gpr null1 .32 ?1 0\n";
return strdup (profile);
}
RArchPlugin r_arch_plugin_null = {
.name = "null",
.desc = "Fallback/Null arch plugin",
.arch = "none",
.license = "LGPL3",
.bits = R_SYS_BITS_PACK4 (8, 16, 32, 64)
.bits = R_SYS_BITS_PACK4 (8, 16, 32, 64),
.regs = regs
};
#ifndef R2_PLUGIN_INCORE

View File

@ -298,33 +298,6 @@ R_API bool r_asm_use(RAsm *a, const char *name) {
} else {
R_FREE (dotname);
}
#if 0
RListIter *iter;
RAsmPlugin *h;
r_list_foreach (a->plugins, iter, h) {
if (!strcmp (h->name, name)) {
if (!a->cur || (a->cur && h->arch && strcmp (a->cur->arch, h->arch))) {
a->cur = h;
load_asm_descriptions (a);
r_asm_set_cpu (a, NULL);
}
a->cur = h;
return true;
}
if (dotname && h->arch && !strcmp (dotname, h->arch)) {
char *arch = r_str_ndup (name, vv - name);
#if 0
r_arch_config_set_cpu (a->config, arch);
#else
r_asm_set_cpu (a, arch);
#endif
a->cur = h;
load_asm_descriptions (a);
free (arch);
return true;
}
}
#endif
if (a->analb.anal) {
if (a->analb.use (a->analb.anal, name)) {
load_asm_descriptions (a);
@ -334,11 +307,6 @@ R_API bool r_asm_use(RAsm *a, const char *name) {
}
R_LOG_ERROR ("Cannot find '%s' asm/arch/anal plugin. See rasm2 -L or -LL", name);
}
#if 0
// check if its a valid analysis plugin
sdb_free (a->pair);
a->pair = NULL;
#endif
if (strcmp (name, "null")) {
return r_asm_use (a, "null");
}

View File

@ -611,6 +611,9 @@ static bool linkcb(void *user, void *data, ut32 id) {
R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
r_return_val_if_fail (r && r->io, false);
if (r_str_startswith (filenameuri, "malloc://")) {
return true;
}
R_CRITICAL_ENTER (r);
ut64 laddr = r_config_get_i (r->config, "bin.laddr");
RBinFile *binfile = NULL;
@ -768,7 +771,6 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
if (plugin && binfile && plugin->file_type && plugin->file_type (binfile) == R_BIN_TYPE_CORE) {
ut64 sp_addr = (ut64)-1;
RIOMap *stack_map = NULL;
// Setting the right arch and bits, so regstate will be shown correctly
if (plugin->info) {
RBinInfo *inf = plugin->info (binfile);
@ -912,7 +914,6 @@ R_API RIODesc *r_core_file_open(RCore *r, const char *file, int flags, ut64 load
fd = NULL;
goto beach;
}
{
const char *cp = r_config_get (r->config, "cmd.open");
if (cp && *cp) {

View File

@ -2337,10 +2337,11 @@ static int cmd_open(void *data, const char *input) {
r_core_fini (core);
r_core_init (core);
r_core_task_sync_begin (&core->tasks);
if (!r_core_file_open (core, input + 2, R_PERM_RX, 0)) {
if (r_core_file_open (core, input + 2, R_PERM_RX, 0)) {
(void)r_core_bin_load (core, NULL, baddr);
} else {
R_LOG_ERROR ("Cannot open file");
}
(void)r_core_bin_load (core, NULL, baddr);
} else {
R_LOG_ERROR ("Missing argument");
}

View File

@ -1567,7 +1567,6 @@ extern RAnalPlugin r_anal_plugin_8051;
extern RAnalPlugin r_anal_plugin_arm_cs;
extern RAnalPlugin r_anal_plugin_arm_gnu;
extern RAnalPlugin r_anal_plugin_avr;
extern RAnalPlugin r_anal_plugin_bf;
extern RAnalPlugin r_anal_plugin_chip8;
extern RAnalPlugin r_anal_plugin_dalvik;
extern RAnalPlugin r_anal_plugin_gb;

View File

@ -327,6 +327,8 @@ extern RArchPlugin r_arch_plugin_ebc;
extern RArchPlugin r_arch_plugin_msp430;
extern RArchPlugin r_arch_plugin_pyc;
extern RArchPlugin r_arch_plugin_h8300;
extern RArchPlugin r_arch_plugin_bf;
#ifdef __cplusplus
}

View File

@ -46,6 +46,7 @@ arch_plugins = [ 'null',
'tricore',
'cris',
'cr16',
'bf',
]
bin_plugins = [ 'any' ]
bin_ldr_plugins = [ 'ldr_linux' ]
@ -159,7 +160,6 @@ anal_plugins += [
'8051',
'arm_cs',
'avr',
'bf',
'chip8',
'dalvik',
'gb',

View File

@ -38,7 +38,7 @@ libr/anal/esil.c
libr/anal/data.c
libr/anal/flirt.c
libr/arch/p/arc/plugin.c
libr/anal/p/anal_bf.c
libr/arch/p/bf/bf.c
libr/config/config.c
libr/config/callback.c

45
test/db/anal/bf Normal file
View File

@ -0,0 +1,45 @@
NAME=bf decode
FILE=bins/bf/hello-ok.bf
CMDS=<<EOF
e asm.arch=bf
e asm.bits=32
e asm.parser=x86.pseudo
ao@0xA
ao@0x61
EOF
EXPECT=<<EOF
address: 0xa
opcode: while [ptr]
esilcost: 4
disasm: while [ptr]
pseudo: while [ptr]
mnemonic: while
mask: 00
id: 1
bytes: 5b
size: 1
sign: false
type: cjmp
cycles: 0
esil: 0xa,brk,=[1],brk,++=,ptr,[1],!,?{,0x2a,pc,=,brk,--=,}
jump: 0x0000002a
fail: 0x0000000b
cond: al
family: cpu
address: 0x61
opcode: sub [ptr], 8
esilcost: 4
disasm: sub [ptr], 8
pseudo: [ptr] -= 8
mnemonic: sub
mask: ffffffffffffffff
id: 6
bytes: 2d2d2d2d2d2d2d2d
size: 8
sign: false
type: sub
cycles: 0
esil: 8,ptr,-=[1]
family: cpu
EOF
RUN

View File

@ -3,7 +3,6 @@ FILE=bins/bf/hello-ok.bf
ARGS=-b32
CMDS=<<EOF
e asm.arch = bf
e anal.arch = bf
f input 128 0x3000
o malloc://128 0x3000~z
f screen 80*25 0x4000
@ -35,7 +34,6 @@ FILE=bins/bf/hello-unbalanced-loop.bf
ARGS=-b32
CMDS=<<EOF
e asm.arch = bf
e anal.arch = bf
f input 128 0x3000
o malloc://128 0x3000~z
f screen 80*25 0x4000
@ -64,7 +62,6 @@ FILE=bins/bf/hello-loops.bf
ARGS=-b32
CMDS=<<EOF
e asm.arch = bf
e anal.arch = bf
f input 128 0x3000
o malloc://128 0x3000~z
f screen 80*25 0x4000