Initial commit for EFI Byte Code (EBC) disassembler.
This commit is contained in:
parent
b5b6348691
commit
1a72cdec24
|
@ -10,7 +10,7 @@ all: ${ALL_TARGETS} ;
|
|||
|
||||
ALL_TARGETS=
|
||||
# TODO: rename to enabled plugins
|
||||
ARCHS=x86_im.mk x86_udis.mk x86_simple.mk ppc.mk arm.mk avr.mk csr.mk dalvik.mk sh.mk
|
||||
ARCHS=x86_im.mk x86_udis.mk x86_simple.mk ppc.mk arm.mk avr.mk csr.mk dalvik.mk sh.mk ebc.mk
|
||||
include $(ARCHS)
|
||||
|
||||
clean:
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
#include <r_anal.h>
|
||||
|
||||
#include <ebc_disas.h>
|
||||
|
||||
static int ebc_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
int ret;
|
||||
ebc_command_t cmd;
|
||||
ut8 opcode = buf[0] & EBC_OPCODE_MASK;
|
||||
|
||||
if (op == NULL)
|
||||
return 2;
|
||||
|
||||
ret = op->length = ebc_decode_command(buf, &cmd);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (opcode == EBC_JMP || opcode == EBC_JMP8) {
|
||||
op->addr = addr;
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
|
||||
if (opcode == EBC_JMP8) {
|
||||
unsigned jmpadr = buf[1];
|
||||
op->jump = addr + 2 + (jmpadr * 2);
|
||||
op->fail = addr + (jmpadr * 2);
|
||||
}
|
||||
} else if ((opcode >= EBC_MOVBW && opcode <= EBC_MOVSND) ||
|
||||
opcode == EBC_MOVQQ || opcode == EBC_MOVNW ||
|
||||
opcode == EBC_MOVND || opcode == EBC_MOVREL ||
|
||||
opcode == EBC_MOVI || opcode == EBC_MOVIN ||
|
||||
opcode == EBC_EXTNDB || opcode == EBC_EXTNDW ||
|
||||
opcode == EBC_EXTNDD) {
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
} else if (opcode == EBC_RET) {
|
||||
op->type = R_ANAL_OP_TYPE_RET;
|
||||
} else if ((opcode >= EBC_CMPEQ && opcode <= EBC_CMPUGTE) ||
|
||||
(opcode >= EBC_CMPIEQ && opcode <= EBC_CMPIUGTE)) {
|
||||
op->type = R_ANAL_OP_TYPE_CMP;
|
||||
} else if (opcode == EBC_SHR) {
|
||||
op->type = R_ANAL_OP_TYPE_SHR;
|
||||
} else if (opcode == EBC_SHL) {
|
||||
op->type = R_ANAL_OP_TYPE_SHL;
|
||||
} else if (opcode == EBC_OR) {
|
||||
op->type = R_ANAL_OP_TYPE_OR;
|
||||
} else if (opcode == EBC_XOR) {
|
||||
op->type = R_ANAL_OP_TYPE_XOR;
|
||||
} else if (opcode == EBC_MUL) {
|
||||
op->type = R_ANAL_OP_TYPE_MUL;
|
||||
} else if (opcode == EBC_PUSH) {
|
||||
op->type = R_ANAL_OP_TYPE_PUSH;
|
||||
} else if (opcode == EBC_POP) {
|
||||
op->type = R_ANAL_OP_TYPE_POP;
|
||||
} else if (opcode == EBC_AND) {
|
||||
op->type = R_ANAL_OP_TYPE_AND;
|
||||
} else if (opcode == EBC_ADD) {
|
||||
op->type = R_ANAL_OP_TYPE_ADD;
|
||||
} else if (opcode == EBC_SUB) {
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
} else if (opcode == EBC_NEG) {
|
||||
op->type = R_ANAL_OP_TYPE_SUB;
|
||||
} else if (opcode == EBC_CALL) {
|
||||
int32_t addr_call;
|
||||
|
||||
if ((buf[1] & 0x7) == 0 && TEST_BIT(buf[0], 6) == 0) {
|
||||
addr_call = *(int32_t*)(buf + 2);
|
||||
|
||||
if (TEST_BIT(buf[1], 4)) {
|
||||
op->jump = (addr + 6 + addr_call);
|
||||
} else {
|
||||
op->jump = addr_call;
|
||||
}
|
||||
}
|
||||
op->type = R_ANAL_OP_TYPE_UCALL;
|
||||
|
||||
} else if (opcode == EBC_RET) {
|
||||
op->type = R_ANAL_OP_TYPE_LEAVE;
|
||||
} else if (opcode == EBC_BREAK) {
|
||||
op->type = R_ANAL_OP_TYPE_SWI;
|
||||
} else op->type = R_ANAL_OP_TYPE_UNK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct r_anal_plugin_t r_anal_plugin_ebc = {
|
||||
.name = "ebc",
|
||||
.desc = "EBC code analysis plugin",
|
||||
.arch = R_SYS_ARCH_EBC,
|
||||
.bits = 64,
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.op = &ebc_op,
|
||||
.set_reg_profile = NULL,
|
||||
.fingerprint_bb = NULL,
|
||||
.fingerprint_fcn = NULL,
|
||||
.diff_bb = NULL,
|
||||
.diff_fcn = NULL,
|
||||
.diff_eval = NULL
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ANAL,
|
||||
.data = &r_anal_plugin_ebc
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,11 @@
|
|||
OBJ_EBC=anal_ebc.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_EBC}
|
||||
SHARED_OBJ+=../asm/arch/ebc/ebc_disas.o
|
||||
TARGET_EBC=anal_ebc.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_EBC}
|
||||
|
||||
${TARGET_EBC}: ${OBJ_EBC}
|
||||
$(call pwd)
|
||||
${CC} $(call libname,anal_ebc) ${CFLAGS} -I../../include/ -o ${TARGET_EBC} ${OBJ_EBC}
|
|
@ -0,0 +1,13 @@
|
|||
include ../../config-user.mk
|
||||
include ../../mk/${COMPILER}.mk
|
||||
|
||||
CFLAGS+=-fPIC
|
||||
OBJS=ebc_disas.o
|
||||
|
||||
all: out
|
||||
|
||||
#out: ${OBJS}
|
||||
# ${CC} -g ${LDFLAGS} ${CFLAGS} -I. ${OBJS}
|
||||
|
||||
#clean:
|
||||
# rm -rf ${OBJS} a.out
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@ ALL_TARGETS=
|
|||
# TODO: rename to enabled plugins
|
||||
ARCHS=mips.mk sparc.mk java.mk bf.mk arm.mk dalvik.mk x86_as.mk x86_nz.mk
|
||||
ARCHS+=ppc.mk x86_olly.mk x86.mk csr.mk x86_nasm.mk psosvm.mk avr.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk c55plus.mk gb.mk snes.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk c55plus.mk gb.mk snes.mk ebc.mk
|
||||
include $(ARCHS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_asm.h>
|
||||
|
||||
#include <ebc_disas.h>
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
int ret = 1;
|
||||
ebc_command_t cmd;
|
||||
|
||||
ret = ebc_decode_command(buf, &cmd);
|
||||
|
||||
snprintf(op->buf_asm, R_ASM_BUFSIZE, "%s\t%s", cmd.instr, cmd.operands);
|
||||
|
||||
op->inst_len = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_ebc = {
|
||||
.name = "ebc",
|
||||
.desc = "EFI Byte Code disassembly plugin",
|
||||
.arch = "ebc",
|
||||
.bits = (int[]){ 32, 64 },
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.modify = NULL,
|
||||
.assemble = NULL,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_ebc
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
OBJ_EBC=asm_ebc.o
|
||||
OBJ_EBC+=../arch/ebc/ebc_disas.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_EBC}
|
||||
TARGET_EBC=asm_ebc.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_EBC}
|
||||
|
||||
${TARGET_EBC}: ${OBJ_EBC}
|
||||
${CC} ${LDFLAGS} ${CFLAGS} -I../arc/ebc/ -o ${TARGET_EBC} ${OBJ_EBC}
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef EBC_DISAS_H
|
||||
#define EBC_DISAS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define EBC_OPCODE_MASK 0x3F
|
||||
#define EBC_MODIFIER_MASK 0xC0
|
||||
#define EBC_OPERAND1_MASK 0x07
|
||||
#define EBC_OPERAND2_MASK (0x07 << 4)
|
||||
#define EBC_OPERAND1_DIRECT 0x08
|
||||
#define EBC_OPERAND2_DIRECT 0xA0
|
||||
#define EBC_OPERAND1_INDX 0x01
|
||||
#define EBC_OPERAND2_INDX 0x02
|
||||
|
||||
#define EBC_GET_OPCODE(byte) (byte & EBC_OPCODE_MASK)
|
||||
|
||||
#define EBC_INSTR_MAXLEN 32
|
||||
#define EBC_OPERANDS_MAXLEN 32
|
||||
|
||||
#define EBC_NTH_BIT(n) (1ULL << n)
|
||||
#define EBC_N_BIT_MASK(n) (~(~0U << (n)))
|
||||
#define EBC_GET_BIT(v,n) ((v >> n) & 1)
|
||||
|
||||
#define TEST_BIT(x,n) (x & (1 << n))
|
||||
|
||||
enum ebc_opcodes {
|
||||
EBC_BREAK = 0x00,
|
||||
EBC_JMP = 0x01,
|
||||
EBC_JMP8 = 0x02,
|
||||
EBC_CALL = 0x03,
|
||||
EBC_RET = 0x04,
|
||||
EBC_CMPEQ = 0x05,
|
||||
EBC_CMPLTE = 0x06,
|
||||
EBC_CMPGTE = 0x07,
|
||||
EBC_CMPULTE = 0x08,
|
||||
EBC_CMPUGTE = 0x09,
|
||||
EBC_NOT = 0x0A,
|
||||
EBC_NEG = 0x0B,
|
||||
EBC_ADD = 0x0C,
|
||||
EBC_SUB = 0x0D,
|
||||
EBC_MUL = 0x0E,
|
||||
EBC_MULU = 0x0F,
|
||||
EBC_DIV = 0x10,
|
||||
EBC_DIVU = 0x11,
|
||||
EBC_MOD = 0x12,
|
||||
EBC_MODU = 0x13,
|
||||
EBC_AND = 0x14,
|
||||
EBC_OR = 0x15,
|
||||
EBC_XOR = 0x16,
|
||||
EBC_SHL = 0x17,
|
||||
EBC_SHR = 0x18,
|
||||
EBC_ASHR = 0x19,
|
||||
EBC_EXTNDB = 0x1A,
|
||||
EBC_EXTNDW = 0x1B,
|
||||
EBC_EXTNDD = 0x1C,
|
||||
EBC_MOVBW = 0x1D,
|
||||
EBC_MOVWW = 0x1E,
|
||||
EBC_MOVDW = 0x1F,
|
||||
EBC_MOVQW = 0x20,
|
||||
EBC_MOVBD = 0x21,
|
||||
EBC_MOVWD = 0x22,
|
||||
EBC_MOVDD = 0x23,
|
||||
EBC_MOVQD = 0x24,
|
||||
EBC_MOVSNW = 0x25,
|
||||
EBC_MOVSND = 0x26,
|
||||
EBC_UNDEFINED = 0x27,
|
||||
EBC_MOVQQ = 0x28,
|
||||
EBC_LOADSP = 0x29,
|
||||
EBC_STORESP = 0x2A,
|
||||
EBC_PUSH = 0x2B,
|
||||
EBC_POP = 0x2C,
|
||||
EBC_CMPIEQ = 0x2D,
|
||||
EBC_CMPILTE = 0x2E,
|
||||
EBC_CMPIGTE = 0x2F,
|
||||
EBC_CMPIULTE = 0x30,
|
||||
EBC_CMPIUGTE = 0x31,
|
||||
EBC_MOVNW = 0x32,
|
||||
EBC_MOVND = 0x33,
|
||||
EBC_UNDEFINED2 = 0x34,
|
||||
EBC_PUSHN = 0x35,
|
||||
EBC_POPN = 0x36,
|
||||
EBC_MOVI = 0x37,
|
||||
EBC_MOVIN = 0x38,
|
||||
EBC_MOVREL = 0x39,
|
||||
EBC_COMMAND_NUM
|
||||
};
|
||||
|
||||
|
||||
typedef struct ebc_command {
|
||||
char instr[EBC_INSTR_MAXLEN];
|
||||
char operands[EBC_OPERANDS_MAXLEN];
|
||||
} ebc_command_t;
|
||||
|
||||
int decode_command(const uint8_t *instr, ebc_command_t *cmd);
|
||||
|
||||
#endif /* EBC_DISAS_H */
|
|
@ -942,6 +942,7 @@ extern RAnalPlugin r_anal_plugin_z80;
|
|||
extern RAnalPlugin r_anal_plugin_i8080;
|
||||
extern RAnalPlugin r_anal_plugin_8051;
|
||||
extern RAnalPlugin r_anal_plugin_arc;
|
||||
extern RAnalPlugin r_anal_plugin_ebc;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -185,6 +185,7 @@ extern RAsmPlugin r_asm_plugin_8051;
|
|||
extern RAsmPlugin r_asm_plugin_c55plus;
|
||||
extern RAsmPlugin r_asm_plugin_gb;
|
||||
extern RAsmPlugin r_asm_plugin_snes;
|
||||
extern RAsmPlugin r_asm_plugin_ebc;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -256,6 +256,7 @@ enum {
|
|||
R_SYS_ARCH_RAR = 0x20000,
|
||||
R_SYS_ARCH_8051 = 0x40000,
|
||||
R_SYS_ARCH_C55PLUS = 0x80000,
|
||||
R_SYS_ARCH_EBC = 0x100000,
|
||||
};
|
||||
|
||||
/* os */
|
||||
|
|
|
@ -31,6 +31,7 @@ asm.msil
|
|||
asm.c55plus
|
||||
asm.gb
|
||||
asm.snes
|
||||
asm.ebc
|
||||
anal.sh
|
||||
anal.x86_im
|
||||
anal.x86_udis
|
||||
|
@ -50,6 +51,7 @@ anal.avr
|
|||
anal.m68k
|
||||
anal.ppc
|
||||
anal.sparc
|
||||
anal.ebc
|
||||
bin.any
|
||||
bin.bios
|
||||
bin.fs
|
||||
|
|
Loading…
Reference in New Issue