/src/capstonenext/arch/EVM/EVMDisassembler.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Capstone Disassembly Engine */ |
2 | | /* By Nguyen Anh Quynh, 2018 */ |
3 | | /* By Andelf, 2025 */ |
4 | | |
5 | | #include <string.h> |
6 | | #include <stddef.h> // offsetof macro |
7 | | // alternatively #include "../../utils.h" like everyone else |
8 | | |
9 | | #include "EVMDisassembler.h" |
10 | | #include "EVMMapping.h" |
11 | | |
12 | | static const short opcodes[256] = { |
13 | | EVM_INS_STOP, |
14 | | EVM_INS_ADD, |
15 | | EVM_INS_MUL, |
16 | | EVM_INS_SUB, |
17 | | EVM_INS_DIV, |
18 | | EVM_INS_SDIV, |
19 | | EVM_INS_MOD, |
20 | | EVM_INS_SMOD, |
21 | | EVM_INS_ADDMOD, |
22 | | EVM_INS_MULMOD, |
23 | | EVM_INS_EXP, |
24 | | EVM_INS_SIGNEXTEND, |
25 | | -1, |
26 | | -1, |
27 | | -1, |
28 | | -1, |
29 | | EVM_INS_LT, |
30 | | EVM_INS_GT, |
31 | | EVM_INS_SLT, |
32 | | EVM_INS_SGT, |
33 | | EVM_INS_EQ, |
34 | | EVM_INS_ISZERO, |
35 | | EVM_INS_AND, |
36 | | EVM_INS_OR, |
37 | | EVM_INS_XOR, |
38 | | EVM_INS_NOT, |
39 | | EVM_INS_BYTE, |
40 | | EVM_INS_SHL, |
41 | | EVM_INS_SHR, |
42 | | EVM_INS_SAR, |
43 | | -1, |
44 | | -1, |
45 | | EVM_INS_SHA3, |
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 | | -1, |
61 | | EVM_INS_ADDRESS, |
62 | | EVM_INS_BALANCE, |
63 | | EVM_INS_ORIGIN, |
64 | | EVM_INS_CALLER, |
65 | | EVM_INS_CALLVALUE, |
66 | | EVM_INS_CALLDATALOAD, |
67 | | EVM_INS_CALLDATASIZE, |
68 | | EVM_INS_CALLDATACOPY, |
69 | | EVM_INS_CODESIZE, |
70 | | EVM_INS_CODECOPY, |
71 | | EVM_INS_GASPRICE, |
72 | | EVM_INS_EXTCODESIZE, |
73 | | EVM_INS_EXTCODECOPY, |
74 | | EVM_INS_RETURNDATASIZE, |
75 | | EVM_INS_RETURNDATACOPY, |
76 | | -1, |
77 | | EVM_INS_BLOCKHASH, |
78 | | EVM_INS_COINBASE, |
79 | | EVM_INS_TIMESTAMP, |
80 | | EVM_INS_NUMBER, |
81 | | EVM_INS_DIFFICULTY, |
82 | | EVM_INS_GASLIMIT, |
83 | | EVM_INS_CHAINID, |
84 | | EVM_INS_SELFBALANCE, |
85 | | EVM_INS_BASEFEE, |
86 | | EVM_INS_BLOBHASH, |
87 | | EVM_INS_BLOBBASEFEE, |
88 | | -1, |
89 | | -1, |
90 | | -1, |
91 | | -1, |
92 | | -1, |
93 | | EVM_INS_POP, |
94 | | EVM_INS_MLOAD, |
95 | | EVM_INS_MSTORE, |
96 | | EVM_INS_MSTORE8, |
97 | | EVM_INS_SLOAD, |
98 | | EVM_INS_SSTORE, |
99 | | EVM_INS_JUMP, |
100 | | EVM_INS_JUMPI, |
101 | | EVM_INS_PC, |
102 | | EVM_INS_MSIZE, |
103 | | EVM_INS_GAS, |
104 | | EVM_INS_JUMPDEST, |
105 | | EVM_INS_TLOAD, |
106 | | EVM_INS_TSTORE, |
107 | | EVM_INS_MCOPY, |
108 | | EVM_INS_PUSH0, |
109 | | EVM_INS_PUSH1, |
110 | | EVM_INS_PUSH2, |
111 | | EVM_INS_PUSH3, |
112 | | EVM_INS_PUSH4, |
113 | | EVM_INS_PUSH5, |
114 | | EVM_INS_PUSH6, |
115 | | EVM_INS_PUSH7, |
116 | | EVM_INS_PUSH8, |
117 | | EVM_INS_PUSH9, |
118 | | EVM_INS_PUSH10, |
119 | | EVM_INS_PUSH11, |
120 | | EVM_INS_PUSH12, |
121 | | EVM_INS_PUSH13, |
122 | | EVM_INS_PUSH14, |
123 | | EVM_INS_PUSH15, |
124 | | EVM_INS_PUSH16, |
125 | | EVM_INS_PUSH17, |
126 | | EVM_INS_PUSH18, |
127 | | EVM_INS_PUSH19, |
128 | | EVM_INS_PUSH20, |
129 | | EVM_INS_PUSH21, |
130 | | EVM_INS_PUSH22, |
131 | | EVM_INS_PUSH23, |
132 | | EVM_INS_PUSH24, |
133 | | EVM_INS_PUSH25, |
134 | | EVM_INS_PUSH26, |
135 | | EVM_INS_PUSH27, |
136 | | EVM_INS_PUSH28, |
137 | | EVM_INS_PUSH29, |
138 | | EVM_INS_PUSH30, |
139 | | EVM_INS_PUSH31, |
140 | | EVM_INS_PUSH32, |
141 | | EVM_INS_DUP1, |
142 | | EVM_INS_DUP2, |
143 | | EVM_INS_DUP3, |
144 | | EVM_INS_DUP4, |
145 | | EVM_INS_DUP5, |
146 | | EVM_INS_DUP6, |
147 | | EVM_INS_DUP7, |
148 | | EVM_INS_DUP8, |
149 | | EVM_INS_DUP9, |
150 | | EVM_INS_DUP10, |
151 | | EVM_INS_DUP11, |
152 | | EVM_INS_DUP12, |
153 | | EVM_INS_DUP13, |
154 | | EVM_INS_DUP14, |
155 | | EVM_INS_DUP15, |
156 | | EVM_INS_DUP16, |
157 | | EVM_INS_SWAP1, |
158 | | EVM_INS_SWAP2, |
159 | | EVM_INS_SWAP3, |
160 | | EVM_INS_SWAP4, |
161 | | EVM_INS_SWAP5, |
162 | | EVM_INS_SWAP6, |
163 | | EVM_INS_SWAP7, |
164 | | EVM_INS_SWAP8, |
165 | | EVM_INS_SWAP9, |
166 | | EVM_INS_SWAP10, |
167 | | EVM_INS_SWAP11, |
168 | | EVM_INS_SWAP12, |
169 | | EVM_INS_SWAP13, |
170 | | EVM_INS_SWAP14, |
171 | | EVM_INS_SWAP15, |
172 | | EVM_INS_SWAP16, |
173 | | EVM_INS_LOG0, |
174 | | EVM_INS_LOG1, |
175 | | EVM_INS_LOG2, |
176 | | EVM_INS_LOG3, |
177 | | EVM_INS_LOG4, |
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 | | -1, |
253 | | EVM_INS_CREATE, |
254 | | EVM_INS_CALL, |
255 | | EVM_INS_CALLCODE, |
256 | | EVM_INS_RETURN, |
257 | | EVM_INS_DELEGATECALL, |
258 | | EVM_INS_CREATE2, |
259 | | -1, |
260 | | -1, |
261 | | -1, |
262 | | -1, |
263 | | EVM_INS_STATICCALL, |
264 | | -1, |
265 | | -1, |
266 | | EVM_INS_REVERT, |
267 | | -1, |
268 | | EVM_INS_SELFDESTRUCT, |
269 | | }; |
270 | | |
271 | | bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
272 | | MCInst *MI, uint16_t *size, uint64_t address, void *inst_info) |
273 | 19.4k | { |
274 | 19.4k | unsigned char opcode; |
275 | | |
276 | 19.4k | if (code_len == 0) |
277 | 0 | return false; |
278 | | |
279 | 19.4k | opcode = code[0]; |
280 | 19.4k | if (opcodes[opcode] == -1) { |
281 | | // invalid opcode |
282 | 50 | return false; |
283 | 50 | } |
284 | | |
285 | | // valid opcode |
286 | 19.3k | MI->address = address; |
287 | 19.3k | MI->OpcodePub = MI->Opcode = opcode; |
288 | | |
289 | 19.3k | if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) { |
290 | 633 | unsigned char len = (opcode - EVM_INS_PUSH1 + 1); |
291 | 633 | if (code_len < 1 + len) { |
292 | | // not enough data |
293 | 17 | return false; |
294 | 17 | } |
295 | | |
296 | 616 | *size = 1 + len; |
297 | 616 | memcpy(MI->evm_data, code + 1, len); |
298 | 616 | } else |
299 | 18.7k | *size = 1; |
300 | | |
301 | 19.3k | if (MI->flat_insn->detail) { |
302 | 19.3k | memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm)); |
303 | 19.3k | EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode); |
304 | | |
305 | 19.3k | if (MI->flat_insn->detail->evm.pop) { |
306 | 16.0k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ; |
307 | 16.0k | MI->flat_insn->detail->groups_count++; |
308 | 16.0k | } |
309 | | |
310 | 19.3k | if (MI->flat_insn->detail->evm.push) { |
311 | 11.8k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE; |
312 | 11.8k | MI->flat_insn->detail->groups_count++; |
313 | 11.8k | } |
314 | | |
315 | | // setup groups |
316 | 19.3k | switch(opcode) { |
317 | 2.32k | default: |
318 | 2.32k | break; |
319 | 2.32k | case EVM_INS_ADD: |
320 | 1.30k | case EVM_INS_MUL: |
321 | 1.71k | case EVM_INS_SUB: |
322 | 1.93k | case EVM_INS_DIV: |
323 | 3.05k | case EVM_INS_SDIV: |
324 | 3.26k | case EVM_INS_MOD: |
325 | 3.96k | case EVM_INS_SMOD: |
326 | 4.30k | case EVM_INS_ADDMOD: |
327 | 4.51k | case EVM_INS_MULMOD: |
328 | 4.72k | case EVM_INS_EXP: |
329 | 5.22k | case EVM_INS_SIGNEXTEND: |
330 | 5.52k | case EVM_INS_SHL: |
331 | 6.00k | case EVM_INS_SHR: |
332 | 6.84k | case EVM_INS_SAR: |
333 | 6.84k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH; |
334 | 6.84k | MI->flat_insn->detail->groups_count++; |
335 | 6.84k | break; |
336 | | |
337 | 200 | case EVM_INS_MSTORE: |
338 | 411 | case EVM_INS_MSTORE8: |
339 | 2.21k | case EVM_INS_CALLDATACOPY: |
340 | 2.44k | case EVM_INS_CODECOPY: |
341 | 2.91k | case EVM_INS_EXTCODECOPY: |
342 | 3.10k | case EVM_INS_MCOPY: |
343 | 3.10k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE; |
344 | 3.10k | MI->flat_insn->detail->groups_count++; |
345 | 3.10k | break; |
346 | | |
347 | 857 | case EVM_INS_MLOAD: |
348 | 1.17k | case EVM_INS_CREATE: |
349 | 1.36k | case EVM_INS_CALL: |
350 | 1.87k | case EVM_INS_CALLCODE: |
351 | 2.13k | case EVM_INS_RETURN: |
352 | 2.38k | case EVM_INS_DELEGATECALL: |
353 | 2.59k | case EVM_INS_REVERT: |
354 | 2.70k | case EVM_INS_CREATE2: |
355 | 2.70k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ; |
356 | 2.70k | MI->flat_insn->detail->groups_count++; |
357 | 2.70k | break; |
358 | | |
359 | 205 | case EVM_INS_SSTORE: |
360 | 657 | case EVM_INS_TSTORE: |
361 | 657 | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE; |
362 | 657 | MI->flat_insn->detail->groups_count++; |
363 | 657 | break; |
364 | | |
365 | 465 | case EVM_INS_SLOAD: |
366 | 659 | case EVM_INS_TLOAD: |
367 | 659 | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ; |
368 | 659 | MI->flat_insn->detail->groups_count++; |
369 | 659 | break; |
370 | | |
371 | 202 | case EVM_INS_JUMP: |
372 | 272 | case EVM_INS_JUMPI: |
373 | 272 | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP; |
374 | 272 | MI->flat_insn->detail->groups_count++; |
375 | 272 | break; |
376 | | |
377 | 2.32k | case EVM_INS_STOP: |
378 | 2.76k | case EVM_INS_SELFDESTRUCT: |
379 | 2.76k | MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT; |
380 | 2.76k | MI->flat_insn->detail->groups_count++; |
381 | 2.76k | break; |
382 | | |
383 | 19.3k | } |
384 | 19.3k | } |
385 | | |
386 | 19.3k | return true; |
387 | 19.3k | } |