Esempio n. 1
0
    def state_blank(self,
                    addr=None,
                    initial_prefix=None,
                    stack_size=1024 * 1024 * 8,
                    **kwargs):
        """
        Initialize a blank state.

        All parameters are optional.

        :param addr:            The execution start address.
        :param initial_prefix:
        :param stack_size:      The number of bytes to allocate for stack space
        :return:                The initialized SimState.

        Any additional arguments will be passed to the SimState constructor
        """
        if kwargs.get('mode', None) is None:
            kwargs['mode'] = self.project._default_analysis_mode
        if kwargs.get('permissions_backer', None) is None:
            # just a dict of address ranges to permission bits
            permission_map = {}
            for obj in self.project.loader.all_objects:
                for seg in obj.segments:
                    perms = 0
                    # bit values based off of protection bit values from sys/mman.h
                    if seg.is_readable:
                        perms |= 1  # PROT_READ
                    if seg.is_writable:
                        perms |= 2  # PROT_WRITE
                    if seg.is_executable:
                        perms |= 4  # PROT_EXEC
                    permission_map[(seg.min_addr, seg.max_addr)] = perms
            permissions_backer = (self.project.loader.main_bin.execstack,
                                  permission_map)
            kwargs['permissions_backer'] = permissions_backer
        if kwargs.get('memory_backer', None) is None:
            kwargs['memory_backer'] = self.project.loader.memory
        if kwargs.get('os_name', None) is None:
            kwargs['os_name'] = self.name

        state = SimState(self.project, **kwargs)

        stack_end = state.arch.initial_sp
        if o.ABSTRACT_MEMORY not in state.options:
            state.memory.mem._preapproved_stack = IRange(
                stack_end - stack_size, stack_end)

        if o.INITIALIZE_ZERO_REGISTERS in state.options:
            highest_reg_offset, reg_size = max(state.arch.registers.values())
            for i in range(0, highest_reg_offset + reg_size, state.arch.bytes):
                state.registers.store(i, state.se.BVV(0, state.arch.bits))
        if hasattr(state.regs, "sp"):
            state.regs.sp = stack_end

        if initial_prefix is not None:
            for reg in state.arch.default_symbolic_registers:
                state.registers.store(
                    reg,
                    claripy.BVS(initial_prefix + "_" + reg,
                                state.arch.bits,
                                explicit_name=True))

        for reg, val, is_addr, mem_region in state.arch.default_register_values:

            region_base = None  # so pycharm does not complain

            if is_addr:
                if isinstance(mem_region, tuple):
                    # unpack it
                    mem_region, region_base = mem_region
                elif mem_region == 'global':
                    # Backward compatibility
                    region_base = 0
                else:
                    raise AngrSimOSError(
                        'You must specify the base address for memory region "%s". '
                        % mem_region)

            if o.ABSTRACT_MEMORY in state.options and is_addr:
                address = claripy.ValueSet(state.arch.bits, mem_region,
                                           region_base, val)
                state.registers.store(reg, address)
            else:
                state.registers.store(reg, val)

        if addr is None: addr = self.project.entry
        state.regs.ip = addr

        # set up the "root history" node
        state.scratch.ins_addr = addr
        state.scratch.bbl_addr = addr
        state.scratch.stmt_idx = 0
        state.history.jumpkind = 'Ijk_Boring'
        return state
Esempio n. 2
0
File: simos.py Progetto: pbst/angr
    def state_blank(self,
                    addr=None,
                    initial_prefix=None,
                    brk=None,
                    stack_end=None,
                    stack_size=1024 * 1024 * 8,
                    stdin=None,
                    **kwargs):
        """
        Initialize a blank state.

        All parameters are optional.

        :param addr:            The execution start address.
        :param initial_prefix:
        :param stack_end:       The end of the stack (i.e., the byte after the last valid stack address).
        :param stack_size:      The number of bytes to allocate for stack space
        :param brk:             The address of the process' break.
        :return:                The initialized SimState.

        Any additional arguments will be passed to the SimState constructor
        """
        # TODO: move ALL of this into the SimState constructor
        if kwargs.get('mode', None) is None:
            kwargs['mode'] = self.project._default_analysis_mode
        if kwargs.get('permissions_backer', None) is None:
            # just a dict of address ranges to permission bits
            permission_map = {}
            for obj in self.project.loader.all_objects:
                for seg in obj.segments:
                    perms = 0
                    # bit values based off of protection bit values from sys/mman.h
                    if seg.is_readable:
                        perms |= 1  # PROT_READ
                    if seg.is_writable:
                        perms |= 2  # PROT_WRITE
                    if seg.is_executable:
                        perms |= 4  # PROT_EXEC
                    permission_map[(seg.min_addr, seg.max_addr)] = perms
            permissions_backer = (self.project.loader.main_object.execstack,
                                  permission_map)
            kwargs['permissions_backer'] = permissions_backer
        if kwargs.get('memory_backer', None) is None:
            kwargs['memory_backer'] = self.project.loader.memory
        if kwargs.get('os_name', None) is None:
            kwargs['os_name'] = self.name

        state = SimState(self.project, **kwargs)

        if stdin is not None and not isinstance(stdin, SimFileBase):
            if type(stdin) is type:
                stdin = stdin(name='stdin', has_end=False)
            else:
                stdin = SimFileStream(name='stdin',
                                      content=stdin,
                                      has_end=True)

        last_addr = self.project.loader.main_object.max_addr
        actual_brk = (last_addr - last_addr % 0x1000 +
                      0x1000) if brk is None else brk
        state.register_plugin('posix',
                              SimSystemPosix(stdin=stdin, brk=actual_brk))

        actual_stack_end = state.arch.initial_sp if stack_end is None else stack_end
        if o.ABSTRACT_MEMORY not in state.options:
            state.memory.mem._preapproved_stack = IRange(
                actual_stack_end - stack_size, actual_stack_end)

        if o.INITIALIZE_ZERO_REGISTERS in state.options:
            highest_reg_offset, reg_size = max(state.arch.registers.values())
            for i in range(0, highest_reg_offset + reg_size, state.arch.bytes):
                state.registers.store(i, state.solver.BVV(0, state.arch.bits))
        if state.arch.sp_offset is not None:
            state.regs.sp = actual_stack_end

        if initial_prefix is not None:
            for reg in state.arch.default_symbolic_registers:
                state.registers.store(
                    reg,
                    state.solver.BVS(initial_prefix + "_" + reg,
                                     state.arch.bits,
                                     explicit_name=True,
                                     key=('reg', reg),
                                     eternal=True))

        for reg, val, is_addr, mem_region in state.arch.default_register_values:

            region_base = None  # so pycharm does not complain

            if is_addr:
                if isinstance(mem_region, tuple):
                    # unpack it
                    mem_region, region_base = mem_region
                elif mem_region == 'global':
                    # Backward compatibility
                    region_base = 0
                else:
                    raise AngrSimOSError(
                        'You must specify the base address for memory region "%s". '
                        % mem_region)

            # special case for stack pointer override
            if actual_stack_end is not None and state.arch.registers[reg][
                    0] == state.arch.sp_offset:
                continue

            if o.ABSTRACT_MEMORY in state.options and is_addr:
                address = claripy.ValueSet(state.arch.bits, mem_region,
                                           region_base, val)
                state.registers.store(reg, address)
            else:
                state.registers.store(reg, val)

        if addr is None: addr = self.project.entry
        state.regs.ip = addr

        # set up the "root history" node
        state.scratch.ins_addr = addr
        state.scratch.bbl_addr = addr
        state.scratch.stmt_idx = 0
        state.history.jumpkind = 'Ijk_Boring'

        return state
Esempio n. 3
0
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))
Esempio n. 4
0
 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)
Esempio n. 5
0
    def state_blank(self,
                    addr=None,
                    initial_prefix=None,
                    brk=None,
                    stack_end=None,
                    stack_size=1024 * 1024 * 8,
                    stdin=None,
                    thread_idx=None,
                    permissions_backer=None,
                    **kwargs):
        """
        Initialize a blank state.

        All parameters are optional.

        :param addr:            The execution start address.
        :param initial_prefix:
        :param stack_end:       The end of the stack (i.e., the byte after the last valid stack address).
        :param stack_size:      The number of bytes to allocate for stack space
        :param brk:             The address of the process' break.
        :return:                The initialized SimState.

        Any additional arguments will be passed to the SimState constructor
        """
        # TODO: move ALL of this into the SimState constructor
        if kwargs.get('mode', None) is None:
            kwargs['mode'] = self.project._default_analysis_mode
        if permissions_backer is not None:
            kwargs['permissions_map'] = permissions_backer[1]
            kwargs['default_permissions'] = 7 if permissions_backer[0] else 3
        if kwargs.get('cle_memory_backer', None) is None:
            kwargs['cle_memory_backer'] = self.project.loader
        if kwargs.get('os_name', None) is None:
            kwargs['os_name'] = self.name
        actual_stack_end = stack_end
        if stack_end is None:
            stack_end = self.arch.initial_sp

        if kwargs.get('permissions_map', None) is None:
            # just a dict of address ranges to permission bits
            permission_map = {}
            for obj in self.project.loader.all_objects:
                for seg in obj.segments:
                    perms = 0
                    # bit values based off of protection bit values from sys/mman.h
                    if seg.is_readable:
                        perms |= 1  # PROT_READ
                    if seg.is_writable:
                        perms |= 2  # PROT_WRITE
                    if seg.is_executable:
                        perms |= 4  # PROT_EXEC
                    permission_map[(seg.min_addr, seg.max_addr)] = perms
            kwargs['permissions_map'] = permission_map
        if self.project.loader.main_object.execstack:
            stack_perms = 1 | 2 | 4  # RWX
        else:
            stack_perms = 1 | 2  # RW

        state = SimState(self.project,
                         stack_end=stack_end,
                         stack_size=stack_size,
                         stack_perms=stack_perms,
                         **kwargs)

        if stdin is not None and not isinstance(stdin, SimFileBase):
            if type(stdin) is type:
                stdin = stdin(name='stdin', has_end=False)
            else:
                if isinstance(stdin, claripy.Bits):
                    num_bytes = len(stdin) // self.project.arch.byte_width
                else:
                    num_bytes = len(stdin)
                _l.warning(
                    "stdin is constrained to %d bytes (has_end=True). If you are only providing the first "
                    "%d bytes instead of the entire stdin, please use "
                    "stdin=SimFileStream(name='stdin', content=your_first_n_bytes, has_end=False).",
                    num_bytes, num_bytes)
                stdin = SimFileStream(name='stdin',
                                      content=stdin,
                                      has_end=True)

        last_addr = self.project.loader.main_object.max_addr
        actual_brk = (last_addr - last_addr % 0x1000 +
                      0x1000) if brk is None else brk
        state.register_plugin('posix',
                              SimSystemPosix(stdin=stdin, brk=actual_brk))

        if state.arch.sp_offset is not None:
            state.regs.sp = stack_end

        if initial_prefix is not None:
            for reg in state.arch.default_symbolic_registers:
                state.registers.store(
                    reg,
                    state.solver.BVS(initial_prefix + "_" + reg,
                                     state.arch.bits,
                                     explicit_name=True,
                                     key=('reg', reg),
                                     eternal=True))

        for reg, val, is_addr, mem_region in state.arch.default_register_values:
            region_base = None  # so pycharm does not complain

            if is_addr:
                if isinstance(mem_region, tuple):
                    # unpack it
                    mem_region, region_base = mem_region
                elif mem_region == 'global':
                    # Backward compatibility
                    region_base = 0
                else:
                    raise AngrSimOSError(
                        'You must specify the base address for memory region "%s". '
                        % mem_region)

            # special case for stack_end overriding sp default
            if actual_stack_end is not None and state.arch.registers[reg][
                    0] == state.arch.sp_offset:
                continue

            if o.ABSTRACT_MEMORY in state.options and is_addr:
                address = claripy.ValueSet(state.arch.bits, mem_region,
                                           region_base, val)
                state.registers.store(reg, address)
            else:
                state.registers.store(reg, val)

        if addr is None:
            state.regs.ip = self.project.entry

        thread_name = self.project.loader.main_object.threads[
            thread_idx] if thread_idx is not None else None
        for reg, val in self.project.loader.main_object.thread_registers(
                thread_name).items():
            if reg in ('fs', 'gs', 'cs', 'ds', 'es',
                       'ss') and state.arch.name == 'X86':
                state.registers.store(reg, val >> 16)  # oh boy big hack
            elif reg in state.arch.registers or reg in ('flags', 'eflags',
                                                        'rflags'):
                state.registers.store(reg, val)
            elif reg == 'fctrl':
                state.regs.fpround = (val & 0xC00) >> 10
            elif reg == 'fstat':
                state.regs.fc3210 = (val & 0x4700)
            elif reg == 'ftag':
                empty_bools = [((val >> (x * 2)) & 3) == 3 for x in range(8)]
                tag_chars = [
                    claripy.BVV(0 if x else 1, 8) for x in empty_bools
                ]
                for i, tag in enumerate(tag_chars):
                    setattr(state.regs, 'fpu_t%d' % i, tag)
            elif reg in ('fiseg', 'fioff', 'foseg', 'fooff', 'fop'):
                pass
            elif reg == 'mxcsr':
                state.regs.sseround = (val & 0x600) >> 9
            else:
                _l.error("What is this register %s I have to translate?", reg)

        if addr is not None:
            state.regs.ip = addr

        # set up the "root history" node
        state.scratch.ins_addr = addr
        state.scratch.bbl_addr = addr
        state.scratch.stmt_idx = 0
        state.history.jumpkind = 'Ijk_Boring'

        return state
Esempio n. 6
0
    def state_blank(self, addr=None, initial_prefix=None, **kwargs):
        """
        Initialize a blank state.

        All parameters are optional.

        :param addr:            The execution start address.
        :param initial_prefix:
        :return:                The initialized SimState.
        :rtype:                 simuvex.SimState
        """
        if kwargs.get('mode', None) is None:
            kwargs['mode'] = self.proj._default_analysis_mode
        if kwargs.get('permissions_backer', None) is None:
            # just a dict of address ranges to permission bits
            permission_map = {}
            for obj in self.proj.loader.all_objects:
                for seg in obj.segments:
                    perms = 0
                    # bit values based off of protection bit values from sys/mman.h
                    if seg.is_readable:
                        perms |= 1  # PROT_READ
                    if seg.is_writable:
                        perms |= 2  # PROT_WRITE
                    if seg.is_executable:
                        perms |= 4  # PROT_EXEC
                    permission_map[(obj.rebase_addr + seg.min_addr,
                                    obj.rebase_addr + seg.max_addr)] = perms
            permissions_backer = (self.proj.loader.main_bin.execstack,
                                  permission_map)
            kwargs['permissions_backer'] = permissions_backer
        if kwargs.get('memory_backer', None) is None:
            kwargs['memory_backer'] = self.proj.loader.memory
        if kwargs.get('arch', None) is None:
            kwargs['arch'] = self.proj.arch

        state = SimState(**kwargs)

        if o.INITIALIZE_ZERO_REGISTERS in state.options:
            for r in self.arch.registers:
                setattr(state.regs, r, 0)

        state.regs.sp = self.arch.initial_sp

        if initial_prefix is not None:
            for reg in state.arch.default_symbolic_registers:
                state.registers.store(
                    reg,
                    claripy.BVS(initial_prefix + "_" + reg,
                                state.arch.bits,
                                explicit_name=True))

        for reg, val, is_addr, mem_region in state.arch.default_register_values:
            if o.ABSTRACT_MEMORY in state.options and is_addr:
                address = claripy.ValueSet(region=mem_region,
                                           bits=state.arch.bits,
                                           val=val)
                state.registers.store(reg, address)
            else:
                state.registers.store(reg, val)

        if addr is None: addr = self.proj.entry
        state.regs.ip = addr

        state.scratch.ins_addr = addr
        state.scratch.bbl_addr = addr
        state.scratch.stmt_idx = 0
        state.scratch.jumpkind = 'Ijk_Boring'

        state.procedure_data.hook_addr = self.continue_addr
        return state
Esempio n. 7
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
    #

    vs_1 = claripy.ValueSet(bits=32)
    nose.tools.assert_true(vsa_model(vs_1).is_empty, True)
    # Test merging two addresses
    vsa_model(vs_1).merge_si('global', vsa_model(si1))
    vsa_model(vs_1).merge_si('global', 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 = claripy.ValueSet(name='boo', bits=32)
    vs_2 = claripy.ValueSet(name='foo', bits=32)
    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', vsa_model(si1))
    nose.tools.assert_false(claripy.backends.vsa.identical(vs_1, vs_2))
    vsa_model(vs_2).merge_si('global', 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', 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 = claripy.ValueSet(name='foo', region='global', bits=32, val=0x400010)
    vs_2 = claripy.ValueSet(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 = 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.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)))