Initial commit for EFI Byte Code (EBC) disassembler.

This commit is contained in:
Fedor Sakharov 2013-11-29 17:55:34 +04:00 committed by pancake
parent b5b6348691
commit 1a72cdec24
13 changed files with 1488 additions and 2 deletions

View File

@ -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:

109
libr/anal/p/anal_ebc.c Normal file
View File

@ -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

11
libr/anal/p/ebc.mk Normal file
View File

@ -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}

View File

@ -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

View File

@ -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}

38
libr/asm/p/asm_ebc.c Normal file
View File

@ -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

10
libr/asm/p/ebc.mk Normal file
View File

@ -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}

96
libr/include/ebc_disas.h Normal file
View File

@ -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 */

View File

@ -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
}

View File

@ -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

View File

@ -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 */

View File

@ -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