コード例 #1
0
ファイル: solver.py プロジェクト: AOS002/angr-fork
    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)
コード例 #2
0
ファイル: solver.py プロジェクト: sjcomeau43543/angr
    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)
コード例 #3
0
    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)
コード例 #4
0
ファイル: test_vsa.py プロジェクト: zhuyue1314/claripy
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))
コード例 #5
0
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)))