Apply new EVM opcode updates (#2602)
* evm: apply new opcode updates and add test cases * evm: use predefined invalid opcode 0xfe * python: add CsInsn.is_invalid_insn to bypass evm issue
This commit is contained in:
parent
3c4d7fc8d6
commit
3060117630
|
@ -1,5 +1,6 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh, 2018 */
|
||||
/* By Andelf, 2025 */
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h> // offsetof macro
|
||||
|
@ -36,9 +37,9 @@ static const short opcodes[256] = {
|
|||
EVM_INS_XOR,
|
||||
EVM_INS_NOT,
|
||||
EVM_INS_BYTE,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
EVM_INS_SHL,
|
||||
EVM_INS_SHR,
|
||||
EVM_INS_SAR,
|
||||
-1,
|
||||
-1,
|
||||
EVM_INS_SHA3,
|
||||
|
@ -79,11 +80,11 @@ static const short opcodes[256] = {
|
|||
EVM_INS_NUMBER,
|
||||
EVM_INS_DIFFICULTY,
|
||||
EVM_INS_GASLIMIT,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
EVM_INS_CHAINID,
|
||||
EVM_INS_SELFBALANCE,
|
||||
EVM_INS_BASEFEE,
|
||||
EVM_INS_BLOBHASH,
|
||||
EVM_INS_BLOBBASEFEE,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
|
@ -101,10 +102,10 @@ static const short opcodes[256] = {
|
|||
EVM_INS_MSIZE,
|
||||
EVM_INS_GAS,
|
||||
EVM_INS_JUMPDEST,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
EVM_INS_TLOAD,
|
||||
EVM_INS_TSTORE,
|
||||
EVM_INS_MCOPY,
|
||||
EVM_INS_PUSH0,
|
||||
EVM_INS_PUSH1,
|
||||
EVM_INS_PUSH2,
|
||||
EVM_INS_PUSH3,
|
||||
|
@ -254,7 +255,7 @@ static const short opcodes[256] = {
|
|||
EVM_INS_CALLCODE,
|
||||
EVM_INS_RETURN,
|
||||
EVM_INS_DELEGATECALL,
|
||||
EVM_INS_CALLBLACKBOX,
|
||||
EVM_INS_CREATE2,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
|
@ -264,7 +265,7 @@ static const short opcodes[256] = {
|
|||
-1,
|
||||
EVM_INS_REVERT,
|
||||
-1,
|
||||
EVM_INS_SUICIDE,
|
||||
EVM_INS_SELFDESTRUCT,
|
||||
};
|
||||
|
||||
bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
||||
|
@ -326,6 +327,9 @@ bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
case EVM_INS_MULMOD:
|
||||
case EVM_INS_EXP:
|
||||
case EVM_INS_SIGNEXTEND:
|
||||
case EVM_INS_SHL:
|
||||
case EVM_INS_SHR:
|
||||
case EVM_INS_SAR:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MATH;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
@ -335,6 +339,7 @@ bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
case EVM_INS_CALLDATACOPY:
|
||||
case EVM_INS_CODECOPY:
|
||||
case EVM_INS_EXTCODECOPY:
|
||||
case EVM_INS_MCOPY:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_MEM_WRITE;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
@ -346,16 +351,19 @@ bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
case EVM_INS_RETURN:
|
||||
case EVM_INS_DELEGATECALL:
|
||||
case EVM_INS_REVERT:
|
||||
case EVM_INS_CREATE2:
|
||||
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:
|
||||
case EVM_INS_TSTORE:
|
||||
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:
|
||||
case EVM_INS_TLOAD:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_STORE_READ;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
@ -367,7 +375,7 @@ bool EVM_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|||
break;
|
||||
|
||||
case EVM_INS_STOP:
|
||||
case EVM_INS_SUICIDE:
|
||||
case EVM_INS_SELFDESTRUCT:
|
||||
MI->flat_insn->detail->groups[MI->flat_insn->detail->groups_count] = EVM_GRP_HALT;
|
||||
MI->flat_insn->detail->groups_count++;
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh, 2018 */
|
||||
/* By Andelf, 2025 */
|
||||
|
||||
#ifdef CAPSTONE_HAS_EVM
|
||||
|
||||
|
@ -73,9 +74,9 @@ static const name_map insn_name_maps[256] = {
|
|||
{ EVM_INS_XOR, "xor" },
|
||||
{ EVM_INS_NOT, "not" },
|
||||
{ EVM_INS_BYTE, "byte" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_SHL, "shl" },
|
||||
{ EVM_INS_SHR, "shr" },
|
||||
{ EVM_INS_SAR, "sar" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_SHA3, "sha3" },
|
||||
|
@ -116,11 +117,11 @@ static const name_map insn_name_maps[256] = {
|
|||
{ EVM_INS_NUMBER, "number" },
|
||||
{ EVM_INS_DIFFICULTY, "difficulty" },
|
||||
{ EVM_INS_GASLIMIT, "gaslimit" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_CHAINID, "chainid" },
|
||||
{ EVM_INS_SELFBALANCE, "selfbalance" },
|
||||
{ EVM_INS_BASEFEE, "basefee" },
|
||||
{ EVM_INS_BLOBHASH, "blobhash" },
|
||||
{ EVM_INS_BLOBBASEFEE, "blobbasefee" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
|
@ -138,10 +139,10 @@ static const name_map insn_name_maps[256] = {
|
|||
{ EVM_INS_MSIZE, "msize" },
|
||||
{ EVM_INS_GAS, "gas" },
|
||||
{ EVM_INS_JUMPDEST, "jumpdest" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_TLOAD, "tload" },
|
||||
{ EVM_INS_TSTORE, "tstore" },
|
||||
{ EVM_INS_MCOPY, "mcopy" },
|
||||
{ EVM_INS_PUSH0, "push0" },
|
||||
{ EVM_INS_PUSH1, "push1" },
|
||||
{ EVM_INS_PUSH2, "push2" },
|
||||
{ EVM_INS_PUSH3, "push3" },
|
||||
|
@ -291,7 +292,7 @@ static const name_map insn_name_maps[256] = {
|
|||
{ EVM_INS_CALLCODE, "callcode" },
|
||||
{ EVM_INS_RETURN, "return" },
|
||||
{ EVM_INS_DELEGATECALL, "delegatecall" },
|
||||
{ EVM_INS_CALLBLACKBOX, "callblackbox" },
|
||||
{ EVM_INS_CREATE2, "create2" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
|
@ -301,7 +302,7 @@ static const name_map insn_name_maps[256] = {
|
|||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_REVERT, "revert" },
|
||||
{ EVM_INS_INVALID, NULL },
|
||||
{ EVM_INS_SUICIDE, "suicide" },
|
||||
{ EVM_INS_SELFDESTRUCT, "selfdestruct" },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh, 2018 */
|
||||
/* By Andelf, 2025 */
|
||||
|
||||
{ 0, 0, 0 }, // STOP
|
||||
{ 2, 1, 3 }, // ADD
|
||||
|
@ -28,9 +29,9 @@
|
|||
{ 2, 1, 3 }, // XOR
|
||||
{ 1, 1, 3 }, // NOT
|
||||
{ 2, 1, 3 }, // BYTE
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 2, 1, 3 }, // SHL
|
||||
{ 2, 1, 3 }, // SHR
|
||||
{ 2, 1, 3 }, // SAR
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 2, 1, 30 }, // SHA3
|
||||
|
@ -71,11 +72,11 @@
|
|||
{ 0, 1, 2 }, // NUMBER
|
||||
{ 0, 1, 2 }, // DIFFICULTY
|
||||
{ 0, 1, 2 }, // GASLIMIT
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 1, 2 }, // CHAINID
|
||||
{ 0, 1, 5 }, // SELFBALANCE
|
||||
{ 0, 1, 2 }, // BASEFEE
|
||||
{ 0, 1, 3 }, // BLOBHASH
|
||||
{ 0, 1, 2 }, // BLOBBASEFEE
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
|
@ -93,10 +94,10 @@
|
|||
{ 0, 1, 2 }, // MSIZE
|
||||
{ 0, 1, 2 }, // GAS
|
||||
{ 0, 0, 1 }, // JUMPDEST
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 1, 1, 100 }, // TLOAD
|
||||
{ 2, 0, 100 }, // TSTORE
|
||||
{ 3, 0, 3 }, // MCOPY
|
||||
{ 0, 1, 3 }, // PUSH0
|
||||
{ 0, 1, 3 }, // PUSH1
|
||||
{ 0, 1, 3 }, // PUSH2
|
||||
{ 0, 1, 3 }, // PUSH3
|
||||
|
@ -242,18 +243,18 @@
|
|||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 3, 1, 32000 }, // CREATE
|
||||
{ 7, 1, 40 }, // CALL
|
||||
{ 7, 1, 40 }, // CALLCODE
|
||||
{ 7, 1, 100 }, // CALL
|
||||
{ 7, 1, 100 }, // CALLCODE
|
||||
{ 2, 0, 0 }, // RETURN
|
||||
{ 6, 1, 40 }, // DELEGATECALL
|
||||
{ 7, 1, 40 }, // CALLBLACKBOX
|
||||
{ 6, 1, 100 }, // DELEGATECALL
|
||||
{ 4, 1, 32000 }, // CREATE2
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 6, 1, 40 }, // STATICCALL
|
||||
{ 6, 1, 100 }, // STATICCALL
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 2, 0, 0 }, // REVERT
|
||||
{ 0, 0, 0xffffffff }, // unused
|
||||
{ 1, 0, 0 }, // SUICIDE
|
||||
{ 1, 0, 5000 }, // SELFDESTRUCT
|
||||
|
|
|
@ -26,6 +26,9 @@ public class Evm_const {
|
|||
public static final int EVM_INS_XOR = 24;
|
||||
public static final int EVM_INS_NOT = 25;
|
||||
public static final int EVM_INS_BYTE = 26;
|
||||
public static final int EVM_INS_SHL = 27;
|
||||
public static final int EVM_INS_SHR = 28;
|
||||
public static final int EVM_INS_SAR = 29;
|
||||
public static final int EVM_INS_SHA3 = 32;
|
||||
public static final int EVM_INS_ADDRESS = 48;
|
||||
public static final int EVM_INS_BALANCE = 49;
|
||||
|
@ -48,6 +51,11 @@ public class Evm_const {
|
|||
public static final int EVM_INS_NUMBER = 67;
|
||||
public static final int EVM_INS_DIFFICULTY = 68;
|
||||
public static final int EVM_INS_GASLIMIT = 69;
|
||||
public static final int EVM_INS_CHAINID = 70;
|
||||
public static final int EVM_INS_SELFBALANCE = 71;
|
||||
public static final int EVM_INS_BASEFEE = 72;
|
||||
public static final int EVM_INS_BLOBHASH = 73;
|
||||
public static final int EVM_INS_BLOBBASEFEE = 74;
|
||||
public static final int EVM_INS_POP = 80;
|
||||
public static final int EVM_INS_MLOAD = 81;
|
||||
public static final int EVM_INS_MSTORE = 82;
|
||||
|
@ -60,6 +68,10 @@ public class Evm_const {
|
|||
public static final int EVM_INS_MSIZE = 89;
|
||||
public static final int EVM_INS_GAS = 90;
|
||||
public static final int EVM_INS_JUMPDEST = 91;
|
||||
public static final int EVM_INS_TLOAD = 92;
|
||||
public static final int EVM_INS_TSTORE = 93;
|
||||
public static final int EVM_INS_MCOPY = 94;
|
||||
public static final int EVM_INS_PUSH0 = 95;
|
||||
public static final int EVM_INS_PUSH1 = 96;
|
||||
public static final int EVM_INS_PUSH2 = 97;
|
||||
public static final int EVM_INS_PUSH3 = 98;
|
||||
|
@ -134,12 +146,12 @@ public class Evm_const {
|
|||
public static final int EVM_INS_CALLCODE = 242;
|
||||
public static final int EVM_INS_RETURN = 243;
|
||||
public static final int EVM_INS_DELEGATECALL = 244;
|
||||
public static final int EVM_INS_CALLBLACKBOX = 245;
|
||||
public static final int EVM_INS_CREATE2 = 245;
|
||||
public static final int EVM_INS_STATICCALL = 250;
|
||||
public static final int EVM_INS_REVERT = 253;
|
||||
public static final int EVM_INS_SUICIDE = 255;
|
||||
public static final int EVM_INS_INVALID = 512;
|
||||
public static final int EVM_INS_ENDING = 513;
|
||||
public static final int EVM_INS_INVALID = 254;
|
||||
public static final int EVM_INS_SELFDESTRUCT = 255;
|
||||
public static final int EVM_INS_ENDING = 256;
|
||||
|
||||
public static final int EVM_GRP_INVALID = 0;
|
||||
public static final int EVM_GRP_JUMP = 1;
|
||||
|
|
|
@ -23,6 +23,9 @@ let _EVM_INS_OR = 23;;
|
|||
let _EVM_INS_XOR = 24;;
|
||||
let _EVM_INS_NOT = 25;;
|
||||
let _EVM_INS_BYTE = 26;;
|
||||
let _EVM_INS_SHL = 27;;
|
||||
let _EVM_INS_SHR = 28;;
|
||||
let _EVM_INS_SAR = 29;;
|
||||
let _EVM_INS_SHA3 = 32;;
|
||||
let _EVM_INS_ADDRESS = 48;;
|
||||
let _EVM_INS_BALANCE = 49;;
|
||||
|
@ -45,6 +48,11 @@ let _EVM_INS_TIMESTAMP = 66;;
|
|||
let _EVM_INS_NUMBER = 67;;
|
||||
let _EVM_INS_DIFFICULTY = 68;;
|
||||
let _EVM_INS_GASLIMIT = 69;;
|
||||
let _EVM_INS_CHAINID = 70;;
|
||||
let _EVM_INS_SELFBALANCE = 71;;
|
||||
let _EVM_INS_BASEFEE = 72;;
|
||||
let _EVM_INS_BLOBHASH = 73;;
|
||||
let _EVM_INS_BLOBBASEFEE = 74;;
|
||||
let _EVM_INS_POP = 80;;
|
||||
let _EVM_INS_MLOAD = 81;;
|
||||
let _EVM_INS_MSTORE = 82;;
|
||||
|
@ -57,6 +65,10 @@ let _EVM_INS_PC = 88;;
|
|||
let _EVM_INS_MSIZE = 89;;
|
||||
let _EVM_INS_GAS = 90;;
|
||||
let _EVM_INS_JUMPDEST = 91;;
|
||||
let _EVM_INS_TLOAD = 92;;
|
||||
let _EVM_INS_TSTORE = 93;;
|
||||
let _EVM_INS_MCOPY = 94;;
|
||||
let _EVM_INS_PUSH0 = 95;;
|
||||
let _EVM_INS_PUSH1 = 96;;
|
||||
let _EVM_INS_PUSH2 = 97;;
|
||||
let _EVM_INS_PUSH3 = 98;;
|
||||
|
@ -131,12 +143,12 @@ let _EVM_INS_CALL = 241;;
|
|||
let _EVM_INS_CALLCODE = 242;;
|
||||
let _EVM_INS_RETURN = 243;;
|
||||
let _EVM_INS_DELEGATECALL = 244;;
|
||||
let _EVM_INS_CALLBLACKBOX = 245;;
|
||||
let _EVM_INS_CREATE2 = 245;;
|
||||
let _EVM_INS_STATICCALL = 250;;
|
||||
let _EVM_INS_REVERT = 253;;
|
||||
let _EVM_INS_SUICIDE = 255;;
|
||||
let _EVM_INS_INVALID = 512;;
|
||||
let _EVM_INS_ENDING = 513;;
|
||||
let _EVM_INS_INVALID = 254;;
|
||||
let _EVM_INS_SELFDESTRUCT = 255;;
|
||||
let _EVM_INS_ENDING = 256;;
|
||||
|
||||
let _EVM_GRP_INVALID = 0;;
|
||||
let _EVM_GRP_JUMP = 1;;
|
||||
|
|
|
@ -788,7 +788,7 @@ class CsInsn(object):
|
|||
def __init__(self, cs, all_info):
|
||||
self._raw = copy_ctypes(all_info)
|
||||
self._cs = cs
|
||||
if self._cs._detail and self._raw.id != 0:
|
||||
if self._cs._detail and not self.is_invalid_insn():
|
||||
# save detail
|
||||
self._raw.detail = ctypes.pointer(all_info.detail._type_())
|
||||
ctypes.memmove(ctypes.byref(self._raw.detail[0]), ctypes.byref(all_info.detail[0]),
|
||||
|
@ -797,6 +797,14 @@ class CsInsn(object):
|
|||
def __repr__(self):
|
||||
return '<CsInsn 0x%x [%s]: %s %s>' % (self.address, self.bytes.hex(), self.mnemonic, self.op_str)
|
||||
|
||||
# return if the instruction is invalid
|
||||
def is_invalid_insn(self):
|
||||
arch = self._cs.arch
|
||||
if arch == CS_ARCH_EVM:
|
||||
return self.id == evm.EVM_INS_INVALID
|
||||
else:
|
||||
return self.id == 0
|
||||
|
||||
# return instruction's ID.
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -853,7 +861,7 @@ class CsInsn(object):
|
|||
# return list of all implicit registers being read.
|
||||
@property
|
||||
def regs_read(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -868,7 +876,7 @@ class CsInsn(object):
|
|||
# return list of all implicit registers being modified
|
||||
@property
|
||||
def regs_write(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -883,7 +891,7 @@ class CsInsn(object):
|
|||
# return list of semantic groups this instruction belongs to.
|
||||
@property
|
||||
def groups(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -898,7 +906,7 @@ class CsInsn(object):
|
|||
# return whether instruction has writeback operands.
|
||||
@property
|
||||
def writeback(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -911,7 +919,7 @@ class CsInsn(object):
|
|||
raise CsError(CS_ERR_DETAIL)
|
||||
|
||||
def __gen_detail(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
# do nothing in skipdata mode
|
||||
return
|
||||
|
||||
|
@ -980,7 +988,7 @@ class CsInsn(object):
|
|||
if 'operands' not in _dict:
|
||||
self.__gen_detail()
|
||||
if name not in _dict:
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
raise AttributeError(f"'CsInsn' has no attribute '{name}'")
|
||||
return _dict[name]
|
||||
|
@ -1003,7 +1011,7 @@ class CsInsn(object):
|
|||
# Diet engine cannot provide instruction name
|
||||
raise CsError(CS_ERR_DIET)
|
||||
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
return default
|
||||
|
||||
return _ascii_name_or_default(_cs.cs_insn_name(self._cs.csh, self.id), default)
|
||||
|
@ -1018,7 +1026,7 @@ class CsInsn(object):
|
|||
|
||||
# verify if this insn belong to group with id as @group_id
|
||||
def group(self, group_id):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -1029,7 +1037,7 @@ class CsInsn(object):
|
|||
|
||||
# verify if this instruction implicitly read register @reg_id
|
||||
def reg_read(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -1040,7 +1048,7 @@ class CsInsn(object):
|
|||
|
||||
# verify if this instruction implicitly modified register @reg_id
|
||||
def reg_write(self, reg_id):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
if self._cs._diet:
|
||||
|
@ -1051,7 +1059,7 @@ class CsInsn(object):
|
|||
|
||||
# return number of operands having same operand type @op_type
|
||||
def op_count(self, op_type):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
c = 0
|
||||
|
@ -1062,7 +1070,7 @@ class CsInsn(object):
|
|||
|
||||
# get the operand at position @position of all operands having the same type @op_type
|
||||
def op_find(self, op_type, position):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
c = 0
|
||||
|
@ -1075,7 +1083,7 @@ class CsInsn(object):
|
|||
# Return (list-of-registers-read, list-of-registers-modified) by this instructions.
|
||||
# This includes all the implicit & explicit registers.
|
||||
def regs_access(self):
|
||||
if self._raw.id == 0:
|
||||
if self.is_invalid_insn():
|
||||
raise CsError(CS_ERR_SKIPDATA)
|
||||
|
||||
regs_read = (ctypes.c_uint16 * 64)()
|
||||
|
|
|
@ -24,6 +24,9 @@ EVM_INS_OR = 23
|
|||
EVM_INS_XOR = 24
|
||||
EVM_INS_NOT = 25
|
||||
EVM_INS_BYTE = 26
|
||||
EVM_INS_SHL = 27
|
||||
EVM_INS_SHR = 28
|
||||
EVM_INS_SAR = 29
|
||||
EVM_INS_SHA3 = 32
|
||||
EVM_INS_ADDRESS = 48
|
||||
EVM_INS_BALANCE = 49
|
||||
|
@ -46,6 +49,11 @@ EVM_INS_TIMESTAMP = 66
|
|||
EVM_INS_NUMBER = 67
|
||||
EVM_INS_DIFFICULTY = 68
|
||||
EVM_INS_GASLIMIT = 69
|
||||
EVM_INS_CHAINID = 70
|
||||
EVM_INS_SELFBALANCE = 71
|
||||
EVM_INS_BASEFEE = 72
|
||||
EVM_INS_BLOBHASH = 73
|
||||
EVM_INS_BLOBBASEFEE = 74
|
||||
EVM_INS_POP = 80
|
||||
EVM_INS_MLOAD = 81
|
||||
EVM_INS_MSTORE = 82
|
||||
|
@ -58,6 +66,10 @@ EVM_INS_PC = 88
|
|||
EVM_INS_MSIZE = 89
|
||||
EVM_INS_GAS = 90
|
||||
EVM_INS_JUMPDEST = 91
|
||||
EVM_INS_TLOAD = 92
|
||||
EVM_INS_TSTORE = 93
|
||||
EVM_INS_MCOPY = 94
|
||||
EVM_INS_PUSH0 = 95
|
||||
EVM_INS_PUSH1 = 96
|
||||
EVM_INS_PUSH2 = 97
|
||||
EVM_INS_PUSH3 = 98
|
||||
|
@ -132,12 +144,12 @@ EVM_INS_CALL = 241
|
|||
EVM_INS_CALLCODE = 242
|
||||
EVM_INS_RETURN = 243
|
||||
EVM_INS_DELEGATECALL = 244
|
||||
EVM_INS_CALLBLACKBOX = 245
|
||||
EVM_INS_CREATE2 = 245
|
||||
EVM_INS_STATICCALL = 250
|
||||
EVM_INS_REVERT = 253
|
||||
EVM_INS_SUICIDE = 255
|
||||
EVM_INS_INVALID = 512
|
||||
EVM_INS_ENDING = 513
|
||||
EVM_INS_INVALID = 254
|
||||
EVM_INS_SELFDESTRUCT = 255
|
||||
EVM_INS_ENDING = 256
|
||||
|
||||
EVM_GRP_INVALID = 0
|
||||
EVM_GRP_JUMP = 1
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
/* Capstone Disassembly Engine */
|
||||
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2018 */
|
||||
/* By Andelf <andelf@gmail.com>, 2025 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -46,6 +47,9 @@ typedef enum evm_insn {
|
|||
EVM_INS_XOR = 24,
|
||||
EVM_INS_NOT = 25,
|
||||
EVM_INS_BYTE = 26,
|
||||
EVM_INS_SHL = 27,
|
||||
EVM_INS_SHR = 28,
|
||||
EVM_INS_SAR = 29,
|
||||
EVM_INS_SHA3 = 32,
|
||||
EVM_INS_ADDRESS = 48,
|
||||
EVM_INS_BALANCE = 49,
|
||||
|
@ -68,6 +72,11 @@ typedef enum evm_insn {
|
|||
EVM_INS_NUMBER = 67,
|
||||
EVM_INS_DIFFICULTY = 68,
|
||||
EVM_INS_GASLIMIT = 69,
|
||||
EVM_INS_CHAINID = 70,
|
||||
EVM_INS_SELFBALANCE = 71,
|
||||
EVM_INS_BASEFEE = 72,
|
||||
EVM_INS_BLOBHASH = 73,
|
||||
EVM_INS_BLOBBASEFEE = 74,
|
||||
EVM_INS_POP = 80,
|
||||
EVM_INS_MLOAD = 81,
|
||||
EVM_INS_MSTORE = 82,
|
||||
|
@ -80,6 +89,10 @@ typedef enum evm_insn {
|
|||
EVM_INS_MSIZE = 89,
|
||||
EVM_INS_GAS = 90,
|
||||
EVM_INS_JUMPDEST = 91,
|
||||
EVM_INS_TLOAD = 92,
|
||||
EVM_INS_TSTORE = 93,
|
||||
EVM_INS_MCOPY = 94,
|
||||
EVM_INS_PUSH0 = 95,
|
||||
EVM_INS_PUSH1 = 96,
|
||||
EVM_INS_PUSH2 = 97,
|
||||
EVM_INS_PUSH3 = 98,
|
||||
|
@ -154,12 +167,12 @@ typedef enum evm_insn {
|
|||
EVM_INS_CALLCODE = 242,
|
||||
EVM_INS_RETURN = 243,
|
||||
EVM_INS_DELEGATECALL = 244,
|
||||
EVM_INS_CALLBLACKBOX = 245,
|
||||
EVM_INS_CREATE2 = 245,
|
||||
EVM_INS_STATICCALL = 250,
|
||||
EVM_INS_REVERT = 253,
|
||||
EVM_INS_SUICIDE = 255,
|
||||
EVM_INS_INVALID = 254,
|
||||
EVM_INS_SELFDESTRUCT = 255, // originally called SUICIDE
|
||||
|
||||
EVM_INS_INVALID = 512,
|
||||
EVM_INS_ENDING, // <-- mark the end of the list of instructions
|
||||
} evm_insn;
|
||||
|
||||
|
|
|
@ -21,4 +21,197 @@ test_cases:
|
|||
pop: 1
|
||||
fee: 2
|
||||
groups: [ EVM_GRP_STACK_READ ]
|
||||
|
||||
-
|
||||
input:
|
||||
bytes: [ 0x60, 0x80, 0x60, 0x40, 0x52, 0x60, 0x04, 0x36, 0x10, 0x61, 0x00, 0x2c, 0x57, 0x5f, 0x35 ]
|
||||
arch: "evm"
|
||||
options: [ CS_OPT_DETAIL ]
|
||||
address: 0x0
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "push1 80"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "push1 40"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "mstore"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_MEM_WRITE ]
|
||||
-
|
||||
asm_text: "push1 04"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "calldatasize"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 2
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "lt"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "push2 002c"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "jumpi"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
fee: 10
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_JUMP ]
|
||||
-
|
||||
asm_text: "push0"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "calldataload"
|
||||
details:
|
||||
evm:
|
||||
pop: 1
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
input:
|
||||
bytes: [ 0x5b, 0x5f, 0x1c, 0x47, 0x46, 0x15, 0x90, 0x20, 0x54, 0x42, 0x1a, 0x6d, 0x15, 0xc1, 0xfd, 0xdc, 0xd5, 0x55, 0x64, 0x73, 0x6f, 0x6c, 0x63, 0x43, 0x00, 0x08, 0x00, 0x33, 0xff ]
|
||||
arch: "evm"
|
||||
options: [ CS_OPT_DETAIL ]
|
||||
address: 0x0
|
||||
expected:
|
||||
insns:
|
||||
-
|
||||
asm_text: "jumpdest"
|
||||
details:
|
||||
evm:
|
||||
fee: 1
|
||||
-
|
||||
asm_text: "push0"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "shr"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE, EVM_GRP_MATH ]
|
||||
-
|
||||
asm_text: "selfbalance"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 5
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "chainid"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 2
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "iszero"
|
||||
details:
|
||||
evm:
|
||||
pop: 1
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "swap1"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
push: 2
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "sha3"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
push: 1
|
||||
fee: 30
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "sload"
|
||||
details:
|
||||
evm:
|
||||
pop: 1
|
||||
push: 1
|
||||
fee: 50
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE, EVM_GRP_STORE_READ ]
|
||||
-
|
||||
asm_text: "timestamp"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 2
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "byte"
|
||||
details:
|
||||
evm:
|
||||
pop: 2
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "push14 15c1fddcd55564736f6c63430008"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 3
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "stop"
|
||||
details:
|
||||
groups: [ EVM_GRP_HALT ]
|
||||
-
|
||||
asm_text: "caller"
|
||||
details:
|
||||
evm:
|
||||
push: 1
|
||||
fee: 2
|
||||
groups: [ EVM_GRP_STACK_WRITE ]
|
||||
-
|
||||
asm_text: "selfdestruct"
|
||||
details:
|
||||
evm:
|
||||
pop: 1
|
||||
fee: 5000
|
||||
groups: [ EVM_GRP_STACK_READ, EVM_GRP_HALT ]
|
Loading…
Reference in New Issue