* Better plugin context management. Example UseDef logging plugin for evm * Example plugin to log use-def * Better plugin name checking hints * Better plugin name checking hints2 * Fix uninititalize-plugins (found via the warning) * Remove redundant variables in example * Typo * Better warning print (class name) * better safety check + context fix * better variabke naming * Update manticore.py
111 lines
3.0 KiB
Python
111 lines
3.0 KiB
Python
from manticore.ethereum import ManticoreEVM, Plugin
|
|
from manticore.core.smtlib import solver
|
|
from manticore.core.smtlib.visitors import arithmetic_simplifier, pretty_print, constant_folder
|
|
################ Script #######################
|
|
|
|
m = ManticoreEVM()
|
|
m.verbosity(0)
|
|
#And now make the contract account to analyze
|
|
# cat | solc --bin
|
|
source_code = '''
|
|
pragma solidity ^0.4;
|
|
contract C {
|
|
uint c;
|
|
bool enabled;
|
|
bool i;
|
|
function C() public {
|
|
c =0;
|
|
enabled = false;
|
|
i = false;
|
|
|
|
}
|
|
function f1() public {
|
|
c+=1;
|
|
}
|
|
function f2() public {
|
|
if(c>100)
|
|
enabled=true;
|
|
|
|
}
|
|
function f3() public{
|
|
if (!enabled)
|
|
return;
|
|
i = true;
|
|
|
|
}
|
|
}
|
|
'''
|
|
print source_code
|
|
class EVMUseDef(Plugin):
|
|
def _get_concrete_hex(self, state, array):
|
|
r = ''
|
|
for i in array:
|
|
l = state.solve_n(i, 2)
|
|
if len(l) == 1:
|
|
r += '%02x'%l[0]
|
|
if len(r) != 8:
|
|
return
|
|
return r
|
|
|
|
|
|
def did_evm_write_storage_callback(self, state, offset, value, **kwargs):
|
|
m = self.manticore
|
|
world = state.platform
|
|
tx = world.all_transactions[-1]
|
|
md = m.get_metadata(tx.address)
|
|
|
|
r = self._get_concrete_hex(state, tx.data[0:4])
|
|
if r is None:
|
|
return
|
|
|
|
|
|
offsets = state.solve_n(offset, 3000)
|
|
with self.locked_context('storage_writes', dict) as storage_writes:
|
|
contract_function = (md.name, md.get_func_name(r))
|
|
if contract_function not in storage_writes:
|
|
storage_writes[contract_function] = set()
|
|
for off in offsets:
|
|
storage_writes[contract_function].add(off)
|
|
|
|
def did_evm_read_storage_callback(self, state, offset, value, **kwargs):
|
|
m = self.manticore
|
|
world = state.platform
|
|
tx = world.all_transactions[-1]
|
|
md = m.get_metadata(tx.address)
|
|
|
|
r = self._get_concrete_hex(state, tx.data[0:4])
|
|
if r is None:
|
|
return
|
|
|
|
offsets = state.solve_n(offset, 3000)
|
|
with self.locked_context('storage_reads', dict) as storage_reads:
|
|
contract_function = (md.name, md.get_func_name(r))
|
|
if contract_function not in storage_reads:
|
|
storage_reads[contract_function] = set()
|
|
for off in offsets:
|
|
storage_reads[contract_function].add(off)
|
|
|
|
#Initialize accounts
|
|
user_account = m.create_account(balance=1000)
|
|
contract_account = m.solidity_create_contract(source_code, owner=user_account)
|
|
p = EVMUseDef()
|
|
m.register_plugin(p)
|
|
|
|
|
|
symbolic_data = m.make_symbolic_buffer(320)
|
|
symbolic_value = m.make_symbolic_value()
|
|
m.transaction( caller=user_account,
|
|
address=contract_account,
|
|
value=symbolic_value,
|
|
data=symbolic_data
|
|
)
|
|
print "READS", p.context['storage_reads']
|
|
print "WRITES", p.context['storage_writes']
|
|
|
|
print "It makes no sense to try f3() after 1 tx"
|
|
|
|
m.finalize()
|
|
print "[+] Look for results in %s"% m.workspace
|
|
|
|
|