Coverage Report

Created: 2025-08-28 06:43

/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>
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
  EVM_INS_SHL,
40
  EVM_INS_SHR,
41
  EVM_INS_SAR,
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
  EVM_INS_CHAINID,
83
  EVM_INS_SELFBALANCE,
84
  EVM_INS_BASEFEE,
85
  EVM_INS_BLOBHASH,
86
  EVM_INS_BLOBBASEFEE,
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
  EVM_INS_TLOAD,
105
  EVM_INS_TSTORE,
106
  EVM_INS_MCOPY,
107
  EVM_INS_PUSH0,
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_CREATE2,
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_SELFDESTRUCT,
268
};
269
270
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
271
      MCInst *MI, uint16_t *size, uint64_t address,
272
      void *inst_info)
273
9.53k
{
274
9.53k
  unsigned char opcode;
275
276
9.53k
  if (code_len == 0)
277
0
    return false;
278
279
9.53k
  opcode = code[0];
280
9.53k
  if (opcodes[opcode] == -1) {
281
    // invalid opcode
282
52
    return false;
283
52
  }
284
285
  // valid opcode
286
9.48k
  MI->address = address;
287
9.48k
  MI->OpcodePub = MI->Opcode = opcode;
288
289
9.48k
  if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
290
329
    unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
291
329
    if (code_len < 1 + len) {
292
      // not enough data
293
21
      return false;
294
21
    }
295
296
308
    *size = 1 + len;
297
308
    memcpy(MI->evm_data, code + 1, len);
298
308
  } else
299
9.15k
    *size = 1;
300
301
9.46k
  if (MI->flat_insn->detail) {
302
9.46k
    memset(MI->flat_insn->detail, 0,
303
9.46k
           offsetof(cs_detail, evm) + sizeof(cs_evm));
304
9.46k
    EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
305
306
9.46k
    if (MI->flat_insn->detail->evm.pop) {
307
8.12k
      MI->flat_insn->detail
308
8.12k
        ->groups[MI->flat_insn->detail->groups_count] =
309
8.12k
        EVM_GRP_STACK_READ;
310
8.12k
      MI->flat_insn->detail->groups_count++;
311
8.12k
    }
312
313
9.46k
    if (MI->flat_insn->detail->evm.push) {
314
5.54k
      MI->flat_insn->detail
315
5.54k
        ->groups[MI->flat_insn->detail->groups_count] =
316
5.54k
        EVM_GRP_STACK_WRITE;
317
5.54k
      MI->flat_insn->detail->groups_count++;
318
5.54k
    }
319
320
    // setup groups
321
9.46k
    switch (opcode) {
322
1.01k
    default:
323
1.01k
      break;
324
1.01k
    case EVM_INS_ADD:
325
432
    case EVM_INS_MUL:
326
641
    case EVM_INS_SUB:
327
839
    case EVM_INS_DIV:
328
1.04k
    case EVM_INS_SDIV:
329
1.25k
    case EVM_INS_MOD:
330
1.46k
    case EVM_INS_SMOD:
331
1.66k
    case EVM_INS_ADDMOD:
332
1.86k
    case EVM_INS_MULMOD:
333
2.06k
    case EVM_INS_EXP:
334
2.26k
    case EVM_INS_SIGNEXTEND:
335
2.47k
    case EVM_INS_SHL:
336
2.68k
    case EVM_INS_SHR:
337
2.94k
    case EVM_INS_SAR:
338
2.94k
      MI->flat_insn->detail
339
2.94k
        ->groups[MI->flat_insn->detail->groups_count] =
340
2.94k
        EVM_GRP_MATH;
341
2.94k
      MI->flat_insn->detail->groups_count++;
342
2.94k
      break;
343
344
255
    case EVM_INS_MSTORE:
345
452
    case EVM_INS_MSTORE8:
346
774
    case EVM_INS_CALLDATACOPY:
347
981
    case EVM_INS_CODECOPY:
348
1.18k
    case EVM_INS_EXTCODECOPY:
349
1.39k
    case EVM_INS_MCOPY:
350
1.39k
      MI->flat_insn->detail
351
1.39k
        ->groups[MI->flat_insn->detail->groups_count] =
352
1.39k
        EVM_GRP_MEM_WRITE;
353
1.39k
      MI->flat_insn->detail->groups_count++;
354
1.39k
      break;
355
356
195
    case EVM_INS_MLOAD:
357
397
    case EVM_INS_CREATE:
358
601
    case EVM_INS_CALL:
359
816
    case EVM_INS_CALLCODE:
360
1.01k
    case EVM_INS_RETURN:
361
1.22k
    case EVM_INS_DELEGATECALL:
362
1.42k
    case EVM_INS_REVERT:
363
1.66k
    case EVM_INS_CREATE2:
364
1.66k
      MI->flat_insn->detail
365
1.66k
        ->groups[MI->flat_insn->detail->groups_count] =
366
1.66k
        EVM_GRP_MEM_READ;
367
1.66k
      MI->flat_insn->detail->groups_count++;
368
1.66k
      break;
369
370
244
    case EVM_INS_SSTORE:
371
453
    case EVM_INS_TSTORE:
372
453
      MI->flat_insn->detail
373
453
        ->groups[MI->flat_insn->detail->groups_count] =
374
453
        EVM_GRP_STORE_WRITE;
375
453
      MI->flat_insn->detail->groups_count++;
376
453
      break;
377
378
212
    case EVM_INS_SLOAD:
379
420
    case EVM_INS_TLOAD:
380
420
      MI->flat_insn->detail
381
420
        ->groups[MI->flat_insn->detail->groups_count] =
382
420
        EVM_GRP_STORE_READ;
383
420
      MI->flat_insn->detail->groups_count++;
384
420
      break;
385
386
195
    case EVM_INS_JUMP:
387
405
    case EVM_INS_JUMPI:
388
405
      MI->flat_insn->detail
389
405
        ->groups[MI->flat_insn->detail->groups_count] =
390
405
        EVM_GRP_JUMP;
391
405
      MI->flat_insn->detail->groups_count++;
392
405
      break;
393
394
779
    case EVM_INS_STOP:
395
1.15k
    case EVM_INS_SELFDESTRUCT:
396
1.15k
      MI->flat_insn->detail
397
1.15k
        ->groups[MI->flat_insn->detail->groups_count] =
398
1.15k
        EVM_GRP_HALT;
399
1.15k
      MI->flat_insn->detail->groups_count++;
400
1.15k
      break;
401
9.46k
    }
402
9.46k
  }
403
404
9.46k
  return true;
405
9.46k
}