Example #1
0
 def deploy_contracts(self):
     # Gathering existing libraries
     self.contract_name_to_contract, lib_name_to_address = svm_utils.generate_contract_objects(self.contract_to_build_data, self.hash_to_func_name)
     self.swarm_hash_to_contract = svm_utils.resolve_swarmhashes(self.contract_name_to_contract)
     for contract in self.contract_name_to_contract.values():
         swarm_hashes = tuple(contract.creation_disassembly.swarm_hashes)
         self.swarm_hash_tuple_to_contract[swarm_hashes] = contract
     for address, contract in self.address_to_contract.items():
         int_address = int(address[2:], 16)
         account = Account(int_address, self.contract_name_to_contract[contract.name])
         self.root_wstate.address_to_account[int_address] = account
     logging.info(f'Deployed contracts: {pprint.pformat(self.root_wstate.address_to_account)}')
     self.gen_to_wstates[self.root_wstate.gen].append(self.root_wstate)
     timestamp_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.TIMESTAMP,
                                                          self.root_wstate.gen)
     timestamp_constraint = ULT(1438214400, timestamp_vec)
     self.root_wstate.constraints.append(timestamp_constraint)
from opcodes import BYTE, SHR, DIV
from rule import Rule
from z3 import BitVec, ULT
"""
byte(A, shr(B, X))
given A < B / 8
->
0
"""

rule = Rule()

n_bits = 256

# Input vars
X = BitVec('X', n_bits)
A = BitVec('A', n_bits)
B = BitVec('B', n_bits)

# Non optimized result
nonopt = BYTE(A, SHR(B, X))
# Optimized result
opt = 0

rule.require(ULT(A, DIV(B, 8)))

rule.check(nonopt, opt)
 def visit_MLIL_CMP_ULT(self, expr):
     left = self.visit(expr.left)
     right = self.visit(expr.right)
     if None not in (left, right):
         return ULT(left, right)
Example #4
0
 def visit_MLIL_CMP_ULT(self, expr):
     left, right = self.visit_both_sides(expr)
     if right.size() != left.size():
         right = ZeroExt(left.size() - right.size(), right)
     return ULT(left, right)
Example #5
0
from opcodes import SIGNEXTEND, AND
from rule import Rule
from z3 import BitVec, BitVecVal, ULT
"""
Rule:
AND(A, SIGNEXTEND(B, X)) -> AND(A, X)
given
    B < WordSize / 8 - 1 AND
    A & (1 << ((B + 1) * 8) - 1) == A
"""

n_bits = 128

# Input vars
X = BitVec('X', n_bits)
A = BitVec('A', n_bits)
B = BitVec('B', n_bits)

rule = Rule()
# Requirements
rule.require(ULT(B, BitVecVal(n_bits // 8 - 1, n_bits)))
rule.require((A & ((BitVecVal(1, n_bits) << ((B + 1) * 8)) - 1)) == A)
rule.check(AND(A, SIGNEXTEND(B, X)), AND(A, X))
Example #6
0
 def lt_(self, global_state):
     state = global_state.mstate
     exp = ULT(util.pop_bitvec(state), util.pop_bitvec(state))
     state.stack.append(exp)
     return [global_state]
Example #7
0
 def operate_LT(self, *values):
     s0 = hlp.convert_to_bitvec(values[0])
     s1 = hlp.convert_to_bitvec(values[1])
     return hlp.get_concrete_int(ULT(s0, s1))
SHL(B, AND(A, X)) -> AND(SHL(B, X), A << B)
Requirements:
B < BitWidth
"""

rule = Rule()

n_bits = 128

# Input vars
X = BitVec('X', n_bits)
A = BitVec('A', n_bits)
B = BitVec('B', n_bits)

# Constants
BitWidth = BitVecVal(n_bits, n_bits)

# Requirements
rule.require(ULT(B, BitWidth))

# Non optimized result
nonopt_1 = SHL(B, AND(X, A))
nonopt_2 = SHL(B, AND(A, X))

# Optimized result
Mask = SHL(B, A)
opt = AND(SHL(B, X), Mask)

rule.check(nonopt_1, opt)
rule.check(nonopt_2, opt)
Example #9
0
def LT(x, y):
	return If(ULT(x, y), BitVecVal(1, x.size()), BitVecVal(0, x.size()))
Example #10
0
    def sym_call_address(self, address, wstate, method=None, arguments=None, amount=None, timestamp=None):
        # Initialize the execution environment
        account = wstate.address_to_account[address]
        if account.typ == AccountType.LIBRARY:
            return []
        child_wstate = wstate.child()
        logging.debug(BColors.GREEN + BColors.REVERSED + 'Starting SVM execution' + BColors.ENDC
                      + ' with address: ' + hex(address)
                      + ' contract: ' + account.contract.name)

        caller_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLER,
                                                          child_wstate.gen)

        caller_constraint = z3.Or([caller_vec == p for p in self.possible_caller_addresses])
        child_wstate.constraints.append(caller_constraint)

        calldata = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLDATA_ARRAY,
                                                        child_wstate.gen,
                                                        acc=account.id)
        if method is not None and method.name != Method.FALLBACK:
            calldata_0 = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLDATA,
                                                              child_wstate.gen,
                                                              index=0)
            calldata_4bytes, _  = svm_utils.split_bv(calldata_0, calldata_0.size() - 32)
            calldatasize = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLDATASIZE,
                                                                child_wstate.gen,
                                                                acc=account.id)
            entry_account = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.ENTRY_ACCOUNT,
                                                                 child_wstate.gen)
            method_constraint = z3.And(calldata_4bytes == method.idd, z3.ULE(4, calldatasize), entry_account == address)
            child_wstate.constraints.append(method_constraint)
            if arguments is not None and len(arguments):
                encoded_args = utils.abi_encode(method.inputs, arguments)
                for i, arg in enumerate(encoded_args):
                    if arg is None:
                        continue
                    calldata_i = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLDATA,
                                                                      child_wstate.gen,
                                                                      index=4+32*i)
                    child_wstate.constraints.append(calldata_i == z3.BitVecVal(arg, 256))
        gasprice_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.GASPRICE,
                                                            child_wstate.gen)
        callvalue_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.CALLVALUE,
                                                             child_wstate.gen)
        origin_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.ORIGIN,
                                                          child_wstate.gen)
        timestamp_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.TIMESTAMP,
                                                             child_wstate.gen)
        parent_timestamp_vec = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.TIMESTAMP,
                                                                    wstate.gen)
        callvalue_constraint = ULT(callvalue_vec, svm_utils.ETHER_LIMIT)
        timestamp_constraint = ULT(parent_timestamp_vec, timestamp_vec)

        entry_account = self.sym_bv_generator.get_sym_bitvec(constraints.ConstraintType.ENTRY_ACCOUNT,
                                                             child_wstate.gen)
        child_wstate.constraints.append(callvalue_constraint)
        child_wstate.constraints.append(timestamp_constraint)
        child_wstate.constraints.append(entry_account == account.address)
        environment = Environment(active_address=address,
                                  sender=caller_vec,
                                  calldata=calldata,
                                  gasprice=gasprice_vec,
                                  callvalue=callvalue_vec,
                                  origin=origin_vec,
                                  calldata_type=CalldataType.UNDEFINED,
                                  disassembly=account.contract.disassembly,
                                  runtime_bytecode_bytes=list(account.contract.disassembly.bytecode),
                                  timestamp=timestamp_vec)

        gstate = GlobalState(child_wstate, environment)
        return self.executor.execute_gstate(gstate)
from opcodes import BYTE, DIV, SHR
from rule import Rule
from z3 import BitVec, UGE, ULE, ULT
"""
byte(A, shr(B, X))
given B % 8 == 0 && A < n_bits/8 && B <= n_bits && A >= B / 8
->
byte(A - B / 8, X)
"""

rule = Rule()

n_bits = 256

# Input vars
X = BitVec('X', n_bits)
A = BitVec('A', n_bits)
B = BitVec('B', n_bits)

# Non optimized result
nonopt = BYTE(A, SHR(B, X))
# Optimized result
opt = BYTE(A - B / 8, X)

rule.require(B % 8 == 0)
rule.require(ULT(A, n_bits / 8))
rule.require(ULE(B, n_bits))
rule.require(UGE(A, DIV(B, 8)))

rule.check(nonopt, opt)
Example #12
0
from rule import Rule
from z3 import BitVec, BitVecVal, If, UGE, ULT
"""
Rule:
1) SIGNEXTEND(A, X) -> X if A >= Pattern::WordSize / 8 - 1;

2) SIGNEXTEND(X, SIGNEXTEND(X, Y)) -> SIGNEXTEND(X, Y)

3) SIGNEXTEND(A, SIGNEXTEND(B, X)) -> SIGNEXTEND(min(A, B), X)
"""

n_bits = 128

# Input vars
X = BitVec('X', n_bits)
Y = BitVec('Y', n_bits)
A = BitVec('A', n_bits)
B = BitVec('B', n_bits)

rule1 = Rule()
# Requirements
rule1.require(UGE(A, BitVecVal(n_bits // 8 - 1, n_bits)))
rule1.check(SIGNEXTEND(A, X), X)

rule2 = Rule()
rule2.check(SIGNEXTEND(X, SIGNEXTEND(X, Y)), SIGNEXTEND(X, Y))

rule3 = Rule()
rule3.check(SIGNEXTEND(A, SIGNEXTEND(B, X)),
            SIGNEXTEND(If(ULT(A, B), A, B), X))