1 /* Capstone Disassembly Engine */
2 /* By Nguyen Anh Quynh, 2018 */
3
4 #include <string.h>
5 #include <stddef.h> // offsetof macro
6 // alternatively #include "../../utils.h" like everyone else
7
8 #include "EVMDisassembler.h"
9 #include "EVMMapping.h"
10
11 static short opcodes[256] = {
12 EVM_INS_STOP,
13 EVM_INS_ADD,
14 EVM_INS_MUL,
15 EVM_INS_SUB,
16 EVM_INS_DIV,
17 EVM_INS_SDIV,
18 EVM_INS_MOD,
19 EVM_INS_SMOD,
20 EVM_INS_ADDMOD,
21 EVM_INS_MULMOD,
22 EVM_INS_EXP,
23 EVM_INS_SIGNEXTEND,
24 -1,
25 -1,
26 -1,
27 -1,
28 EVM_INS_LT,
29 EVM_INS_GT,
30 EVM_INS_SLT,
31 EVM_INS_SGT,
32 EVM_INS_EQ,
33 EVM_INS_ISZERO,
34 EVM_INS_AND,
35 EVM_INS_OR,
36 EVM_INS_XOR,
37 EVM_INS_NOT,
38 EVM_INS_BYTE,
39 -1,
40 -1,
41 -1,
42 -1,
43 -1,
44 EVM_INS_SHA3,
45 -1,
46 -1,
47 -1,
48 -1,
49 -1,
50 -1,
51 -1,
52 -1,
53 -1,
54 -1,
55 -1,
56 -1,
57 -1,
58 -1,
59 -1,
60 EVM_INS_ADDRESS,
61 EVM_INS_BALANCE,
62 EVM_INS_ORIGIN,
63 EVM_INS_CALLER,
64 EVM_INS_CALLVALUE,
65 EVM_INS_CALLDATALOAD,
66 EVM_INS_CALLDATASIZE,
67 EVM_INS_CALLDATACOPY,
68 EVM_INS_CODESIZE,
69 EVM_INS_CODECOPY,
70 EVM_INS_GASPRICE,
71 EVM_INS_EXTCODESIZE,
72 EVM_INS_EXTCODECOPY,
73 EVM_INS_RETURNDATASIZE,
74 EVM_INS_RETURNDATACOPY,
75 -1,
76 EVM_INS_BLOCKHASH,
77 EVM_INS_COINBASE,
78 EVM_INS_TIMESTAMP,
79 EVM_INS_NUMBER,
80 EVM_INS_DIFFICULTY,
81 EVM_INS_GASLIMIT,
82 -1,
83 -1,
84 -1,
85 -1,
86 -1,
87 -1,
88 -1,
89 -1,
90 -1,
91 -1,
92 EVM_INS_POP,
93 EVM_INS_MLOAD,
94 EVM_INS_MSTORE,
95 EVM_INS_MSTORE8,
96 EVM_INS_SLOAD,
97 EVM_INS_SSTORE,
98 EVM_INS_JUMP,
99 EVM_INS_JUMPI,
100 EVM_INS_PC,
101 EVM_INS_MSIZE,
102 EVM_INS_GAS,
103 EVM_INS_JUMPDEST,
104 -1,
105 -1,
106 -1,
107 -1,
108 EVM_INS_PUSH1,
109 EVM_INS_PUSH2,
110 EVM_INS_PUSH3,
111 EVM_INS_PUSH4,
112 EVM_INS_PUSH5,
113 EVM_INS_PUSH6,
114 EVM_INS_PUSH7,
115 EVM_INS_PUSH8,
116 EVM_INS_PUSH9,
117 EVM_INS_PUSH10,
118 EVM_INS_PUSH11,
119 EVM_INS_PUSH12,
120 EVM_INS_PUSH13,
121 EVM_INS_PUSH14,
122 EVM_INS_PUSH15,
123 EVM_INS_PUSH16,
124 EVM_INS_PUSH17,
125 EVM_INS_PUSH18,
126 EVM_INS_PUSH19,
127 EVM_INS_PUSH20,
128 EVM_INS_PUSH21,
129 EVM_INS_PUSH22,
130 EVM_INS_PUSH23,
131 EVM_INS_PUSH24,
132 EVM_INS_PUSH25,
133 EVM_INS_PUSH26,
134 EVM_INS_PUSH27,
135 EVM_INS_PUSH28,
136 EVM_INS_PUSH29,
137 EVM_INS_PUSH30,
138 EVM_INS_PUSH31,
139 EVM_INS_PUSH32,
140 EVM_INS_DUP1,
141 EVM_INS_DUP2,
142 EVM_INS_DUP3,
143 EVM_INS_DUP4,
144 EVM_INS_DUP5,
145 EVM_INS_DUP6,
146 EVM_INS_DUP7,
147 EVM_INS_DUP8,
148 EVM_INS_DUP9,
149 EVM_INS_DUP10,
150 EVM_INS_DUP11,
151 EVM_INS_DUP12,
152 EVM_INS_DUP13,
153 EVM_INS_DUP14,
154 EVM_INS_DUP15,
155 EVM_INS_DUP16,
156 EVM_INS_SWAP1,
157 EVM_INS_SWAP2,
158 EVM_INS_SWAP3,
159 EVM_INS_SWAP4,
160 EVM_INS_SWAP5,
161 EVM_INS_SWAP6,
162 EVM_INS_SWAP7,
163 EVM_INS_SWAP8,
164 EVM_INS_SWAP9,
165 EVM_INS_SWAP10,
166 EVM_INS_SWAP11,
167 EVM_INS_SWAP12,
168 EVM_INS_SWAP13,
169 EVM_INS_SWAP14,
170 EVM_INS_SWAP15,
171 EVM_INS_SWAP16,
172 EVM_INS_LOG0,
173 EVM_INS_LOG1,
174 EVM_INS_LOG2,
175 EVM_INS_LOG3,
176 EVM_INS_LOG4,
177 -1,
178 -1,
179 -1,
180 -1,
181 -1,
182 -1,
183 -1,
184 -1,
185 -1,
186 -1,
187 -1,
188 -1,
189 -1,
190 -1,
191 -1,
192 -1,
193 -1,
194 -1,
195 -1,
196 -1,
197 -1,
198 -1,
199 -1,
200 -1,
201 -1,
202 -1,
203 -1,
204 -1,
205 -1,
206 -1,
207 -1,
208 -1,
209 -1,
210 -1,
211 -1,
212 -1,
213 -1,
214 -1,
215 -1,
216 -1,
217 -1,
218 -1,
219 -1,
220 -1,
221 -1,
222 -1,
223 -1,
224 -1,
225 -1,
226 -1,
227 -1,
228 -1,
229 -1,
230 -1,
231 -1,
232 -1,
233 -1,
234 -1,
235 -1,
236 -1,
237 -1,
238 -1,
239 -1,
240 -1,
241 -1,
242 -1,
243 -1,
244 -1,
245 -1,
246 -1,
247 -1,
248 -1,
249 -1,
250 -1,
251 -1,
252 EVM_INS_CREATE,
253 EVM_INS_CALL,
254 EVM_INS_CALLCODE,
255 EVM_INS_RETURN,
256 EVM_INS_DELEGATECALL,
257 EVM_INS_CALLBLACKBOX,
258 -1,
259 -1,
260 -1,
261 -1,
262 EVM_INS_STATICCALL,
263 -1,
264 -1,
265 EVM_INS_REVERT,
266 -1,
267 EVM_INS_SUICIDE,
268 };
269
EVM_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * MI,uint16_t * size,uint64_t address,void * inst_info)270 bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
271 MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
272 {
273 unsigned char opcode;
274
275 if (code_len == 0)
276 return false;
277
278 opcode = code[0];
279 if (opcodes[opcode] == -1) {
280 // invalid opcode
281 return false;
282 }
283
284 // valid opcode
285 MI->address = address;
286 MI->OpcodePub = MI->Opcode = opcode;
287
288 if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
289 unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
290 if (code_len < 1 + len) {
291 // not enough data
292 return false;
293 }
294
295 *size = 1 + len;
296 memcpy(MI->evm_data, code + 1, len);
297 } else
298 *size = 1;
299
300 if (MI->flat_insn->detail) {
301 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
302 EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
303
304 if (MI->flat_insn->detail->evm.pop) {
305 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
306 MI->flat_insn->detail->groups_count++;
307 }
308
309 if (MI->flat_insn->detail->evm.push) {
310 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
311 MI->flat_insn->detail->groups_count++;
312 }
313
314 // setup groups
315 switch(opcode) {
316 default:
317 break;
318 case EVM_INS_ADD:
319 case EVM_INS_MUL:
320 case EVM_INS_SUB:
321 case EVM_INS_DIV:
322 case EVM_INS_SDIV:
323 case EVM_INS_MOD:
324 case EVM_INS_SMOD:
325 case EVM_INS_ADDMOD:
326 case EVM_INS_MULMOD:
327 case EVM_INS_EXP:
328 case EVM_INS_SIGNEXTEND:
329 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
330 MI->flat_insn->detail->groups_count++;
331 break;
332
333 case EVM_INS_MSTORE:
334 case EVM_INS_MSTORE8:
335 case EVM_INS_CALLDATACOPY:
336 case EVM_INS_CODECOPY:
337 case EVM_INS_EXTCODECOPY:
338 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
339 MI->flat_insn->detail->groups_count++;
340 break;
341
342 case EVM_INS_MLOAD:
343 case EVM_INS_CREATE:
344 case EVM_INS_CALL:
345 case EVM_INS_CALLCODE:
346 case EVM_INS_RETURN:
347 case EVM_INS_DELEGATECALL:
348 case EVM_INS_REVERT:
349 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
350 MI->flat_insn->detail->groups_count++;
351 break;
352
353 case EVM_INS_SSTORE:
354 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
355 MI->flat_insn->detail->groups_count++;
356 break;
357
358 case EVM_INS_SLOAD:
359 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
360 MI->flat_insn->detail->groups_count++;
361 break;
362
363 case EVM_INS_JUMP:
364 case EVM_INS_JUMPI:
365 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
366 MI->flat_insn->detail->groups_count++;
367 break;
368
369 case EVM_INS_STOP:
370 case EVM_INS_SUICIDE:
371 MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
372 MI->flat_insn->detail->groups_count++;
373 break;
374
375 }
376 }
377
378 return true;
379 }
380