Rizin
unix-like reverse engineering framework and cli tools
EVMDisassembler.c
Go to the documentation of this file.
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 short opcodes[256] = {
24  -1,
25  -1,
26  -1,
27  -1,
28  EVM_INS_LT,
29  EVM_INS_GT,
32  EVM_INS_EQ,
35  EVM_INS_OR,
39  -1,
40  -1,
41  -1,
42  -1,
43  -1,
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,
75  -1,
82  -1,
83  -1,
84  -1,
85  -1,
86  -1,
87  -1,
88  -1,
89  -1,
90  -1,
91  -1,
100  EVM_INS_PC,
102  EVM_INS_GAS,
104  -1,
105  -1,
106  -1,
107  -1,
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,
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,
253  EVM_INS_CALL,
258  -1,
259  -1,
260  -1,
261  -1,
263  -1,
264  -1,
266  -1,
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 {
273  unsigned char opcode;
274 
275  if (code_len == 0)
276  return false;
277 
278  opcode = code[0];
279  if (opcodes[opcode] == -1) {
280  // invalid opcode
281  return false;
282  }
283 
284  // valid opcode
285  MI->address = address;
286  MI->OpcodePub = MI->Opcode = opcode;
287 
288  if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
289  unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
290  if (code_len < 1 + len) {
291  // not enough data
292  return false;
293  }
294 
295  *size = 1 + len;
296  memcpy(MI->evm_data, code + 1, len);
297  } else
298  *size = 1;
299 
300  if (MI->flat_insn->detail) {
301  memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
302  EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
303 
304  if (MI->flat_insn->detail->evm.pop) {
305  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
306  MI->flat_insn->detail->groups_count++;
307  }
308 
309  if (MI->flat_insn->detail->evm.push) {
310  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
311  MI->flat_insn->detail->groups_count++;
312  }
313 
314  // setup groups
315  switch(opcode) {
316  default:
317  break;
318  case EVM_INS_ADD:
319  case EVM_INS_MUL:
320  case EVM_INS_SUB:
321  case EVM_INS_DIV:
322  case EVM_INS_SDIV:
323  case EVM_INS_MOD:
324  case EVM_INS_SMOD:
325  case EVM_INS_ADDMOD:
326  case EVM_INS_MULMOD:
327  case EVM_INS_EXP:
328  case EVM_INS_SIGNEXTEND:
329  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
330  MI->flat_insn->detail->groups_count++;
331  break;
332 
333  case EVM_INS_MSTORE:
334  case EVM_INS_MSTORE8:
336  case EVM_INS_CODECOPY:
337  case EVM_INS_EXTCODECOPY:
338  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
339  MI->flat_insn->detail->groups_count++;
340  break;
341 
342  case EVM_INS_MLOAD:
343  case EVM_INS_CREATE:
344  case EVM_INS_CALL:
345  case EVM_INS_CALLCODE:
346  case EVM_INS_RETURN:
348  case EVM_INS_REVERT:
349  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
350  MI->flat_insn->detail->groups_count++;
351  break;
352 
353  case EVM_INS_SSTORE:
354  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
355  MI->flat_insn->detail->groups_count++;
356  break;
357 
358  case EVM_INS_SLOAD:
359  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
360  MI->flat_insn->detail->groups_count++;
361  break;
362 
363  case EVM_INS_JUMP:
364  case EVM_INS_JUMPI:
365  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
366  MI->flat_insn->detail->groups_count++;
367  break;
368 
369  case EVM_INS_STOP:
370  case EVM_INS_SUICIDE:
371  MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
372  MI->flat_insn->detail->groups_count++;
373  break;
374 
375  }
376  }
377 
378  return true;
379 }
size_t len
Definition: 6502dis.c:15
static short opcodes[256]
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
void EVM_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
size_t csh
Definition: capstone.h:71
@ EVM_INS_DUP12
Definition: evm.h:126
@ EVM_INS_AND
Definition: evm.h:44
@ EVM_INS_DUP14
Definition: evm.h:128
@ EVM_INS_CALLDATASIZE
Definition: evm.h:56
@ EVM_INS_PUSH11
Definition: evm.h:93
@ EVM_INS_PUSH12
Definition: evm.h:94
@ EVM_INS_PUSH15
Definition: evm.h:97
@ EVM_INS_DIV
Definition: evm.h:30
@ EVM_INS_CODECOPY
Definition: evm.h:59
@ EVM_INS_SLOAD
Definition: evm.h:75
@ EVM_INS_DUP11
Definition: evm.h:125
@ EVM_INS_RETURNDATACOPY
Definition: evm.h:64
@ EVM_INS_CALLDATALOAD
Definition: evm.h:55
@ EVM_INS_PUSH7
Definition: evm.h:89
@ EVM_INS_CALL
Definition: evm.h:153
@ EVM_INS_PUSH21
Definition: evm.h:103
@ EVM_INS_CALLBLACKBOX
Definition: evm.h:157
@ EVM_INS_MLOAD
Definition: evm.h:72
@ EVM_INS_SMOD
Definition: evm.h:33
@ EVM_INS_DUP1
Definition: evm.h:115
@ EVM_INS_MUL
Definition: evm.h:28
@ EVM_INS_PUSH13
Definition: evm.h:95
@ EVM_INS_PUSH9
Definition: evm.h:91
@ EVM_INS_PUSH5
Definition: evm.h:87
@ EVM_INS_DUP5
Definition: evm.h:119
@ EVM_INS_GT
Definition: evm.h:39
@ EVM_INS_COINBASE
Definition: evm.h:66
@ EVM_INS_GASPRICE
Definition: evm.h:60
@ EVM_INS_DELEGATECALL
Definition: evm.h:156
@ EVM_INS_LOG2
Definition: evm.h:149
@ EVM_INS_SWAP12
Definition: evm.h:142
@ EVM_INS_PUSH30
Definition: evm.h:112
@ EVM_INS_SWAP3
Definition: evm.h:133
@ EVM_INS_PUSH17
Definition: evm.h:99
@ EVM_INS_RETURN
Definition: evm.h:155
@ EVM_INS_ADDMOD
Definition: evm.h:34
@ EVM_INS_ISZERO
Definition: evm.h:43
@ EVM_INS_STATICCALL
Definition: evm.h:158
@ EVM_INS_MSIZE
Definition: evm.h:80
@ EVM_INS_SWAP7
Definition: evm.h:137
@ EVM_INS_SWAP11
Definition: evm.h:141
@ EVM_INS_PUSH16
Definition: evm.h:98
@ EVM_INS_SSTORE
Definition: evm.h:76
@ EVM_INS_PUSH25
Definition: evm.h:107
@ EVM_INS_PUSH20
Definition: evm.h:102
@ EVM_INS_ADDRESS
Definition: evm.h:50
@ EVM_INS_CALLDATACOPY
Definition: evm.h:57
@ EVM_INS_GAS
Definition: evm.h:81
@ EVM_INS_DUP3
Definition: evm.h:117
@ EVM_INS_ADD
Definition: evm.h:27
@ EVM_INS_PUSH1
Definition: evm.h:83
@ EVM_INS_CALLVALUE
Definition: evm.h:54
@ EVM_INS_DUP9
Definition: evm.h:123
@ EVM_INS_PUSH3
Definition: evm.h:85
@ EVM_INS_PUSH18
Definition: evm.h:100
@ EVM_INS_PUSH24
Definition: evm.h:106
@ EVM_INS_TIMESTAMP
Definition: evm.h:67
@ EVM_INS_DUP15
Definition: evm.h:129
@ EVM_INS_DUP13
Definition: evm.h:127
@ EVM_INS_SWAP8
Definition: evm.h:138
@ EVM_INS_PUSH19
Definition: evm.h:101
@ EVM_INS_POP
Definition: evm.h:71
@ EVM_INS_MSTORE8
Definition: evm.h:74
@ EVM_INS_ORIGIN
Definition: evm.h:52
@ EVM_INS_DUP4
Definition: evm.h:118
@ EVM_INS_SLT
Definition: evm.h:40
@ EVM_INS_EXP
Definition: evm.h:36
@ EVM_INS_RETURNDATASIZE
Definition: evm.h:63
@ EVM_INS_GASLIMIT
Definition: evm.h:70
@ EVM_INS_SUB
Definition: evm.h:29
@ EVM_INS_SWAP4
Definition: evm.h:134
@ EVM_INS_NOT
Definition: evm.h:47
@ EVM_INS_SWAP10
Definition: evm.h:140
@ EVM_INS_SWAP13
Definition: evm.h:143
@ EVM_INS_CALLER
Definition: evm.h:53
@ EVM_INS_DUP10
Definition: evm.h:124
@ EVM_INS_PUSH4
Definition: evm.h:86
@ EVM_INS_PUSH31
Definition: evm.h:113
@ EVM_INS_PUSH26
Definition: evm.h:108
@ EVM_INS_MULMOD
Definition: evm.h:35
@ EVM_INS_SWAP6
Definition: evm.h:136
@ EVM_INS_DUP7
Definition: evm.h:121
@ EVM_INS_PUSH2
Definition: evm.h:84
@ EVM_INS_OR
Definition: evm.h:45
@ EVM_INS_PUSH32
Definition: evm.h:114
@ EVM_INS_LOG0
Definition: evm.h:147
@ EVM_INS_PUSH29
Definition: evm.h:111
@ EVM_INS_DIFFICULTY
Definition: evm.h:69
@ EVM_INS_BYTE
Definition: evm.h:48
@ EVM_INS_EQ
Definition: evm.h:42
@ EVM_INS_EXTCODECOPY
Definition: evm.h:62
@ EVM_INS_PUSH23
Definition: evm.h:105
@ EVM_INS_STOP
Definition: evm.h:26
@ EVM_INS_SWAP9
Definition: evm.h:139
@ EVM_INS_PUSH22
Definition: evm.h:104
@ EVM_INS_CREATE
Definition: evm.h:152
@ EVM_INS_REVERT
Definition: evm.h:159
@ EVM_INS_MSTORE
Definition: evm.h:73
@ EVM_INS_PUSH10
Definition: evm.h:92
@ EVM_INS_SGT
Definition: evm.h:41
@ EVM_INS_LOG1
Definition: evm.h:148
@ EVM_INS_LOG4
Definition: evm.h:151
@ EVM_INS_CALLCODE
Definition: evm.h:154
@ EVM_INS_JUMP
Definition: evm.h:77
@ EVM_INS_EXTCODESIZE
Definition: evm.h:61
@ EVM_INS_SWAP5
Definition: evm.h:135
@ EVM_INS_DUP8
Definition: evm.h:122
@ EVM_INS_DUP6
Definition: evm.h:120
@ EVM_INS_SDIV
Definition: evm.h:31
@ EVM_INS_SIGNEXTEND
Definition: evm.h:37
@ EVM_INS_DUP16
Definition: evm.h:130
@ EVM_INS_SHA3
Definition: evm.h:49
@ EVM_INS_PUSH6
Definition: evm.h:88
@ EVM_INS_BLOCKHASH
Definition: evm.h:65
@ EVM_INS_NUMBER
Definition: evm.h:68
@ EVM_INS_MOD
Definition: evm.h:32
@ EVM_INS_XOR
Definition: evm.h:46
@ EVM_INS_JUMPI
Definition: evm.h:78
@ EVM_INS_DUP2
Definition: evm.h:116
@ EVM_INS_SWAP1
Definition: evm.h:131
@ EVM_INS_JUMPDEST
Definition: evm.h:82
@ EVM_INS_PC
Definition: evm.h:79
@ EVM_INS_SWAP14
Definition: evm.h:144
@ EVM_INS_SUICIDE
Definition: evm.h:160
@ EVM_INS_PUSH28
Definition: evm.h:110
@ EVM_INS_SWAP2
Definition: evm.h:132
@ EVM_INS_PUSH14
Definition: evm.h:96
@ EVM_INS_SWAP15
Definition: evm.h:145
@ EVM_INS_LT
Definition: evm.h:38
@ EVM_INS_BALANCE
Definition: evm.h:51
@ EVM_INS_CODESIZE
Definition: evm.h:58
@ EVM_INS_PUSH27
Definition: evm.h:109
@ EVM_INS_LOG3
Definition: evm.h:150
@ EVM_INS_PUSH8
Definition: evm.h:90
@ EVM_INS_SWAP16
Definition: evm.h:146
@ EVM_GRP_MATH
math instructions
Definition: evm.h:172
@ EVM_GRP_STORE_READ
instructions read from storage
Definition: evm.h:178
@ EVM_GRP_STACK_WRITE
instructions write to stack
Definition: evm.h:173
@ EVM_GRP_JUMP
all jump instructions
Definition: evm.h:170
@ EVM_GRP_MEM_WRITE
instructions write to memory
Definition: evm.h:175
@ EVM_GRP_MEM_READ
instructions read from memory
Definition: evm.h:176
@ EVM_GRP_STACK_READ
instructions read from stack
Definition: evm.h:174
@ EVM_GRP_HALT
instructions halt execution
Definition: evm.h:179
@ EVM_GRP_STORE_WRITE
instructions write to storage
Definition: evm.h:177
voidpf void uLong size
Definition: ioapi.h:138
#define offsetof(type, member)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
unsigned short uint16_t
Definition: sftypes.h:30
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
unsigned OpcodePub
Definition: MCInst.h:89
unsigned char evm_data[32]
Definition: MCInst.h:110
unsigned Opcode
Definition: MCInst.h:93
uint64_t address
Definition: MCInst.h:96
Definition: inftree9.h:24
Instruction structure.
Definition: evm.h:18