
أداة تحليل أمان لوحدات WebAssembly (wasm) وعقود البلوكشين الذكية (BTC/ETH/NEO/EOS)
شكر جزيل لـ QuoScient لرعايتها لهذا المشروع.
أخطبوط هو إطار تحليل أمني لوحدات WebAssembly والعقود الذكية على سلاسل الكتل (Blockchain).
الهدف من أخطبوط هو توفير طريقة سهلة لتحليل وحدات WebAssembly مغلقة المصدر والبايت كود للعقود الذكية لفهم سلوكياتها الداخلية بشكل أعمق.
يدعم أخطبوط الأنواع التالية من البرامج/العقود الذكية:
✔️ مكتمل / ➕ قيد العمل / ✖️ مستقبلي / ⭕ غير قابل للتطبيق
أخطبوط مدعوم على لينكس (يفضل Ubuntu 16.04) ويتطلب Python >=3.5 (يفضل 3.6).
التبعيات:
sudo apt-get update && sudo apt-get install python-pip graphviz xdg-utils -y
- تثبيت Octopus:```
# Download Octopus
git clone https://github.com/pventuzelo/octopus
cd octopus
# Install Octopus library/CLI and its dependencies
python3 setup.py install
أو```
pip3 install octopus
- تشغيل الاختبارات```
# 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
حاوية Docker توفر مجموعة الأدوات متاحة على docker hub. في الطرفية، قم بتشغيل الأوامر التالية:``` docker pull smartbugs/octopus docker run -it smartbugs/octopus cd octopus python3 octopus_eth_evm.py -s -f examples/ETH/evm_bytecode/61EDCDf5bb737ADffE5043706e7C5bb1f1a56eEA.bytecode
## أدوات سطر الأوامر
* 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)
## أمثلة متعمقة باستخدام APIs
<details><summary>WebAssembly</summary>
<p>
#### مفكك الشفرة
تفكيك وحدة Wasm:```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
تفكيك bytecode wasm:```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>
#### تحليلات تعليمات الدوال```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>
وسيلة الإيضاح:
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>
#### تحويل IR (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 |
|---|
| المتصفح | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⭕ | |
| مفكك التجميع | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
| تحليل تدفق التحكم | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | |
| تحليل تدفق الاستدعاءات | ✖️ | ➕ | ✔️ | ✔️ | ➕ | ✔️ | |
| تحويل SSA | ✖️ | ✔️ | ➕ | ➕ | ✖️ | ✔️ | |
| التنفيذ الرمزي | ✖️ | ➕ | ➕ | ➕ | ✖️ | ➕ |
#### مفكك```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 (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)
#### مفكك
تفكيك وحدة Wasm:```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
تفكيك bytecode wasm:```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>
#### تحليلات تعليمات الدوال```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>
الأسطورة:
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/6916/332b97a2eb228b9a43dd7a13857b7e593353ebea1555d2d0efd38964ef902d20.png" height="400px"/>
</p>
#### تحويل IR (SSA)```python
# TODO
print(contract['script'])
#### مفكك الشفرة```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>
#### مستكشف```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>
#### تحليل تدفق المكالمات```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>
#### مستكشف```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>
يرجى العثور على الأمثلة في مجلد [examples](https://github.com/fuzzinglabs/octopus/blob/HEAD/examples).
## المنشورات والفيديوهات
* BLACKALPS 2018 [بحث الانعكاس والثغرات في العقود الذكية لإيثريوم](https://www.blackalps.ch/ba-18/talks.php#111)
* Devcon iv. [انعكاس العقود الذكية لإيثريوم لمعرفة ما وراء bytecode EVM](https://guidebook.com/guide/117233/event/21956134/)
* hack.lu 2018 [بحث الانعكاس والثغرات في العقود الذكية لإيثريوم](https://2018.hack.lu/talks/#Reversing+and+Vulnerability+research+of+Ethereum+Smart+Contracts)
* ToorCon XX - 2018 [انعكاس العقود الذكية لإيثريوم (مقدمة)](https://frab.toorcon.net/en/toorcon20/public/events/97)
* ToorCon XX - 2018 [تشريح وحدة WebAssembly](https://frab.toorcon.net/en/toorcon20/public/events/92)
* REcon Montreal 2018: [هندسة عكسية للعقود الذكية للبلوكشين](https://recon.cx/2018/montreal/schedule/system/event_attachments/attachments/000/000/053/original/RECON-MTL-2018-Reversing_blockchains_smart_contracts.pdf)
## المؤلفون
- **Patrick Ventuzelo** - *المنشئ* - [@Pat_Ventuzelo](https://twitter.com/pat_ventuzelo)
انظر أيضًا قائمة [المساهمين](https://github.com/quoscient/octopus/contributors) الذين شاركوا في هذا المشروع.
## الترخيص
هذا المشروع مرخص بموجب رخصة MIT - راجع ملف [LICENSE](https://github.com/fuzzinglabs/octopus/blob/HEAD/LICENSE) للتفاصيل
## الإقرارات
الراعي:
* [QuoScient](https://www.quoscient.io/)
مستوحى من:
* [Manticore](https://github.com/trailofbits/manticore)
* [Mythril](https://github.com/ConsenSys/mythril)
* [Rattle](https://github.com/trailofbits/rattle)
* [ethersplay](https://github.com/trailofbits/ethersplay)
* ...
# التدريبات والاتصال
Patrick Ventuzelo - [@pat_ventuzelo](https://twitter.com/pat_ventuzelo)
* باحث أمني مستقل / مدرب.
* دورات مجانية عبر الإنترنت: [هنا](https://academy.fuzzinglabs.com/)