rizin/librz/asm/p/asm_bf.c
Heersin e0d3d6bc66
New RZIL integration (#1663)
The new intermediate language is based on the BAP (Binary Analysis Platform) Core Theory.
It operates on SMT-like bitvectors and their arrays to represent values and memory.
Apart from that, it has also representation for the data and code side effects.
2021-10-09 18:14:44 +08:00

128 lines
2.7 KiB
C

// SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
// SPDX-FileCopyrightText: 2009-2021 nibble <nibble.ds@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_asm.h>
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
const char *buf_asm = "invalid";
switch (*buf) {
case '[':
buf_asm = "while [ptr]";
break;
case ']':
buf_asm = "loop";
break;
case '>':
buf_asm = "inc ptr";
break;
case '<':
buf_asm = "dec ptr";
break;
case '+':
buf_asm = "inc [ptr]";
break;
case '-':
buf_asm = "dec [ptr]";
break;
case ',':
buf_asm = "in [ptr]";
break;
case '.':
buf_asm = "out [ptr]";
break;
case 0xff:
case 0x00:
buf_asm = "trap";
break;
default:
buf_asm = "nop";
break;
}
rz_strbuf_set(&op->buf_asm, buf_asm);
op->size = 1;
return op->size;
}
static bool _write_asm(RzAsmOp *op, int value, int n) {
ut8 *opbuf = malloc(n);
if (opbuf == NULL) {
return true;
}
memset(opbuf, value, n);
rz_strbuf_setbin(&op->buf, opbuf, n);
free(opbuf);
return false;
}
static int assemble(RzAsm *a, RzAsmOp *op, const char *buf) {
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;
}
if (!strncmp(buf, "trap", 4)) {
write_err = _write_asm(op, 0xcc, n);
} else if (!strncmp(buf, "nop", 3)) {
write_err = _write_asm(op, 0x90, n);
} else if (!strncmp(buf, "inc", 3)) {
char ch = ref ? '+' : '>';
n = 1;
write_err = _write_asm(op, ch, n);
} else if (!strncmp(buf, "dec", 3)) {
char ch = ref ? '-' : '<';
n = 1;
write_err = _write_asm(op, ch, n);
} else if (!strncmp(buf, "sub", 3)) {
char ch = ref ? '-' : '<';
write_err = _write_asm(op, ch, n);
} else if (!strncmp(buf, "add", 3)) {
char ch = ref ? '+' : '>';
write_err = _write_asm(op, ch, n);
} else if (!strncmp(buf, "while", 5)) {
n = 1;
write_err = _write_asm(op, '[', 1);
} else if (!strncmp(buf, "loop", 4)) {
n = 1;
write_err = _write_asm(op, ']', 1);
} else if (!strncmp(buf, "in", 2)) {
write_err = _write_asm(op, ',', n);
} else if (!strncmp(buf, "out", 3)) {
write_err = _write_asm(op, '.', n);
} else {
n = 0;
}
if (write_err) {
return 0;
}
return n;
}
RzAsmPlugin rz_asm_plugin_bf = {
.name = "bf",
.author = "pancake, nibble",
.version = "4.0.0",
.arch = "bf",
.license = "LGPL3",
.bits = 16 | 32 | 64,
.endian = RZ_SYS_ENDIAN_NONE,
.desc = "Brainfuck",
.disassemble = &disassemble,
.assemble = &assemble
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_ASM,
.data = &rz_asm_plugin_bf,
.version = RZ_VERSION
};
#endif