Coverage Report

Created: 2025-07-01 07:03

/src/capstonev5/arch/EVM/EVMDisassembler.c
Line
Count
Source (jump to first uncovered line)
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
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
12.9k
{
273
12.9k
  unsigned char opcode;
274
275
12.9k
  if (code_len == 0)
276
0
    return false;
277
278
12.9k
  opcode = code[0];
279
12.9k
  if (opcodes[opcode] == -1) {
280
    // invalid opcode
281
56
    return false;
282
56
  }
283
284
  // valid opcode
285
12.9k
  MI->address = address;
286
12.9k
  MI->OpcodePub = MI->Opcode = opcode;
287
288
12.9k
  if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
289
392
    unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
290
392
    if (code_len < 1 + len) {
291
      // not enough data
292
17
      return false;
293
17
    }
294
295
375
    *size = 1 + len;
296
375
    memcpy(MI->evm_data, code + 1, len);
297
375
  } else
298
12.5k
    *size = 1;
299
300
12.8k
  if (MI->flat_insn->detail) {
301
12.8k
    memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
302
12.8k
    EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
303
304
12.8k
    if (MI->flat_insn->detail->evm.pop) {
305
10.7k
      MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
306
10.7k
      MI->flat_insn->detail->groups_count++;
307
10.7k
    }
308
309
12.8k
    if (MI->flat_insn->detail->evm.push) {
310
7.82k
      MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
311
7.82k
      MI->flat_insn->detail->groups_count++;
312
7.82k
    }
313
314
    // setup groups
315
12.8k
    switch(opcode) {
316
1.07k
      default:
317
1.07k
        break;
318
1.07k
      case EVM_INS_ADD:
319
1.77k
      case EVM_INS_MUL:
320
2.11k
      case EVM_INS_SUB:
321
2.40k
      case EVM_INS_DIV:
322
2.69k
      case EVM_INS_SDIV:
323
2.96k
      case EVM_INS_MOD:
324
3.14k
      case EVM_INS_SMOD:
325
3.52k
      case EVM_INS_ADDMOD:
326
3.74k
      case EVM_INS_MULMOD:
327
3.94k
      case EVM_INS_EXP:
328
4.70k
      case EVM_INS_SIGNEXTEND:
329
4.70k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
330
4.70k
        MI->flat_insn->detail->groups_count++;
331
4.70k
        break;
332
333
235
      case EVM_INS_MSTORE:
334
453
      case EVM_INS_MSTORE8:
335
781
      case EVM_INS_CALLDATACOPY:
336
984
      case EVM_INS_CODECOPY:
337
1.21k
      case EVM_INS_EXTCODECOPY:
338
1.21k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
339
1.21k
        MI->flat_insn->detail->groups_count++;
340
1.21k
        break;
341
342
552
      case EVM_INS_MLOAD:
343
778
      case EVM_INS_CREATE:
344
1.30k
      case EVM_INS_CALL:
345
1.51k
      case EVM_INS_CALLCODE:
346
1.72k
      case EVM_INS_RETURN:
347
2.11k
      case EVM_INS_DELEGATECALL:
348
2.61k
      case EVM_INS_REVERT:
349
2.61k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
350
2.61k
        MI->flat_insn->detail->groups_count++;
351
2.61k
        break;
352
353
199
      case EVM_INS_SSTORE:
354
199
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
355
199
        MI->flat_insn->detail->groups_count++;
356
199
        break;
357
358
174
      case EVM_INS_SLOAD:
359
174
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
360
174
        MI->flat_insn->detail->groups_count++;
361
174
        break;
362
363
879
      case EVM_INS_JUMP:
364
948
      case EVM_INS_JUMPI:
365
948
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
366
948
        MI->flat_insn->detail->groups_count++;
367
948
        break;
368
369
1.48k
      case EVM_INS_STOP:
370
1.96k
      case EVM_INS_SUICIDE:
371
1.96k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
372
1.96k
        MI->flat_insn->detail->groups_count++;
373
1.96k
        break;
374
375
12.8k
    }
376
12.8k
  }
377
378
12.8k
  return true;
379
12.8k
}