diff --git a/librz/asm/arch/evm/evmasm.c b/librz/asm/arch/evm/evmasm.c new file mode 100644 index 00000000000..c54c571eb72 --- /dev/null +++ b/librz/asm/arch/evm/evmasm.c @@ -0,0 +1,359 @@ +// SPDX-FileCopyrightText: 2023 gogo +// SPDX-FileCopyrightText: 2012-2020 pancake +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include + +static int evmAsm(RzAsm *a, RzAsmOp *op, const char *buf) { + int j, len = 1; + size_t i; + if (!a || !op || !buf) { + return 0; + } + ut8 opbuf[40] = { 0 }; + + if (!strcmp("stop", buf)) { + opbuf[0] = 0x00; + } else if (!strcmp("add", buf)) { + opbuf[0] = 0x01; + } else if (!strcmp("sub", buf)) { + opbuf[0] = 0x03; + } else if (!strcmp("div", buf)) { + opbuf[0] = 0x04; + } else if (!strcmp("sdiv", buf)) { + opbuf[0] = 0x05; + } else if (!strcmp("mod", buf)) { + opbuf[0] = 0x06; + } else if (!strcmp("smod", buf)) { + opbuf[0] = 0x07; + } else if (!strcmp("addmod", buf)) { + opbuf[0] = 0x08; + } else if (!strcmp("mulmod", buf)) { + opbuf[0] = 0x09; + } else if (!strcmp("exp", buf)) { + opbuf[0] = 0x0a; + } else if (!strcmp("signextend", buf)) { + opbuf[0] = 0x0b; + } else if (!strcmp("gt", buf)) { + opbuf[0] = 0x11; + } else if (!strcmp("slt", buf)) { + opbuf[0] = 0x12; + } else if (!strcmp("sgt", buf)) { + opbuf[0] = 0x13; + } else if (!strcmp("eq", buf)) { + opbuf[0] = 0x14; + } else if (!strcmp("iszero", buf)) { + opbuf[0] = 0x15; + } else if (!strcmp("and", buf)) { + opbuf[0] = 0x16; + } else if (!strcmp("or", buf)) { + opbuf[0] = 0x17; + } else if (!strcmp("xor", buf)) { + opbuf[0] = 0x18; + } else if (!strcmp("not", buf)) { + opbuf[0] = 0x19; + } else if (!strcmp("byte", buf)) { + opbuf[0] = 0x1a; + } else if (!strcmp("shl", buf)) { + opbuf[0] = 0x1b; + } else if (!strcmp("shr", buf)) { + opbuf[0] = 0x1c; + } else if (!strcmp("sar", buf)) { + opbuf[0] = 0x1d; + } else if (!strcmp("sha3", buf)) { + opbuf[0] = 0x20; + } else if (!strcmp("address", buf)) { + opbuf[0] = 0x30; + } else if (!strcmp("balance", buf)) { + opbuf[0] = 0x31; + } else if (!strcmp("origin", buf)) { + opbuf[0] = 0x32; + } else if (!strcmp("caller", buf)) { + opbuf[0] = 0x33; + } else if (!strcmp("callvalue", buf)) { + opbuf[0] = 0x34; + } else if (!strcmp("calldataload", buf)) { + opbuf[0] = 0x35; + } else if (!strcmp("calldatasize", buf)) { + opbuf[0] = 0x36; + } else if (!strcmp("calldatacopy", buf)) { + opbuf[0] = 0x37; + } else if (!strcmp("codesize", buf)) { + opbuf[0] = 0x38; + } else if (!strcmp("codecopy", buf)) { + opbuf[0] = 0x39; + } else if (!strcmp("gasprice", buf)) { + opbuf[0] = 0x3a; + } else if (!strcmp("extcodesize", buf)) { + opbuf[0] = 0x3b; + } else if (!strcmp("extcodecopy", buf)) { + opbuf[0] = 0x3c; + } else if (!strcmp("returndatasize", buf)) { + opbuf[0] = 0x3d; + } else if (!strcmp("returndatacopy", buf)) { + opbuf[0] = 0x3e; + } else if (!strcmp("extcodehash", buf)) { + opbuf[0] = 0x3f; + } else if (!strcmp("blockhash", buf)) { + opbuf[0] = 0x40; + } else if (!strcmp("coinbase", buf)) { + opbuf[0] = 0x41; + } else if (!strcmp("timestamp", buf)) { + opbuf[0] = 0x42; + } else if (!strcmp("number", buf)) { + opbuf[0] = 0x43; + } else if (!strcmp("difficulty", buf)) { + opbuf[0] = 0x44; + } else if (!strcmp("gaslimit", buf)) { + opbuf[0] = 0x45; + } else if (!strcmp("chainid", buf)) { + opbuf[0] = 0x46; + } else if (!strcmp("selfbalance", buf)) { + opbuf[0] = 0x47; + } else if (!strcmp("pop", buf)) { + opbuf[0] = 0x50; + } else if (!strcmp("mload", buf)) { + opbuf[0] = 0x51; + } else if (!strcmp("mstore", buf)) { + opbuf[0] = 0x52; + } else if (!strcmp("mstore8", buf)) { + opbuf[0] = 0x53; + } else if (!strcmp("sload", buf)) { + opbuf[0] = 0x54; + } else if (!strcmp("sstore", buf)) { + opbuf[0] = 0x55; + } else if (!strcmp("jump", buf)) { + opbuf[0] = 0x56; + } else if (!strcmp("jump", buf)) { + opbuf[0] = 0x56; + } else if (!strcmp("jumpi", buf)) { + opbuf[0] = 0x57; + } else if (!strcmp("pc", buf)) { + opbuf[0] = 0x58; + } else if (!strcmp("msize", buf)) { + opbuf[0] = 0x59; + } else if (!strcmp("gas", buf)) { + opbuf[0] = 0x5a; + } else if (!strcmp("jumpdest", buf)) { + opbuf[0] = 0x5b; + } else if (!strncmp("push", buf, 3)) { + char out[100]; + int number = atoi(buf+4); + switch (number) { + case 1: + len = 2; + opbuf[0] = 0x60; + break; + case 2: + len = 3; + opbuf[0] = 0x61; + break; + case 3: + len = 4; + opbuf[0] = 0x62; + break; + case 4: + len = 5; + opbuf[0] = 0x63; + break; + case 5: + len = 6; + opbuf[0] = 0x64; + break; + case 6: + len = 7; + opbuf[0] = 0x65; + break; + case 7: + len = 8; + opbuf[0] = 0x66; + break; + case 8: + len = 9; + opbuf[0] = 0x67; + break; + case 9: + len = 10; + opbuf[0] = 0x68; + break; + case 10: + len = 11; + opbuf[0] = 0x69; + break; + case 11: + len = 12; + opbuf[0] = 0x6a; + break; + case 12: + len = 13; + opbuf[0] = 0x6b; + break; + case 13: + len = 14; + opbuf[0] = 0x6c; + break; + case 14: + len = 15; + opbuf[0] = 0x6d; + break; + case 15: + len = 16; + opbuf[0] = 0x6e; + break; + case 16: + len = 17; + opbuf[0] = 0x6f; + break; + case 17: + len = 18; + opbuf[0] = 0x70; + break; + case 18: + len = 19; + opbuf[0] = 0x71; + break; + case 19: + len = 20; + opbuf[0] = 0x72; + break; + case 20: + len = 21; + opbuf[0] = 0x73; + break; + case 21: + len = 22; + opbuf[0] = 0x74; + break; + case 22: + len = 23; + opbuf[0] = 0x75; + break; + case 23: + len = 24; + opbuf[0] = 0x76; + break; + case 24: + len = 25; + opbuf[0] = 0x77; + break; + case 25: + len = 26; + opbuf[0] = 0x78; + break; + case 26: + len = 27; + opbuf[0] = 0x79; + break; + case 27: + len = 28; + opbuf[0] = 0x7a; + break; + case 28: + len = 29; + opbuf[0] = 0x7b; + break; + case 29: + len = 30; + opbuf[0] = 0x7c; + break; + case 30: + len = 31; + opbuf[0] = 0x7d; + break; + case 31: + len = 32; + opbuf[0] = 0x7e; + break; + case 32: + len = 33; + opbuf[0] = 0x7f; + break; + } + int opbuf_len; + char two_chars_str[3]; + if (number <= 9) { + for (int j = 8, i = 0; i < len-1; j += 2, i ++) { + two_chars_str[0] = buf[j]; + two_chars_str[1] = buf[j+1]; + two_chars_str[2] = '\0'; + opbuf[i+1] = strtol(two_chars_str, NULL, 16); + } + } else if (number > 9) { + for (int j = 9, i = 0; i < len-1; j += 2, i ++) { + two_chars_str[0] = buf[j]; + two_chars_str[1] = buf[j+1]; + two_chars_str[2] = '\0'; + opbuf[i+1] = strtol(two_chars_str, NULL, 16); + } + } + } else if (!strcmp("swap1", buf)) { + opbuf[0] = 0x90; + } else if (!strcmp("swap2", buf)) { + opbuf[0] = 0x91; + } else if (!strcmp("swap3", buf)) { + opbuf[0] = 0x92; + } else if (!strcmp("swap4", buf)) { + opbuf[0] = 0x93; + } else if (!strcmp("swap5", buf)) { + opbuf[0] = 0x94; + } else if (!strcmp("swap6", buf)) { + opbuf[0] = 0x95; + } else if (!strcmp("swap7", buf)) { + opbuf[0] = 0x96; + } else if (!strcmp("swap8", buf)) { + opbuf[0] = 0x97; + } else if (!strcmp("swap9", buf)) { + opbuf[0] = 0x98; + } else if (!strcmp("swap10", buf)) { + opbuf[0] = 0x99; + } else if (!strcmp("swap11", buf)) { + opbuf[0] = 0x9a; + } else if (!strcmp("swap12", buf)) { + opbuf[0] = 0x9b; + } else if (!strcmp("swap13", buf)) { + opbuf[0] = 0x9c; + } else if (!strcmp("swap14", buf)) { + opbuf[0] = 0x9d; + } else if (!strcmp("swap15", buf)) { + opbuf[0] = 0x9e; + } else if (!strcmp("swap16", buf)) { + opbuf[0] = 0x9f; + } else if (!strcmp("log0", buf)) { + opbuf[0] = 0xa0; + } else if (!strcmp("log1", buf)) { + opbuf[0] = 0xa1; + } else if (!strcmp("log2", buf)) { + opbuf[0] = 0xa2; + } else if (!strcmp("log3", buf)) { + opbuf[0] = 0xa3; + } else if (!strcmp("log4", buf)) { + opbuf[0] = 0xa4; + } else if (!strcmp("create", buf)) { + opbuf[0] = 0xf0; + } else if (!strcmp("call", buf)) { + opbuf[0] = 0xf1; + } else if (!strcmp("callcode", buf)) { + opbuf[0] = 0xf2; + } else if (!strcmp("return", buf)) { + opbuf[0] = 0xf3; + } else if (!strcmp("delegatecall", buf)) { + opbuf[0] = 0xf4; + } else if (!strcmp("create2", buf)) { + opbuf[0] = 0xf5; + } else if (!strcmp("staticcall", buf)) { + opbuf[0] = 0xfa; + } else if (!strcmp("revert", buf)) { + opbuf[0] = 0xfd; + } else if (!strcmp("selfdestruct", buf)) { + opbuf[0] = 0xff; + } else { + len = 0; + } + + memcpy(rz_strbuf_get(&op->buf), opbuf, sizeof(ut8) * len); + return op->size = len; +} diff --git a/librz/asm/arch/evm/evmdis.c b/librz/asm/arch/evm/evmdis.c new file mode 100644 index 00000000000..74f5cafd900 --- /dev/null +++ b/librz/asm/arch/evm/evmdis.c @@ -0,0 +1,374 @@ +// SPDX-FileCopyrightText: 2023 gogo +// SPDX-FileCopyrightText: 2013-2018 pancake +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include + +static int evmDisass(RzAsmOp *op, const ut8 *buf, int len) { + int instruction_size = 1; + char buf_asm[2000]; + const unsigned char out[256]; + const unsigned char opcode[256]; + switch (buf[0]) { + case 0x00: + rz_str_cpy(buf_asm, "STOP") break; + case 0x01: + rz_str_cpy(buf_asm, "ADD") break; + case 0x02: + rz_str_cpy(buf_asm, "MUL") break; + case 0x03: + rz_str_cpy(buf_asm, "SUB") break; + case 0x04: + rz_str_cpy(buf_asm, "DIV") break; + case 0x05: + rz_str_cpy(buf_asm, "SDIV") break; + case 0x06: + rz_str_cpy(buf_asm, "MOD") break; + case 0x07: + rz_str_cpy(buf_asm, "SMOD") break; + case 0x8: + rz_str_cpy(buf_asm, "ADDMOD") break; + case 0x9: + rz_str_cpy(buf_asm, "MULMOD") break; + case 0x0a: + rz_str_cpy(buf_asm, "EXP") break; + case 0x0b: + rz_str_cpy(buf_asm, "SIGNEXTEND") break; + case 0x11: + rz_str_cpy(buf_asm, "GT") break; + case 0x12: + rz_str_cpy(buf_asm, "SLT") break; + case 0x13: + rz_str_cpy(buf_asm, "SGT") break; + case 0x14: + rz_str_cpy(buf_asm, "EQ") break; + case 0x15: + rz_str_cpy(buf_asm, "ISZERO") break; + case 0x16: + rz_str_cpy(buf_asm, "AND") break; + case 0x17: + rz_str_cpy(buf_asm, "OR") break; + case 0x18: + rz_str_cpy(buf_asm, "XOR") break; + case 0x19: + rz_str_cpy(buf_asm, "NOT") break; + case 0x1a: + rz_str_cpy(buf_asm, "BYTE") break; + case 0x1b: + rz_str_cpy(buf_asm, "SHL") break; + case 0x1c: + rz_str_cpy(buf_asm, "SHR") break; + case 0x1d: + rz_str_cpy(buf_asm, "SAR") break; + case 0x20: + rz_str_cpy(buf_asm, "SHA3") break; + case 0x30: + rz_str_cpy(buf_asm, "ADDRESS") break; + case 0x31: + rz_str_cpy(buf_asm, "BALANCE") break; + case 0x32: + rz_str_cpy(buf_asm, "ORIGIN") break; + case 0x33: + rz_str_cpy(buf_asm, "CALLER") break; + case 0x34: + rz_str_cpy(buf_asm, "CALLVALUE") break; + case 0x35: + rz_str_cpy(buf_asm, "CALLDATALOAD") break; + case 0x36: + rz_str_cpy(buf_asm, "CALLDATASIZE") break; + case 0x37: + rz_str_cpy(buf_asm, "CALLDATACOPY") break; + case 0x38: + rz_str_cpy(buf_asm, "CODESIZE") break; + case 0x39: + rz_str_cpy(buf_asm, "CODECOPY") break; + case 0x3a: + rz_str_cpy(buf_asm, "GASPRICE") break; + case 0x3b: + rz_str_cpy(buf_asm, "EXTCODESIZE") break; + case 0x3c: + rz_str_cpy(buf_asm, "EXTCODECOPY") break; + case 0x3d: + rz_str_cpy(buf_asm, "RETURNDATASIZE") break; + case 0x3e: + rz_str_cpy(buf_asm, "RETURNDATACOPY") break; + case 0x3f: + rz_str_cpy(buf_asm, "EXTCODEHASH") break; + case 0x40: + rz_str_cpy(buf_asm, "BLOCKHASH") break; + case 0x41: + rz_str_cpy(buf_asm, "COINBASE") break; + case 0x42: + rz_str_cpy(buf_asm, "TIMESTAMP") break; + case 0x43: + rz_str_cpy(buf_asm, "NUMBER") break; + case 0x44: + rz_str_cpy(buf_asm, "DIFFICULTY") break; + case 0x45: + rz_str_cpy(buf_asm, "GASLIMIT") break; + case 0x46: + rz_str_cpy(buf_asm, "CHAINID") break; + case 0x47: + rz_str_cpy(buf_asm, "SELFBALANCE") break; + case 0x48: + rz_str_cpy(buf_asm, "BASEFEE") break; + case 0x50: + rz_str_cpy(buf_asm, "POP") break; + case 0x51: + rz_str_cpy(buf_asm, "MLOAD") break; + case 0x52: + rz_str_cpy(buf_asm, "MSTORE") break; + case 0x53: + rz_str_cpy(buf_asm, "MSTORE8") break; + case 0x54: + rz_str_cpy(buf_asm, "SLOAD") break; + case 0x55: + rz_str_cpy(buf_asm, "SSTORE") break; + case 0x56: + rz_str_cpy(buf_asm, "JUMP") break; + case 0x57: + rz_str_cpy(buf_asm, "JUMPI") break; + case 0x58: + rz_str_cpy(buf_asm, "PC") break; + case 0x59: + rz_str_cpy(buf_asm, "MSIZE") break; + case 0x5a: + rz_str_cpy(buf_asm, "GAS") break; + case 0x5b: + rz_str_cpy(buf_asm, "JUMPDEST") break; + case 0x60: + instruction_size = 2; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH1 0x%s", opcode); break; + case 0x61: + instruction_size = 3; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH2 0x%s", opcode); break; + case 0x62: + instruction_size = 4; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH3 0x%s", opcode); break; + case 0x63: + instruction_size = 5; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH4 0x%s", opcode); break; + case 0x64: + instruction_size = 6; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH5 0x%s", opcode); break; + case 0x65: + instruction_size = 7; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH6 0x%s", opcode); break; + case 0x66: + instruction_size = 8; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH7 0x%s", opcode); break; + case 0x67: + instruction_size = 9; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH8 0x%s", opcode); break; + case 0x68: + instruction_size = 10; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH9 0x%s", opcode); break; + case 0x69: + instruction_size = 11; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH10 0x%s", opcode); break; + case 0x6a: + instruction_size = 12; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH11 0x%s", opcode); break; + case 0x6b: + instruction_size = 13; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH12 0x%s", opcode); break; + case 0x6c: + instruction_size = 14; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH13 0x%s", opcode); break; + case 0x6d: + instruction_size = 15; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH14 0x%s", opcode); break; + case 0x6e: + instruction_size = 16; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH15 0x%s", opcode); break; + case 0x6f: + instruction_size = 17; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH16 0x%s", opcode); break; + case 0x70: + instruction_size = 18; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH17 0x%s", opcode); break; + case 0x71: + instruction_size = 19; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH18 0x%s", opcode); break; + case 0x72: + instruction_size = 20; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH19 0x%s", opcode); break; + case 0x73: + instruction_size = 21; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH20 0x%s", opcode); break; + case 0x74: + instruction_size = 22; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH21 0x%s", opcode); break; + case 0x75: + instruction_size = 23; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH22 0x%s", opcode); break; + case 0x76: + instruction_size = 24; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH23 0x%s", opcode); break; + case 0x77: + instruction_size = 25; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH24 0x%s", opcode); break; + case 0x78: + instruction_size = 26; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH25 0x%s", opcode); break; + case 0x79: + instruction_size = 27; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH26 0x%s", opcode); break; + case 0x7a: + instruction_size = 28; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH27 0x%s", opcode); break; + case 0x7b: + instruction_size = 29; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH28 0x%s", opcode); break; + case 0x7c: + instruction_size = 30; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH29 0x%s", opcode); break; + case 0x7d: + instruction_size = 31; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH30 0x%s", opcode); break; + case 0x7e: + instruction_size = 32; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH31 0x%s", opcode); break; + case 0x7f: + instruction_size = 33; + rz_hex_bin2str(buf+1, instruction_size-1, opcode); + rz_strf(buf_asm, "PUSH32 0x%s", opcode); break; + case 0x80: + rz_str_cpy(buf_asm, "DUP1") break; + case 0x81: + rz_str_cpy(buf_asm, "DUP2") break; + case 0x82: + rz_str_cpy(buf_asm, "DUP3") break; + case 0x83: + rz_str_cpy(buf_asm, "DUP4") break; + case 0x84: + rz_str_cpy(buf_asm, "DUP5") break; + case 0x85: + rz_str_cpy(buf_asm, "DUP6") break; + case 0x86: + rz_str_cpy(buf_asm, "DUP7") break; + case 0x87: + rz_str_cpy(buf_asm, "DUP8") break; + case 0x88: + rz_str_cpy(buf_asm, "DUP9") break; + case 0x89: + rz_str_cpy(buf_asm, "DUP10") break; + case 0x8a: + rz_str_cpy(buf_asm, "DUP11") break; + case 0x8b: + rz_str_cpy(buf_asm, "DUP12") break; + case 0x8c: + rz_str_cpy(buf_asm, "DUP13") break; + case 0x8d: + rz_str_cpy(buf_asm, "DUP14") break; + case 0x8e: + rz_str_cpy(buf_asm, "DUP15") break; + case 0x8f: + rz_str_cpy(buf_asm, "DUP16") break; + case 0x90: + rz_str_cpy(buf_asm, "SWAP1") break; + case 0x91: + rz_str_cpy(buf_asm, "SWAP2") break; + case 0x92: + rz_str_cpy(buf_asm, "SWAP3") break; + case 0x93: + rz_str_cpy(buf_asm, "SWAP4") break; + case 0x94: + rz_str_cpy(buf_asm, "SWAP5") break; + case 0x95: + rz_str_cpy(buf_asm, "SWAP6") break; + case 0x96: + rz_str_cpy(buf_asm, "SWAP7") break; + case 0x97: + rz_str_cpy(buf_asm, "SWAP8") break; + case 0x98: + rz_str_cpy(buf_asm, "SWAP9") break; + case 0x99: + rz_str_cpy(buf_asm, "SWAP10") break; + case 0x9a: + rz_str_cpy(buf_asm, "SWAP11") break; + case 0x9b: + rz_str_cpy(buf_asm, "SWAP12") break; + case 0x9c: + rz_str_cpy(buf_asm, "SWAP13") break; + case 0x9d: + rz_str_cpy(buf_asm, "SWAP14") break; + case 0x9e: + rz_str_cpy(buf_asm, "SWAP15") break; + case 0x9f: + rz_str_cpy(buf_asm, "SWAP16") break; + case 0xa0: + rz_str_cpy(buf_asm, "LOG0") break; + case 0xa1: + rz_str_cpy(buf_asm, "LOG1") break; + case 0xa2: + rz_str_cpy(buf_asm, "LOG2") break; + case 0xa3: + rz_str_cpy(buf_asm, "LOG3") break; + case 0xa4: + rz_str_cpy(buf_asm, "LOG4") break; + case 0xb0: + rz_str_cpy(buf_asm, "PUSH") break; //requires arguments? + case 0xb1: + rz_str_cpy(buf_asm, "DUP") break; //requires arguments? + case 0xb2: + rz_str_cpy(buf_asm, "SWAP") break; + case 0xf0: + rz_str_cpy(buf_asm, "CREATE") break; + case 0xf1: + rz_str_cpy(buf_asm, "CALL") break; //requires arguments? + case 0xf2: + rz_str_cpy(buf_asm, "CALLCODE") break; + case 0xf3: + rz_str_cpy(buf_asm, "RETURN") break; + case 0xf4: + rz_str_cpy(buf_asm, "DELEGATECALL") break; + case 0xf5: + rz_str_cpy(buf_asm, "CREATE2") break; + case 0xfa: + rz_str_cpy(buf_asm, "STATICCALL") break; + case 0xfd: + rz_str_cpy(buf_asm, "REVERT") break; + case 0xff: + rz_str_cpy(buf_asm, "SELFDESTRUCT") break; + default: + rz_str_cpy(buf_asm, "Invalid") break; + } + + rz_strbuf_set(&op->buf_asm, buf_asm); + return instruction_size; +} diff --git a/librz/asm/meson.build b/librz/asm/meson.build index b004e81b1fe..e12065ebcd8 100644 --- a/librz/asm/meson.build +++ b/librz/asm/meson.build @@ -12,6 +12,7 @@ asm_plugins_list = [ 'dalvik', 'dcpu16', 'ebc', + 'evm', 'gb', 'h8300', 'hexagon', @@ -99,6 +100,7 @@ rz_asm_sources = [ 'p/asm_dalvik.c', 'p/asm_dcpu16.c', 'p/asm_ebc.c', + 'p/asm_evm.c', 'p/asm_gb.c', 'p/asm_h8300.c', 'p/asm_hexagon.c', @@ -155,6 +157,8 @@ rz_asm_sources = [ #'arch/dcpu16/dis.c', #'arch/dcpu16/main.c', 'arch/ebc/ebc_disas.c', + 'arch/evm/evmdis.c', + 'arch/evm/evmasm.c', #'arch/gb/gbasm.c', #'arch/gb/gbdis.c', 'arch/h8300/h8300_disas.c', @@ -298,6 +302,7 @@ rz_asm_inc = [ 'arch/v850', 'arch/propeller', 'arch/ebc', + 'arch/evm', 'arch/cr16', 'arch/8051', 'arch/v810', diff --git a/librz/asm/p/asm_evm.c b/librz/asm/p/asm_evm.c new file mode 100644 index 00000000000..1c1568c50c8 --- /dev/null +++ b/librz/asm/p/asm_evm.c @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2023 gogo +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include "../arch/evm/evmdis.c" +#include "../arch/evm/evmasm.c" + +static int disassemble(RzAsm *a, RzAsmOp *rz_op, const ut8 *buf, int len) { + int dlen = evmDisass(rz_op, buf, len); + return rz_op->size = RZ_MAX(0, dlen); +} + +static int assemble(RzAsm *a, RzAsmOp *rz_op, const char *buf) { + return evmAsm(a, rz_op, buf); +} + +RzAsmPlugin rz_asm_plugin_evm = { + .name = "evm", + .desc = "EVM solidity bytecode", + .arch = "evm", + .author = "gogo", + .license = "LGPL3", + .bits = 256, + .endian = RZ_SYS_ENDIAN_LITTLE, + .disassemble = &disassemble, + .assemble = &assemble, +}; + +#ifndef RZ_PLUGIN_INCORE +RZ_API RzLibStruct rizin_plugin = { + .type = RZ_LIB_TYPE_ASM, + .data = &rz_asm_plugin_evm, + .version = RZ_VERSION +}; +#endif diff --git a/librz/include/rz_asm.h b/librz/include/rz_asm.h index 783fb536173..615fd050f05 100644 --- a/librz/include/rz_asm.h +++ b/librz/include/rz_asm.h @@ -229,6 +229,7 @@ extern RzAsmPlugin rz_asm_plugin_cris_gnu; extern RzAsmPlugin rz_asm_plugin_dalvik; extern RzAsmPlugin rz_asm_plugin_dcpu16; extern RzAsmPlugin rz_asm_plugin_ebc; +extern RzAsmPlugin rz_asm_plugin_evm; extern RzAsmPlugin rz_asm_plugin_gb; extern RzAsmPlugin rz_asm_plugin_h8300; extern RzAsmPlugin rz_asm_plugin_hexagon; diff --git a/test/db/asm/evm b/test/db/asm/evm new file mode 100644 index 00000000000..270d68bc2fa --- /dev/null +++ b/test/db/asm/evm @@ -0,0 +1,258 @@ +d "STOP" 00 +d "ADD" 01 +d "SUB" 03 +d "DIV" 04 +d "SDIV" 05 +d "MOD" 06 +d "SMOD" 07 +d "ADDMOD" 08 +d "MULMOD" 09 +d "EXP" 0a +d "SIGNEXTEND" 0b +d "GT" 11 +d "SLT" 12 +d "SGT" 13 +d "EQ" 14 +d "ISZERO" 15 +d "AND" 16 +d "OR" 17 +d "XOR" 18 +d "NOT" 19 +d "BYTE" 1a +d "SHL" 1b +d "SHR" 1c +d "SAR" 1d +d "SHA3" 20 +d "ADDRESS" 30 +d "BALANCE" 31 +d "ORIGIN" 32 +d "CALLER" 33 +d "CALLVALUE" 34 +d "CALLDATALOAD" 35 +d "CALLDATASIZE" 36 +d "CALLDATACOPY" 37 +d "CODESIZE" 38 +d "CODECOPY" 39 +d "GASPRICE" 3a +d "EXTCODESIZE" 3b +d "EXTCODECOPY" 3c +d "RETURNDATASIZE" 3d +d "RETURNDATACOPY" 3e +d "CODESIZE" 38 +d "CODECOPY" 39 +d "GASPRICE" 3a +d "EXTCODESIZE" 3b +d "EXTCODECOPY" 3c +d "RETURNDATASIZE" 3d +d "RETURNDATACOPY" 3e +d "EXTCODEHASH" 3f +d "BLOCKHASH" 40 +d "COINBASE" 41 +d "TIMESTAMP" 42 +d "NUMBER" 43 +d "DIFFICULTY" 44 +d "GASLIMIT" 45 +d "CHAINID" 46 +d "SELFBALANCE" 47 +d "POP" 50 +d "MLOAD" 51 +d "MSTORE" 52 +d "MSTORE8" 53 +d "SLOAD" 54 +d "SSTORE" 55 +d "JUMP" 56 +d "JUMPI" 57 +d "PC" 58 +d "MSIZE" 59 +d "GAS" 5a +d "JUMPDEST" 5b +d "PUSH1 0x01" 6001 +d "PUSH2 0x0102" 610102 +d "PUSH3 0x010203" 62010203 +d "PUSH4 0x01020304" 6301020304 +d "PUSH5 0x0102030405" 640102030405 +d "PUSH6 0x010203040506" 65010203040506 +d "PUSH7 0x01020304050607" 6601020304050607 +d "PUSH8 0x0102030405060708" 670102030405060708 +d "PUSH9 0x010203040506070809" 68010203040506070809 +d "PUSH10 0x01020304050607080901" 6901020304050607080901 +d "PUSH11 0x0102030405060708090102" 6a0102030405060708090102 +d "PUSH12 0x010203040506070809010203" 6b010203040506070809010203 +d "PUSH13 0x01020304050607080901020304" 6c01020304050607080901020304 +d "PUSH14 0x0102030405060708090102030405" 6d0102030405060708090102030405 +d "PUSH15 0x010203040506070809010203040506" 6e010203040506070809010203040506 +d "PUSH16 0x01020304050607080901020304050607" 6f01020304050607080901020304050607 +d "PUSH17 0x0102030405060708090102030405060708" 700102030405060708090102030405060708 +d "PUSH18 0x010203040506070809010203040506070809" 71010203040506070809010203040506070809 +d "PUSH19 0x01020304050607080901020304050607080901" 7201020304050607080901020304050607080901 +d "PUSH20 0x0102030405060708090102030405060708090102" 730102030405060708090102030405060708090102 +d "PUSH21 0x010203040506070809010203040506070809010203" 74010203040506070809010203040506070809010203 +d "PUSH22 0x01020304050607080901020304050607080901020304" 7501020304050607080901020304050607080901020304 +d "PUSH23 0x0102030405060708090102030405060708090102030405" 760102030405060708090102030405060708090102030405 +d "PUSH24 0x010203040506070809010203040506070809010203040506" 77010203040506070809010203040506070809010203040506 +d "PUSH25 0x01020304050607080901020304050607080901020304050607" 7801020304050607080901020304050607080901020304050607 +d "PUSH26 0x0102030405060708090102030405060708090102030405060708" 790102030405060708090102030405060708090102030405060708 +d "PUSH27 0x010203040506070809010203040506070809010203040506070809" 7a010203040506070809010203040506070809010203040506070809 +d "PUSH28 0x01020304050607080901020304050607080901020304050607080901" 7b01020304050607080901020304050607080901020304050607080901 +d "PUSH29 0x0102030405060708090102030405060708090102030405060708090102" 7c0102030405060708090102030405060708090102030405060708090102 +d "PUSH30 0x010203040506070809010203040506070809010203040506070809010203" 7d010203040506070809010203040506070809010203040506070809010203 +d "PUSH31 0x01020304050607080901020304050607080901020304050607080901020304" 7e01020304050607080901020304050607080901020304050607080901020304 +d "PUSH32 0x0102030405060708090102030405060708090102030405060708090102030405" 7f0102030405060708090102030405060708090102030405060708090102030405 +d "SWAP1" 90 +d "SWAP2" 91 +d "SWAP3" 92 +d "SWAP4" 93 +d "SWAP5" 94 +d "SWAP6" 95 +d "SWAP7" 96 +d "SWAP8" 97 +d "SWAP9" 98 +d "SWAP10" 99 +d "SWAP11" 9a +d "SWAP12" 9b +d "SWAP13" 9c +d "SWAP14" 9d +d "SWAP15" 9e +d "SWAP16" 9f +d "LOG0" a0 +d "LOG1" a1 +d "LOG2" a2 +d "LOG3" a3 +d "LOG4" a4 +d "CREATE" f0 +d "CALL" f1 +d "CALLCODE" f2 +d "RETURN" f3 +d "DELEGATECALL" f4 +d "CREATE2" f5 +d "STATICCALL" fa +d "REVERT" fd +d "SELFDESTRUCT" ff + +d "PUSH" b0 + +a "STOP" 00 +a "ADD" 01 +a "SUB" 03 +a "DIV" 04 +a "SDIV" 05 +a "MOD" 06 +a "SMOD" 07 +a "ADDMOD" 08 +a "MULMOD" 09 +a "EXP" 0a +a "SIGNEXTEND" 0b +a "GT" 11 +a "SLT" 12 +a "SGT" 13 +a "EQ" 14 +a "ISZERO" 15 +a "AND" 16 +a "OR" 17 +a "XOR" 18 +a "NOT" 19 +a "BYTE" 1a +a "SHL" 1b +a "SHR" 1c +a "SAR" 1d +a "SHA3" 20 +a "ADDRESS" 30 +a "BALANCE" 31 +a "ORIGIN" 32 +a "CALLER" 33 +a "CALLVALUE" 34 +a "CALLDATALOAD" 35 +a "CALLDATASIZE" 36 +a "CALLDATACOPY" 37 +a "CODESIZE" 38 +a "CODECOPY" 39 +a "GASPRICE" 3a +a "EXTCODESIZE" 3b +a "EXTCODECOPY" 3c +a "RETURNDATASIZE" 3d +a "RETURNDATACOPY" 3e +a "EXTCODEHASH" 3f +a "BLOCKHASH" 40 +a "COINBASE" 41 +a "TIMESTAMP" 42 +a "NUMBER" 43 +a "DIFFICULTY" 44 +a "GASLIMIT" 45 +a "CHAINID" 46 +a "SELFBALANCE" 47 +a "POP" 50 +a "MLOAD" 51 +a "MSTORE" 52 +a "MSTORE8" 53 +a "SLOAD" 54 +a "SSTORE" 55 +a "JUMP" 56 +a "JUMPI" 57 +a "PC" 58 +a "MSIZE" 59 +a "GAS" 5a +a "JUMPDEST" 5b +a "PUSH1 0x01" 6001 +d "PUSH2 0x0102" 610102 +a "PUSH3 0x010203" 62010203 +a "PUSH4 0x01020304" 6301020304 +a "PUSH5 0x0102030405" 640102030405 +a "PUSH6 0x010203040506" 65010203040506 +a "PUSH7 0x01020304050607" 6601020304050607 +a "PUSH8 0x0102030405060708" 670102030405060708 +a "PUSH9 0x010203040506070809" 68010203040506070809 +a "PUSH10 0x01020304050607080901" 6901020304050607080901 +a "PUSH11 0x0102030405060708090102" 6a0102030405060708090102 +a "PUSH12 0x010203040506070809010203" 6b010203040506070809010203 +a "PUSH13 0x01020304050607080901020304" 6c01020304050607080901020304 +a "PUSH14 0x0102030405060708090102030405" 6d0102030405060708090102030405 +a "PUSH15 0x010203040506070809010203040506" 6e010203040506070809010203040506 +a "PUSH16 0x01020304050607080901020304050607" 6f01020304050607080901020304050607 +a "PUSH17 0x0102030405060708090102030405060708" 700102030405060708090102030405060708 +a "PUSH18 0x010203040506070809010203040506070809" 71010203040506070809010203040506070809 +a "PUSH19 0x01020304050607080901020304050607080901" 7201020304050607080901020304050607080901 +a "PUSH20 0x0102030405060708090102030405060708090102" 730102030405060708090102030405060708090102 +a "PUSH21 0x010203040506070809010203040506070809010203" 74010203040506070809010203040506070809010203 +a "PUSH22 0x01020304050607080901020304050607080901020304" 7501020304050607080901020304050607080901020304 +a "PUSH23 0x0102030405060708090102030405060708090102030405" 760102030405060708090102030405060708090102030405 +a "PUSH24 0x010203040506070809010203040506070809010203040506" 77010203040506070809010203040506070809010203040506 +a "PUSH25 0x01020304050607080901020304050607080901020304050607" 7801020304050607080901020304050607080901020304050607 +a "PUSH26 0x0102030405060708090102030405060708090102030405060708" 790102030405060708090102030405060708090102030405060708 +a "PUSH27 0x010203040506070809010203040506070809010203040506070809" 7a010203040506070809010203040506070809010203040506070809 +a "PUSH28 0x01020304050607080901020304050607080901020304050607080901" 7b01020304050607080901020304050607080901020304050607080901 +a "PUSH29 0x0102030405060708090102030405060708090102030405060708090102" 7c0102030405060708090102030405060708090102030405060708090102 +a "PUSH30 0x010203040506070809010203040506070809010203040506070809010203" 7d010203040506070809010203040506070809010203040506070809010203 +a "PUSH31 0x01020304050607080901020304050607080901020304050607080901020304" 7e01020304050607080901020304050607080901020304050607080901020304 + +#a "PUSH32 0x0102030405060708090102030405060708090102030405060708090102030405" 7f0102030405060708090102030405060708090102030405060708090102030405 + +a "SWAP1" 90 +a "SWAP2" 91 +a "SWAP3" 92 +a "SWAP4" 93 +a "SWAP5" 94 +a "SWAP6" 95 +a "SWAP7" 96 +a "SWAP8" 97 +a "SWAP9" 98 +a "SWAP10" 99 +a "SWAP11" 9a +a "SWAP12" 9b +a "SWAP13" 9c +a "SWAP14" 9d +a "SWAP15" 9e +a "SWAP16" 9f +a "LOG0" a0 +a "LOG1" a1 +a "LOG2" a2 +a "LOG3" a3 +a "LOG4" a4 +a "CREATE" f0 +a "CALL" f1 +a "CALLCODE" f2 +a "RETURN" f3 +a "DELEGATECALL" f4 +a "CREATE2" f5 +a "STATICCALL" fa +a "REVERT" fd +a "SELFDESTRUCT" ff diff --git a/test/db/cmd/cmd_list b/test/db/cmd/cmd_list index 67d988cac89..46faee0fb6b 100644 --- a/test/db/cmd/cmd_list +++ b/test/db/cmd/cmd_list @@ -85,7 +85,7 @@ FILE== BROKEN=1 CMDS=Loj EXPECT=<