Add Capstone SystemZ and SPARC disassembler and analysis plugins

This commit is contained in:
pancake 2014-05-17 02:37:29 +02:00
parent 12037a14aa
commit ca18aedb94
16 changed files with 501 additions and 10 deletions

View File

@ -87,7 +87,7 @@ static int extract_binobj (RBinFile *bf, RBinObject *o, int idx ) {
ut64 boffset = o ? o->boffset : 0;
ut64 bin_size = o ? o->obj_size : 0;
const ut8 *bytes = bf ? r_buf_buffer (bf->buf) : NULL;
ut64 sz = bf ? r_buf_size (bf->buf) : 0;
//ut64 sz = bf ? r_buf_size (bf->buf) : 0;
RBinInfo *info = o ? o->info : NULL;
const char *arch = info ? info->arch : "unknown";
char bits = info ? info->bits : 0;

161
libr/anal/p/anal_sparc_cs.c Normal file
View File

@ -0,0 +1,161 @@
/* radare2 - LGPL - Copyright 2014 - pancake */
#include <r_anal.h>
#include <r_lib.h>
#include <capstone.h>
#include <sparc.h>
#if CS_API_MAJOR < 2
#error Old Capstone not supported
#endif
#if CS_API_MINOR < 1
#error Old Capstone not supported
#endif
#define esilprintf(op, fmt, arg...) r_strbuf_setf (&op->esil, fmt, ##arg)
#define INSOP(n) insn->detail->sparc.operands[n]
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
csh handle;
cs_insn *insn;
int mode, n, ret;
mode = CS_MODE_BIG_ENDIAN;
if (!strcmp (a->cpu, "v9"))
mode |= CS_MODE_V9;
ret = cs_open (CS_ARCH_SPARC, mode, &handle);
op->type = R_ANAL_OP_TYPE_NULL;
op->size = 0;
op->delay = 0;
r_strbuf_init (&op->esil);
if (ret == CS_ERR_OK) {
cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
// capstone-next
n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
if (n<1) {
op->type = R_ANAL_OP_TYPE_ILL;
} else {
op->size = insn->size;
switch (insn->id) {
case SPARC_INS_RETT:
op->type = R_ANAL_OP_TYPE_RET;
case SPARC_INS_CALL:
op->type = R_ANAL_OP_TYPE_CALL;
op->jump = INSOP(0).imm;
break;
case SPARC_INS_CMP:
op->type = R_ANAL_OP_TYPE_CMP;
break;
case SPARC_INS_JMP:
case SPARC_INS_JMPL:
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = INSOP(0).imm;
break;
case SPARC_INS_BRGEZ:
case SPARC_INS_BRGZ:
case SPARC_INS_BRLEZ:
case SPARC_INS_BRLZ:
case SPARC_INS_BRNZ:
case SPARC_INS_BRZ:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = INSOP(0).imm;
op->fail = UT64_MAX;
break;
case SPARC_INS_FHSUBD:
case SPARC_INS_FHSUBS:
case SPARC_INS_FPSUB16:
case SPARC_INS_FPSUB16S:
case SPARC_INS_FPSUB32:
case SPARC_INS_FPSUB32S:
case SPARC_INS_FSUBD:
case SPARC_INS_FSUBQ:
case SPARC_INS_FSUBS:
case SPARC_INS_SUBCC:
case SPARC_INS_SUBX:
case SPARC_INS_SUBXCC:
case SPARC_INS_SUB:
case SPARC_INS_TSUBCCTV:
case SPARC_INS_TSUBCC:
op->type = R_ANAL_OP_TYPE_SUB;
break;
case SPARC_INS_ADDCC:
case SPARC_INS_ADDX:
case SPARC_INS_ADDXCC:
case SPARC_INS_ADDXC:
case SPARC_INS_ADDXCCC:
case SPARC_INS_ADD:
case SPARC_INS_FADDD:
case SPARC_INS_FADDQ:
case SPARC_INS_FADDS:
case SPARC_INS_FHADDD:
case SPARC_INS_FHADDS:
case SPARC_INS_FNADDD:
case SPARC_INS_FNADDS:
case SPARC_INS_FNHADDD:
case SPARC_INS_FNHADDS:
case SPARC_INS_FPADD16:
case SPARC_INS_FPADD16S:
case SPARC_INS_FPADD32:
case SPARC_INS_FPADD32S:
case SPARC_INS_FPADD64:
case SPARC_INS_TADDCCTV:
case SPARC_INS_TADDCC:
op->type = R_ANAL_OP_TYPE_ADD;
break;
case SPARC_INS_FDMULQ:
case SPARC_INS_FMUL8SUX16:
case SPARC_INS_FMUL8ULX16:
case SPARC_INS_FMUL8X16:
case SPARC_INS_FMUL8X16AL:
case SPARC_INS_FMUL8X16AU:
case SPARC_INS_FMULD:
case SPARC_INS_FMULD8SUX16:
case SPARC_INS_FMULD8ULX16:
case SPARC_INS_FMULQ:
case SPARC_INS_FMULS:
case SPARC_INS_FSMULD:
case SPARC_INS_MULX:
case SPARC_INS_SMULCC:
case SPARC_INS_SMUL:
case SPARC_INS_UMULCC:
case SPARC_INS_UMULXHI:
case SPARC_INS_UMUL:
case SPARC_INS_XMULX:
case SPARC_INS_XMULXHI:
op->type = R_ANAL_OP_TYPE_MUL;
break;
case SPARC_INS_FDIVD:
case SPARC_INS_FDIVQ:
case SPARC_INS_FDIVS:
case SPARC_INS_SDIVCC:
case SPARC_INS_SDIVX:
case SPARC_INS_SDIV:
case SPARC_INS_UDIVCC:
case SPARC_INS_UDIVX:
case SPARC_INS_UDIV:
op->type = R_ANAL_OP_TYPE_DIV;
break;
}
}
cs_free (insn, n);
cs_close (&handle);
}
return op->size;
}
RAnalPlugin r_anal_plugin_sparc_cs = {
.name = "sparc.cs",
.desc = "Capstone SPARC analysis",
.license = "BSD",
.arch = R_SYS_ARCH_SPARC,
.bits = 32|64,
.op = &analop,
//.set_reg_profile = &set_reg_profile,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_sparc_cs
};
#endif

128
libr/anal/p/anal_sysz.c Normal file
View File

@ -0,0 +1,128 @@
/* radare2 - LGPL - Copyright 2014 - pancake */
#include <r_anal.h>
#include <r_lib.h>
#include <capstone.h>
#include <systemz.h>
// instruction set: http://www.tachyonsoft.com/inst390m.htm
#if CS_API_MAJOR < 2
#error Old Capstone not supported
#endif
#if CS_API_MINOR < 1
#error Old Capstone not supported
#endif
#define esilprintf(op, fmt, arg...) r_strbuf_setf (&op->esil, fmt, ##arg)
#define INSOP(n) insn->detail->sysz.operands[n]
static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
csh handle;
cs_insn *insn;
int mode, n, ret;
mode = CS_MODE_BIG_ENDIAN;
ret = cs_open (CS_ARCH_SYSZ, mode, &handle);
op->type = R_ANAL_OP_TYPE_NULL;
op->size = 0;
op->delay = 0;
r_strbuf_init (&op->esil);
if (ret == CS_ERR_OK) {
cs_option (handle, CS_OPT_DETAIL, CS_OPT_ON);
// capstone-next
n = cs_disasm_ex (handle, (const ut8*)buf, len, addr, 1, &insn);
if (n<1) {
op->type = R_ANAL_OP_TYPE_ILL;
} else {
op->size = insn->size;
switch (insn->id) {
case SYSZ_INS_BRCL:
case SYSZ_INS_BRASL:
op->type = R_ANAL_OP_TYPE_CALL;
break;
case SYSZ_INS_BR:
op->type = R_ANAL_OP_TYPE_JMP;
break;
case SYSZ_INS_BRC:
case SYSZ_INS_BER:
case SYSZ_INS_BHR:
case SYSZ_INS_BHER:
case SYSZ_INS_BLR:
case SYSZ_INS_BLER:
case SYSZ_INS_BLHR:
case SYSZ_INS_BNER:
case SYSZ_INS_BNHR:
case SYSZ_INS_BNHER:
case SYSZ_INS_BNLR:
case SYSZ_INS_BNLER:
case SYSZ_INS_BNLHR:
case SYSZ_INS_BNOR:
case SYSZ_INS_BOR:
case SYSZ_INS_BASR:
case SYSZ_INS_BRAS:
case SYSZ_INS_BRCT:
case SYSZ_INS_BRCTG:
op->type = R_ANAL_OP_TYPE_CJMP;
break;
case SYSZ_INS_JE:
case SYSZ_INS_JGE:
case SYSZ_INS_JHE:
case SYSZ_INS_JGHE:
case SYSZ_INS_JH:
case SYSZ_INS_JGH:
case SYSZ_INS_JLE:
case SYSZ_INS_JGLE:
case SYSZ_INS_JLH:
case SYSZ_INS_JGLH:
case SYSZ_INS_JL:
case SYSZ_INS_JGL:
case SYSZ_INS_JNE:
case SYSZ_INS_JGNE:
case SYSZ_INS_JNHE:
case SYSZ_INS_JGNHE:
case SYSZ_INS_JNH:
case SYSZ_INS_JGNH:
case SYSZ_INS_JNLE:
case SYSZ_INS_JGNLE:
case SYSZ_INS_JNLH:
case SYSZ_INS_JGNLH:
case SYSZ_INS_JNL:
case SYSZ_INS_JGNL:
case SYSZ_INS_JNO:
case SYSZ_INS_JGNO:
case SYSZ_INS_JO:
case SYSZ_INS_JGO:
case SYSZ_INS_JG:
op->type = R_ANAL_OP_TYPE_CJMP;
op->jump = INSOP(0).imm;
op->fail = addr+op->size;
break;
case SYSZ_INS_J:
op->type = R_ANAL_OP_TYPE_JMP;
op->jump = INSOP(0).imm;
op->fail = UT64_MAX;
break;
}
}
cs_free (insn, n);
cs_close (&handle);
}
return op->size;
}
RAnalPlugin r_anal_plugin_sysz = {
.name = "systemz.cs",
.desc = "Capstone SystemZ microanalysis",
.license = "BSD",
.arch = R_SYS_ARCH_SYSZ,
.bits = 32|64,
.op = &analop,
//.set_reg_profile = &set_reg_profile,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ANAL,
.data = &r_anal_plugin_sysz
};
#endif

13
libr/anal/p/sparc_cs.mk Normal file
View File

@ -0,0 +1,13 @@
OBJ_SPARC_CS=anal_sparc_cs.o
CFLAGS+=-I../../shlr/capstone/include
STATIC_OBJ+=${OBJ_SPARC_CS}
SHARED_SPARC_CS=../../shlr/capstone/libcapstone.a
SHARED_OBJ+=${SHARED_SPARC_CS}
TARGET_SPARC_CS=anal_sparc_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_SPARC_CS}
${TARGET_SPARC_CS}: ${OBJ_SPARC_CS}
${CC} ${CFLAGS} $(call libname,anal_sparc_cs) \
-o anal_sparc_cs.${EXT_SO} ${OBJ_SPARC_CS}

13
libr/anal/p/sysz.mk Normal file
View File

@ -0,0 +1,13 @@
OBJ_SYSTEMZ_CS=anal_sysz.o
CFLAGS+=-I../../shlr/capstone/include
STATIC_OBJ+=${OBJ_SYSTEMZ_CS}
SHARED_SYSTEMZ_CS=../../shlr/capstone/libcapstone.a
SHARED_OBJ+=${SHARED_SYSTEMZ_CS}
TARGET_SYSTEMZ_CS=anal_sysz.${EXT_SO}
ALL_TARGETS+=${TARGET_SYSTEMZ_CS}
${TARGET_SYSTEMZ_CS}: ${OBJ_SYSTEMZ_CS}
${CC} ${CFLAGS} $(call libname,anal_sysz) \
-o anal_sysz.${EXT_SO} ${OBJ_SYSTEMZ_CS}

View File

@ -9,10 +9,10 @@
#include <r_lib.h>
#include "../arch/6502/6502dis.c"
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, ut64 len) {
int dlen = _6502Disass (op,buf,len);
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
int dlen = _6502Disass (op, buf, len);
if(dlen<0) dlen=0;
op->size=dlen;
op->size = dlen;
return dlen;
}

61
libr/asm/p/asm_sparc_cs.c Normal file
View File

@ -0,0 +1,61 @@
/* radare2 - LGPL - Copyright 2014 - pancake */
#include <r_asm.h>
#include <r_lib.h>
#include <capstone.h>
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
csh handle;
cs_insn* insn;
int mode, n, ret = -1;
mode = a->big_endian? CS_MODE_BIG_ENDIAN: CS_MODE_LITTLE_ENDIAN;
if (a->cpu) {
if (!strcmp (a->cpu, "v9")) {
mode |= CS_MODE_V9;
}
}
memset (op, 0, sizeof (RAsmOp));
op->size = 4;
ret = cs_open (CS_ARCH_SPARC, mode, &handle);
if (ret) goto fin;
cs_option (handle, CS_OPT_DETAIL, CS_OPT_OFF);
n = cs_disasm_ex (handle, (ut8*)buf, len, a->pc, 1, &insn);
if (n<1) {
strcpy (op->buf_asm, "invalid");
op->size = 4;
ret = -1;
goto beach;
} else ret = 4;
if (insn->size<1)
goto beach;
op->size = insn->size;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
insn->mnemonic, insn->op_str[0]? " ": "",
insn->op_str);
// TODO: remove the '$'<registername> in the string
beach:
cs_free (insn, n);
cs_close (&handle);
fin:
return ret;
}
RAsmPlugin r_asm_plugin_sparc_cs = {
.name = "sparc.cs",
.desc = "Capstone SPARC disassembler",
.license = "BSD",
.arch = "sparc",
.cpus = "v9",
.bits = 32|64,
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,
.assemble = NULL
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_sparc_cs
};
#endif

75
libr/asm/p/asm_sysz.c Normal file
View File

@ -0,0 +1,75 @@
/* radare2 - LGPL - Copyright 2013-2014 - pancake */
// instruction set : http://www.tachyonsoft.com/inst390m.htm
#include <r_asm.h>
#include <r_lib.h>
#include <capstone.h>
static csh cd = 0;
static int the_end(void *p) {
if (cd) {
cs_close (&cd);
cd = 0;
}
return R_TRUE;
}
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
static int omode = 0;
int mode, n, ret;
ut64 off = a->pc;
cs_insn* insn = NULL;
mode = CS_MODE_BIG_ENDIAN;
if (cd && mode != omode) {
cs_close (&cd);
cd = 0;
}
op->size = 0;
omode = mode;
if (cd == 0) {
ret = cs_open (CS_ARCH_SYSZ, mode, &cd);
if (ret) return 0;
cs_option (cd, CS_OPT_DETAIL, CS_OPT_OFF);
}
n = cs_disasm_ex (cd, (const ut8*)buf, len, off, 1, &insn);
if (n>0) {
if (insn->size>0) {
op->size = insn->size;
if (insn->op_str) {
char *ptrstr;
snprintf (op->buf_asm, R_ASM_BUFSIZE, "%s%s%s",
insn->mnemonic, insn->op_str[0]?" ":"",
insn->op_str);
ptrstr = strstr (op->buf_asm, "ptr ");
if (ptrstr) {
memmove (ptrstr, ptrstr+4, strlen (ptrstr+4)+1);
}
} else {
eprintf ("op_str is null wtf\n");
}
}
}
cs_free (insn, n);
return op->size;
}
RAsmPlugin r_asm_plugin_sysz = {
.name = "sysz",
.desc = "SystemZ CPU disassembler",
.license = "BSD",
.arch = "sysz",
.bits = 32,
.init = NULL,
.fini = the_end,
.disassemble = &disassemble,
.assemble = NULL
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_ASM,
.data = &r_asm_plugin_sysz
};
#endif

15
libr/asm/p/sparc_cs.mk Normal file
View File

@ -0,0 +1,15 @@
OBJ_SPARCCS=asm_sparc_cs.o
CFLAGS+=-I../../shlr/capstone/include
SHARED_SPARCCS=../../shlr/capstone/libcapstone.a
SHARED2_SPARCCS=$(addprefix ../,${SHARED_SPARCCS})
STATIC_OBJ+=${OBJ_SPARCCS}
SHARED_OBJ+=${SHARED_SPARCCS}
TARGET_SPARCCS=asm_sparc_cs.${EXT_SO}
ALL_TARGETS+=${TARGET_SPARCCS}
${TARGET_SPARCCS}: ${OBJ_SPARCCS}
${CC} $(call libname,asm_sparc) ${LDFLAGS} ${CFLAGS} \
-o ${TARGET_SPARCCS} ${OBJ_SPARCCS} ${SHARED2_SPARCCS}

15
libr/asm/p/sysz.mk Normal file
View File

@ -0,0 +1,15 @@
OBJ_SYSZCS=asm_sysz.o
CFLAGS+=-I../../shlr/capstone/include
SHARED_SYSZCS=../../shlr/capstone/libcapstone.a
SHARED2_SYSZCS=$(addprefix ../,${SHARED_SYSZCS})
STATIC_OBJ+=${OBJ_SYSZCS}
SHARED_OBJ+=${SHARED_SYSZCS}
TARGET_SYSZCS=asm_sysz.${EXT_SO}
ALL_TARGETS+=${TARGET_SYSZCS}
${TARGET_SYSZCS}: ${OBJ_SYSZCS}
${CC} $(call libname,asm_sysz) ${LDFLAGS} ${CFLAGS} \
-o ${TARGET_SYSZCS} ${OBJ_SYSZCS} ${SHARED2_SYSZCS}

View File

@ -16,7 +16,9 @@ static Sdb* get_sdb (RBinObject *o) {
}
static void * load_bytes(const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb){
return check_bytes (buf, sz);
check_bytes (buf, sz);
// XXX: this may be wrong if check_bytes is true
return NULL;
}
static int load(RBinFile *arch) {
@ -65,11 +67,9 @@ static int check(RBinFile *arch) {
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
ut64 sz = arch ? r_buf_size (arch->buf): 0;
return check_bytes (bytes, sz);
}
static int check_bytes(const ut8 *buf, ut64 length) {
if ((buf) && (length > 0xffff)) {
const ut32 ep = length - 0x10000 + 0xfff0; /* F000:FFF0 address */
/* Check if this a 'jmp' opcode */

View File

@ -1,6 +1,7 @@
/* radare - LGPL - Copyright 2008-2014 - pancake */
#include <r_cons.h>
#include <r_print.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

View File

@ -1201,6 +1201,8 @@ extern RAnalPlugin r_anal_plugin_ws;
extern RAnalPlugin r_anal_plugin_h8300;
extern RAnalPlugin r_anal_plugin_cr16;
extern RAnalPlugin r_anal_plugin_v850;
extern RAnalPlugin r_anal_plugin_sysz;
extern RAnalPlugin r_anal_plugin_sparc_cs;
#ifdef __cplusplus
}
#endif

View File

@ -197,6 +197,8 @@ extern RAsmPlugin r_asm_plugin_6502;
extern RAsmPlugin r_asm_plugin_h8300;
extern RAsmPlugin r_asm_plugin_cr16;
extern RAsmPlugin r_asm_plugin_v850;
extern RAsmPlugin r_asm_plugin_sysz;
extern RAsmPlugin r_asm_plugin_sparc_cs;
#endif
#ifdef __cplusplus

View File

@ -304,9 +304,10 @@ enum {
R_SYS_ARCH_8051 = 0x40000,
R_SYS_ARCH_TMS320 = 0x80000,
R_SYS_ARCH_EBC = 0x100000,
R_SYS_ARCH_H8300 = 0x8300,
R_SYS_ARCH_CR16 = 0xc160,
R_SYS_ARCH_V850 = 0x0850, //XXX fixme
R_SYS_ARCH_H8300 = 0x200000,
R_SYS_ARCH_CR16 = 0x400000,
R_SYS_ARCH_V850 = 0x800000,
R_SYS_ARCH_SYSZ = 0x1000000,
};
/* os */

View File

@ -16,7 +16,9 @@ asm.sh
asm.csr
asm.avr
asm.dalvik
asm.sysz
asm.sparc
asm.sparc_cs
asm.ppc
asm.ppc_cs
asm.nios2
@ -62,7 +64,9 @@ anal.avr
anal.m68k
anal.ppc
anal.ppc_cs
anal.sysz
anal.sparc
anal.sparc_cs
anal.ebc
anal.gb
anal.malbolge