def Unconstrained(self, name, bits, uninitialized=True, inspect=True, events=True, key=None, eternal=False, **kwargs): """ Creates an unconstrained symbol or a default concrete value (0), based on the state options. :param name: The name of the symbol. :param bits: The size (in bits) of the symbol. :param uninitialized: Whether this value should be counted as an "uninitialized" value in the course of an analysis. :param inspect: Set to False to avoid firing SimInspect breakpoints :param events: Set to False to avoid generating a SimEvent for the occasion :param key: Set this to a tuple of increasingly specific identifiers (for example, ``('mem', 0xffbeff00)`` or ``('file', 4, 0x20)`` to cause it to be tracked, i.e. accessable through ``solver.get_variables``. :param eternal: Set to True in conjunction with setting a key to cause all states with the same ancestry to retrieve the same symbol when trying to create the value. If False, a counter will be appended to the key. :returns: an unconstrained symbol (or a concrete value of 0). """ if o.SYMBOLIC_INITIAL_VALUES in self.state.options: # Return a symbolic value if o.ABSTRACT_MEMORY in self.state.options: l.debug("Creating new top StridedInterval") r = claripy.TSI(bits=bits, name=name, uninitialized=uninitialized, **kwargs) else: l.debug("Creating new unconstrained BV named %s", name) if o.UNDER_CONSTRAINED_SYMEXEC in self.state.options: r = self.BVS(name, bits, uninitialized=uninitialized, key=key, eternal=eternal, inspect=inspect, events=events, **kwargs) else: r = self.BVS(name, bits, uninitialized=uninitialized, key=key, eternal=eternal, inspect=inspect, events=events, **kwargs) return r else: # Return a default value, aka. 0 return claripy.BVV(0, bits)
def Unconstrained(self, name, bits, uninitialized=True, **kwargs): if o.SYMBOLIC_INITIAL_VALUES in self.state.options: # Return a symbolic value if o.ABSTRACT_MEMORY in self.state.options: l.debug("Creating new top StridedInterval") r = claripy.TSI(bits=bits, name=name, uninitialized=uninitialized, **kwargs) else: l.debug("Creating new unconstrained BV named %s", name) if o.UNDER_CONSTRAINED_SYMEXEC in self.state.options: r = self.BVS(name, bits, uninitialized=uninitialized, **kwargs) else: r = self.BVS(name, bits, uninitialized=uninitialized, **kwargs) return r else: # Return a default value, aka. 0 return claripy.BVV(0, bits)
def Unconstrained(self, name, bits, **kwargs): if o.SYMBOLIC_INITIAL_VALUES in self.state.options: # Return a symbolic value if o.ABSTRACT_MEMORY in self.state.options: l.debug("Creating new top StridedInterval") r = claripy.TSI(bits=bits, name=name, uninitialized=True, **kwargs) else: l.debug("Creating new unconstrained BV named %s", name) r = claripy.BitVec(name, bits, **kwargs) self.state.log.add_event('unconstrained', name=iter(r.variables).next(), bits=bits, **kwargs) return r else: # Return a default value, aka. 0 return claripy.BitVecVal(0, bits)
def test_vsa(): # Set backend b = claripy.backend_vsa SI = claripy.StridedInterval VS = claripy.ValueSet BVV = claripy.BVV # Disable the use of DiscreteStridedIntervalSet claripy.vsa.strided_interval.allow_dsis = False def is_equal(ast_0, ast_1): return ast_0.identical(ast_1) si1 = claripy.TSI(32, name="foo") nose.tools.assert_equal(si1.model.name, "foo") # Normalization si1 = SI(bits=32, stride=1, lower_bound=10, upper_bound=10) nose.tools.assert_equal(si1.model.stride, 0) # Integers si1 = claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10) si2 = claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10) si3 = claripy.SI(bits=32, stride=0, lower_bound=28, upper_bound=28) # Strided intervals si_a = claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20) si_b = claripy.SI(bits=32, stride=2, lower_bound=-100, upper_bound=200) si_c = claripy.SI(bits=32, stride=3, lower_bound=-100, upper_bound=200) si_d = claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=60) si_e = claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x3000) si_f = claripy.SI(bits=16, stride=1, lower_bound=0, upper_bound=255) si_g = claripy.SI(bits=16, stride=1, lower_bound=0, upper_bound=0xff) si_h = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) nose.tools.assert_true(is_equal(si1, claripy.SI(bits=32, to_conv=10))) nose.tools.assert_true(is_equal(si2, claripy.SI(bits=32, to_conv=10))) nose.tools.assert_true(is_equal(si1, si2)) # __add__ si_add_1 = si1 + si2 nose.tools.assert_true( is_equal(si_add_1, claripy.SI(bits=32, stride=0, lower_bound=20, upper_bound=20))) si_add_2 = si1 + si_a nose.tools.assert_true( is_equal(si_add_2, claripy.SI(bits=32, stride=2, lower_bound=20, upper_bound=30))) si_add_3 = si_a + si_b nose.tools.assert_true( is_equal( si_add_3, claripy.SI(bits=32, stride=2, lower_bound=-90, upper_bound=220))) si_add_4 = si_b + si_c nose.tools.assert_true( is_equal( si_add_4, claripy.SI(bits=32, stride=1, lower_bound=-200, upper_bound=400))) # __add__ with overflow si_add_5 = si_h + 0xffffffff nose.tools.assert_true( is_equal( si_add_5, claripy.SI(bits=32, stride=0, lower_bound=0x7fffffff, upper_bound=0x7fffffff))) # __sub__ si_minus_1 = si1 - si2 nose.tools.assert_true( is_equal(si_minus_1, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0))) si_minus_2 = si_a - si_b nose.tools.assert_true( is_equal( si_minus_2, claripy.SI(bits=32, stride=2, lower_bound=-190, upper_bound=120))) si_minus_3 = si_b - si_c nose.tools.assert_true( is_equal( si_minus_3, claripy.SI(bits=32, stride=1, lower_bound=-300, upper_bound=300))) # __neg__ / __invert__ / bitwise not si_neg_1 = ~si1 nose.tools.assert_true(is_equal(si_neg_1, claripy.SI(bits=32, to_conv=-11))) si_neg_2 = ~si_b nose.tools.assert_true( is_equal( si_neg_2, claripy.SI(bits=32, stride=2, lower_bound=-201, upper_bound=99))) # __or__ si_or_1 = si1 | si3 nose.tools.assert_true(is_equal(si_or_1, claripy.SI(bits=32, to_conv=30))) si_or_2 = si1 | si2 nose.tools.assert_true(is_equal(si_or_2, claripy.SI(bits=32, to_conv=10))) si_or_3 = si1 | si_a # An integer | a strided interval nose.tools.assert_true( is_equal(si_or_3, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=30))) si_or_3 = si_a | si1 # Exchange the operands nose.tools.assert_true( is_equal(si_or_3, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=30))) si_or_4 = si_a | si_d # A strided interval | another strided interval nose.tools.assert_true( is_equal(si_or_4, claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=62))) si_or_4 = si_d | si_a # Exchange the operands nose.tools.assert_true( is_equal(si_or_4, claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=62))) si_or_5 = si_e | si_f # nose.tools.assert_true( is_equal( si_or_5, claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x30ff))) si_or_6 = si_e | si_g # nose.tools.assert_true( is_equal( si_or_6, claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x30ff))) # Shifting si_shl_1 = si1 << 3 nose.tools.assert_equal(si_shl_1.size(), 32) nose.tools.assert_true( is_equal(si_shl_1, claripy.SI(bits=32, stride=0, lower_bound=80, upper_bound=80))) # Multiplication si_mul_1 = si1 * 3 nose.tools.assert_equal(si_mul_1.size(), 32) nose.tools.assert_true( is_equal(si_mul_1, claripy.SI(bits=32, stride=0, lower_bound=30, upper_bound=30))) si_mul_2 = si_a * 3 nose.tools.assert_equal(si_mul_2.size(), 32) nose.tools.assert_true( is_equal(si_mul_2, claripy.SI(bits=32, stride=6, lower_bound=30, upper_bound=60))) si_mul_3 = si_a * si_b nose.tools.assert_equal(si_mul_3.size(), 32) nose.tools.assert_true( is_equal( si_mul_3, claripy.SI(bits=32, stride=2, lower_bound=-2000, upper_bound=4000))) # Division si_div_1 = si1 / 3 nose.tools.assert_equal(si_div_1.size(), 32) nose.tools.assert_true( is_equal(si_div_1, claripy.SI(bits=32, stride=0, lower_bound=3, upper_bound=3))) si_div_2 = si_a / 3 nose.tools.assert_equal(si_div_2.size(), 32) nose.tools.assert_true( is_equal(si_div_2, claripy.SI(bits=32, stride=1, lower_bound=3, upper_bound=6))) # Modulo si_mo_1 = si1 % 3 nose.tools.assert_equal(si_mo_1.size(), 32) nose.tools.assert_true( is_equal(si_mo_1, claripy.SI(bits=32, stride=0, lower_bound=1, upper_bound=1))) si_mo_2 = si_a % 3 nose.tools.assert_equal(si_mo_2.size(), 32) nose.tools.assert_true( is_equal(si_mo_2, claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2))) # # Extracting the sign bit # # a negative integer si = claripy.SI(bits=64, stride=0, lower_bound=-1, upper_bound=-1) sb = si[63:63] nose.tools.assert_true(is_equal(sb, claripy.SI(bits=1, to_conv=1))) # non-positive integers si = claripy.SI(bits=64, stride=1, lower_bound=-1, upper_bound=0) sb = si[63:63] nose.tools.assert_true( is_equal(sb, claripy.SI(bits=1, stride=1, lower_bound=0, upper_bound=1))) # Extracting an integer si = claripy.SI(bits=64, stride=0, lower_bound=0x7fffffffffff0000, upper_bound=0x7fffffffffff0000) part1 = si[63:32] part2 = si[31:0] nose.tools.assert_true( is_equal( part1, claripy.SI(bits=32, stride=0, lower_bound=0x7fffffff, upper_bound=0x7fffffff))) nose.tools.assert_true( is_equal( part2, claripy.SI(bits=32, stride=0, lower_bound=0xffff0000, upper_bound=0xffff0000))) # Concatenating two integers si_concat = part1.concat(part2) nose.tools.assert_true(is_equal(si_concat, si)) # Extracting a claripy.SI si = claripy.SI(bits=64, stride=0x9, lower_bound=0x1, upper_bound=0xa) part1 = si[63:32] part2 = si[31:0] nose.tools.assert_true( is_equal( part1, claripy.SI(bits=32, stride=0, lower_bound=0x0, upper_bound=0x0))) nose.tools.assert_true( is_equal(part2, claripy.SI(bits=32, stride=9, lower_bound=1, upper_bound=10))) # Concatenating two claripy.SIs si_concat = part1.concat(part2) nose.tools.assert_true(is_equal(si_concat, si)) # Zero-Extend the low part si_zeroextended = part2.zero_extend(32) nose.tools.assert_true( is_equal(si_zeroextended, claripy.SI(bits=64, stride=9, lower_bound=1, upper_bound=10))) # Sign-extension si_signextended = part2.sign_extend(32) nose.tools.assert_true( is_equal(si_signextended, claripy.SI(bits=64, stride=9, lower_bound=1, upper_bound=10))) # Extract from the result above si_extracted = si_zeroextended[31:0] nose.tools.assert_true( is_equal(si_extracted, claripy.SI(bits=32, stride=9, lower_bound=1, upper_bound=10))) # Union si_union_1 = si1.union(si2) nose.tools.assert_true( is_equal(si_union_1, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_union_2 = si1.union(si3) nose.tools.assert_true( is_equal( si_union_2, claripy.SI(bits=32, stride=18, lower_bound=10, upper_bound=28))) si_union_3 = si1.union(si_a) nose.tools.assert_true( is_equal(si_union_3, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20))) si_union_4 = si_a.union(si_b) nose.tools.assert_true( is_equal( si_union_4, claripy.SI(bits=32, stride=2, lower_bound=-100, upper_bound=200))) si_union_5 = si_b.union(si_c) nose.tools.assert_true( is_equal( si_union_5, claripy.SI(bits=32, stride=1, lower_bound=-100, upper_bound=200))) # Intersection si_intersection_1 = si1.intersection(si1) nose.tools.assert_true(is_equal(si_intersection_1, si2)) si_intersection_2 = si1.intersection(si2) nose.tools.assert_true( is_equal(si_intersection_2, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_intersection_3 = si1.intersection(si_a) nose.tools.assert_true( is_equal(si_intersection_3, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_intersection_4 = si_a.intersection(si_b) nose.tools.assert_true( is_equal(si_intersection_4, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20))) si_intersection_5 = si_b.intersection(si_c) nose.tools.assert_true( is_equal( si_intersection_5, claripy.SI(bits=32, stride=6, lower_bound=-100, upper_bound=200))) # Sign-extension si = claripy.SI(bits=1, stride=0, lower_bound=1, upper_bound=1) si_signextended = si.sign_extend(31) nose.tools.assert_true( is_equal( si_signextended, claripy.SI(bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) # Comparison between claripy.SI and BVV si = claripy.SI(bits=32, stride=1, lower_bound=-0x7f, upper_bound=0x7f) si.uninitialized = True bvv = BVV(0x30, 32) comp = (si < bvv) nose.tools.assert_equal(comp.model, MaybeResult()) # Better extraction # si = <32>0x1000000[0xcffffff, 0xdffffff]R si = claripy.SI(bits=32, stride=0x1000000, lower_bound=0xcffffff, upper_bound=0xdffffff) si_byte0 = si[7:0] si_byte1 = si[15:8] si_byte2 = si[23:16] si_byte3 = si[31:24] nose.tools.assert_true( is_equal( si_byte0, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true( is_equal( si_byte1, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true( is_equal( si_byte2, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true( is_equal( si_byte3, claripy.SI(bits=8, stride=1, lower_bound=0xc, upper_bound=0xd))) # Optimization on bitwise-and si_1 = claripy.SI(bits=32, stride=1, lower_bound=0x0, upper_bound=0xffffffff) si_2 = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) si = si_1 & si_2 nose.tools.assert_true( is_equal( si, claripy.SI(bits=32, stride=0x80000000, lower_bound=0, upper_bound=0x80000000))) si_1 = claripy.SI(bits=32, stride=1, lower_bound=0x0, upper_bound=0x7fffffff) si_2 = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) si = si_1 & si_2 nose.tools.assert_true( is_equal(si, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0))) # # ValueSet # vs_1 = claripy.ValueSet(bits=32) nose.tools.assert_true(vs_1.model.is_empty, True) # Test merging two addresses vs_1.model.merge_si('global', si1) vs_1.model.merge_si('global', si3) nose.tools.assert_true( vs_1.model.get_si('global').identical( SI(bits=32, stride=18, lower_bound=10, upper_bound=28).model)) # Length of this ValueSet nose.tools.assert_equal(len(vs_1.model), 32) vs_1 = claripy.ValueSet(name='boo', bits=32) vs_2 = claripy.ValueSet(name='boo', bits=32) nose.tools.assert_true(vs_1.identical(vs_1)) nose.tools.assert_true(vs_1.identical(vs_2)) vs_1.model.merge_si('global', si1) nose.tools.assert_false(vs_1.identical(vs_2)) vs_2.model.merge_si('global', si1) nose.tools.assert_true(vs_1.identical(vs_2)) vs_1.model.merge_si('global', si3) nose.tools.assert_false(vs_1.identical(vs_2)) # # IfProxy # # max and min on IfProxy si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=0xffffffff) if_0 = claripy.If(si == 0, si, si - 1) max_val = b.max(if_0) min_val = b.min(if_0) nose.tools.assert_true(max_val, 0xffffffff) nose.tools.assert_true(min_val, -0x80000000) # if_1 = And(VS_2, IfProxy(si == 0, 0, 1)) vs_2 = VS(region='global', bits=32, val=0xFA7B00B) si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=1) if_1 = (vs_2 & claripy.If( si == 0, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0), claripy.SI( bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) nose.tools.assert_true( claripy.is_true( if_1.model.trueexpr == VS(region='global', bits=32, val=0).model)) nose.tools.assert_true(claripy.is_true(if_1.model.falseexpr == vs_2.model)) # if_2 = And(VS_3, IfProxy(si != 0, 0, 1) vs_3 = claripy.ValueSet(region='global', bits=32, val=0xDEADCA7) si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=1) if_2 = (vs_3 & claripy.If( si != 0, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0), claripy.SI( bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) nose.tools.assert_true( claripy.is_true( if_2.model.trueexpr == VS(region='global', bits=32, val=0).model)) nose.tools.assert_true(claripy.is_true(if_2.model.falseexpr == vs_3.model)) # Something crazy is gonna happen... if_3 = if_1 + if_2 nose.tools.assert_true(claripy.is_true(if_3.model.trueexpr == vs_3.model)) nose.tools.assert_true(claripy.is_true(if_3.model.falseexpr == vs_2.model))
def test_vsa(): # Set backend b = claripy.backends.vsa SI = claripy.SI VS = claripy.ValueSet BVV = claripy.BVV # Disable the use of DiscreteStridedIntervalSet claripy.vsa.strided_interval.allow_dsis = False def is_equal(ast_0, ast_1): return claripy.backends.vsa.identical(ast_0, ast_1) si1 = claripy.TSI(32, name="foo", explicit_name=True) nose.tools.assert_equal(vsa_model(si1).name, "foo") # Normalization si1 = SI(bits=32, stride=1, lower_bound=10, upper_bound=10) nose.tools.assert_equal(vsa_model(si1).stride, 0) # Integers si1 = claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10) si2 = claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10) si3 = claripy.SI(bits=32, stride=0, lower_bound=28, upper_bound=28) # Strided intervals si_a = claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20) si_b = claripy.SI(bits=32, stride=2, lower_bound=-100, upper_bound=200) si_c = claripy.SI(bits=32, stride=3, lower_bound=-100, upper_bound=200) si_d = claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=60) si_e = claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x3000) si_f = claripy.SI(bits=16, stride=1, lower_bound=0, upper_bound=255) si_g = claripy.SI(bits=16, stride=1, lower_bound=0, upper_bound=0xff) si_h = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) nose.tools.assert_true(is_equal(si1, claripy.SI(bits=32, to_conv=10))) nose.tools.assert_true(is_equal(si2, claripy.SI(bits=32, to_conv=10))) nose.tools.assert_true(is_equal(si1, si2)) # __add__ si_add_1 = si1 + si2 nose.tools.assert_true(is_equal(si_add_1, claripy.SI(bits=32, stride=0, lower_bound=20, upper_bound=20))) si_add_2 = si1 + si_a nose.tools.assert_true(is_equal(si_add_2, claripy.SI(bits=32, stride=2, lower_bound=20, upper_bound=30))) si_add_3 = si_a + si_b nose.tools.assert_true(is_equal(si_add_3, claripy.SI(bits=32, stride=2, lower_bound=-90, upper_bound=220))) si_add_4 = si_b + si_c nose.tools.assert_true(is_equal(si_add_4, claripy.SI(bits=32, stride=1, lower_bound=-200, upper_bound=400))) # __add__ with overflow si_add_5 = si_h + 0xffffffff nose.tools.assert_true(is_equal(si_add_5, claripy.SI(bits=32, stride=0, lower_bound=0x7fffffff, upper_bound=0x7fffffff))) # __sub__ si_minus_1 = si1 - si2 nose.tools.assert_true(is_equal(si_minus_1, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0))) si_minus_2 = si_a - si_b nose.tools.assert_true(is_equal(si_minus_2, claripy.SI(bits=32, stride=2, lower_bound=-190, upper_bound=120))) si_minus_3 = si_b - si_c nose.tools.assert_true(is_equal(si_minus_3, claripy.SI(bits=32, stride=1, lower_bound=-300, upper_bound=300))) # __neg__ / __invert__ / bitwise not si_neg_1 = ~si1 nose.tools.assert_true(is_equal(si_neg_1, claripy.SI(bits=32, to_conv=-11))) si_neg_2 = ~si_b nose.tools.assert_true(is_equal(si_neg_2, claripy.SI(bits=32, stride=2, lower_bound=-201, upper_bound=99))) # __or__ si_or_1 = si1 | si3 nose.tools.assert_true(is_equal(si_or_1, claripy.SI(bits=32, to_conv=30))) si_or_2 = si1 | si2 nose.tools.assert_true(is_equal(si_or_2, claripy.SI(bits=32, to_conv=10))) si_or_3 = si1 | si_a # An integer | a strided interval nose.tools.assert_true(is_equal(si_or_3 , claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=30))) si_or_3 = si_a | si1 # Exchange the operands nose.tools.assert_true(is_equal(si_or_3, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=30))) si_or_4 = si_a | si_d # A strided interval | another strided interval nose.tools.assert_true(is_equal(si_or_4, claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=62))) si_or_4 = si_d | si_a # Exchange the operands nose.tools.assert_true(is_equal(si_or_4, claripy.SI(bits=32, stride=2, lower_bound=50, upper_bound=62))) si_or_5 = si_e | si_f # nose.tools.assert_true(is_equal(si_or_5, claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x30ff))) si_or_6 = si_e | si_g # nose.tools.assert_true(is_equal(si_or_6, claripy.SI(bits=16, stride=1, lower_bound=0x2000, upper_bound=0x30ff))) # Shifting si_shl_1 = si1 << 3 nose.tools.assert_equal(si_shl_1.size(), 32) nose.tools.assert_true(is_equal(si_shl_1, claripy.SI(bits=32, stride=0, lower_bound=80, upper_bound=80))) # Multiplication si_mul_1 = si1 * 3 nose.tools.assert_equal(si_mul_1.size(), 32) nose.tools.assert_true(is_equal(si_mul_1, claripy.SI(bits=32, stride=0, lower_bound=30, upper_bound=30))) si_mul_2 = si_a * 3 nose.tools.assert_equal(si_mul_2.size(), 32) nose.tools.assert_true(is_equal(si_mul_2, claripy.SI(bits=32, stride=6, lower_bound=30, upper_bound=60))) si_mul_3 = si_a * si_b nose.tools.assert_equal(si_mul_3.size(), 32) nose.tools.assert_true(is_equal(si_mul_3, claripy.SI(bits=32, stride=2, lower_bound=-2000, upper_bound=4000))) # Division si_div_1 = si1 / 3 nose.tools.assert_equal(si_div_1.size(), 32) nose.tools.assert_true(is_equal(si_div_1, claripy.SI(bits=32, stride=0, lower_bound=3, upper_bound=3))) si_div_2 = si_a / 3 nose.tools.assert_equal(si_div_2.size(), 32) nose.tools.assert_true(is_equal(si_div_2, claripy.SI(bits=32, stride=1, lower_bound=3, upper_bound=6))) # Modulo si_mo_1 = si1 % 3 nose.tools.assert_equal(si_mo_1.size(), 32) nose.tools.assert_true(is_equal(si_mo_1, claripy.SI(bits=32, stride=0, lower_bound=1, upper_bound=1))) si_mo_2 = si_a % 3 nose.tools.assert_equal(si_mo_2.size(), 32) nose.tools.assert_true(is_equal(si_mo_2, claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2))) # # Extracting the sign bit # # a negative integer si = claripy.SI(bits=64, stride=0, lower_bound=-1, upper_bound=-1) sb = si[63: 63] nose.tools.assert_true(is_equal(sb, claripy.SI(bits=1, to_conv=1))) # non-positive integers si = claripy.SI(bits=64, stride=1, lower_bound=-1, upper_bound=0) sb = si[63: 63] nose.tools.assert_true(is_equal(sb, claripy.SI(bits=1, stride=1, lower_bound=0, upper_bound=1))) # Extracting an integer si = claripy.SI(bits=64, stride=0, lower_bound=0x7fffffffffff0000, upper_bound=0x7fffffffffff0000) part1 = si[63 : 32] part2 = si[31 : 0] nose.tools.assert_true(is_equal(part1, claripy.SI(bits=32, stride=0, lower_bound=0x7fffffff, upper_bound=0x7fffffff))) nose.tools.assert_true(is_equal(part2, claripy.SI(bits=32, stride=0, lower_bound=0xffff0000, upper_bound=0xffff0000))) # Concatenating two integers si_concat = part1.concat(part2) nose.tools.assert_true(is_equal(si_concat, si)) # Extracting a claripy.SI si = claripy.SI(bits=64, stride=0x9, lower_bound=0x1, upper_bound=0xa) part1 = si[63 : 32] part2 = si[31 : 0] nose.tools.assert_true(is_equal(part1, claripy.SI(bits=32, stride=0, lower_bound=0x0, upper_bound=0x0))) nose.tools.assert_true(is_equal(part2, claripy.SI(bits=32, stride=9, lower_bound=1, upper_bound=10))) # Concatenating two claripy.SIs si_concat = part1.concat(part2) nose.tools.assert_true(is_equal(si_concat, si)) # Concatenating two SIs that are of different sizes si_1 = SI(bits=64, stride=1, lower_bound=0, upper_bound=0xffffffffffffffff) si_2 = SI(bits=32, stride=1, lower_bound=0, upper_bound=0xffffffff) si_concat = si_1.concat(si_2) nose.tools.assert_true(is_equal(si_concat, SI(bits=96, stride=1, lower_bound=0, upper_bound=0xffffffffffffffffffffffff))) # Zero-Extend the low part si_zeroextended = part2.zero_extend(32) nose.tools.assert_true(is_equal(si_zeroextended, claripy.SI(bits=64, stride=9, lower_bound=1, upper_bound=10))) # Sign-extension si_signextended = part2.sign_extend(32) nose.tools.assert_true(is_equal(si_signextended, claripy.SI(bits=64, stride=9, lower_bound=1, upper_bound=10))) # Extract from the result above si_extracted = si_zeroextended[31:0] nose.tools.assert_true(is_equal(si_extracted, claripy.SI(bits=32, stride=9, lower_bound=1, upper_bound=10))) # Union si_union_1 = si1.union(si2) nose.tools.assert_true(is_equal(si_union_1, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_union_2 = si1.union(si3) nose.tools.assert_true(is_equal(si_union_2, claripy.SI(bits=32, stride=18, lower_bound=10, upper_bound=28))) si_union_3 = si1.union(si_a) nose.tools.assert_true(is_equal(si_union_3, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20))) si_union_4 = si_a.union(si_b) nose.tools.assert_true(is_equal(si_union_4, claripy.SI(bits=32, stride=2, lower_bound=-100, upper_bound=200))) si_union_5 = si_b.union(si_c) nose.tools.assert_true(is_equal(si_union_5, claripy.SI(bits=32, stride=1, lower_bound=-100, upper_bound=200))) # Intersection si_intersection_1 = si1.intersection(si1) nose.tools.assert_true(is_equal(si_intersection_1, si2)) si_intersection_2 = si1.intersection(si2) nose.tools.assert_true(is_equal(si_intersection_2, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_intersection_3 = si1.intersection(si_a) nose.tools.assert_true(is_equal(si_intersection_3, claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10))) si_intersection_4 = si_a.intersection(si_b) nose.tools.assert_true(is_equal(si_intersection_4, claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=20))) si_intersection_5 = si_b.intersection(si_c) nose.tools.assert_true(is_equal(si_intersection_5, claripy.SI(bits=32, stride=6, lower_bound=-100, upper_bound=200))) # More intersections t0 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=0x27) t1 = claripy.SI(bits=32, stride=0x7fffffff, lower_bound=0x80000002, upper_bound=1) si_is_6 = t0.intersection(t1) nose.tools.assert_true(is_equal(si_is_6, claripy.SI(bits=32, stride=0, lower_bound=1, upper_bound=1))) t2 = claripy.SI(bits=32, stride=5, lower_bound=20, upper_bound=30) t3 = claripy.SI(bits=32, stride=1, lower_bound=27, upper_bound=0xffffffff) si_is_7 = t2.intersection(t3) nose.tools.assert_true(is_equal(si_is_7, claripy.SI(bits=32, stride=0, lower_bound=30, upper_bound=30))) t4 = claripy.SI(bits=32, stride=5, lower_bound=-400, upper_bound=400) t5 = claripy.SI(bits=32, stride=1, lower_bound=395, upper_bound=-395) si_is_8 = t4.intersection(t5) nose.tools.assert_true(is_equal(si_is_8, claripy.SI(bits=32, stride=5, lower_bound=-400, upper_bound=400))) # Sign-extension si = claripy.SI(bits=1, stride=0, lower_bound=1, upper_bound=1) si_signextended = si.sign_extend(31) nose.tools.assert_true(is_equal(si_signextended, claripy.SI(bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) # Comparison between claripy.SI and BVV si = claripy.SI(bits=32, stride=1, lower_bound=-0x7f, upper_bound=0x7f) si._model_vsa.uninitialized = True bvv = BVV(0x30, 32) comp = (si < bvv) nose.tools.assert_true(vsa_model(comp).identical(MaybeResult())) # Better extraction # si = <32>0x1000000[0xcffffff, 0xdffffff]R si = claripy.SI(bits=32, stride=0x1000000, lower_bound=0xcffffff, upper_bound=0xdffffff) si_byte0 = si[7: 0] si_byte1 = si[15: 8] si_byte2 = si[23: 16] si_byte3 = si[31: 24] nose.tools.assert_true(is_equal(si_byte0, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true(is_equal(si_byte1, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true(is_equal(si_byte2, claripy.SI(bits=8, stride=0, lower_bound=0xff, upper_bound=0xff))) nose.tools.assert_true(is_equal(si_byte3, claripy.SI(bits=8, stride=1, lower_bound=0xc, upper_bound=0xd))) # Optimization on bitwise-and si_1 = claripy.SI(bits=32, stride=1, lower_bound=0x0, upper_bound=0xffffffff) si_2 = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) si = si_1 & si_2 nose.tools.assert_true(is_equal(si, claripy.SI(bits=32, stride=0x80000000, lower_bound=0, upper_bound=0x80000000))) si_1 = claripy.SI(bits=32, stride=1, lower_bound=0x0, upper_bound=0x7fffffff) si_2 = claripy.SI(bits=32, stride=0, lower_bound=0x80000000, upper_bound=0x80000000) si = si_1 & si_2 nose.tools.assert_true(is_equal(si, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0))) # Concatenation: concat with zeros only increases the stride si_1 = claripy.SI(bits=8, stride=0xff, lower_bound=0x0, upper_bound=0xff) si_2 = claripy.SI(bits=8, stride=0, lower_bound=0, upper_bound=0) si = si_1.concat(si_2) nose.tools.assert_true(is_equal(si, claripy.SI(bits=16, stride=0xff00, lower_bound=0, upper_bound=0xff00))) # Extract from a reversed value si_1 = claripy.SI(bits=64, stride=0xff, lower_bound=0x0, upper_bound=0xff) si_2 = si_1.reversed[63 : 56] nose.tools.assert_true(is_equal(si_2, claripy.SI(bits=8, stride=0xff, lower_bound=0x0, upper_bound=0xff))) # # ValueSet # def VS(name=None, bits=None, region=None, val=None): region = 'foobar' if region is None else region return claripy.ValueSet(bits, region=region, region_base_addr=0, value=val, name=name) vs_1 = VS(bits=32, val=0) vs_1 = vs_1.intersection(VS(bits=32, val=1)) nose.tools.assert_true(vsa_model(vs_1).is_empty) # Test merging two addresses vsa_model(vs_1)._merge_si('global', 0, vsa_model(si1)) vsa_model(vs_1)._merge_si('global', 0, vsa_model(si3)) nose.tools.assert_true(vsa_model(vs_1).get_si('global').identical(vsa_model(SI(bits=32, stride=18, lower_bound=10, upper_bound=28)))) # Length of this ValueSet nose.tools.assert_equal(len(vsa_model(vs_1)), 32) vs_1 = VS(name='boo', bits=32, val=0).intersection(VS(name='makeitempty', bits=32, val=1)) vs_2 = VS(name='foo', bits=32, val=0).intersection(VS(name='makeitempty', bits=32, val=1)) nose.tools.assert_true(claripy.backends.vsa.identical(vs_1, vs_1)) nose.tools.assert_true(claripy.backends.vsa.identical(vs_2, vs_2)) vsa_model(vs_1)._merge_si('global', 0, vsa_model(si1)) nose.tools.assert_false(claripy.backends.vsa.identical(vs_1, vs_2)) vsa_model(vs_2)._merge_si('global', 0, vsa_model(si1)) nose.tools.assert_true(claripy.backends.vsa.identical(vs_1, vs_2)) nose.tools.assert_true(claripy.backends.vsa.is_true((vs_1 & vs_2) == vs_1)) vsa_model(vs_1)._merge_si('global', 0, vsa_model(si3)) nose.tools.assert_false(claripy.backends.vsa.identical(vs_1, vs_2)) # Subtraction # Subtraction of two pointers yields a concrete value vs_1 = VS(name='foo', region='global', bits=32, val=0x400010) vs_2 = VS(name='bar', region='global', bits=32, val=0x400000) si = vs_1 - vs_2 nose.tools.assert_is(type(vsa_model(si)), StridedInterval) nose.tools.assert_true(claripy.backends.vsa.identical(si, claripy.SI(bits=32, stride=0, lower_bound=0x10, upper_bound=0x10))) # # IfProxy # si = claripy.SI(bits=32, stride=1, lower_bound=10, upper_bound=0xffffffff) if_0 = claripy.If(si == 0, si, si - 1) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_0)) nose.tools.assert_false(claripy.backends.vsa.identical(if_0, si)) # max and min on IfProxy si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=0xffffffff) if_0 = claripy.If(si == 0, si, si - 1) max_val = b.max(if_0) min_val = b.min(if_0) nose.tools.assert_equal(max_val, 0xffffffff) nose.tools.assert_equal(min_val, 0x00000000) # identical nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_0)) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, si)) if_0_copy = claripy.If(si == 0, si, si - 1) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_0_copy)) if_1 = claripy.If(si == 1, si, si - 1) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_1)) si = SI(bits=32, stride=0, lower_bound=1, upper_bound=1) if_0 = claripy.If(si == 0, si, si - 1) if_0_copy = claripy.If(si == 0, si, si - 1) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_0_copy)) if_1 = claripy.If(si == 1, si, si - 1) nose.tools.assert_false(claripy.backends.vsa.identical(if_0, if_1)) if_1 = claripy.If(si == 0, si + 1, si - 1) nose.tools.assert_true(claripy.backends.vsa.identical(if_0, if_1)) if_1 = claripy.If(si == 0, si, si) nose.tools.assert_false(claripy.backends.vsa.identical(if_0, if_1)) # if_1 = And(VS_2, IfProxy(si == 0, 0, 1)) vs_2 = VS(region='global', bits=32, val=0xFA7B00B) si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=1) if_1 = (vs_2 & claripy.If(si == 0, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0), claripy.SI(bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) nose.tools.assert_true(claripy.backends.vsa.is_true(vsa_model(if_1.ite_excavated.args[1]) == vsa_model(VS(region='global', bits=32, val=0)))) nose.tools.assert_true(claripy.backends.vsa.is_true(vsa_model(if_1.ite_excavated.args[2]) == vsa_model(vs_2))) # if_2 = And(VS_3, IfProxy(si != 0, 0, 1) vs_3 = VS(region='global', bits=32, val=0xDEADCA7) si = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=1) if_2 = (vs_3 & claripy.If(si != 0, claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0), claripy.SI(bits=32, stride=0, lower_bound=0xffffffff, upper_bound=0xffffffff))) nose.tools.assert_true(claripy.backends.vsa.is_true(vsa_model(if_2.ite_excavated.args[1]) == vsa_model(VS(region='global', bits=32, val=0)))) nose.tools.assert_true(claripy.backends.vsa.is_true(vsa_model(if_2.ite_excavated.args[2]) == vsa_model(vs_3)))