Пример #1
0
    def testRelated(self):
        cs = ConstraintSet()
        aa1 = cs.new_bool(name="AA1")
        aa2 = cs.new_bool(name="AA2")
        bb1 = cs.new_bool(name="BB1")
        bb2 = cs.new_bool(name="BB2")
        cs.add(Operators.OR(aa1, aa2))
        cs.add(Operators.OR(bb1, bb2))
        self.assertTrue(self.solver.check(cs))
        # No BB variables related to AA
        self.assertNotIn("BB", cs.related_to(aa1).to_string())
        self.assertNotIn("BB", cs.related_to(aa2).to_string())
        self.assertNotIn("BB", cs.related_to(aa1 == aa2).to_string())
        self.assertNotIn("BB", cs.related_to(aa1 == False).to_string())
        # No AA variables related to BB
        self.assertNotIn("AA", cs.related_to(bb1).to_string())
        self.assertNotIn("AA", cs.related_to(bb2).to_string())
        self.assertNotIn("AA", cs.related_to(bb1 == bb2).to_string())
        self.assertNotIn("AA", cs.related_to(bb1 == False).to_string())

        # Nothing is related to tautologies?
        self.assertEqual("", cs.related_to(simplify(bb1 == bb1)).to_string())

        # But if the tautollogy can not get simplified we have to ask the solver
        # and send in all the other stuff
        self.assertNotIn("AA", cs.related_to(bb1 == bb1).to_string())
Пример #2
0
    def test_CHR(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        cs.add(Operators.CHR(a) == Operators.CHR(0x41))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), 0x41)
Пример #3
0
 def testBool4(self):
     cs = ConstraintSet()
     bf = BoolConstant(value=False)
     bt = BoolConstant(value=True)
     cs.add(Operators.OR(True, bf))
     cs.add(Operators.OR(bt, bt, False))
     self.assertTrue(self.solver.check(cs))
Пример #4
0
    def test_ORD(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        cs.add(Operators.ORD(a) == Operators.ORD('Z'))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), ord('Z'))
Пример #5
0
    def test_CMPXCHG8B_symbolic(self):
        '''CMPXCHG8B'''

        cs = ConstraintSet()
        mem = SMemory32(cs)
        cpu = I386Cpu(mem)

        #alloc/map a little mem
        code = mem.mmap(0x1000, 0x1000, 'rwx')
        data = mem.mmap(0x2000, 0x1000, 'rwx')

        mem[code:code+5] = '\xf0\x0f\xc7\x0f;'
        cpu.EIP = code

        cpu.EDI = cs.new_bitvec(32, 'EDI')
        cs.add( Operators.OR(cpu.EDI == 0x2000, cpu.EDI == 0x2100, cpu.EDI == 0x2200 ) )
        self.assertEqual(sorted(solver.get_all_values(cs, cpu.EDI)),[0x2000,0x2100,0x2200])
        self.assertEqual(cpu.read_int(0x2000,64), 0)
        self.assertEqual(cpu.read_int(0x2100,64), 0)
        self.assertEqual(cpu.read_int(0x2200,64), 0)
        self.assertItemsEqual(solver.get_all_values(cs, cpu.read_int(cpu.EDI,64)), [0])
        #self.assertEqual(cpu.read_int(cpu.EDI,64), 0 )

        cpu.write_int(0x2100, 0x4142434445464748, 64)


        cpu.EAX = cs.new_bitvec(32, 'EAX')
        cs.add( Operators.OR(cpu.EAX == 0x41424344, cpu.EAX == 0x0badf00d, cpu.EAX == 0xf7f7f7f7 ) )
        cpu.EDX= 0x45464748

        cpu.execute()
        self.assertTrue(solver.check(cs))

        self.assertItemsEqual(solver.get_all_values(cs, cpu.read_int(cpu.EDI,64)), [0, 4702394921427289928])
Пример #6
0
 def test_simplify_OR(self):
     cs = ConstraintSet()
     bf = BoolConstant(value=False)
     bt = BoolConstant(value=True)
     var = cs.new_bool()
     cs.add(simplify(Operators.OR(var, var)) == var)
     cs.add(simplify(Operators.OR(var, bt)) == bt)
     self.assertTrue(self.solver.check(cs))
Пример #7
0
    def test_ORD_proper_extract(self):
        solver = self.solver
        cs = ConstraintSet()
        a = cs.new_bitvec(32)
        cs.add(Operators.ORD(a) == Operators.ORD("\xff"))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), ord("\xff"))
Пример #8
0
    def test_NOT(self):
        solver = self.solver
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)

        cs.add(a == 0x1)  # 1
        cs.add(b == 0x86)  # -122
        self.assertTrue(solver.must_be_true(cs, Operators.NOT(False)))
        self.assertTrue(solver.must_be_true(cs, Operators.NOT(a == b)))
Пример #9
0
    def test_arithmetic_simplify_udiv(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(32, name="VARA")
        b = a + Operators.UDIV(BitVecConstant(size=32, value=0), BitVecConstant(size=32, value=2))
        self.assertEqual(translate_to_smtlib(b), "(bvadd VARA (bvudiv #x00000000 #x00000002))")
        self.assertEqual(translate_to_smtlib(simplify(b)), "VARA")

        c = a + Operators.UDIV(BitVecConstant(size=32, value=2), BitVecConstant(size=32, value=2))
        self.assertEqual(translate_to_smtlib(c), "(bvadd VARA (bvudiv #x00000002 #x00000002))")
        self.assertEqual(translate_to_smtlib(simplify(c)), "(bvadd VARA #x00000001)")
Пример #10
0
    def test_CONCAT(self):
        solver = self.solver
        cs = ConstraintSet()
        a = cs.new_bitvec(16)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)

        cs.add(b == 0x41)
        cs.add(c == 0x42)
        cs.add(a == Operators.CONCAT(a.size, b, c))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), Operators.CONCAT(a.size, 0x41, 0x42))
Пример #11
0
    def test_SAR_2_symbolicsa(self):
        cs = ConstraintSet()
        mem = SMemory32(cs)
        cpu = I386Cpu(mem)
        mem.mmap(0x0041e000, 0x1000, 'rwx')

        mem[0x0041e10a] = '\xc0'
        mem[0x0041e10b] = '\xf8'
        mem[0x0041e10c] = '\xff'
        cpu.RIP = 0x41e10a

        cpu.PF = cs.new_bool()
        cs.add(cpu.PF == True)
        cpu.CF = cs.new_bool()
        cs.add(cpu.CF == False)
        cpu.SF = cs.new_bool()
        cs.add(cpu.SF == True)
        cpu.ZF = cs.new_bool()
        cs.add(cpu.ZF == False)
        cpu.AF = cs.new_bool()
        cs.add(cpu.AF == False)
        cpu.OF = cs.new_bool()
        cs.add(cpu.OF == False)
        cpu.EAX = cs.new_bitvec(32)
        cs.add(cpu.EAX == 0xffffffff)

        done = False
        while not done:
            try:
                cpu.execute()
                done = True
            except ConcretizeRegister as e:
                symbol = getattr(cpu, e.reg_name)
                values = solver.get_all_values(cs, symbol)
                self.assertEqual(len(values), 1)
                setattr(cpu, e.reg_name, values[0])

        condition = True
        condition = Operators.AND(condition, cpu.EAX == 0xffffffff)
        condition = Operators.AND(condition, cpu.ZF == False)
        condition = Operators.AND(condition, cpu.PF == True)
        condition = Operators.AND(condition, cpu.SF == True)
        condition = Operators.AND(condition, cpu.CF == True)

        with cs as temp_cs:
            temp_cs.add(condition)
            self.assertTrue(solver.check(temp_cs))
        with cs as temp_cs:
            temp_cs.add(condition == False)
            self.assertFalse(solver.check(temp_cs))
Пример #12
0
    def test_SAR(self):
        solver = self.solver
        A = 0xBADF00D
        for B in range(32):
            cs = ConstraintSet()
            a = cs.new_bitvec(32)
            b = cs.new_bitvec(32)
            c = cs.new_bitvec(32)

            cs.add(c == Operators.SAR(32, a, b))
            cs.add(a == A)
            cs.add(b == B)

            self.assertTrue(solver.check(cs))
            self.assertEqual(solver.get_value(cs, c), Operators.SAR(32, A, B))
Пример #13
0
 def serialize_uint(value, size=32):
     '''takes an int and packs it into a 32 byte string, msb first'''
     assert size >= 1
     bytes = []
     for position in range(size):
         bytes.append(Operators.EXTRACT(value, position * 8, 8))
     chars = map(Operators.CHR, bytes)
     return tuple(reversed(chars))
Пример #14
0
 def compare_buffers(a, b):
     if len(a) != len(b):
         return False
     cond = True
     for i in range(len(a)):
         cond = Operators.AND(a[i] == b[i], cond)
         if cond is False:
             return False
     return cond
Пример #15
0
 def testBasicITETaint(self):
     a = BitVecConstant(32, 100, taint=('SOURCE1', ))
     b = BitVecConstant(32, 200, taint=('SOURCE2', ))
     c = BitVecConstant(32, 300, taint=('SOURCE3', ))
     d = BitVecConstant(32, 400, taint=('SOURCE4', ))
     x = Operators.ITEBV(32, a > b, c, d)
     self.assertTrue('SOURCE1' in x.taint)
     self.assertTrue('SOURCE2' in x.taint)
     self.assertTrue('SOURCE3' in x.taint)
     self.assertTrue('SOURCE4' in x.taint)
Пример #16
0
 def testBasicITETaint(self):
     a = BitVecConstant(size=32, value=100, taint=("SOURCE1",))
     b = BitVecConstant(size=32, value=200, taint=("SOURCE2",))
     c = BitVecConstant(size=32, value=300, taint=("SOURCE3",))
     d = BitVecConstant(size=32, value=400, taint=("SOURCE4",))
     x = Operators.ITEBV(32, a > b, c, d)
     self.assertTrue("SOURCE1" in x.taint)
     self.assertTrue("SOURCE2" in x.taint)
     self.assertTrue("SOURCE3" in x.taint)
     self.assertTrue("SOURCE4" in x.taint)
Пример #17
0
    def test_related_to(self):
        import gzip
        import pickle, sys

        filename = os.path.abspath(
            os.path.join(DIRPATH, "data", "ErrRelated.pkl.gz"))

        # A constraint set and a contraint caught in the act of making related_to fail
        constraints, constraint = pickle.loads(
            gzip.open(filename, "rb").read())

        Z3Solver.instance().can_be_true.cache_clear()
        ground_truth = Z3Solver.instance().can_be_true(constraints, constraint)
        self.assertEqual(ground_truth, False)

        Z3Solver.instance().can_be_true.cache_clear()
        self.assertEqual(
            ground_truth,
            Z3Solver.instance().can_be_true(
                constraints.related_to(constraints), constraint),
        )

        # Replace
        new_constraint = Operators.UGE(
            Operators.SEXTEND(BitVecConstant(256, 0x1A), 256, 512) *
            BitVecConstant(512, 1),
            0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000,
        )
        self.assertEqual(translate_to_smtlib(constraint),
                         translate_to_smtlib(new_constraint))

        Z3Solver.instance().can_be_true.cache_clear()
        self.assertEqual(
            ground_truth,
            Z3Solver.instance().can_be_true(constraints, new_constraint))

        Z3Solver.instance().can_be_true.cache_clear()
        self.assertEqual(
            ground_truth,
            Z3Solver.instance().can_be_true(
                constraints.related_to(new_constraint), new_constraint),
        )
Пример #18
0
    def test_ITEBV_2(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)

        cs.add(b == 0x44)
        cs.add(c == 0x44)
        cs.add(a == Operators.ITEBV(8, b == c, b, c))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), 0x44)
Пример #19
0
    def test_ITE(self):
        cs = ConstraintSet()
        a = cs.new_bool()
        b = cs.new_bool()
        c = cs.new_bool()

        cs.add(b == True)
        cs.add(c == False)
        cs.add(a == Operators.ITE(b == c, b, c))

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), False)
Пример #20
0
    def test_visitors(self):
        solver = Z3Solver.instance()
        cs = ConstraintSet()
        arr = cs.new_array(name="MEM")
        a = cs.new_bitvec(32, name="VAR")
        self.assertEqual(get_depth(a), 1)
        cond = Operators.AND(a < 200, a > 100)
        arr[0] = ord("a")
        arr[1] = ord("b")

        self.assertEqual(get_depth(cond), 3)
        self.assertEqual(get_depth(arr[a + 1]), 4)
        self.assertEqual(
            translate_to_smtlib(arr[a + 1]),
            "(select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))",
        )

        arr[3] = arr[a + 1]
        aux = arr[a + Operators.ZEXTEND(arr[a], 32)]

        self.assertEqual(get_depth(aux), 9)
        self.maxDiff = 1500
        self.assertEqual(
            translate_to_smtlib(aux),
            "(select (store (store (store MEM #x00000000 #x61) #x00000001 #x62) #x00000003 (select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))) (bvadd VAR ((_ zero_extend 24) (select (store (store (store MEM #x00000000 #x61) #x00000001 #x62) #x00000003 (select (store (store MEM #x00000000 #x61) #x00000001 #x62) (bvadd VAR #x00000001))) VAR))))",
        )

        values = arr[0:2]
        self.assertEqual(len(values), 2)
        self.assertItemsEqual(solver.get_all_values(cs, values[0]), [ord("a")])
        self.assertItemsEqual(solver.get_all_values(cs, values[1]), [ord("b")])
        arr[1:3] = "cd"

        values = arr[0:3]
        self.assertEqual(len(values), 3)
        self.assertItemsEqual(solver.get_all_values(cs, values[0]), [ord("a")])
        self.assertItemsEqual(solver.get_all_values(cs, values[1]), [ord("c")])
        self.assertItemsEqual(solver.get_all_values(cs, values[2]), [ord("d")])
        self.assertEqual(
            pretty_print(aux, depth=2),
            "ArraySelect\n  ArrayStore\n    ...\n  BitVecAdd\n    ...\n")
        self.assertEqual(pretty_print(Operators.EXTRACT(a, 0, 8), depth=1),
                         "BitVecExtract{0:7}\n  ...\n")
        self.assertEqual(pretty_print(a, depth=2), "VAR\n")

        x = BitVecConstant(32, 100, taint=("important", ))
        y = BitVecConstant(32, 200, taint=("stuff", ))
        z = constant_folder(x + y)
        self.assertItemsEqual(z.taint, ("important", "stuff"))
        self.assertEqual(z.value, 300)

        self.assertRaises(Exception, translate_to_smtlib, 1)

        self.assertEqual(
            translate_to_smtlib(simplify(Operators.ZEXTEND(a, 32))), "VAR")
        self.assertEqual(
            translate_to_smtlib(
                simplify(Operators.EXTRACT(Operators.EXTRACT(a, 0, 8), 0, 8))),
            "((_ extract 7 0) VAR)",
        )
Пример #21
0
    def test_SREM(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)
        d = cs.new_bitvec(8)

        cs.add(b == 0x86)  #-122
        cs.add(c == 0x11)  #17
        cs.add(a == Operators.SREM(b, c))
        cs.add(d == b.srem(c))
        cs.add(a == d)

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), -3 & 0xFF)
Пример #22
0
    def test_UDIV(self):
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)
        d = cs.new_bitvec(8)

        cs.add(b == 0x86)  #134
        cs.add(c == 0x11)  #17
        cs.add(a == Operators.UDIV(b, c))
        cs.add(d == b.udiv(c))
        cs.add(a == d)

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), 7)
Пример #23
0
    def test_SDIV(self):
        solver = self.solver
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)
        d = cs.new_bitvec(8)

        cs.add(b == 0x86)  # -122
        cs.add(c == 0x11)  # 17
        cs.add(a == Operators.SDIV(b, c))
        cs.add(d == (b // c))
        cs.add(a == d)
        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), -7 & 0xFF)
Пример #24
0
    def test_UREM(self):
        solver = Z3Solver.instance()
        cs = ConstraintSet()
        a = cs.new_bitvec(8)
        b = cs.new_bitvec(8)
        c = cs.new_bitvec(8)
        d = cs.new_bitvec(8)

        cs.add(b == 0x86)  # 134
        cs.add(c == 0x11)  # 17
        cs.add(a == Operators.UREM(b, c))
        cs.add(d == b.urem(c))
        cs.add(a == d)

        self.assertTrue(solver.check(cs))
        self.assertEqual(solver.get_value(cs, a), 0xF)
Пример #25
0
    def test_cache_003(self):
        cs = ConstraintSet()
        mem = SMemory64(cs)
        cpu = AMD64Cpu(mem)

        #alloc/map a little mem
        addr = mem.mmap(0x1000, 0x1000, 'rwx')
        self.assertEqual(addr, 0x1000)

        cpu.write_int(0x1000, 0x4142434445464748, 64)
        cpu.write_int(0x1008, 0x6162636465666768, 64)

        self.assertEqual(cpu.read_int(0x1000, 64), 0x4142434445464748)
        self.assertEqual(cpu.read_int(0x1008, 64), 0x6162636465666768)

        for i in range(8):
            self.assertEqual(cpu.read_int(0x1000 + i, 8), ord("HGFEDCBA"[i]))
        for i in range(8):
            self.assertEqual(cpu.read_int(0x1008 + i, 8), ord("hgfedcba"[i]))

        addr1 = cs.new_bitvec(64)
        cs.add(addr1 == 0x1004)
        cpu.write_int(addr1, 0x58, 8)

        # 48 47 46 45 58 43 42 41 68 67 66 65 64 63 62 61

        value = cpu.read_int(0x1004, 16)
        self.assertItemsEqual(solver.get_all_values(cs, value), [0x4358])

        addr2 = cs.new_bitvec(64)
        cs.add(Operators.AND(addr2 >= 0x1000, addr2 <= 0x100c))

        cpu.write_int(addr2, 0x5959, 16)

        solutions = solver.get_all_values(cs, cpu.read_int(addr2, 32))

        self.assertEqual(len(solutions), 0x100c - 0x1000 + 1)
        self.assertEqual(
            set(solutions),
            set([
                0x45465959, 0x41425959, 0x58455959, 0x65665959, 0x67685959,
                0x43585959, 0x68415959, 0x42435959, 0x66675959, 0x62635959,
                0x64655959, 0x63645959, 0x61625959
            ]))
Пример #26
0
    def test_arithmetic_simplify_extract(self):
        cs = ConstraintSet()
        arr = cs.new_array(name='MEM')
        a = cs.new_bitvec(32, name='VARA')
        b = Operators.CONCAT(32, Operators.EXTRACT(a, 24, 8),
                             Operators.EXTRACT(a, 16, 8),
                             Operators.EXTRACT(a, 8, 8),
                             Operators.EXTRACT(a, 0, 8))
        self.assertEqual(
            translate_to_smtlib(b),
            '(concat ((_ extract 31 24) VARA) ((_ extract 23 16) VARA) ((_ extract 15 8) VARA) ((_ extract 7 0) VARA))'
        )
        self.assertEqual(translate_to_smtlib(simplify(b)), 'VARA')

        c = Operators.CONCAT(16, Operators.EXTRACT(a, 16, 8),
                             Operators.EXTRACT(a, 8, 8))
        self.assertEqual(
            translate_to_smtlib(c),
            '(concat ((_ extract 23 16) VARA) ((_ extract 15 8) VARA))')
        self.assertEqual(translate_to_smtlib(simplify(c)),
                         '((_ extract 23 8) VARA)')
Пример #27
0
    def testBasicMigration(self):
        solver = self.solver
        cs1 = ConstraintSet()
        cs2 = ConstraintSet()
        var1 = cs1.new_bitvec(32, "var")
        var2 = cs2.new_bitvec(32, "var")
        cs1.add(Operators.ULT(var1, 3))  # var1 can be 0, 1, 2

        # make a migration map dict
        migration_map1 = {}

        # this expression is composed with variables of both cs
        expression = var1 > var2
        migrated_expression = cs1.migrate(expression, migration_map1)
        cs1.add(migrated_expression)

        expression = var2 > 0
        migrated_expression = cs1.migrate(expression, migration_map1)
        cs1.add(migrated_expression)

        self.assertItemsEqual(solver.get_all_values(cs1, var1), [2])  # should only be [2]
from manticore.ethereum.abi import ABI

ETHER = 10**18

m = ManticoreEVM()  # initiate the blockchain

# Generate the accounts
user_account = m.create_account(balance=1000 * ETHER)
with open('exercise_2.sol') as f:
    contract = m.solidity_create_contract(f, owner=user_account)

#First add won't overflow uint256 representation
value_0 = m.make_symbolic_value()
contract.add(value_0, caller=user_account)
#Potential overflow
value_1 = m.make_symbolic_value()
contract.add(value_1, caller=user_account)
contract.sellerBalance(caller=user_account)

for state in m.ready_states:
    # Check if input0 > sellerBalance

    # last_return is the data returned
    sellerBalance_tx = state.platform.transactions[-1]
    # retrieve last_return and input0 in a similar format
    seller_balance = ABI.deserialize("uint", sellerBalance_tx.return_data)

    condition = Operators.UGT(value_0, seller_balance)

    if m.generate_testcase(state, name="BugFound", only_if=condition):
        print(f'Bug found, results are in {m.workspace}')
Пример #29
0
contract_account = m.solidity_create_contract(source_code, owner=user_account, balance=0)
contract_account.balanceOf(to_account, caller=user_account)
contract_account.balanceOf(from_account, caller=user_account)
contract_account.balanceOf(user_account, caller=user_account)

symbolic_val1 = m.make_symbolic_value()
#m.constrain(symbolic_val1 > 100)

contract_account.transfer(to_account, symbolic_val1, caller=from_account)
contract_account.balanceOf(user_account, caller=user_account)
contract_account.balanceOf(from_account, caller=user_account)
contract_account.balanceOf(to_account, caller=user_account)

for state in m.ready_states:    
   
    #for tx in state.platform.transactions:
    #    print("From address: (0x%x) \n" % (tx.caller))
    #print("********\n")
        
    balance_before = state.platform.transactions[1].return_data
    balance_before = ABI.deserialize("uint", balance_before)

    balance_after = state.platform.transactions[-1].return_data
    balance_after = ABI.deserialize("uint", balance_after)

    state.constrain(Operators.ULT(balance_before, balance_after))

    if solver.check(state.constraints):
        print("Found! see {}".format(m.workspace))
        m.generate_testcase(state, "Found")
Пример #30
0
 def write(mem, where, val, size):
     mem[where:where + size / 8] = [
         Operators.CHR(Operators.EXTRACT(val, offset, 8))
         for offset in xrange(0, size, 8)
     ]