
Sicherheitsanalyse-Tool für WebAssembly-Module (wasm) und Blockchain-Smart-Contracts (BTC/ETH/NEO/EOS)
Großes Dankeschön an QuoScient für die Finanzierung dieses Projekts.
Octopus ist ein Sicherheitsanalyse-Framework für WebAssembly-Module und Blockchain-Smart-Contracts.
Der Zweck von Octopus ist es, eine einfache Möglichkeit zur Analyse von Closed-Source-WebAssembly-Modulen und Smart-Contract-Bytecode zu bieten, um deren internes Verhalten besser zu verstehen.
Octopus unterstützt die folgenden Arten von Programmen/Smart-Contracts:
✔️ DONE / ➕ WIP / ✖️ TODO / ⭕ N/A
Octopus wird unter Linux (idealerweise Ubuntu 16.04) unterstützt und benötigt Python >=3.5 (idealerweise 3.6).
Abhängigkeiten:
sudo apt-get update && sudo apt-get install python-pip graphviz xdg-utils -y
- Installiere Octopus:```
# Download Octopus
git clone https://github.com/pventuzelo/octopus
cd octopus
# Install Octopus library/CLI and its dependencies
python3 setup.py install
oder```
pip3 install octopus
- Tests ausführen```
# Run tests for all platforms (disassembly, CFG, ...)
./run_tests.sh
# Run tests that require internet access (explorer tests)
./run_explorer_tests.sh
# Run tests for only one platforms
# {btc, eth, eos, neo, wasm}_run_tests.sh
cd octopus/tests/
./wasm_run_tests.sh
Ein Docker-Container, der den Werkzeugsatz bereitstellt, ist unter Docker Hub verfügbar. Führen Sie in einem Terminal die folgenden Befehle aus:``` docker pull smartbugs/octopus docker run -it smartbugs/octopus cd octopus python3 octopus_eth_evm.py -s -f examples/ETH/evm_bytecode/61EDCDf5bb737ADffE5043706e7C5bb1f1a56eEA.bytecode
## Kommandozeilenwerkzeuge
* WebAssembly: [octopus_wasm.py](https://github.com/fuzzinglabs/octopus/blob/HEAD/octopus_wasm.py)
* Ethereum (EVM): [octopus_eth_evm.py](https://github.com/fuzzinglabs/octopus/blob/HEAD/octopus_eth_evm.py)
## Tiefgehende Beispiele mit APIs
<details><summary>WebAssembly</summary>
<p>
#### Disassembler
Disassemblierung eines Wasm-Moduls:```python
from octopus.arch.wasm.disassembler import WasmDisassembler
FILE = "examples/wasm/samples/helloworld.wasm"
with open(FILE, 'rb') as f:
module_bytecode = f.read()
disasm = WasmDisassembler()
# return list of functions instructions (list)
print(disasm.disassemble_module(module_bytecode))
#[[<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904278>,<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904f60>,<octopus.arch.wasm.instruction.WasmInstruction at 0x7f85e4904ef0>]]
print()
# return text of functions code
print(disasm.disassemble_module(module_bytecode, r_format='text'))
# func 0
# i32.const 0
# call 0
# end
Disassemblierung des wasm-Bytecodes:```python from octopus.arch.wasm.disassembler import WasmDisassembler
bytecode = b'\x02\x7fA\x18\x10\x1cA\x00\x0f\x0b'
disasm = WasmDisassembler(bytecode)
print(disasm.disassemble())
#[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904eb8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>] print() print(disasm.disassemble(r_format='reverse'))
#{0: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>, 1: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904240>, 2: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, 3: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, 4: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, 5: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>} print() print(disasm.disassemble(r_format='text'))
#### ModuleAnalyzer```python
from octopus.arch.wasm.analyzer import WasmModuleAnalyzer
FILE = "examples/wasm/samples/hello_wasm_studio.wasm"
with open(FILE, 'rb') as f:
module_bytecode = f.read()
# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = WasmModuleAnalyzer(module_bytecode)
# show analyzer attributes
print(analyzer.func_prototypes)
# [('putc_js', 'i32', ''),
# ('__syscall0', 'i32', 'i32'),
# ('__syscall3', 'i32 i32 i32 i32', 'i32'),
# ('__syscall1', 'i32 i32', 'i32'),
# ('__syscall5', 'i32 i32 i32 i32 i32 i32', 'i32'),
# ('__syscall4', 'i32 i32 i32 i32 i32', 'i32'),
# ('$func6', '', ''),
# ('main', '', 'i32'),
# ('writev_c', 'i32 i32 i32', 'i32'),
# ('$func9', '', 'i32'),
# ('$func10', 'i32', 'i32'),
# ('$func11', 'i32', 'i32'),
# ('$func12', 'i32', ''),
# ('$func13', 'i32', 'i32'),
# ('$func14', 'i32 i32 i32 i32', 'i32'),
# ('$func15', 'i32 i32', 'i32'),
# ('$func16', 'i32 i32', 'i32'),
# ('$func17', 'i32', 'i32'),
# ('$func18', 'i32', 'i32'),
# ('$func19', 'i32', 'i32'),
# ('$func20', 'i32 i32 i32', 'i32'),
# ('$func21', 'i32 i32 i32', 'i32'),
# ('$func22', 'i32 i64 i32', 'i64'),
# ('$func23', 'i32 i32 i32', 'i32'),
# ('$func24', 'i32', 'i32'),
# ('$func25', 'i32 i32 i32 i32', '')]
print()
print(analyzer.contains_emscripten_syscalls())
#[('__syscall0', 'restart_syscall'),
# ('__syscall3', 'read'),
# ('__syscall1', 'exit'),
# ('__syscall5', 'open'),
# ('__syscall4', 'write')]
from octopus.arch.wasm.cfg import WasmCFG
file_name = "examples/wasm/samples/fib.wasm"
with open(file_name, 'rb') as f: raw = f.read()
cfg = WasmCFG(raw)
cfg.visualize()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/a317892fc1e0ce1939535b5f1e0fd00188634ec14f21e7f5eee950e4c2f92206.png" height="400px"/>
</p>
#### Analyse der Funktionsanweisungen```python
from octopus.arch.wasm.cfg import WasmCFG
# complete wasm module
file_name = "examples/wasm/samples/hello_wasm_studio.wasm"
# read file
with open(file_name, 'rb') as f:
raw = f.read()
# create the cfg
cfg = WasmCFG(raw)
# visualization
cfg.visualize_instrs_per_funcs()
from octopus.arch.wasm.cfg import WasmCFG
file_name = "examples/wasm/samples/hello_wasm_studio.wasm"
with open(file_name, 'rb') as f: raw = f.read()
cfg = WasmCFG(raw)
cfg.visualize_call_flow()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/62fcb93f3dcec6856fdcb2618024b5e72da74112e8277d6113c9e2e008c5ecf6.png" height="400px"/>
</p>
Legende:
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>
#### IR-Konvertierung (SSA)```python
from octopus.arch.wasm.emulator import WasmSSAEmulatorEngine
# complete wasm module
file_name = "examples/wasm/samples/fib.wasm"
# read file
with open(file_name, 'rb') as f:
raw = f.read()
# run the emulator for SSA
emul = WasmSSAEmulatorEngine(raw)
emul.emulate_one_function('fib')
# or emul.emulate_functions(['fib'])
# or emul.emulate_functions() # emulate all the function
# visualization of the cfg with SSA
emul.cfg.visualize(ssa=True)
from octopus.platforms.ETH.explorer import EthereumInfuraExplorer from octopus.platforms.ETH.explorer import INFURA_ROPSTEN
KEY_API = "bHuaQhX91nkQBac8Wtgj"
explorer = EthereumInfuraExplorer(KEY_API, network=INFURA_ROPSTEN)
block_number = explorer.eth_blockNumber() print(block_number)
addr = "0x3c6B10a5239B1a8A27398583F49771485382818F" code = explorer.eth_getCode(addr) print(code)
from octopus.platforms.ETH.explorer import EthereumInfuraExplorer from octopus.platforms.ETH.explorer import INFURA_KOVAN
explorer = EthereumInfuraExplorer("bHuaQhX91nkQBac8Wtgj", network=INFURA_KOVAN)
block_number = explorer.eth_blockNumber() print('blockNumber = %d' % block_number)
addr = "0x1120e596b173d953ba52ce262f73ce3734b0e40e" code = explorer.eth_getCode(addr) print() print(code)
from octopus.platforms.NEO.explorer import NeoExplorerRPC
explorer = NeoExplorerRPC(host='seed2.neo.org')
print(explorer.getblockcount())
contract = explorer.getcontractstate("d3cce84d0800172d09c88ccad61130611bd047a4") print(contract)
| BTC | ETH (EVM) | ETH (WASM) | EOS | NEO | WASM |
|---|
| Explorer | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⭕ | |
| Disassembler | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
| Kontrollflussanalyse | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
| Aufrufflussanalyse | ✖️ | ➕ | ✔️ | ✔️ | ➕ | ✔️ | |
| IR-Konvertierung (SSA) | ✖️ | ✔️ | ➕ | ➕ | ✖️ | ✔️ | |
| Symbolische Ausführung | ✖️ | ➕ | ➕ | ➕ | ✖️ | ➕ |
#### Disassembler```python
from octopus.platforms.ETH.disassembler import EthereumDisassembler
# smart contract bytecode
bytecode_hex = "60606040526000357c0100000000000000000000000000000000000000000000000000000000900480635fd8c7101461004f578063c0e317fb1461005e578063f8b2cb4f1461006d5761004d565b005b61005c6004805050610099565b005b61006b600480505061013e565b005b610083600480803590602001909190505061017d565b6040518082815260200191505060405180910390f35b3373ffffffffffffffffffffffffffffffffffffffff16611111600060005060003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060005054604051809050600060405180830381858888f19350505050151561010657610002565b6000600060005060003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600050819055505b565b34600060005060003373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828282505401925050819055505b565b6000600060005060008373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000505490506101b6565b91905056"
disasm = EthereumDisassembler()
disasm.disassemble(bytecode_hex)
# disassemble bytecode into a list of EthereumInstruction
# attributes r_format='list' by default
print(disasm.disassemble(bytecode_hex))
#[<octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4add5c0>, <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8588>, <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8c50>]
print()
print(disasm.disassemble(bytecode_hex, r_format='reverse'))
# {0: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8160>, ..., 229: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad8630>, 230: <octopus.platforms.ETH.instruction.EthereumInstruction object at 0x7f85d4ad87b8>}
print()
print(disasm.disassemble(bytecode_hex,r_format='text'))
# PUSH1 0x60
# PUSH1 0x40
# MSTORE
# PUSH1 0x0
# CALLDATALOAD
# PUSH29 0x100000000000000000000000000000000000000000000000000000000
# SWAP1
# DIV
# DUP1
# PUSH4 0x5fd8c710
# EQ
# PUSH2 0x4f
# JUMPI
# ...
# SWAP2
# SWAP1
# POP
# JUMP
from octopus.analysis.graph import CFGGraph from octopus.platforms.ETH.cfg import EthereumCFG
file_name = "examples/ETH/evm_bytecode/Zeppelin_Hello_ethernaut0.bytecode"
with open(file_name) as f: bytecode_hex = f.read()
cfg = EthereumCFG(bytecode_hex)
graph = CFGGraph(cfg) graph.view()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/f1ab0983ab68ff22aa4d97893fa25466cf220562fecdffebd6de1333877a8b57.png"/>
</p>
#### IR-Konvertierung (SSA)```python
# The conversion to SSA is already done by the SSAEmulator
# when the CFG is reconstruct
# by default you have just to visualize it
from octopus.platforms.ETH.cfg import EthereumCFG
# ethernaut0 bytecode
file_name = "examples/ETH/evm_bytecode/Zeppelin_Hello_ethernaut0.bytecode"
# read file
with open(file_name) as f:
bytecode_hex = f.read()
# create the CFG
cfg = EthereumCFG(bytecode_hex)
# SSA visualization
cfg.visualize(ssa=True)
#### Disassembler
Disassemblierung eines Wasm-Moduls:```python
from octopus.platforms.ETH.disassembler import EthereumDisassembler
FILE = "examples/ETH/wasm/helloworld_kovan.bytecode"
with open(FILE, 'r') as f:
module_bytecode = f.read()
disasm = EthereumDisassembler(arch='wasm')
# return list of functions instructions (list)
print(disasm.disassemble_module(module_bytecode))
#[[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa898>], [<octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa7b8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa780>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa748>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa6d8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7efc0ceaa710>]]
print()
# return text of functions code
print(disasm.disassemble_module(module_bytecode, r_format='text'))
# func 0
# end
#
# func 1
# call 1
# i32.const 1036
# i32.const 232
# call 0
# end
Disassemblierung des wasm-Bytecodes:```python from octopus.platforms.ETH.disassembler import EthereumDisassembler
bytecode = b'\x02\x7fA\x18\x10\x1cA\x00\x0f\x0b'
disasm = EthereumDisassembler(bytecode, arch='wasm')
print(disasm.disassemble())
#[<octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904eb8>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>] print() print(disasm.disassemble(r_format='reverse'))
#{0: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4901048>, 1: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904240>, 2: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904f60>, 3: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904ef0>, 4: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904278>, 5: <octopus.arch.wasm.instruction.WasmInstruction object at 0x7f85e4904390>} print() print(disasm.disassemble(r_format='text'))
#### ModuleAnalyzer```python
from octopus.arch.wasm.analyzer import WasmModuleAnalyzer
FILE = "examples/ETH/wasm/helloworld_kovan.bytecode"
with open(FILE, 'r') as f:
module_bytecode = f.read()
# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = WasmModuleAnalyzer(module_bytecode)
# show analyzer attributes
print(analyzer.func_prototypes)
# [('ret', 'i32 i32', '', 'import'), ('$func1', '', '', 'local'), ('call', '', '', 'export')]
print()
print(analyzer.exports)
# [{'field_str': 'call', 'kind': 0, 'index': 2}]
print()
print(analyzer.imports_func)
# [('env', 'ret', 1)]
print()
print(analyzer.datas)
# [{'data': b'Hello world', 'index': 0, 'offset': None, 'size': 11},
# {'data': b'\x00asm\x01\x00\x00\x00\x01\t\x02`\x00\x00`\x02\x7f\x7f\x00\x02\x1a\x02\x03env\x03ret\x00\x01\x03env\x06memory\x02\x01\x02\x10\x03\x03\x02\x00\x00\x04\x05\x01p\x01\x01\x01\x05\x01\x00\x06\x01\x00\x07\x08\x01\x04call\x00\x01\n\x12\x02\x05\x00\x10\x02\x00\x0b\n\x00A\x80\x08A\x0b\x10\x00\x00\x0b\x0b\x12\x01\x00A\x80\x08\x0b\x0bHello world\x00\x0b\x07linking\x03\x01\x0b\x00f\x04name\x01_\x06\x00\x03ret\x01\x05panic\x02\x04call\x03/_ZN14pwasm_ethereum3ext3ret17h604d8098d1686c80E\x04\x06deploy\x05\x11rust_begin_unwind',
# 'index': 0,
# 'offset': None,
# 'size': 232}]
from octopus.platforms.ETH.cfg import EthereumCFG
file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"
with open(file_name) as f: bytecode_hex = f.read()
cfg = EthereumCFG(bytecode_hex, arch='wasm') cfg.visualize()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/7a8e6cc4ce71f467e09100a231e1916c4101a56094a5883bd42534c419ba0dc2.png" height="400px"/>
</p>
#### Analyse der Funktionsanweisungen```python
from octopus.platforms.ETH.cfg import EthereumCFG
# HelloWorld on Kovan Parity Network
file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"
# read file
with open(file_name) as f:
bytecode_hex = f.read()
# create the CFG
cfg = EthereumCFG(bytecode_hex, arch='wasm')
# visualization
cfg.visualize_instrs_per_funcs()
from octopus.platforms.ETH.cfg import EthereumCFG
file_name = "examples/ETH/wasm/helloworld_kovan.bytecode"
with open(file_name) as f: bytecode_hex = f.read()
cfg = EthereumCFG(bytecode_hex, arch='wasm')
cfg.visualize_call_flow()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/a3b69354067c4b7c707fc60c7c844688a30bbb6dd4de54528545554148e83d0e.png" height="400px"/>
</p>
Legende:
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>
#### IR-Konvertierung (SSA)```python
# TODO
print(contract['script'])
#### Disassembler```python
from octopus.platforms.NEO.disassembler import NeoDisassembler
# lock contract
file_name = "examples/NEO/samples/Lock.bytecode"
# read file
with open(file_name) as f:
bytecode = f.read()
disasm = NeoDisassembler()
print(disasm.disassemble(bytecode, r_format='text'))
# PUSH6
# NEWARRAY
# TOALTSTACK
# FROMALTSTACK
# DUP
# TOALTSTACK
# PUSH0
# PUSH2
# ROLL
# SETITEM
# FROMALTSTACK
# ....
# PICKITEM
# NOP
# FROMALTSTACK
# DROP
# RET
from octopus.analysis.graph import CFGGraph from octopus.platforms.NEO.cfg import NeoCFG
file_name = "examples/NEO/samples/Lock.bytecode"
with open(file_name) as f: raw = f.read()
cfg = NeoCFG(raw)
graph = CFGGraph(cfg, filename="Lock_cfg") graph.view_functions()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/049c210aab8b977951cb7236f6f5d3361f0dd4be330df21392543b1e6538f5de.png"/>
</p>
</p>
</details>
<details><summary>EOS</summary>
<p>
#### Explorer
``````python
from octopus.platforms.EOS.explorer import EosExplorer
host = "api.cypherglass.com"
# by defaul the port is 8888
explo = EosExplorer(host=host)
# get info about the node
explo.get_info()
'''
{'block_cpu_limit': 180289,
'block_net_limit': 1045680,
'chain_id': 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
'head_block_id': '018d6e2bcf6295126cd74cf694b5cca3529eefc42b334b394ef87c3a43876739',
'head_block_num': 26045995,
'head_block_producer': 'eosswedenorg',
'head_block_time': '2018-11-09T14:11:29.500',
'last_irreversible_block_id': '018d6cdcff78bbd9f25c605b02fb67c47a337ece78ddcf73089cee4bf6a410ee',
'last_irreversible_block_num': 26045660,
'server_version': 'c71d2245',
'server_version_string': 'mainnet-1.3.0',
'virtual_block_cpu_limit': 38092879,
'virtual_block_net_limit': 1048576000}
'''
explo.get_block(1337)
'''
{'action_mroot': 'bcb9763baa3bbf98ed36379b4be0ecb2d9cd21c75df01729c63b2b021001c10c',
'block_extensions': [],
'block_num': 1337,
'confirmed': 0,
'header_extensions': [],
'id': '00000539d17a03af7126e073be4c4d99a72b7f58793cf2c87b9bfd41b6c711fb',
'new_producers': None,
'previous': '00000538b374c1cbfaeed7253ad3075ddc72a28f0a0515301fc1bbed675f2316',
'producer': 'eosio',
'producer_signature': 'SIG_K1_K5jWf36t6j454Hb2fGuV37YTwMTvuQ51ZPBtpru8Ud2axtMTEauWyvtpJuTpnvqzReUndDgEDXvoeEP4jdj2bpnYKBt6g2',
'ref_block_prefix': 1944069745,
'schedule_version': 0,
'timestamp': '2018-06-09T12:09:21.500',
'transaction_mroot': '0000000000000000000000000000000000000000000000000000000000000000',
'transactions': []}
'''
from octopus.platforms.EOS.disassembler import EosDisassembler
file_name = "examples/EOS/samples/eos_ping.wasm"
with open(file_name, 'rb') as f: raw = f.read()
disasm = EosDisassembler()
text = disasm.disassemble_module(raw, r_format="text") print(text)
#### ModuleAnalyzer```python
from octopus.platforms.EOS.analyzer import EosAnalyzer
# complete wasm module
file_name = "examples/EOS/samples/eos_ping.wasm"
with open(file_name, 'rb') as f:
module_bytecode = f.read()
# return list of functions instructions (list)
# attributes analysis=True by default
analyzer = EosAnalyzer(module_bytecode)
# show analyzer attributes
print(analyzer.func_prototypes)
#[('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')]
print()
print(analyzer.exports)
# [{'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}]
print()
print(analyzer.imports_func)
# [('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)]
from octopus.platforms.EOS.cfg import EosCFG from octopus.analysis.graph import CFGGraph
file_name = "examples/EOS/samples/eos_ping.wasm"
with open(file_name, 'rb') as f: raw = f.read()
cfg = EosCFG(raw)
graph = CFGGraph(cfg) graph.view_functions()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/18a84dcc6e2fd330c93192f2c9850ddacec3981e2d3f1f0c6eae676791ad0bec.png"/>
</p>
#### Anrufablaufanalyse```python
from octopus.platforms.EOS.cfg import EosCFG
# complete wasm module
file_name = "examples/EOS/samples/eos_ping.wasm"
# read file
with open(file_name, 'rb') as f:
raw = f.read()
# create the cfg
cfg = EosCFG(raw)
# visualize
cfg.visualize_call_flow()
from octopus.platforms.EOS.cfg import EosCFG
file_name = "examples/EOS/samples/eos_ping.wasm"
with open(file_name, 'rb') as f: raw = f.read()
cfg = EosCFG(raw)
cfg.visualize_instrs_per_funcs()
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/c5b52a71702f65f6edc5be98fa1683679313c3be85aaf86202d68c5bad9205f9.png"/>
</p>
</p>
</details>
<details><summary>Bitcoin</summary>
<p>
#### Explorer```python
from octopus.platforms.BTC.explorer import BitcoinExplorerRPC
RPC_USER = 'test'
RPC_PASSWORD = 'test'
RPC_HOST = 'localhost'
host = '%s:%s@%s' % (RPC_USER, RPC_PASSWORD, RPC_HOST)
explorer = BitcoinExplorerRPC(host)
explorer.getbestblockhash()
# '00000000000000000012085cfe8c79bcdacf81fbd82f6ab52c3cb3a454d4987c'
explorer.getblockcount()
#550859
from octopus.platforms.BTC.disassembler import BitcoinDisassembler
file_name = "examples/BTC/witness_script.hex"
with open(file_name) as f: bytecode = f.read()
disasm = BitcoinDisassembler()
print(disasm.disassemble(bytecode, r_format='text'))
</p>
</details>
Beispiele finden Sie im Ordner [examples](https://github.com/fuzzinglabs/octopus/blob/HEAD/examples).
## Veröffentlichungen und Videos
* BLACKALPS 2018 [Reverse Engineering und Sicherheitsforschung von Ethereum Smart Contracts](https://www.blackalps.ch/ba-18/talks.php#111)
* Devcon iv. [Reverse Engineering von Ethereum Smart Contracts: Was hinter dem EVM-Bytecode steckt](https://guidebook.com/guide/117233/event/21956134/)
* hack.lu 2018 [Reverse Engineering und Sicherheitsforschung von Ethereum Smart Contracts](https://2018.hack.lu/talks/#Reversing+and+Vulnerability+research+of+Ethereum+Smart+Contracts)
* ToorCon XX - 2018 [Reverse Engineering von Ethereum Smart Contracts (Einführung)](https://frab.toorcon.net/en/toorcon20/public/events/97)
* ToorCon XX - 2018 [Analyse von WebAssembly-Modulen](https://frab.toorcon.net/en/toorcon20/public/events/92)
* REcon Montreal 2018: [Reverse Engineering von Blockchain Smart Contracts](https://recon.cx/2018/montreal/schedule/system/event_attachments/attachments/000/000/053/original/RECON-MTL-2018-Reversing_blockchains_smart_contracts.pdf)
## Autoren
**Patrick Ventuzelo** - *Ersteller* - [@Pat_Ventuzelo](https://twitter.com/pat_ventuzelo)
Siehe auch die Liste der [Mitwirkenden](https://github.com/quoscient/octopus/contributors), die an diesem Projekt teilgenommen haben.
## Lizenz
Dieses Projekt ist unter der MIT-Lizenz lizenziert – siehe die Datei [LICENSE](https://github.com/fuzzinglabs/octopus/blob/HEAD/LICENSE) für Details
## Danksagungen
Sponsor:
* [QuoScient](https://www.quoscient.io/)
Inspiriert von:
* [Manticore](https://github.com/trailofbits/manticore)
* [Mythril](https://github.com/ConsenSys/mythril)
* [Rattle](https://github.com/trailofbits/rattle)
* [ethersplay](https://github.com/trailofbits/ethersplay)
* ...
# Schulungen & Kontakt
Patrick Ventuzelo - [@pat_ventuzelo](https://twitter.com/pat_ventuzelo)
* Unabhängiger Sicherheitsforscher / Trainer.
* Kostenlose Online-Kurse: [hier](https://academy.fuzzinglabs.com/)