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