* WIP New Policy class * WIP pubsub * Update Signal tests * EVM support - Wip * EVM support - dependencies fixed * EVM support - fix decree merge * fix decode instrucion event * Fix small bugs in evm opcodes (too many arguments + wrong LOG name) (#380) Fix wrong call parameters + typo * Fix Create/Call * Fix depth * Default fixed point in arithmetic simplifier * small fixes from github comments * Fix event decode_instruction signature * wip wip * Auto tests for evm * New EVM tests * Ran 9556 FAILED (failures=166, errors=8, skipped=62) * Fix some arithmetic instructions * Ran 9556 FAILED (failures=136, errors=8, skipped=62) * More instructions - Optimizing symbolic memory * Added gas to opcodes description - FIX DELEGATECALL POPS * Add wip wallet example * The tests * Solidity constructors need argument after bytecode * Simple integer overflow working * Good merge * Good good merge * WIP manticore refactor * Fix default old-style initial state * context now working * Fix context serialization * Fix test models. Can not set a state constraints * typo * A few typos (constraints setter) and use of public properties in internal methods * Fix init wallet example * State __init__ needs to initialize platform constraints * Internal methods use internal properties * Better attack modeling * Better example layout * Storage backup on CALL is now faster .. and correct * Add LOG support * Minimal SE test * Added examples * Send ether bugfix * EVM: Fix wrong balance destination on CALL + decrease caller balance on CREATE * New balance management * Trying to maintain known hashes * Known hash concretization policy * CALLDATA max size bugfix * Minimal SE example * Remove evm tests * add -> enqueue * @m.init * Fix workspace url * Some test skipped * Ad Fixme to platform specific stuff in State * add -> enqueue * Enqueue created state * Fix m.init Use a messy hack to adhere to the spec (callback func receive 1 state argument) * Add _coverage_file ivar to Manticore * Fix symbolic files * remove extra enqueue * Fixing __main__ * comments * Fix visitors oddity * setup merged * remove duplicates and add pysha3 * Remove EVMTests import * Refactor platform specific code out of ManticoreOutput (#505) * Initial moving work * Clean * Make linux.generate_workspace_files work * Fix * clean * Add test * Test workspace for platform files * Skip EVM cpu pretty print * Remove bad import * Fix coverage.py for testing * Clean comment * Comment hack * Print evm cpu * pretty print evm world instead of platform * delet old scripts/examples * delet old tests * Remove z3 install script * Array.max_size can be None, include check for that * Rm unused _symbolic_files add_symbolic_files was moved to linux, so this is not needed * Rm unused args * Import evm * Rm dup function * Rm stray prints * Add docs for new classmethod apis * minimal * minimal example * fix minimal * Fair symbolic SHA3 handling * Simple mapping example * coverage example * fix tests * fix minimal * Some eko fixes * New SETH * integer_overflow refactored * Fixing the examples * init_bytecode -> init ' * Concrete reentrancy exampole * concrete reentrancy selfdestruct * Update minimal.py * It's a new Minimal * Integer overflow example * New minimal * minimal fix * Examples last minute fixes * Remove debug print * add plugin.py * Fixing event subscription * remove temp params * Remove param * Update uncovered will_exec callback prototype * Clean up debug output * Automatically generated intruction tests * Uninplemented instruction test removed * Unused concretization policy removed * Fixes enabling default bplugins * solc from PATH * Removed unused import * Logger name updated
249 lines
11 KiB
Python
249 lines
11 KiB
Python
from pprint import pformat
|
|
from cStringIO import StringIO
|
|
|
|
def pretty(value, htchar=' ', lfchar='\n', indent=0, width=100):
|
|
nlch = lfchar + htchar * (indent + 1)
|
|
if type(value) is dict:
|
|
items = [
|
|
nlch + repr(key) + ': ' + pretty(value[key], htchar, lfchar, indent + 1, width)
|
|
for key in value
|
|
]
|
|
return '{%s}' % (','.join(items) + lfchar + htchar * indent)
|
|
elif type(value) is list:
|
|
items = [
|
|
nlch + pretty(item, htchar, lfchar, indent + 1, width)
|
|
for item in value
|
|
]
|
|
return '[%s]' % (','.join(items) + lfchar + htchar * indent)
|
|
elif type(value) is tuple:
|
|
items = [
|
|
nlch + pretty(item, htchar, lfchar, indent + 1, width)
|
|
for item in value
|
|
]
|
|
return '(%s)' % (','.join(items) + lfchar + htchar * indent)
|
|
elif type(value) in (str, unicode):
|
|
if len(value) ==0:
|
|
return repr(value)
|
|
|
|
if width is not None and isinstance(value, str):
|
|
width = width - indent
|
|
width = max(1, width)
|
|
o = []
|
|
for pos in range(0, len(value), width):
|
|
o.append(repr(value[pos: pos+width]) )
|
|
return ('\\' + lfchar + htchar * indent).join(o)
|
|
return repr(value)
|
|
|
|
else:
|
|
return repr(value)
|
|
pprint = pretty
|
|
pp = pretty
|
|
def spprint(x, indent=0, width=None,**kwargs):
|
|
if width is not None and isinstance(x, str):
|
|
o = ''
|
|
for pos in range(0, len(x), width):
|
|
o += ' '*indent + repr(x[pos: pos+width]) + '\\'
|
|
return o
|
|
x = pformat(x, indent=0)
|
|
return (('\n'+' '*indent)).join(x.split('\n'))
|
|
|
|
def i(x):
|
|
if isinstance(x, (int, long)):
|
|
return x
|
|
assert isinstance(x, (str, unicode))
|
|
if not x.startswith('0x'):
|
|
x = '0x' + x
|
|
return long(x, 0)
|
|
def gen_test(testcase, testname, skip):
|
|
output = ''
|
|
if skip:
|
|
output += ''' @unittest.skip('Gas or performance related')\n'''
|
|
|
|
output += ' def test_%s(self):\n'% (os.path.split(testname)[1].replace('-','_'))
|
|
header = {}
|
|
env = testcase['env']
|
|
for key in env:
|
|
if key.startswith('previous'):
|
|
_key = str(key[8:].lower())
|
|
else:
|
|
_key = str(key[7:].lower())
|
|
try:
|
|
header[_key] = i(env[key])
|
|
except:
|
|
print "XXXXXX" , key, env[key]
|
|
output += ' header =' + pprint (header, indent=18) +'\n'
|
|
|
|
pre = testcase['pre']
|
|
world = {}
|
|
for address in pre.keys():
|
|
iaddress = i(address)
|
|
world[iaddress] = {}
|
|
world[iaddress]['code'] = pre[address][u'code'][2:].decode('hex')
|
|
world[iaddress]['nonce'] = i(pre[address][u'nonce'])
|
|
world[iaddress]['balance'] = i(pre[address][u'balance'])
|
|
world[iaddress]['storage'] = {}
|
|
for key, value in pre[address][u'storage'].items():
|
|
world[iaddress]['storage'][key] = value
|
|
|
|
#output += " pre_world =" + pprint( world, indent=22)+'\n'
|
|
pre_world = world
|
|
exe = testcase['exec']
|
|
transaction = {}
|
|
for key in exe.keys():
|
|
pkey = str(key)
|
|
if key == 'gasPrice':
|
|
pkey = 'price'
|
|
if key in ['data', 'code']:
|
|
value = exe[key][2:].decode('hex')
|
|
else:
|
|
value = i(exe[key])
|
|
|
|
transaction[pkey] = value
|
|
|
|
pos_world = None
|
|
if 'post' in testcase:
|
|
pos = testcase['post']
|
|
world = {}
|
|
for address in pos.keys():
|
|
iaddress = i(address)
|
|
world[iaddress] = {}
|
|
world[iaddress]['code'] = pos[address][u'code'][2:].decode('hex')
|
|
world[iaddress]['nonce'] = i(pos[address][u'nonce'])
|
|
world[iaddress]['balance'] = i(pos[address][u'balance'])
|
|
world[iaddress]['storage'] = {}
|
|
for key, value in pos[address][u'storage'].items():
|
|
world[iaddress]['storage'][i(key)] = i(value)
|
|
output += " pos_world = " + pprint(world, indent=27) + '\n'
|
|
|
|
else:
|
|
output += " pos_world = None\n"
|
|
pos_world = world
|
|
|
|
|
|
#CONTRACT['NONCE'] NOT USED fixme
|
|
output += '''
|
|
constraints = ConstraintSet()
|
|
platform = evm.EVMWorld(constraints)'''
|
|
|
|
for address, contract in pre_world.items():
|
|
output +='''
|
|
platform.create_account(address=%s,
|
|
balance=%s,
|
|
code=%s,
|
|
storage=%s
|
|
)''' % (pp(address),
|
|
pp(contract['balance']),
|
|
pp(contract['code'],width=60, indent=37),
|
|
pp(contract['storage'],width=80, indent=40))
|
|
|
|
output +='''
|
|
platform.create_account(address=%s,
|
|
balance=%s,
|
|
code=%s,
|
|
storage=%s
|
|
)''' % (pp(transaction['caller']),
|
|
pp(contract['balance']),
|
|
pp(contract['code'],width=60, indent=37),
|
|
pp(contract['storage'],width=80, indent=40))
|
|
|
|
|
|
output += '''
|
|
address = %s
|
|
origin = %s
|
|
price = %s
|
|
data = %s
|
|
caller = %s
|
|
value = %s''' % (
|
|
pp(transaction['address']),
|
|
pp(transaction['origin']),
|
|
pp(transaction['price']),
|
|
pp(transaction['data']),
|
|
pp(transaction['caller']),
|
|
pp(transaction['value']) )
|
|
output += '''
|
|
#platform.transaction(address, origin, price, data, caller, value, header)
|
|
bytecode = platform.storage[address]['code']
|
|
new_vm = EVM(constraints, address, origin, price, data, caller, value, bytecode, header, global_storage=platform.storage)
|
|
|
|
|
|
throw = False
|
|
try:
|
|
#platform.run()
|
|
new_vm.run()
|
|
except state.TerminateState as e:
|
|
if e.message != 'STOP':
|
|
throw = True
|
|
|
|
if pos_world is None:
|
|
self.assertTrue(throw)
|
|
else:
|
|
self.assertEqual( pos_world, platform.storage)
|
|
'''
|
|
|
|
|
|
return output
|
|
|
|
import sys, os, json
|
|
if __name__ == '__main__':
|
|
filename = os.path.abspath(sys.argv[1])
|
|
|
|
assert filename.endswith('.json')
|
|
|
|
print '''
|
|
import struct
|
|
import unittest
|
|
import json
|
|
from manticore.platforms import evm
|
|
from manticore.core import state
|
|
from manticore.core.smtlib import Operators, ConstraintSet
|
|
import os
|
|
|
|
|
|
class EVMTest_%s(unittest.TestCase):
|
|
_multiprocess_can_split_ = True
|
|
maxDiff=None
|
|
'''% os.path.split(sys.argv[1][:-5])[1]
|
|
|
|
js = file(filename).read()
|
|
tests = dict(json.loads(js))
|
|
|
|
#print "#processed ", len(tests.keys()), tests.keys()
|
|
count = 0
|
|
for test_name, testcase in tests.items():
|
|
count +=1
|
|
#print "#count", count , test_name, '0c423e4e26c7938c2a82ce40d05a549d617b32303a824ba5a93cb2fb0b037dfd'
|
|
skip = False
|
|
if test_name in ('BlockNumberDynamicJump0_foreverOutOfGas','jump0_foreverOutOfGas', '01a5cf9db140969b2a2410361164fc41c64c070805b82116d217240d4e304f6f', '08d5011d0a278a4d86298cf5a49d99df2662e279100f62fcdbd994df3fe58fbe','3a537f4a02067e6c5a8cf348bdffdb4e6b25475055503a8a5c16690cd51d1060',
|
|
'4341c8f00034ada5203fad4bccf429d2cec28a58dc83e53f4a957694d653dbd4','5340ec41425169e8d8771356443a0a312d3e3c809059eb092b0e2a2f8efb0921', '607ba70d1799c9345e522410e3313582cb9a3e8aecfcb00b3d510e7bbcae522b', '5fc1b8e024dc710ad40a90f6fc18938a90ef020751e3370572d2d4b407e43e63',
|
|
'sha3_3', 'ABAcalls0', 'ABAcalls2', 'ABAcallsSuicide0', 'ABAcallsSuicide1', '0c423e4e26c7938c2a82ce40d05a549d617b32303a824ba5a93cb2fb0b037dfd', '18ee3a269d4408f34f22a0a86c28d2538b48933ceee730a9ae5615bcc21d5435',
|
|
'1dc82eaa4472991b1d8e7a2042e6e6ba59ddc6e6157736fad05d01c5f07d74f1', '2011723095c2f01a6061cea476f2d5aef6f89d9bf8fd65bf19ccbbbfd7f12235',
|
|
'2174a06c481ddff76d7720354934d536b2e65a338db6ed4854a12ad261c0f934', '2c09481e499e7bf0edf21dd42c04cf041d1ef8ab74dfbabc7022791a8f6e35b3',
|
|
'319756923d422ba192da410609ba055adf5964f6d53c23543680721128591fa0','41f8c240c088571b00f7c78e9592c29b2f3b155d9be1089255de4faee3b7fe52',
|
|
'4445aef149dec5c59375104384d94a7c5a1075a465adec36657fe6774bbc200e', '45ae12b67afd7aa490f9c321d137f92d94b04ec0efad268423fc8471d639356f',
|
|
'46e1952a729b786f5f96f160e6fab13a4b78f182a925405df40669a18de94915', '47f0ac8ae67ffd1821270650cb6e6088cb234aabff79f0d0d7d9376c1a3c33bc',
|
|
'499925dd735dd0e62b168507249b64bd19e07ee8abbf185ade4c2cb12a7600f6', '5944d95306be93af8c45c13ec099314aeba52434af09012abd0eb61a80e5d874',
|
|
'5d20205dd04102c2227ddb5624753ef45832d25c4094aeb575c3f21c6c6b58d6', '5f2fc70586e44cea7cf78a2222c7cc4540929df1d47d9659508b1f1d0bd12bbe',
|
|
'6264fce6e5e03527ceac0b4f6d0637cb847e52cde36e5eee085125ce87f82b28','6a1ae314ad4ae7e0e1627a27aa71bc39d335afbe74e8f9f495953bea9e8dc432',
|
|
'6bece201afaedb2fad097d2b7776036166a850565af60697ef3c7735299024ed','7ab1b013a7d76006fe6e61c3e22c05f6dd6a1930117a9c9a9867a8af8e4c0c28',
|
|
'9536ae5ed3a92cd577d0c83a96909f64babd8de29f1f8516dc75fc51afec04cf','95766dcaa8d3e71bb028d8f4f9fefd22cb28ee179e7df5bcc2425b105a8d090c',
|
|
'9c380b88838dca02ff0f517f64a61514654f7e734b989ed272fdc348de57e501', '9f3c956a07536777d6a8fa162b0331ab06b9f0448d48a719df62a8a5ee0c73fe',
|
|
'a5e749f7d3555cfa3cd5b9a1fb7e296bd6d74d37b7eecea5f9404727407ab1dd', 'aef72030bfcd3ea0ded6cc89f3a151eea90987823f3cd2ea5b12b0db7ced5896',
|
|
'b61e68d30132efa1c0e891f04b1ebfcfcaac76db5ac4d316cdcbb60bbe32da5c', 'b8c838c8c9fbd570edb5a783b43c429742af8cfe993dbdcae94cba03390fe3f3',
|
|
'b96dbf50e26807dc7890f55ff5fce3ac378835a115187671c6882e8fe4256897', 'c008ef3e89c2dedbc5e953b74eadc515fd5cd172ba75ec229c67be66b95ec91a',
|
|
'c44dfcdd9c3ebe9c215b5ac20ba1a662523a63e7e9a375200071ab062f23a775','c4ad831e6119348c5c48a840de9bb41efdfbeba5a86aa71d04e8c10611ebe316',
|
|
'c4e33c1a7a3f756b3f9f223bccb70dee15a30f559d7648d3da2081c7862cbb16', 'd12665946c07d88384f335af064dbfc679283062bdbb17b56e1b812c3bd80dc9',
|
|
'd197d4181060d54d4ce3965aca77fc97809b613b42ba95698d146907fd0946d8', 'd9c6725e08f795f167d187609ab9b356e737841c56744069ad581e80071dc6c3',
|
|
'da5e09e2db0ad1cf1d68bd8f0b780cbd2f26f454f37d887bdac9e9fd42e2b1a1', 'e434a52cc9af21ef1204b5cdb333b376900fc5c2ece63b9d34fa4902908a455e',
|
|
'e434a52cc9af21ef1204b5cdb333b376900fc5c2ece63b9d34fa4902908a455e', 'e7c8c8665467646d68964497d222df12d6db05efbc5d5de1bf27c471023c1932',
|
|
'f76b7c41b0a7d2879851037f8eea928fc7302bd60fd6af4b6e4030a3a24436b4','f8660436772f63f5cd6bb20e12150cdc66f5238f78d872196f49bc9bf7b5d68d',
|
|
'fa78200fce12b17e9c320d743ddd7d32094326376fe9f6bf9964b285a9350a7e', 'DynamicJump0_foreverOutOfGas', 'JDfromStorageDynamicJump0_foreverOutOfGas', 'ABAcalls1', 'ABAcalls3', 'CallToNameRegistratorTooMuchMemory1','callcodeToNameRegistrator0'):
|
|
skip = True
|
|
#print filename, test_name, tests[test_name]
|
|
name = 'test_%s_%s'%(filename[:-5],test_name)
|
|
name = str(name.replace('.', '_'))
|
|
print gen_test(testcase, test_name, skip)
|
|
|
|
print '''
|
|
if __name__ == '__main__':
|
|
unittest.main()'''
|