Coverage Report

Created: 2024-08-21 06:24

/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
21.3k
{
273
21.3k
  unsigned char opcode;
274
275
21.3k
  if (code_len == 0)
276
0
    return false;
277
278
21.3k
  opcode = code[0];
279
21.3k
  if (opcodes[opcode] == -1) {
280
    // invalid opcode
281
126
    return false;
282
126
  }
283
284
  // valid opcode
285
21.1k
  MI->address = address;
286
21.1k
  MI->OpcodePub = MI->Opcode = opcode;
287
288
21.1k
  if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
289
1.50k
    unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
290
1.50k
    if (code_len < 1 + len) {
291
      // not enough data
292
65
      return false;
293
65
    }
294
295
1.43k
    *size = 1 + len;
296
1.43k
    memcpy(MI->evm_data, code + 1, len);
297
1.43k
  } else
298
19.6k
    *size = 1;
299
300
21.1k
  if (MI->flat_insn->detail) {
301
21.1k
    memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
302
21.1k
    EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
303
304
21.1k
    if (MI->flat_insn->detail->evm.pop) {
305
17.1k
      MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
306
17.1k
      MI->flat_insn->detail->groups_count++;
307
17.1k
    }
308
309
21.1k
    if (MI->flat_insn->detail->evm.push) {
310
12.8k
      MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
311
12.8k
      MI->flat_insn->detail->groups_count++;
312
12.8k
    }
313
314
    // setup groups
315
21.1k
    switch(opcode) {
316
4.15k
      default:
317
4.15k
        break;
318
4.15k
      case EVM_INS_ADD:
319
982
      case EVM_INS_MUL:
320
1.33k
      case EVM_INS_SUB:
321
1.99k
      case EVM_INS_DIV:
322
2.67k
      case EVM_INS_SDIV:
323
3.41k
      case EVM_INS_MOD:
324
4.54k
      case EVM_INS_SMOD:
325
4.95k
      case EVM_INS_ADDMOD:
326
5.36k
      case EVM_INS_MULMOD:
327
5.72k
      case EVM_INS_EXP:
328
6.28k
      case EVM_INS_SIGNEXTEND:
329
6.28k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
330
6.28k
        MI->flat_insn->detail->groups_count++;
331
6.28k
        break;
332
333
618
      case EVM_INS_MSTORE:
334
972
      case EVM_INS_MSTORE8:
335
1.35k
      case EVM_INS_CALLDATACOPY:
336
1.68k
      case EVM_INS_CODECOPY:
337
2.13k
      case EVM_INS_EXTCODECOPY:
338
2.13k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
339
2.13k
        MI->flat_insn->detail->groups_count++;
340
2.13k
        break;
341
342
705
      case EVM_INS_MLOAD:
343
1.17k
      case EVM_INS_CREATE:
344
1.47k
      case EVM_INS_CALL:
345
1.76k
      case EVM_INS_CALLCODE:
346
2.18k
      case EVM_INS_RETURN:
347
3.06k
      case EVM_INS_DELEGATECALL:
348
3.54k
      case EVM_INS_REVERT:
349
3.54k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
350
3.54k
        MI->flat_insn->detail->groups_count++;
351
3.54k
        break;
352
353
417
      case EVM_INS_SSTORE:
354
417
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
355
417
        MI->flat_insn->detail->groups_count++;
356
417
        break;
357
358
460
      case EVM_INS_SLOAD:
359
460
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
360
460
        MI->flat_insn->detail->groups_count++;
361
460
        break;
362
363
371
      case EVM_INS_JUMP:
364
762
      case EVM_INS_JUMPI:
365
762
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
366
762
        MI->flat_insn->detail->groups_count++;
367
762
        break;
368
369
2.04k
      case EVM_INS_STOP:
370
3.34k
      case EVM_INS_SUICIDE:
371
3.34k
        MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
372
3.34k
        MI->flat_insn->detail->groups_count++;
373
3.34k
        break;
374
375
21.1k
    }
376
21.1k
  }
377
378
21.1k
  return true;
379
21.1k
}