mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-12-04 20:06:41 +00:00
936dca0e2d
* Constify registerinfo.py output Remove two conditionals separating identical bits of code. Add "const" markup to MCRegisterDesc and MCRegisterClass. Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify instrinfo-arch.py output In this case, do not actively strip const. Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the AArch64 backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the EVM backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify M680X backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify M68K backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the Mips backend The Mips backend has not been regenerated from LLVM recently, and there are more fixups required than I'd like. Just apply the fixes to the tables by hand for now. Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the Sparc backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the TMS320C64x backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the X86 backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the XCore backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify systemregister.py output Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the ARM backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the PowerPC backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the MOS65XX backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the SystemZ backend The mapping of system register to indexes is easy to generate read-only. Since we know the indexes are between 0 and 31, use uint8_t instead of unsigned. Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the WASM backend Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify cs.c Signed-off-by: Richard Henderson <rth@twiddle.net> * Constify the BPF backend Signed-off-by: Richard Henderson <rth@twiddle.net>
380 lines
6.0 KiB
C
380 lines
6.0 KiB
C
/* Capstone Disassembly Engine */
|
|
/* By Nguyen Anh Quynh, 2018 */
|
|
|
|
#include <string.h>
|
|
#include <stddef.h> // offsetof macro
|
|
// alternatively #include "../../utils.h" like everyone else
|
|
|
|
#include "EVMDisassembler.h"
|
|
#include "EVMMapping.h"
|
|
|
|
static const short opcodes[256] = {
|
|
EVM_INS_STOP,
|
|
EVM_INS_ADD,
|
|
EVM_INS_MUL,
|
|
EVM_INS_SUB,
|
|
EVM_INS_DIV,
|
|
EVM_INS_SDIV,
|
|
EVM_INS_MOD,
|
|
EVM_INS_SMOD,
|
|
EVM_INS_ADDMOD,
|
|
EVM_INS_MULMOD,
|
|
EVM_INS_EXP,
|
|
EVM_INS_SIGNEXTEND,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_LT,
|
|
EVM_INS_GT,
|
|
EVM_INS_SLT,
|
|
EVM_INS_SGT,
|
|
EVM_INS_EQ,
|
|
EVM_INS_ISZERO,
|
|
EVM_INS_AND,
|
|
EVM_INS_OR,
|
|
EVM_INS_XOR,
|
|
EVM_INS_NOT,
|
|
EVM_INS_BYTE,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_SHA3,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_ADDRESS,
|
|
EVM_INS_BALANCE,
|
|
EVM_INS_ORIGIN,
|
|
EVM_INS_CALLER,
|
|
EVM_INS_CALLVALUE,
|
|
EVM_INS_CALLDATALOAD,
|
|
EVM_INS_CALLDATASIZE,
|
|
EVM_INS_CALLDATACOPY,
|
|
EVM_INS_CODESIZE,
|
|
EVM_INS_CODECOPY,
|
|
EVM_INS_GASPRICE,
|
|
EVM_INS_EXTCODESIZE,
|
|
EVM_INS_EXTCODECOPY,
|
|
EVM_INS_RETURNDATASIZE,
|
|
EVM_INS_RETURNDATACOPY,
|
|
-1,
|
|
EVM_INS_BLOCKHASH,
|
|
EVM_INS_COINBASE,
|
|
EVM_INS_TIMESTAMP,
|
|
EVM_INS_NUMBER,
|
|
EVM_INS_DIFFICULTY,
|
|
EVM_INS_GASLIMIT,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_POP,
|
|
EVM_INS_MLOAD,
|
|
EVM_INS_MSTORE,
|
|
EVM_INS_MSTORE8,
|
|
EVM_INS_SLOAD,
|
|
EVM_INS_SSTORE,
|
|
EVM_INS_JUMP,
|
|
EVM_INS_JUMPI,
|
|
EVM_INS_PC,
|
|
EVM_INS_MSIZE,
|
|
EVM_INS_GAS,
|
|
EVM_INS_JUMPDEST,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_PUSH1,
|
|
EVM_INS_PUSH2,
|
|
EVM_INS_PUSH3,
|
|
EVM_INS_PUSH4,
|
|
EVM_INS_PUSH5,
|
|
EVM_INS_PUSH6,
|
|
EVM_INS_PUSH7,
|
|
EVM_INS_PUSH8,
|
|
EVM_INS_PUSH9,
|
|
EVM_INS_PUSH10,
|
|
EVM_INS_PUSH11,
|
|
EVM_INS_PUSH12,
|
|
EVM_INS_PUSH13,
|
|
EVM_INS_PUSH14,
|
|
EVM_INS_PUSH15,
|
|
EVM_INS_PUSH16,
|
|
EVM_INS_PUSH17,
|
|
EVM_INS_PUSH18,
|
|
EVM_INS_PUSH19,
|
|
EVM_INS_PUSH20,
|
|
EVM_INS_PUSH21,
|
|
EVM_INS_PUSH22,
|
|
EVM_INS_PUSH23,
|
|
EVM_INS_PUSH24,
|
|
EVM_INS_PUSH25,
|
|
EVM_INS_PUSH26,
|
|
EVM_INS_PUSH27,
|
|
EVM_INS_PUSH28,
|
|
EVM_INS_PUSH29,
|
|
EVM_INS_PUSH30,
|
|
EVM_INS_PUSH31,
|
|
EVM_INS_PUSH32,
|
|
EVM_INS_DUP1,
|
|
EVM_INS_DUP2,
|
|
EVM_INS_DUP3,
|
|
EVM_INS_DUP4,
|
|
EVM_INS_DUP5,
|
|
EVM_INS_DUP6,
|
|
EVM_INS_DUP7,
|
|
EVM_INS_DUP8,
|
|
EVM_INS_DUP9,
|
|
EVM_INS_DUP10,
|
|
EVM_INS_DUP11,
|
|
EVM_INS_DUP12,
|
|
EVM_INS_DUP13,
|
|
EVM_INS_DUP14,
|
|
EVM_INS_DUP15,
|
|
EVM_INS_DUP16,
|
|
EVM_INS_SWAP1,
|
|
EVM_INS_SWAP2,
|
|
EVM_INS_SWAP3,
|
|
EVM_INS_SWAP4,
|
|
EVM_INS_SWAP5,
|
|
EVM_INS_SWAP6,
|
|
EVM_INS_SWAP7,
|
|
EVM_INS_SWAP8,
|
|
EVM_INS_SWAP9,
|
|
EVM_INS_SWAP10,
|
|
EVM_INS_SWAP11,
|
|
EVM_INS_SWAP12,
|
|
EVM_INS_SWAP13,
|
|
EVM_INS_SWAP14,
|
|
EVM_INS_SWAP15,
|
|
EVM_INS_SWAP16,
|
|
EVM_INS_LOG0,
|
|
EVM_INS_LOG1,
|
|
EVM_INS_LOG2,
|
|
EVM_INS_LOG3,
|
|
EVM_INS_LOG4,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_CREATE,
|
|
EVM_INS_CALL,
|
|
EVM_INS_CALLCODE,
|
|
EVM_INS_RETURN,
|
|
EVM_INS_DELEGATECALL,
|
|
EVM_INS_CALLBLACKBOX,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
-1,
|
|
EVM_INS_STATICCALL,
|
|
-1,
|
|
-1,
|
|
EVM_INS_REVERT,
|
|
-1,
|
|
EVM_INS_SUICIDE,
|
|
};
|
|
|
|
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
|
{
|
|
unsigned char opcode;
|
|
|
|
if (code_len == 0)
|
|
return false;
|
|
|
|
opcode = code[0];
|
|
if (opcodes[opcode] == -1) {
|
|
// invalid opcode
|
|
return false;
|
|
}
|
|
|
|
// valid opcode
|
|
MI->address = address;
|
|
MI->OpcodePub = MI->Opcode = opcode;
|
|
|
|
if (opcode >= EVM_INS_PUSH1 && opcode <= EVM_INS_PUSH32) {
|
|
unsigned char len = (opcode - EVM_INS_PUSH1 + 1);
|
|
if (code_len < 1 + len) {
|
|
// not enough data
|
|
return false;
|
|
}
|
|
|
|
*size = 1 + len;
|
|
memcpy(MI->evm_data, code + 1, len);
|
|
} else
|
|
*size = 1;
|
|
|
|
if (MI->flat_insn->detail) {
|
|
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, evm)+sizeof(cs_evm));
|
|
EVM_get_insn_id((cs_struct *)ud, MI->flat_insn, opcode);
|
|
|
|
if (MI->flat_insn->detail->evm.pop) {
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_READ;
|
|
MI->flat_insn->detail->groups_count++;
|
|
}
|
|
|
|
if (MI->flat_insn->detail->evm.push) {
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STACK_WRITE;
|
|
MI->flat_insn->detail->groups_count++;
|
|
}
|
|
|
|
// setup groups
|
|
switch(opcode) {
|
|
default:
|
|
break;
|
|
case EVM_INS_ADD:
|
|
case EVM_INS_MUL:
|
|
case EVM_INS_SUB:
|
|
case EVM_INS_DIV:
|
|
case EVM_INS_SDIV:
|
|
case EVM_INS_MOD:
|
|
case EVM_INS_SMOD:
|
|
case EVM_INS_ADDMOD:
|
|
case EVM_INS_MULMOD:
|
|
case EVM_INS_EXP:
|
|
case EVM_INS_SIGNEXTEND:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_MSTORE:
|
|
case EVM_INS_MSTORE8:
|
|
case EVM_INS_CALLDATACOPY:
|
|
case EVM_INS_CODECOPY:
|
|
case EVM_INS_EXTCODECOPY:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_MLOAD:
|
|
case EVM_INS_CREATE:
|
|
case EVM_INS_CALL:
|
|
case EVM_INS_CALLCODE:
|
|
case EVM_INS_RETURN:
|
|
case EVM_INS_DELEGATECALL:
|
|
case EVM_INS_REVERT:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_READ;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_SSTORE:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_WRITE;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_SLOAD:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_JUMP:
|
|
case EVM_INS_JUMPI:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_JUMP;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
case EVM_INS_STOP:
|
|
case EVM_INS_SUICIDE:
|
|
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
|
|
MI->flat_insn->detail->groups_count++;
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|