Coverage Report

Created: 2025-07-01 07:03

/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
}