1 /* radare - LGPL - Copyright 2012-2013 - pancake, fedor.sakharov */
2 
3 #include <string.h>
4 #include <r_types.h>
5 #include <r_lib.h>
6 #include <r_asm.h>
7 #include <r_anal.h>
8 
9 #include <ebc_disas.h>
10 
ebc_anal_jmp8(RAnalOp * op,ut64 addr,const ut8 * buf)11 static void ebc_anal_jmp8(RAnalOp *op, ut64 addr, const ut8 *buf) {
12 	int jmpadr = (int8_t)buf[1];
13 	op->jump = addr + 2 + (jmpadr * 2);
14 	op->addr = addr;
15 	op->fail = addr + 2;
16 
17 	if (TEST_BIT(buf[0], 7)) {
18 		op->type = R_ANAL_OP_TYPE_CJMP;
19 	} else {
20 		op->type = R_ANAL_OP_TYPE_JMP;
21 	}
22 }
23 
ebc_anal_jmp(RAnalOp * op,ut64 addr,const ut8 * buf)24 static void ebc_anal_jmp(RAnalOp *op, ut64 addr, const ut8 *buf) {
25 	op->fail = addr + 6;
26 	op->jump = (ut64)*(int32_t*)(buf + 2);
27 	if (TEST_BIT (buf[1], 4)) {
28 		op->jump += addr + 6;
29 	}
30 	if (buf[1] & 0x7) {
31 		op->type = R_ANAL_OP_TYPE_UJMP;
32 	} else {
33 		if (TEST_BIT(buf[1], 7)) {
34 			op->type = R_ANAL_OP_TYPE_CJMP;
35 		} else {
36 			op->type = R_ANAL_OP_TYPE_JMP;
37 		}
38 	}
39 }
40 
ebc_anal_call(RAnalOp * op,ut64 addr,const ut8 * buf)41 static void ebc_anal_call(RAnalOp *op, ut64 addr, const ut8 *buf) {
42 	int32_t addr_call;
43 
44 	op->fail = addr + 6;
45 	if ((buf[1] & 0x7) == 0 && TEST_BIT(buf[0], 6) == 0
46 			&& TEST_BIT(buf[0], 7)) {
47 		addr_call = *(int32_t*)(buf + 2);
48 
49 		if (TEST_BIT(buf[1], 4)) {
50 			op->jump = (addr + 6 + addr_call);
51 		} else {
52 			op->jump = addr_call;
53 		}
54 		op->type = R_ANAL_OP_TYPE_CALL;
55 	} else {
56 		op->type = R_ANAL_OP_TYPE_UCALL;
57 	}
58 }
59 
ebc_op(RAnal * anal,RAnalOp * op,ut64 addr,const ut8 * buf,int len,RAnalOpMask mask)60 static int ebc_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
61 	int ret;
62 	ebc_command_t cmd;
63 	ut8 opcode = buf[0] & EBC_OPCODE_MASK;
64 
65 	if (!op) {
66 		return 2;
67 	}
68 
69 	op->addr = addr;
70 
71 	ret = op->size = ebc_decode_command(buf, &cmd);
72 
73 	if (ret < 0) {
74 		return ret;
75 	}
76 
77 	switch (opcode) {
78 	case EBC_JMP8:
79 		ebc_anal_jmp8(op, addr, buf);
80 		break;
81 	case EBC_JMP:
82 		ebc_anal_jmp(op, addr, buf);
83 		break;
84 	case EBC_MOVBW:
85 	case EBC_MOVWW:
86 	case EBC_MOVDW:
87 	case EBC_MOVQW:
88 	case EBC_MOVBD:
89 	case EBC_MOVWD:
90 	case EBC_MOVDD:
91 	case EBC_MOVQD:
92 	case EBC_MOVSNW:
93 	case EBC_MOVSND:
94 	case EBC_MOVQQ:
95 	case EBC_MOVNW:
96 	case EBC_MOVND:
97 	case EBC_MOVI:
98 	case EBC_MOVIN:
99 	case EBC_MOVREL:
100 		op->type = R_ANAL_OP_TYPE_MOV;
101 		break;
102 	case EBC_RET:
103 		op->type = R_ANAL_OP_TYPE_RET;
104 		break;
105 	case EBC_CMPEQ:
106 	case EBC_CMPLTE:
107 	case EBC_CMPGTE:
108 	case EBC_CMPULTE:
109 	case EBC_CMPUGTE:
110 	case EBC_CMPIEQ:
111 	case EBC_CMPILTE:
112 	case EBC_CMPIGTE:
113 	case EBC_CMPIULTE:
114 	case EBC_CMPIUGTE:
115 		op->type = R_ANAL_OP_TYPE_CMP;
116 		break;
117 	case EBC_SHR:
118 		op->type = R_ANAL_OP_TYPE_SHR;
119 		break;
120 	case EBC_SHL:
121 		op->type = R_ANAL_OP_TYPE_SHL;
122 		break;
123 	case EBC_OR:
124 		op->type = R_ANAL_OP_TYPE_OR;
125 		break;
126 	case EBC_XOR:
127 		op->type = R_ANAL_OP_TYPE_XOR;
128 		break;
129 	case EBC_MUL:
130 		op->type = R_ANAL_OP_TYPE_MUL;
131 		break;
132 	case EBC_PUSH:
133 		op->type = R_ANAL_OP_TYPE_PUSH;
134 		break;
135 	case EBC_POP:
136 		op->type = R_ANAL_OP_TYPE_POP;
137 		break;
138 	case EBC_AND:
139 		op->type = R_ANAL_OP_TYPE_AND;
140 		break;
141 	case EBC_ADD:
142 		op->type = R_ANAL_OP_TYPE_ADD;
143 		break;
144 	case EBC_SUB:
145 		op->type = R_ANAL_OP_TYPE_SUB;
146 		break;
147 	case EBC_NEG:
148 		op->type = R_ANAL_OP_TYPE_SUB;
149 		break;
150 	case EBC_CALL:
151 		ebc_anal_call(op, addr, buf);
152 		break;
153 	case EBC_BREAK:
154 		op->type = R_ANAL_OP_TYPE_SWI;
155 		break;
156 	default:
157 		op->type = R_ANAL_OP_TYPE_UNK;
158 		break;
159 	}
160 
161 	return ret;
162 }
163 
164 RAnalPlugin r_anal_plugin_ebc = {
165 	.name = "ebc",
166 	.desc = "EBC code analysis plugin",
167 	.license = "LGPL3",
168 	.arch = "ebc",
169 	.bits = 64,
170 	.op = &ebc_op,
171 };
172 
173 #ifndef R2_PLUGIN_INCORE
174 R_API RLibStruct radare_plugin = {
175 	.type = R_LIB_TYPE_ANAL,
176 	.data = &r_anal_plugin_ebc,
177 	.version = R2_VERSION
178 };
179 #endif
180