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