{ "info": { "author": "QuoScient", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Disassemblers" ], "description": "# Octopus\n\n
\n\t
\n
\n\n#### Disassembler\n\nDisassembly of a Wasm module:\n```python\nfrom octopus.arch.wasm.disassembler import WasmDisassembler\n\nFILE = \"examples/wasm/samples/helloworld.wasm\"\n\nwith open(FILE, 'rb') as f:\n module_bytecode = f.read()\n\ndisasm = WasmDisassembler()\n# return list of functions instructions (list)\nprint(disasm.disassemble_module(module_bytecode))\n#[[ \n \n \n \n \n
\n
\n
\n
\n
\n
\n\n#### Explorer\n\n```python\nfrom octopus.platforms.ETH.explorer import EthereumInfuraExplorer\nfrom octopus.platforms.ETH.explorer import INFURA_ROPSTEN\n\nKEY_API = \"bHuaQhX91nkQBac8Wtgj\"\n# connection to ROPSTEN network (testnet)\nexplorer = EthereumInfuraExplorer(KEY_API, network=INFURA_ROPSTEN)\n\n# connection to MAINNET network (mainnet)\n# explorer = EthereumInfuraExplorer(KEY_API)\n\n# Test ROPSTEN network current block number\nblock_number = explorer.eth_blockNumber()\nprint(block_number)\n# 3675552\n\n# Retrieve code of this smart contract\naddr = \"0x3c6B10a5239B1a8A27398583F49771485382818F\"\ncode = explorer.eth_getCode(addr)\nprint(code)\n# 0x6060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820e1f98c821c12eea52047d7324b034ddccc41eaa7365d369b34580ab73c71a8940029\n```\n\n#### Disassembler\n\n```python\nfrom octopus.platforms.ETH.disassembler import EthereumDisassembler\n\n# smart contract bytecode\nbytecode_hex = \"60606040526000357c0100000000000000000000000000000000000000000000000000000000900480635fd8c7101461004f578063c0e317fb1461005e578063f8b2cb4f1461006d5761004d565b005b61005c6004805050610099565b005b61006b600480505061013e565b005b610083600480803590602001909190505061017d565b6040518082815260200191505060405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff16611111600060005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054604051809050600060405180830381858888f19350505050151561010657610002565b6000600060005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b565b34600060005060003373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055505b565b6000600060005060008373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505490506101b6565b91905056\"\n\ndisasm = EthereumDisassembler()\ndisasm.disassemble(bytecode_hex)\n\n# disassemble bytecode into a list of EthereumInstruction\n# attributes r_format='list' by default\nprint(disasm.disassemble(bytecode_hex))\n\n#[ \n \n
\n
\n
\n\n#### Explorer\n\n```python\nfrom octopus.platforms.ETH.explorer import EthereumInfuraExplorer\nfrom octopus.platforms.ETH.explorer import INFURA_KOVAN\n\n# connection to ROPSTEN network (testnet)\nexplorer = EthereumInfuraExplorer(\"bHuaQhX91nkQBac8Wtgj\",\n network=INFURA_KOVAN)\n# connection to MAINNET network (mainnet)\n# explorer = EthereumInfuraExplorer(\"bHuaQhX91nkQBac8Wtgj\")\n\n# test infura access\nblock_number = explorer.eth_blockNumber()\nprint('blockNumber = %d' % block_number)\n\n# retrieve code of this smart contract\naddr = \"0x1120e596b173d953ba52ce262f73ce3734b0e40e\"\ncode = explorer.eth_getCode(addr)\nprint()\nprint(code)\n# blockNumber = 8803487\n# \n# 0x0061736d0100000001090260000060027f7f00021a0203656e7603726574000103656e76066d656d6f7279020102100303020000040501700101010501000601000708010463616c6c00010a120205001002000b0a00418008410b1000000b0b1201004180080b0b48656c6c6f20776f726c64000b076c696e6b696e6703010b0066046e616d65015f060003726574010570616e6963020463616c6c032f5f5a4e3134707761736d5f657468657265756d3365787433726574313768363034643830393864313638366338304504066465706c6f790511727573745f626567696e5f756e77696e64\n```\n\n#### Disassembler\n\nDisassembly of a Wasm module:\n```python\nfrom octopus.platforms.ETH.disassembler import EthereumDisassembler\n\nFILE = \"examples/ETH/wasm/helloworld_kovan.bytecode\"\n\nwith open(FILE, 'r') as f:\n module_bytecode = f.read()\n\ndisasm = EthereumDisassembler(arch='wasm')\n# return list of functions instructions (list)\nprint(disasm.disassemble_module(module_bytecode))\n#[[ \n \n \n \n
\n
\n
\n
\n
\n\n#### Explorer\n\n```python\nfrom octopus.platforms.NEO.explorer import NeoExplorerRPC\n\n# get list nodes here: http://monitor.cityofzion.io/\nexplorer = NeoExplorerRPC(host='seed2.neo.org')\n\n# get current number of block on the blockchain\nprint(explorer.getblockcount())\n# 2534868\n\n# get information on a contract\n# lock smart contract address: d3cce84d0800172d09c88ccad61130611bd047a4\ncontract = explorer.getcontractstate(\"d3cce84d0800172d09c88ccad61130611bd047a4\")\nprint(contract)\n# {'author': 'Erik Zhang',\n# 'code_version': '2.0',\n# 'description': 'Lock 2.0',\n# 'email': 'erik@neo.org',\n# 'hash': '0xd3cce84d0800172d09c88ccad61130611bd047a4',\n# 'name': 'Lock',\n# 'parameters': ['Integer', 'PublicKey', 'Signature'],\n# 'properties': {'dynamic_invoke': False, 'storage': False},\n# 'returntype': 'Boolean',\n# 'script': '56c56b6c766b00527ac46c766b51527ac46c766b52527ac4616168184e656f2e426c6f636b636861696e2e4765744865696768746168184e656f2e426c6f636b636861696e2e4765744865616465726c766b53527ac46c766b00c36c766b53c36168174e656f2e4865616465722e47657454696d657374616d70a06c766b54527ac46c766b54c3640e00006c766b55527ac4621a006c766b51c36c766b52c3617cac6c766b55527ac46203006c766b55c3616c7566',\n# 'version': 0}\n\n# smart contract code in contract['script']\nprint(contract['script'])\n```\n\n#### Disassembler\n\n```python\nfrom octopus.platforms.NEO.disassembler import NeoDisassembler\n\n# lock contract\nfile_name = \"examples/NEO/samples/Lock.bytecode\"\n\n# read file\nwith open(file_name) as f:\n bytecode = f.read()\n\ndisasm = NeoDisassembler()\n\nprint(disasm.disassemble(bytecode, r_format='text'))\n# PUSH6\n# NEWARRAY\n# TOALTSTACK\n# FROMALTSTACK\n# DUP\n# TOALTSTACK\n# PUSH0\n# PUSH2\n# ROLL\n# SETITEM\n# FROMALTSTACK\n# ....\n# PICKITEM\n# NOP\n# FROMALTSTACK\n# DROP\n# RET\n```\n\n#### Control Flow Analysis\n\n```python\nfrom octopus.analysis.graph import CFGGraph\nfrom octopus.platforms.NEO.cfg import NeoCFG\n\n# lock contract\nfile_name = \"examples/NEO/samples/Lock.bytecode\"\n\n# read file\nwith open(file_name) as f:\n raw = f.read()\n\n# create neo cfg - automatic static analysis\ncfg = NeoCFG(raw)\n\n# graph visualization\ngraph = CFGGraph(cfg, filename=\"Lock_cfg\")\ngraph.view_functions()\n```\n\n
\n
\n
\n\n#### Explorer\n\n```python\nfrom octopus.platforms.EOS.explorer import EosExplorer\n\nhost = \"api.cypherglass.com\"\n\n# by defaul the port is 8888\nexplo = EosExplorer(host=host)\n\n# get info about the node\nexplo.get_info()\n\n'''\n{'block_cpu_limit': 180289,\n 'block_net_limit': 1045680,\n 'chain_id': 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',\n 'head_block_id': '018d6e2bcf6295126cd74cf694b5cca3529eefc42b334b394ef87c3a43876739',\n 'head_block_num': 26045995,\n 'head_block_producer': 'eosswedenorg',\n 'head_block_time': '2018-11-09T14:11:29.500',\n 'last_irreversible_block_id': '018d6cdcff78bbd9f25c605b02fb67c47a337ece78ddcf73089cee4bf6a410ee',\n 'last_irreversible_block_num': 26045660,\n 'server_version': 'c71d2245',\n 'server_version_string': 'mainnet-1.3.0',\n 'virtual_block_cpu_limit': 38092879,\n 'virtual_block_net_limit': 1048576000}\n'''\nexplo.get_block(1337)\n\n'''\n{'action_mroot': 'bcb9763baa3bbf98ed36379b4be0ecb2d9cd21c75df01729c63b2b021001c10c',\n 'block_extensions': [],\n 'block_num': 1337,\n 'confirmed': 0,\n 'header_extensions': [],\n 'id': '00000539d17a03af7126e073be4c4d99a72b7f58793cf2c87b9bfd41b6c711fb',\n 'new_producers': None,\n 'previous': '00000538b374c1cbfaeed7253ad3075ddc72a28f0a0515301fc1bbed675f2316',\n 'producer': 'eosio',\n 'producer_signature': 'SIG_K1_K5jWf36t6j454Hb2fGuV37YTwMTvuQ51ZPBtpru8Ud2axtMTEauWyvtpJuTpnvqzReUndDgEDXvoeEP4jdj2bpnYKBt6g2',\n 'ref_block_prefix': 1944069745,\n 'schedule_version': 0,\n 'timestamp': '2018-06-09T12:09:21.500',\n 'transaction_mroot': '0000000000000000000000000000000000000000000000000000000000000000',\n 'transactions': []}\n'''\n```\n\n#### Disassembler\n\n```python\nfrom octopus.platforms.EOS.disassembler import EosDisassembler\n\n# complete wasm module\nfile_name = \"examples/EOS/samples/eos_ping.wasm\"\n\n# read file\nwith open(file_name, 'rb') as f:\n raw = f.read()\n\n# just disassembly\ndisasm = EosDisassembler()\n\n# because we provide full module bytecode\n# we need to use disassemble_module()\n# otherwise just disassemble() is enough\ntext = disasm.disassemble_module(raw, r_format=\"text\")\nprint(text)\n# func 0\n# get_local 0\n# get_local 1\n# i32.const 32\n# call 12\n# i32.eqz\n# end\n# \n# func 1\n# get_local 0\n# i64.load 3, 0\n# get_local 0\n# i64.load 3, 8\n# call 6\n# end\n# \n# func 2\n# ...\n# end\n# \n# ...\n```\n\n#### ModuleAnalyzer\n\n```python\n\nfrom octopus.platforms.EOS.analyzer import EosAnalyzer\n\n# complete wasm module\nfile_name = \"examples/EOS/samples/eos_ping.wasm\"\n\nwith open(file_name, 'rb') as f:\n module_bytecode = f.read()\n\n# return list of functions instructions (list)\n# attributes analysis=True by default\nanalyzer = EosAnalyzer(module_bytecode)\n\n# show analyzer attributes\nprint(analyzer.func_prototypes)\n#[('action_data_size', '', 'i32', 'import'), ('eosio_assert', 'i32 i32', '', 'import'), ('eosio_exit', 'i32', '', 'import'), ('memcpy', 'i32 i32 i32', 'i32', 'import'), ('prints', 'i32', '', 'import'), ('read_action_data', 'i32 i32', 'i32', 'import'), ('require_auth2', 'i64 i64', '', 'import'), ('_ZeqRK11checksum256S1_', 'i32 i32', 'i32', 'export'), ('_ZN5eosio12require_authERKNS_16permission_levelE', 'i32', '', 'export'), ('apply', 'i64 i64 i64', '', 'export'), ('$func10', 'i32 i64', '', 'local'), ('$func11', 'i32 i32', 'i32', 'local'), ('memcmp', 'i32 i32 i32', 'i32', 'export'), ('malloc', 'i32', 'i32', 'export'), ('$func14', 'i32 i32', 'i32', 'local'), ('$func15', 'i32', 'i32', 'local'), ('free', 'i32', '', 'export'), ('$func17', '', '', 'local')]\nprint()\nprint(analyzer.exports)\n# [{'field_str': 'memory', 'kind': 2, 'index': 0}, {'field_str': '_ZeqRK11checksum256S1_', 'kind': 0, 'index': 7}, {'field_str': '_ZN5eosio12require_authERKNS_16permission_levelE', 'kind': 0, 'index': 8}, {'field_str': 'apply', 'kind': 0, 'index': 9}, {'field_str': 'memcmp', 'kind': 0, 'index': 12}, {'field_str': 'malloc', 'kind': 0, 'index': 13}, {'field_str': 'free', 'kind': 0, 'index': 16}]\nprint()\nprint(analyzer.imports_func)\n# [('env', 'action_data_size', 3), ('env', 'eosio_assert', 5), ('env', 'eosio_exit', 2), ('env', 'memcpy', 6), ('env', 'prints', 2), ('env', 'read_action_data', 4), ('env', 'require_auth2', 1)]\n```\n\n#### Control Flow Analysis\n\n```python\nfrom octopus.platforms.EOS.cfg import EosCFG\nfrom octopus.analysis.graph import CFGGraph\n\n# complete wasm module\nfile_name = \"examples/EOS/samples/eos_ping.wasm\"\n\n# read file\nwith open(file_name, 'rb') as f:\n raw = f.read()\n\n# create the cfg\ncfg = EosCFG(raw)\n\n# visualize\ngraph = CFGGraph(cfg)\ngraph.view_functions()\n```\n\n\n
\n
\n
\n
\n
\n
\n
\n\n#### Explorer\n\n```python\nfrom octopus.platforms.BTC.explorer import BitcoinExplorerRPC\n\nRPC_USER = 'test'\nRPC_PASSWORD = 'test'\nRPC_HOST = 'localhost'\n\nhost = '%s:%s@%s' % (RPC_USER, RPC_PASSWORD, RPC_HOST)\n\nexplorer = BitcoinExplorerRPC(host)\n\nexplorer.getbestblockhash()\n# '00000000000000000012085cfe8c79bcdacf81fbd82f6ab52c3cb3a454d4987c'\n\nexplorer.getblockcount()\n#550859\n```\n\n#### Disassembler\n\n```python\nfrom octopus.platforms.BTC.disassembler import BitcoinDisassembler\n\n# Witness Script\nfile_name = \"examples/BTC/witness_script.hex\"\n\n# read file\nwith open(file_name) as f:\n bytecode = f.read()\n\ndisasm = BitcoinDisassembler()\n\nprint(disasm.disassemble(bytecode, r_format='text'))\n# 0\n# OP_ROT\n# OP_ROT\n# 2\n# 0203f4d01d0b35588638631ebb7d46d8387fd1aeb3dbecfdd3faf7c056b023c833\n# 03aa6677e3ce1bd634f4f2e1cd60a60af002e1b30484d4d1611b183b16d391ee96\n# 03bf164811abb8c91ed39e58d4e307f86cb4e487c83f727a2c482bc71a0f96f1db\n# 3\n# OP_CHECKMULTISIG\n```\n\n
\n