Exemplo n.º 1
0
def test_fauxware():

    amd64 = archinfo.arch_from_id('amd64')

    args = {
        'i386': [
            ('authenticate', SimCCCdecl(
                archinfo.arch_from_id('i386'),
                args=[SimStackArg(4, 4), SimStackArg(8, 4)], sp_delta=4, ret_val=SimRegArg('eax', 4),
                )
             ),
        ],
        'x86_64': [
            ('authenticate', SimCCSystemVAMD64(
                amd64,
                args=[SimRegArg('rdi', 8), SimRegArg('rsi', 8)],
                sp_delta=8,
                ret_val=SimRegArg('rax', 8),
                )
             ),
        ],
    }

    for arch, lst in args.items():
        yield run_fauxware, arch, lst
Exemplo n.º 2
0
def test_no_cross_insn_boundary_opt_amd64():

    # 0x4020f8:       sub     rsp, 8
    # 0x4020fc:       mov     rax, qword ptr [rip + 0x221ef5]
    # 0x402103:       test    rax, rax
    # 0x402106:       je      0x40210d

    b = binascii.unhexlify("4883ec08488b05f51e22004885c07405")
    p = angr.load_shellcode(b, 'amd64', load_address=0x4020f8)

    # No optimization
    block = p.factory.block(0x4020f8, size=len(b), opt_level=0)
    assert len(block.vex.statements) == 32
    # Full level-1 optimization
    block = p.factory.block(0x4020f8,
                            size=len(b),
                            opt_level=1,
                            cross_insn_opt=True)
    assert len(block.vex.statements) == 20
    # Level-1 optimization within each instruction
    block = p.factory.block(0x4020f8,
                            size=len(b),
                            opt_level=1,
                            cross_insn_opt=False)
    stmts = block.vex.statements
    assert len(stmts) == 25
    # 12 | ------ IMark(0x402103, 3, 0) ------
    assert isinstance(stmts[12], pyvex.IRStmt.IMark)
    assert stmts[12].addr == 0x402103
    # 13 | t6 = GET:I64(rax)
    assert isinstance(stmts[13], pyvex.IRStmt.WrTmp)
    assert isinstance(stmts[13].data, pyvex.IRExpr.Get)
    assert stmts[13].data.offset == archinfo.arch_from_id(
        'amd64').registers['rax'][0]
    # 14 | PUT(cc_op) = 0x0000000000000014
    assert isinstance(stmts[14], pyvex.IRStmt.Put)
    assert stmts[14].offset == archinfo.arch_from_id(
        'amd64').registers['cc_op'][0]
    assert isinstance(stmts[14].data, pyvex.IRExpr.Const)
    assert stmts[14].data.con.value == 0x14
    # 15 | PUT(cc_dep1) = t6
    assert isinstance(stmts[15], pyvex.IRStmt.Put)
    assert stmts[15].offset == archinfo.arch_from_id(
        'amd64').registers['cc_dep1'][0]
    # 16 | PUT(cc_dep2) = 0x0000000000000000
    assert isinstance(stmts[16], pyvex.IRStmt.Put)
    assert stmts[16].offset == archinfo.arch_from_id(
        'amd64').registers['cc_dep2'][0]
    assert isinstance(stmts[16].data, pyvex.IRExpr.Const)
    assert stmts[16].data.con.value == 0
    # 17 | PUT(rip) = 0x0000000000402106
    assert isinstance(stmts[17], pyvex.IRStmt.Put)
    assert stmts[17].offset == archinfo.arch_from_id(
        'amd64').registers['rip'][0]
    assert isinstance(stmts[17].data, pyvex.IRExpr.Const)
    assert stmts[17].data.con.value == 0x402106
    # 18 | ------ IMark(0x402106, 2, 0) ------
    assert isinstance(stmts[18], pyvex.IRStmt.IMark)
    assert stmts[18].addr == 0x402106
Exemplo n.º 3
0
def test_fauxware():

    amd64 = archinfo.arch_from_id("amd64")

    args = {
        'i386': [
            ('authenticate', SimCCCdecl(archinfo.arch_from_id('i386'), )),
        ],
        'x86_64': [
            ('authenticate', SimCCSystemVAMD64(amd64, )),
        ],
    }

    for arch, lst in args.items():
        yield run_fauxware, arch, lst
Exemplo n.º 4
0
    def compare_arch(arch_0: str, arch_1: str) -> bool:
        if arch_0 == arch_1:
            # fast path
            return True

        try:
            import archinfo
        except ImportError:
            _l.warning(
                "archinfo is not installed. Fall back to exact matching.")
            return arch_0 == arch_1

        arch0 = archinfo.arch_from_id(arch_0)
        arch1 = archinfo.arch_from_id(arch_1)
        return arch0.name == arch1.name and arch0.memory_endness == arch1.memory_endness
Exemplo n.º 5
0
    def test_arg_locs_array(self):
        arch = archinfo.arch_from_id("amd64")
        cc = SimCCSystemVAMD64(arch)
        proto = SimTypeFunction([SimTypeFixedSizeArray(SimTypeInt().with_arch(arch), 2).with_arch(arch)], None)

        # It should not raise any exception!
        cc.arg_locs(proto)
Exemplo n.º 6
0
def from_string(data,
                log_level=logging.WARNING,
                address_offset=None,
                bad_bytes=None,
                filter_func=None):
    gadgets_dict = pickle.loads(data)
    gadgets_list = [
        item for sublist in gadgets_dict.values() for item in sublist
    ]  # Flatten list of lists

    # Turn the names of the arch back into archinfo classes (Which aren't pickle-able)
    for gadget in gadgets_list:
        gadget.arch = archinfo.arch_from_id(gadget.arch)

    # Filter the gadgets if necessary
    if filter_func != None:
        gadgets_list = filter_func(gadgets_list)

    gl = GadgetList(gadgets_list, log_level)
    if address_offset != None:
        gl.adjust_base_address(address_offset)

    if bad_bytes != None:
        just_good_gadgets = GadgetList(log_level=log_level,
                                       bad_bytes=bad_bytes)
        for gadget in gl.foreach():
            if not gadget.has_bad_address(bad_bytes):
                just_good_gadgets.add_gadget(gadget)
        gl = just_good_gadgets

    return gl
Exemplo n.º 7
0
def load_shellcode(shellcode, arch, start_offset=0, load_address=0, thumb=False, **kwargs):
    """
    Load a new project based on a snippet of assembly or bytecode.

    :param shellcode:       The data to load, as either a bytestring of instructions or a string of assembly text
    :param arch:            The name of the arch to use, or an archinfo class
    :param start_offset:    The offset into the data to start analysis (default 0)
    :param load_address:    The address to place the data in memory (default 0)
    :param thumb:           Whether this is ARM Thumb shellcode
    """
    if not isinstance(arch, archinfo.Arch):
        arch = archinfo.arch_from_id(arch)
    if type(shellcode) is str:
        shellcode = arch.asm(shellcode, load_address, thumb=thumb)
    if thumb:
        start_offset |= 1

    return Project(
            BytesIO(shellcode),
            main_opts={
                'backend': 'blob',
                'arch': arch,
                'entry_point': start_offset,
                'base_addr': load_address,
            },
        **kwargs
        )
Exemplo n.º 8
0
Arquivo: xbe.py Projeto: yuzeming/cle
    def __init__(self, *args, **kwargs):
        if Xbe is None:
            raise CLEError(
                "Run `pip install pyxbe==0.0.2` to support loading XBE files")
        super().__init__(*args, **kwargs)
        self.set_arch(archinfo.arch_from_id('x86'))

        self.os = 'xbox'
        if self.binary is None:
            self._xbe = Xbe(data=self._binary_stream.read())
        else:
            self._xbe = Xbe.from_file(self.binary)
        self._entry = self._xbe.entry_addr
        self._image_vmem = bytearray(self._xbe.header.image_size)
        self._min_addr = self._xbe.header.base_addr
        self._max_addr = self._xbe.header.base_addr + self._xbe.header.image_size - 1

        # Add header
        self._add_xbe_section(0, self._xbe.header.image_header_size,
                              self._xbe.header.base_addr,
                              self._xbe.header.image_header_size,
                              self._xbe.header_data)

        # Add each section
        for _, sec in self._xbe.sections.items():
            self._add_xbe_section(sec.header.raw_addr, sec.header.raw_size,
                                  sec.header.virtual_addr,
                                  sec.header.virtual_size, sec.data, sec)

        self.memory.add_backer(0, bytes(self._image_vmem))
        self.mapped_base = self.linked_base = self._xbe.header.base_addr
Exemplo n.º 9
0
def test_skipstmts_toomanyexits():

    # https://github.com/angr/pyvex/issues/153

    old_exit_limit = IRSB.MAX_EXITS
    IRSB.MAX_EXITS = 32

    bytes_ = bytes.fromhex(
        "0DF1B00B2EAB94E8030008938BE803000DF1C0089AE8030083E80300019B0DF1F00A339AE669E26193E8030085E8030098E8030083E80300069B95E8030088E80300A26993E803004A92002363622362A361E362A36238AC029A069484E8030012AC0998299328932B9303C885E8030092E8030084E803009AE8030082E803002A460A9D26993E910B9941910D9942910C992A93409548AD439194E803008AE8030027983F9927913F909BE803000DF5887B269335938BE803000DF58C7B089903C98BE8030098E8030084E8030095E8030088E803004B993391329394E80300349337933693069C059B4C93049B4E9350ABCDF834C1CDF83CE185E8030094E803004B9683E8030015A94498C4F7E2EA"
    )
    arch = archinfo.arch_from_id("ARMEL")
    # Lifting the first four bytes will not cause any problem. Statements should be skipped as expected
    b = IRSB(bytes_[:34],
             0xC6951,
             arch,
             opt_level=1,
             bytes_offset=5,
             skip_stmts=True)
    nose.tools.assert_greater(len(b.exit_statements), 0)
    nose.tools.assert_false(b.has_statements, None)

    # Lifting the entire block will cause the number of exit statements go beyond the limit (currently 32). PyVEX will
    # automatically relift this block without skipping the statements
    b = IRSB(bytes_,
             0xC6951,
             arch,
             opt_level=1,
             bytes_offset=5,
             skip_stmts=True)
    nose.tools.assert_is_not(b.statements, None)
    nose.tools.assert_greater(len(b.exit_statements), 32)

    # Restore the setting
    IRSB.MAX_EXITS = old_exit_limit
Exemplo n.º 10
0
def test_simplify_dead_assign_1():

    # if a register is used ever, it should not be simplified away
    arch = archinfo.arch_from_id('AMD64')
    block = ailment.Block(0x1337, 10)
    n = count(start=1)
    important = 0x999
    block.statements.extend([
        ailment.Assignment(
            next(n),
            ailment.Register(next(n), None, arch.registers['rdi'][0], 64),
            ailment.Const(next(n), None, 0x13371337, 64),
            ins_addr=0x1337,
        ),  # rdi = 0x13371337
        ailment.Stmt.Call(
            important,
            ailment.Const(next(n), None, 0x400080, 64),
            ins_addr=0x1338,
        ),  # Call(0x400080), which uses rdi but also overwrites rdi (since it is a caller-saved argument)
    ])

    b = block_simplify(block)
    nose.tools.assert_equal(len(b.statements), 2)
    nose.tools.assert_equal(b.statements[0].idx, 1)
    nose.tools.assert_equal(b.statements[1].idx, important)
Exemplo n.º 11
0
def test_inspect_syscall():
    class counts: #pylint:disable=no-init
        exit_before = 0
        exit_after = 0

    def handle_syscall_before(state):
        counts.exit_before += 1
        syscall_name = state.inspect.syscall_name
        nose.tools.assert_equal(syscall_name, "close")

    def handle_syscall_after(state):
        counts.exit_after += 1
        syscall_name = state.inspect.syscall_name
        nose.tools.assert_equal(syscall_name, "close")

    s = simuvex.SimState(arch="AMD64", mode="symbolic")
    # set up to call so syscall close
    s.regs.rax = 3
    s.regs.rdi = 2

    # break on syscall
    s.inspect.b('syscall', simuvex.BP_BEFORE, action=handle_syscall_before)
    s.inspect.b('syscall', simuvex.BP_AFTER, action=handle_syscall_after)

    # step it
    proc = simuvex.SimProcedures['syscalls']['close'](s.se.any_int(s.ip), archinfo.arch_from_id('AMD64'))
    simuvex.SimEngineProcedure().process(s, proc, ret_to=s.ip)

    # check counts
    nose.tools.assert_equal(counts.exit_before, 1)
    nose.tools.assert_equal(counts.exit_after, 1)
Exemplo n.º 12
0
Arquivo: pe.py Projeto: 0xbc/cle
    def __init__(self, *args, **kwargs):
        super(PE, self).__init__(*args, **kwargs)

        self._pe = pefile.PE(self.binary)

        if self.arch is None:
            self.set_arch(archinfo.arch_from_id(pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))

        self.requested_base = self._pe.OPTIONAL_HEADER.ImageBase
        self._entry = self._pe.OPTIONAL_HEADER.AddressOfEntryPoint

        if hasattr(self._pe, "DIRECTORY_ENTRY_IMPORT"):
            self.deps = [entry.dll for entry in self._pe.DIRECTORY_ENTRY_IMPORT]
        else:
            self.deps = []

        self.provides = os.path.basename(self.binary)
        if not self.provides.endswith(".dll"):
            self.provides = None

        self._exports = {}
        self._handle_imports()
        self._handle_exports()
        self._register_sections()
        self.linking = "dynamic" if len(self.deps) > 0 else "static"

        self.jmprel = self._get_jmprel()

        self.memory.add_backer(0, self._pe.get_memory_mapped_image())

        l.warning("The PE module is not well-supported. Good luck!")
Exemplo n.º 13
0
    def __init__(self, path, **kwargs):
        super().__init__(path, **kwargs)
        self.set_arch(archinfo.arch_from_id('x86'))

        self.os = 'xbox'
        if self.binary is None:
            self._xbe = Xbe(data=self.binary_stream.read())
        else:
            self._xbe = Xbe.from_file(path)
        self._entry = self._xbe.entry_addr
        self._image_vmem = bytearray(self._xbe.header.image_size)
        self._min_addr = self._xbe.header.base_addr
        self._max_addr = self._xbe.header.base_addr + self._xbe.header.image_size

        # Add header
        self._add_xbe_section(
            0,
            self._xbe.header.image_header_size,
            self._xbe.header.base_addr,
            self._xbe.header.image_header_size,
            self._xbe.header_data)

        # Add each section
        for _, sec in self._xbe.sections.items():
            self._add_xbe_section(
                sec.header.raw_addr,
                sec.header.raw_size,
                sec.header.virtual_addr,
                sec.header.virtual_size,
                sec.data,
                sec)

        self.memory.add_backer(0, bytes(self._image_vmem))
        self.mapped_base = self.linked_base = self._xbe.header.base_addr
Exemplo n.º 14
0
Arquivo: pe.py Projeto: zhuyue1314/cle
    def __init__(self, *args, **kwargs):
        super(PE, self).__init__(*args, **kwargs)

        self._pe = pefile.PE(self.binary)

        if self.arch is None:
            self.set_arch(
                archinfo.arch_from_id(
                    pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))

        self.requested_base = self._pe.OPTIONAL_HEADER.ImageBase
        self._entry = self._pe.OPTIONAL_HEADER.AddressOfEntryPoint

        if hasattr(self._pe, 'DIRECTORY_ENTRY_IMPORT'):
            self.deps = [
                entry.dll for entry in self._pe.DIRECTORY_ENTRY_IMPORT
            ]
        else:
            self.deps = []

        self.soname = os.path.basename(self.binary)
        if not self.soname.endswith('.dll'):
            self.soname = None

        self._exports = {}
        self._handle_imports()
        self._handle_exports()
        self.linking = 'dynamic' if len(self.deps) > 0 else 'static'

        self.jmprel = self._get_jmprel()

        self.memory.add_backer(0, self._pe.get_memory_mapped_image())

        l.warning('The PE module is not well, supported. Good luck!')
Exemplo n.º 15
0
    def __init__(self, arch="AMD64", plugins=None, memory_backer=None, permissions_backer=None, mode=None, options=None,
                 add_options=None, remove_options=None, special_memory_filler=None):
        # the architecture is used for function simulations (autorets) and the bitness
        if isinstance(arch, str):
            self.arch = arch_from_id(arch)
        else:
            self.arch = arch

        # the options
        if options is None:
            if mode is None:
                l.warning("SimState defaulting to symbolic mode.")
                mode = "symbolic"
            options = o.modes[mode]

        options = set(options)
        if add_options is not None:
            options |= add_options
        if remove_options is not None:
            options -= remove_options
        self.options = options
        self.mode = mode

        # plugins
        self.plugins = { }
        if plugins is not None:
            for n,p in plugins.iteritems():
                self.register_plugin(n, p)

        if not self.has_plugin('memory'):
            # we don't set the memory endness because, unlike registers, it's hard to understand
            # which endness the data should be read

            if o.ABSTRACT_MEMORY in self.options:
                # We use SimAbstractMemory in static mode
                # Convert memory_backer into 'global' region
                if memory_backer is not None:
                    memory_backer = {'global': memory_backer}

                # TODO: support permissions backer in SimAbstractMemory
                self.register_plugin('memory', SimAbstractMemory(memory_backer, memory_id="mem"))
            else:
                self.register_plugin('memory', SimSymbolicMemory(memory_backer, permissions_backer, memory_id="mem"))
        if not self.has_plugin('registers'):
            self.register_plugin('registers', SimSymbolicMemory(memory_id="reg", endness=self.arch.register_endness))

        # This is used in static mode as we don't have any constraints there
        self._satisfiable = True

        # states are big, so let's give them UUIDs for ANA right away to avoid
        # extra pickling
        self.make_uuid()

        self.uninitialized_access_handler = None
        self._special_memory_filler = special_memory_filler

        # this is a global condition, applied to all added constraints, memory reads, etc
        self._global_condition = None
        self.ip_constraints = []
Exemplo n.º 16
0
    def check_compatibility(cls, spec, obj):
        if hasattr(spec, 'read') and hasattr(spec, 'seek'):
            pe = pefile.PE(data=spec.read(), fast_load=True)
        else:
            pe = pefile.PE(spec, fast_load=True)

        arch = archinfo.arch_from_id(pefile.MACHINE_TYPE[pe.FILE_HEADER.Machine])
        return arch == obj.arch
Exemplo n.º 17
0
 def test_convert_from_pcode_irsb(self):
     arch = archinfo.arch_from_id('AMD64')
     manager = ailment.Manager(arch=arch)
     p = angr.load_shellcode(self.block_bytes, arch, self.block_addr, self.block_addr,
                             engine=angr.engines.UberEnginePcode)
     irsb = p.factory.block(self.block_addr).vex
     ablock = ailment.IRSBConverter.convert(irsb, manager)
     assert ablock  # TODO: test if this conversion is valid
Exemplo n.º 18
0
Arquivo: pe.py Projeto: angr/cle
    def check_compatibility(cls, spec, obj):
        if hasattr(spec, 'read') and hasattr(spec, 'seek'):
            pe = pefile.PE(data=spec.read(), fast_load=True)
        else:
            pe = pefile.PE(spec, fast_load=True)

        arch = archinfo.arch_from_id(pefile.MACHINE_TYPE[pe.FILE_HEADER.Machine])
        return arch == obj.arch
Exemplo n.º 19
0
    def __init__(self, *args, **kwargs):
        super(PE, self).__init__(*args, **kwargs)
        self.segments = self.sections  # in a PE, sections and segments have the same meaning
        self.os = 'windows'
        if self.binary is None:
            self._pe = pefile.PE(data=self.binary_stream.read())
        elif self.binary in self._pefile_cache:  # these objects are not mutated, so they are reusable within a process
            self._pe = self._pefile_cache[self.binary]
        else:
            self._pe = pefile.PE(self.binary)
            if not self.is_main_bin:
                # only cache shared libraries, the main binary will not be reused
                self._pefile_cache[self.binary] = self._pe

        if self.arch is None:
            self.set_arch(
                archinfo.arch_from_id(
                    pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))

        self.mapped_base = self.linked_base = self._pe.OPTIONAL_HEADER.ImageBase
        self._entry = AT.from_rva(self._pe.OPTIONAL_HEADER.AddressOfEntryPoint,
                                  self).to_lva()

        if hasattr(self._pe, 'DIRECTORY_ENTRY_IMPORT'):
            self.deps = [
                entry.dll.lower() for entry in self._pe.DIRECTORY_ENTRY_IMPORT
            ]
        else:
            self.deps = []

        if self.binary is not None and not self.is_main_bin:
            self.provides = os.path.basename(self.binary).lower()
        else:
            self.provides = None

        self.tls_used = False
        self.tls_data_start = None
        self.tls_data_size = None
        self.tls_index_address = None
        self.tls_callbacks = None
        self.tls_size_of_zero_fill = None
        self.tls_module_id = None
        self.tls_data_pointer = None

        self._exports = {}
        self._ordinal_exports = {}
        self._symbol_cache = self._exports  # same thing
        self._handle_imports()
        self._handle_exports()
        self._handle_relocs()
        self._register_tls()
        self._register_sections()
        self.linking = 'dynamic' if self.deps else 'static'

        self.jmprel = self._get_jmprel()

        self.memory.add_backer(0, self._pe.get_memory_mapped_image())
Exemplo n.º 20
0
    def set_default_cc(self, arch_name, cc_cls):
        """
        Set the default calling convention used for this library under a given architecture

        :param arch_name:   The string name of the architecture, i.e. the ``.name`` field from archinfo.
        :parm cc_cls:       The SimCC class (not an instance!) to use
        """
        arch_name = archinfo.arch_from_id(arch_name).name
        self.default_ccs[arch_name] = cc_cls
Exemplo n.º 21
0
Arquivo: __init__.py Projeto: axt/angr
 def get(self, name, arch):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if name in self.procedures:
         proc = copy.deepcopy(self.procedures[name])
         self._apply_metadata(proc, arch)
         return proc
     else:
         return self.get_stub(name, arch)
Exemplo n.º 22
0
Arquivo: elf.py Projeto: mephi42/cle
    def extract_arch(reader):
        arch_str = reader['e_machine']
        if arch_str == 'ARM':
            if reader.header.e_flags & 0x200:
                return archinfo.ArchARMEL('Iend_LE' if reader.little_endian else 'Iend_BE')
            elif reader.header.e_flags & 0x400:
                return archinfo.ArchARMHF('Iend_LE' if reader.little_endian else 'Iend_BE')

        return archinfo.arch_from_id(arch_str, 'le' if reader.little_endian else 'be', reader.elfclass)
Exemplo n.º 23
0
def convert_arch(arch):
    """
    Convert an arch ID or an archinfo.Arch instance to an archinfo.Arch instance.
    """
    if isinstance(arch, str):
        the_arch = archinfo.arch_from_id(arch)
    else:
        the_arch = arch
    return the_arch
Exemplo n.º 24
0
 def get(self, name, arch):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if name in self.procedures:
         proc = copy.deepcopy(self.procedures[name])
         self._apply_metadata(proc, arch)
         return proc
     else:
         return self.get_stub(name, arch)
Exemplo n.º 25
0
    def set_default_cc(self, arch_name, cc_cls):
        """
        Set the default calling convention used for this library under a given architecture

        :param arch_name:   The string name of the architecture, i.e. the ``.name`` field from archinfo.
        :parm cc_cls:       The SimCC class (not an instance!) to use
        """
        arch_name = archinfo.arch_from_id(arch_name).name
        self.default_ccs[arch_name] = cc_cls
Exemplo n.º 26
0
    def __init__(self, binary, **kwargs):
        super(ELF, self).__init__(binary, **kwargs)
        self.reader = elffile.ELFFile(open(self.binary, 'rb'))

        # Get an appropriate archinfo.Arch for this binary, unless the user specified one
        if self.arch is None:
            if self.reader.header.e_machine == 'EM_ARM' and \
                    self.reader.header.e_flags & 0x200:
                self.set_arch(archinfo.ArchARMEL('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE'))
            elif self.reader.header.e_machine == 'EM_ARM' and \
                    self.reader.header.e_flags & 0x400:
                self.set_arch(archinfo.ArchARMHF('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE'))
            else:
                self.set_arch(archinfo.arch_from_id(self.reader.header.e_machine,
                                                self.reader.header.e_ident.EI_DATA,
                                                self.reader.header.e_ident.EI_CLASS))

        self.strtab = None
        self.dynsym = None
        self.hashtable = None

        self._dynamic = {}
        self.deps = []
        self.rela_type = None

        self._inits_extracted = False
        self._preinit_arr = []
        self._init_func = None
        self._init_arr = []
        self._fini_func = None
        self._fini_arr = []

        self._symbol_cache = {}
        self.symbols_by_addr = {}
        self.imports = {}
        self.resolved_imports = []

        self.relocs = []
        self.jmprel = {}

        self._entry = self.reader.header.e_entry
        self.pic = self.reader.header.e_type == 'ET_DYN'

        self.tls_used = False
        self.tls_module_id = None
        self.tls_block_offset = None
        self.tls_block_size = None
        self.tls_tdata_start = None
        self.tls_tdata_size = None

        self.__register_segments()
        self.__register_sections()

        # call the methods defined by MetaELF
        self._ppc64_abiv1_entry_fix()
        self._load_plt()
Exemplo n.º 27
0
def test_ctype_tolower_loc():
    '''
    test_ctype_locale.test_ctype_tolower_loc

    int32_t * * __ctype_tolower_loc(void);

    Description:
    The __ctype_tolower_loc() function shall return a pointer into an array of
    characters in the current locale that contains lower case equivalents for
    each character in the current character set. The array shall contain a total
    of 384 characters, and can be indexed with any signed or unsigned char (i.e.
    with an index value between -128 and 255). If the application is
    multithreaded, the array shall be local to the current thread.

    This interface is not in the source standard; it is only in the binary
    standard.

    Return Value:
    The __ctype_tolower_loc() function shall return a pointer to the array of
    characters to be used for the ctype() family of functions (see <ctype.h>).
    '''
    # Just load a binary so that we can do the initialization steps from
    # libc_start_main
    bin_path = os.path.join(test_location,
                            '../../binaries/tests/x86_64/ctype_tolower_loc')

    ctype_tolower_loc = lambda state, arguments: simuvex.SimProcedures[
        'libc.so.6']['__ctype_tolower_loc'](
            FAKE_ADDR, archinfo.arch_from_id('AMD64')).execute(
                state, arguments=arguments)

    b = angr.Project(bin_path)
    p = b.factory.full_init_state()
    pg = b.factory.path_group(p)

    # Find main located at 0x400596 to let libc_start_main do its thing
    main = pg.explore(find=0x400596)

    state = main.found[0].state
    tolower_loc_array_ptr = ctype_tolower_loc(state, []).ret_expr
    table_ptr = state.memory.load(tolower_loc_array_ptr,
                                  state.arch.bits / 8,
                                  endness=state.arch.memory_endness)

    result = ''
    for i in range(-128, 256):
        result += "%d->0x%x\n" % (
            i,
            state.se.any_int(
                state.memory.load(
                    table_ptr +
                    (i * 4), 4, endness=state.arch.memory_endness)))

    # Check output of compiled C program that uses ctype_tolower_loc()
    output = subprocess.check_output(bin_path, shell=True)
    nose.tools.assert_equal(result, output)
Exemplo n.º 28
0
    def __init__(self, binary, **kwargs):
        super(ELF, self).__init__(binary, **kwargs)
        self.reader = elffile.ELFFile(open(self.binary, 'rb'))

        # Get an appropriate archinfo.Arch for this binary, unless the user specified one
        if self.arch is None:
            if self.reader.header.e_machine == 'EM_ARM' and \
                    self.reader.header.e_flags & 0x200:
                self.set_arch(archinfo.ArchARMEL('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE'))
            elif self.reader.header.e_machine == 'EM_ARM' and \
                    self.reader.header.e_flags & 0x400:
                self.set_arch(archinfo.ArchARMHF('Iend_LE' if 'LSB' in self.reader.header.e_ident.EI_DATA else 'Iend_BE'))
            else:
                self.set_arch(archinfo.arch_from_id(self.reader.header.e_machine,
                                                self.reader.header.e_ident.EI_DATA,
                                                self.reader.header.e_ident.EI_CLASS))

        self.strtab = None
        self.dynsym = None
        self.hashtable = None

        self._dynamic = {}
        self.deps = []
        self.rela_type = None

        self._inits_extracted = False
        self._preinit_arr = []
        self._init_func = None
        self._init_arr = []
        self._fini_func = None
        self._fini_arr = []

        self._symbol_cache = {}
        self.symbols_by_addr = {}
        self.imports = {}
        self.resolved_imports = []

        self.relocs = []
        self.jmprel = {}

        self._entry = self.reader.header.e_entry
        self.pic = self.reader.header.e_type == 'ET_DYN'

        self.tls_used = False
        self.tls_module_id = None
        self.tls_block_offset = None
        self.tls_block_size = None
        self.tls_tdata_start = None
        self.tls_tdata_size = None

        self.__register_segments()
        self.__register_sections()

        # call the methods defined by MetaELF
        self._ppc64_abiv1_entry_fix()
        self._load_plt()
Exemplo n.º 29
0
 def _canonicalize(self, number, arch):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if type(number) is str:
         return number, arch
     mapping = self.syscall_number_mapping[arch.name]
     if number in mapping:
         return mapping[number], arch
     else:
         return 'sys_%d' % number, arch
Exemplo n.º 30
0
def test_x86_noop_blocks():

    # nop
    arch = archinfo.arch_from_id("x86")
    b = b"\x90\x90\x90\x90\x90\x90\x90\x90"
    p = angr.load_shellcode(b, arch, load_address=0x400000)
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
    assert CFGBase._is_noop_block(arch, block) is True
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
    assert CFGBase._is_noop_block(arch, block) is True
Exemplo n.º 31
0
Arquivo: __init__.py Projeto: axt/angr
 def _canonicalize(self, number, arch):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if type(number) is str:
         return number, arch
     mapping = self.syscall_number_mapping[arch.name]
     if number in mapping:
         return mapping[number], arch
     else:
         return 'sys_%d' % number, arch
Exemplo n.º 32
0
 def _canonicalize(self, number, arch, abi_list):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if type(number) is str:
         return number, arch, None
     for abi in abi_list:
         mapping = self.syscall_number_mapping[abi]
         if number in mapping:
             return mapping[number], arch, abi
     return 'sys_%d' % number, arch, None
Exemplo n.º 33
0
 def _canonicalize(self, number, arch, abi_list):
     if type(arch) is str:
         arch = archinfo.arch_from_id(arch)
     if type(number) is str:
         return number, arch, None
     for abi in abi_list:
         mapping = self.syscall_number_mapping[abi]
         if number in mapping:
             return mapping[number], arch, abi
     return 'sys_%d' % number, arch, None
Exemplo n.º 34
0
    def __init__(self, binary, is_main_bin=False, compatible_with=None, filetype='unknown', **kwargs):
        """
        args: binary
        kwargs: {load=True, custom_base_addr=None, custom_entry_point=None,
                 custom_offset=None}
        """

        # Unfold the kwargs and convert them to class attributes
        for k,v in kwargs.iteritems():
            setattr(self, k, v)

        self.binary = binary
        self.is_main_bin = is_main_bin
        self._entry = None
        self.segments = [] # List of segments
        self.sections = []      # List of sections
        self.sections_map = {}  # Mapping from section name to section
        self.symbols_by_addr = {}
        self.imports = {}
        self.resolved_imports = []
        self.relocs = []
        self.jmprel = {}
        self.symbols = None # Object's symbols
        self.arch = None
        self.filetype = filetype
        self.os = 'windows' if self.filetype == 'pe' else 'unix'
        self.compatible_with = compatible_with

        # These are set by cle, and should not be overriden manually
        self.rebase_addr = 0 # not to be set manually - used by CLE
        self.tls_module_id = None

        self.object_type = None
        self.deps = []           # Needed shared objects (libraries dependencies)
        self.linking = None # Dynamic or static linking
        self.requested_base = None
        self.pic = False

        # Custom options
        self._custom_entry_point = kwargs.get('custom_entry_point', None)
        self.provides = None

        self.memory = None

        custom_arch = kwargs.get('custom_arch', None)
        if custom_arch is None:
            self.arch = None
        elif isinstance(custom_arch, str):
            self.set_arch(archinfo.arch_from_id(custom_arch))
        elif isinstance(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch)
        elif isinstance(custom_arch, type) and issubclass(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch())
        else:
            raise CLEError("Bad parameter: custom_arch=%s" % custom_arch)
Exemplo n.º 35
0
def test_convert_from_vex_irsb():

    arch = archinfo.arch_from_id('AMD64')

    manager = ailment.Manager(arch=arch)

    irsb = pyvex.IRSB(block_bytes, block_addr, arch, opt_level=0)

    ablock = ailment.IRSBConverter.convert(irsb, manager)

    print(str(ablock))
Exemplo n.º 36
0
    def test_SystemVAMD64_flatten_int(self):
        arch = archinfo.arch_from_id("amd64")
        cc = SimCCSystemVAMD64(arch)

        int_type = SimTypeInt().with_arch(arch)
        flattened_int = cc._flatten(int_type)
        self.assertTrue(all(isinstance(key, int) for key in flattened_int))
        self.assertTrue(all(isinstance(value, list) for value in flattened_int.values()))
        for v in flattened_int.values():
            for subtype in v:
                self.assertIsInstance(subtype, SimTypeInt)
Exemplo n.º 37
0
 def __init__(self, *args, offset=0, **kwargs):
     """
     Loader backend for BF programs
     :param path: The file path
     :param offset: Skip this many bytes from the beginning of the file.
     """
     super(BF, self).__init__(*args,
                              arch=arch_from_id("bf"),
                              offset=offset,
                              entry_point=0,
                              **kwargs)
     self.os = "bf"
Exemplo n.º 38
0
def from_string(data, log_level = logging.WARNING, address_offset = None):
  gadgets_dict = pickle.loads(data)
  gadgets_list = [item for sublist in gadgets_dict.values() for item in sublist] # Flatten list of lists

  # Turn the names of the arch back into archinfo classes (Which aren't pickle-able)
  for gadget in gadgets_list:
    gadget.arch = archinfo.arch_from_id(gadget.arch)

  gl = GadgetList(gadgets_list, log_level)
  if address_offset != None:
    gl.adjust_base_address(address_offset)
  return gl
Exemplo n.º 39
0
Arquivo: __init__.py Projeto: 0xbc/cle
    def __init__(self, binary, is_main_bin=False, compatible_with=None, filetype="unknown", **kwargs):
        # Unfold the kwargs and convert them to class attributes
        for k, v in kwargs.iteritems():
            setattr(self, k, v)

        self.binary = binary
        self.is_main_bin = is_main_bin
        self._entry = None
        self.segments = []  # List of segments
        self.sections = []  # List of sections
        self.sections_map = {}  # Mapping from section name to section
        self.symbols_by_addr = {}
        self.imports = {}
        self.resolved_imports = []
        self.relocs = []
        self.irelatives = []  # list of tuples (resolver, destination), dest w/o rebase
        self.jmprel = {}
        self.arch = None
        self.filetype = filetype
        self.os = "windows" if self.filetype == "pe" else "unix"
        self.compatible_with = compatible_with
        self._symbol_cache = {}

        # These are set by cle, and should not be overriden manually
        self.rebase_addr = 0  # not to be set manually - used by CLE
        self.tls_module_id = None

        self.object_type = None
        self.deps = []  # Needed shared objects (libraries dependencies)
        self.linking = None  # Dynamic or static linking
        self.requested_base = None
        self.pic = False
        self.execstack = False

        # Custom options
        self._custom_entry_point = kwargs.get("custom_entry_point", None)
        self.provides = None

        self.memory = None

        custom_arch = kwargs.get("custom_arch", None)
        if custom_arch is None:
            self.arch = None
        elif isinstance(custom_arch, str):
            self.set_arch(archinfo.arch_from_id(custom_arch))
        elif isinstance(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch)
        elif isinstance(custom_arch, type) and issubclass(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch())
        else:
            raise CLEError("Bad parameter: custom_arch=%s" % custom_arch)
Exemplo n.º 40
0
Arquivo: pe.py Projeto: angr/cle
    def __init__(self, *args, **kwargs):
        super(PE, self).__init__(*args, **kwargs)
        self.segments = self.sections # in a PE, sections and segments have the same meaning
        self.os = 'windows'
        if self.binary is None:
            self._pe = pefile.PE(data=self.binary_stream.read())
        elif self.binary in self._pefile_cache: # these objects are not mutated, so they are reusable within a process
            self._pe = self._pefile_cache[self.binary]
        else:
            self._pe = pefile.PE(self.binary)
            if not self.is_main_bin:
                # only cache shared libraries, the main binary will not be reused
                self._pefile_cache[self.binary] = self._pe

        if self.arch is None:
            self.set_arch(archinfo.arch_from_id(pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))

        self.mapped_base = self.linked_base = self._pe.OPTIONAL_HEADER.ImageBase

        self._entry = AT.from_rva(self._pe.OPTIONAL_HEADER.AddressOfEntryPoint, self).to_lva()

        if hasattr(self._pe, 'DIRECTORY_ENTRY_IMPORT'):
            self.deps = [entry.dll.decode().lower() for entry in self._pe.DIRECTORY_ENTRY_IMPORT]
        else:
            self.deps = []

        if self.binary is not None and not self.is_main_bin:
            self.provides = os.path.basename(self.binary).lower()
        else:
            self.provides = None

        self.tls_index_address = None
        self.tls_callbacks = None

        self.supports_nx = self._pe.OPTIONAL_HEADER.DllCharacteristics & 0x100 != 0
        self.pic = self.pic or self._pe.OPTIONAL_HEADER.DllCharacteristics & 0x40 != 0

        self._exports = {}
        self._ordinal_exports = {}
        self._symbol_cache = self._exports # same thing
        self._handle_imports()
        self._handle_exports()
        self.__register_relocs()
        self._register_tls()
        self._register_sections()

        self.linking = 'dynamic' if self.deps else 'static'
        self.jmprel = self._get_jmprel()
        self.memory.add_backer(0, self._pe.get_memory_mapped_image())
def test_fauxware():

    amd64 = archinfo.arch_from_id('amd64')

    args = {
        'i386': [
            ('authenticate', SimCCCdecl(
                archinfo.arch_from_id('i386'),
                args=[SimStackArg(4, 4), SimStackArg(8, 4)], sp_delta=4
                )
             ),
        ],
        'x86_64': [
            ('authenticate', SimCCSystemVAMD64(
                amd64,
                args=[SimRegArg('rdi', 8), SimRegArg('rsi', 8)],
                sp_delta=8
                )
             ),
        ],
    }

    for arch, lst in args.items():
        yield run_fauxware, arch, lst
Exemplo n.º 42
0
Arquivo: elf.py Projeto: angr/cle
    def extract_arch(reader):
        arch_str = reader['e_machine']
        if 'ARM' in arch_str:
            # Check the ARM attributes, if they exist
            arm_attrs = ELF._extract_arm_attrs(reader)
            if arm_attrs and 'TAG_CPU_NAME' in arm_attrs:
                if arm_attrs['TAG_CPU_NAME'].endswith("-M") \
                    or 'Cortex-M' in arm_attrs['TAG_CPU_NAME']:
                    return archinfo.ArchARMCortexM('Iend_LE')
            if reader.header.e_flags & 0x200:
                return archinfo.ArchARMEL('Iend_LE' if reader.little_endian else 'Iend_BE')
            elif reader.header.e_flags & 0x400:
                return archinfo.ArchARMHF('Iend_LE' if reader.little_endian else 'Iend_BE')

        return archinfo.arch_from_id(arch_str, 'le' if reader.little_endian else 'be', reader.elfclass)
Exemplo n.º 43
0
    def get(self, name, arch):
        """
        Get an implementation of the given function specialized for the given arch, or a stub procedure if none exists.

        :param name:    The name of the function as a string
        :param arch:    The architecure to use, as either a string or an archinfo.Arch instance
        :return:        A SimProcedure instance representing the function as found in the library
        """
        if type(arch) is str:
            arch = archinfo.arch_from_id(arch)
        if name in self.procedures:
            proc = copy.deepcopy(self.procedures[name])
            self._apply_metadata(proc, arch)
            return proc
        else:
            return self.get_stub(name, arch)
Exemplo n.º 44
0
def test_skipstmts_toomanyexits():

    # https://github.com/angr/pyvex/issues/153

    old_exit_limit = IRSB.MAX_EXITS
    IRSB.MAX_EXITS = 32

    bytes_ = bytes.fromhex("0DF1B00B2EAB94E8030008938BE803000DF1C0089AE8030083E80300019B0DF1F00A339AE669E26193E8030085E8030098E8030083E80300069B95E8030088E80300A26993E803004A92002363622362A361E362A36238AC029A069484E8030012AC0998299328932B9303C885E8030092E8030084E803009AE8030082E803002A460A9D26993E910B9941910D9942910C992A93409548AD439194E803008AE8030027983F9927913F909BE803000DF5887B269335938BE803000DF58C7B089903C98BE8030098E8030084E8030095E8030088E803004B993391329394E80300349337933693069C059B4C93049B4E9350ABCDF834C1CDF83CE185E8030094E803004B9683E8030015A94498C4F7E2EA")
    arch = archinfo.arch_from_id("ARMEL")
    # Lifting the first four bytes will not cause any problem. Statements should be skipped as expected
    b = IRSB(bytes_[:34], 0xC6951, arch, opt_level=1, bytes_offset=5, skip_stmts=True)
    nose.tools.assert_greater(len(b.exit_statements), 0)
    nose.tools.assert_false(b.has_statements, None)

    # Lifting the entire block will cause the number of exit statements go beyond the limit (currently 32). PyVEX will
    # automatically relift this block without skipping the statements
    b = IRSB(bytes_, 0xC6951, arch, opt_level=1, bytes_offset=5, skip_stmts=True)
    nose.tools.assert_is_not(b.statements, None)
    nose.tools.assert_greater(len(b.exit_statements), 32)

    # Restore the setting
    IRSB.MAX_EXITS = old_exit_limit
Exemplo n.º 45
0
Arquivo: pe.py Projeto: esudyin/cle
    def __init__(self, *args, **kwargs):
        if pefile is None:
            raise CLEError("Install the pefile module to use the PE backend!")

        super(PE, self).__init__(*args, **kwargs)

        if self.binary is not None:
            self._pe = pefile.PE(data=self.binary_stream.read())
        else:
            self._pe = pefile.PE(self.binary)

        if self.arch is None:
            self.set_arch(archinfo.arch_from_id(pefile.MACHINE_TYPE[self._pe.FILE_HEADER.Machine]))

        self.requested_base = self._pe.OPTIONAL_HEADER.ImageBase
        self._entry = self._pe.OPTIONAL_HEADER.AddressOfEntryPoint

        if hasattr(self._pe, 'DIRECTORY_ENTRY_IMPORT'):
            self.deps = [entry.dll for entry in self._pe.DIRECTORY_ENTRY_IMPORT]
        else:
            self.deps = []

        if self.binary is not None and not self.is_main_bin:
            self.provides = os.path.basename(self.binary)
        else:
            self.provides = None

        self._exports = {}
        self._handle_imports()
        self._handle_exports()
        self._handle_relocs()
        self._register_sections()
        self.linking = 'dynamic' if len(self.deps) > 0 else 'static'

        self.jmprel = self._get_jmprel()

        self.memory.add_backer(0, self._pe.get_memory_mapped_image())

        l.warning('The PE module is not well-supported. Good luck!')
Exemplo n.º 46
0
def from_string(data, log_level = logging.WARNING, address_offset = None, bad_bytes = None, filter_func = None):
  gadgets_dict = pickle.loads(data)
  gadgets_list = [item for sublist in gadgets_dict.values() for item in sublist] # Flatten list of lists

  # Turn the names of the arch back into archinfo classes (Which aren't pickle-able)
  for gadget in gadgets_list:
    gadget.arch = archinfo.arch_from_id(gadget.arch)

  # Filter the gadgets if necessary
  if filter_func != None:
    gadgets_list = filter_func(gadgets_list)

  gl = GadgetList(gadgets_list, log_level)
  if address_offset != None:
    gl.adjust_base_address(address_offset)

  if bad_bytes != None:
    just_good_gadgets = GadgetList(log_level = log_level, bad_bytes = bad_bytes)
    for gadget in gl.foreach():
      if not gadget.has_bad_address(bad_bytes):
        just_good_gadgets.add_gadget(gadget)
    gl = just_good_gadgets

  return gl
Exemplo n.º 47
0
Arquivo: elf.py Projeto: shadown/cle
    def __init__(self, binary, **kwargs):
        super(ELF, self).__init__(binary, **kwargs)
        try:
            self.reader = elffile.ELFFile(open(self.binary, 'rb'))
        except ELFError:
            raise CLECompatibilityError

        # Get an appropriate archinfo.Arch for this binary, unless the user specified one
        if self.arch is None:
            arch_str = self.reader['e_machine']
            if arch_str == 'ARM':
                if self.reader.header.e_flags & 0x200:
                    self.set_arch(archinfo.ArchARMEL('Iend_LE' if self.reader.little_endian else 'Iend_BE'))
                elif self.reader.header.e_flags & 0x400:
                    self.set_arch(archinfo.ArchARMHF('Iend_LE' if self.reader.little_endian else 'Iend_BE'))
            else:
                self.set_arch(archinfo.arch_from_id(arch_str,
                                                'le' if self.reader.little_endian else 'be',
                                                self.reader.elfclass))

        self.strtab = None
        self.dynsym = None
        self.hashtable = None

        self._dynamic = {}
        self.deps = []
        self.rela_type = None

        self._inits_extracted = False
        self._preinit_arr = []
        self._init_func = None
        self._init_arr = []
        self._fini_func = None
        self._fini_arr = []
        self._nullsymbol = Symbol(self, '', 0, 0, None, 'STT_NOTYPE', 0)

        self._symbol_cache = {}
        self.symbols_by_addr = {}
        self.demangled_names = {}
        self.imports = {}
        self.resolved_imports = []

        self.relocs = []
        self.jmprel = {}

        self._entry = self.reader.header.e_entry
        self.pic = self.reader.header.e_type == 'ET_DYN'

        self.tls_used = False
        self.tls_module_id = None
        self.tls_block_offset = None
        self.tls_block_size = None
        self.tls_tdata_start = None
        self.tls_tdata_size = None

        self.__parsed_reloc_tables = set()

        self.__register_segments()
        self.__register_sections()

        # call the methods defined by MetaELF
        self._ppc64_abiv1_entry_fix()
        self._load_plt()

        self._populate_demangled_names()
Exemplo n.º 48
0
    def __init__(self, thing,
                 default_analysis_mode=None,
                 ignore_functions=None,
                 use_sim_procedures=True,
                 exclude_sim_procedures_func=None,
                 exclude_sim_procedures_list=(),
                 arch=None, simos=None,
                 load_options=None,
                 translation_cache=True,
                 support_selfmodifying_code=False):
        """
        :param thing:                       The path to the main executable object to analyze, or a CLE Loader object.

        The following parameters are optional.

        :param default_analysis_mode:       The mode of analysis to use by default. Defaults to 'symbolic'.
        :param ignore_functions:            A list of function names that, when imported from shared libraries, should
                                            never be stepped into in analysis (calls will return an unconstrained value).
        :param use_sim_procedure:           Whether to replace resolved dependencies for which simprocedures are
                                            available with said simprocedures.
        :param exclude_sim_procedures_func: A function that, when passed a function name, returns whether or not to wrap
                                            it with a simprocedure.
        :param exclude_sim_procedures_list: A list of functions to *not* wrap with simprocedures.
        :param arch:                        The target architecture (auto-detected otherwise).
        :param simos:                       a SimOS class to use for this project.
        :param load_options:                a dict of keyword arguments to the CLE loader. See CLE's docs.
        :param translation_cache:           If True, cache translated basic blocks rather than re-translating them.
        :param support_selfmodifying_code:  Whether we support self-modifying code. When enabled, Project.sim_block()
                                            will try to read code from the given state, not only from the initial memory
                                            regions.
        :type  support_selfmodifying_code:  bool

        A sample `load_options` value could be:
        ::

            { 'auto_load_libs': False,
              'skip_libs': 'ld.so.2',
              'lib_opts': {
                'libc.so.6': {
                'custom_base_addr': 0x55555400
                }
              }
            }
        """

        # Step 1: Load the binary
        if isinstance(thing, cle.Loader):
            self.loader = thing
            self.filename = self.loader._main_binary_path
        elif not isinstance(thing, (unicode, str)) or not os.path.exists(thing) or not os.path.isfile(thing):
            raise Exception("Not a valid binary file: %s" % repr(thing))
        else:
            # use angr's loader, provided by cle
            l.info("Loading binary %s", thing)
            self.filename = thing
            if load_options is None: load_options = {}
            self.loader = cle.Loader(self.filename, **load_options)

        # Step 2: determine its CPU architecture, ideally falling back to CLE's guess
        if isinstance(arch, str):
            self.arch = archinfo.arch_from_id(arch) # may raise ArchError, let the user see this
        elif isinstance(arch, archinfo.Arch):
            self.arch = arch
        elif arch is None:
            self.arch = self.loader.main_bin.arch
        else:
            raise ValueError("Invalid arch specification.")

        # Step 3: Set some defaults and set the public and private properties
        if not default_analysis_mode:
            default_analysis_mode = 'symbolic'
        if not ignore_functions:
            ignore_functions = []

        if isinstance(exclude_sim_procedures_func, types.LambdaType):
            l.warning("Passing a lambda type as the exclude_sim_procedures_func argument to Project causes the resulting object to be un-serializable.")

        self._sim_procedures = {}
        self._default_analysis_mode = default_analysis_mode
        self._exclude_sim_procedures_func = exclude_sim_procedures_func
        self._exclude_sim_procedures_list = exclude_sim_procedures_list
        self._should_use_sim_procedures = use_sim_procedures
        self._support_selfmodifying_code = support_selfmodifying_code
        self._ignore_functions = ignore_functions
        self._extern_obj = AngrExternObject(self.arch)
        self.loader.add_object(self._extern_obj)

        self._cfg = None
        self._vfg = None
        self._cdg = None

        self.entry = self.loader.main_bin.entry
        self.factory = AngrObjectFactory(self, translation_cache=translation_cache)
        self.analyses = Analyses(self)
        self.surveyors = Surveyors(self)
        self.kb = KnowledgeBase(self, self.loader.main_bin)

        projects[self.filename] = self

        # Step 5: determine the host OS and perform additional initialization
        # in the SimOS constructor
        if isinstance(simos, type) and issubclass(simos, SimOS):
            self._simos = simos(self) #pylint:disable=invalid-name
        elif simos is None:
            self._simos = os_mapping[self.loader.main_bin.os](self)
        else:
            raise ValueError("Invalid OS specification or non-matching architecture.")

        # Step 4: Register simprocedures as appropriate for library functions
        self._use_sim_procedures()
        self._simos.configure_project()
Exemplo n.º 49
0
import logging, collections
import rop_compiler.factories as factories

import argparse

parser = argparse.ArgumentParser(description="Run the gadget locator on the supplied binary")
parser.add_argument('filename', type=str, default=None, help='The file (executable/library) to load gadgets from')
parser.add_argument('-arch', type=str, default="AMD64", help='The architecture of the binary')
parser.add_argument('-big_endian', required=False, action='store_true', help="Whether the architecture is big endian or not")
parser.add_argument('-finder_type', type=str, default="mem", help='The type of gadget finder (memory, file)')
parser.add_argument('-o', type=str, default=None, help='File to write the gadgets to')
parser.add_argument('-parser_type', type=str, default="cle", help='The type of file parser (cle, pyelf, radare)')
parser.add_argument('-v', required=False, action='store_true', help='Verbose mode')
parser.add_argument('-validate', required=False, action='store_true', help='Validate gadgets with z3')
args = parser.parse_args()

finder_type = factories.get_finder_from_name(args.finder_type)
logging_level = logging.DEBUG if args.v else logging.WARNING
arch = archinfo.arch_from_id(args.arch, 'Iend_BE' if args.big_endian else 'Iend_LE')
finder = finder_type(args.filename, arch, 0, logging_level, args.parser_type)
gadget_list = finder.find_gadgets(args.validate)

if args.o == None:
  for gadget in gadget_list.foreach():
    print gadget
else:
  fd = open(args.o, "w")
  fd.write(gadget_list.to_string())
  fd.close()

Exemplo n.º 50
0
    def __init__(self, project=None, arch=None, plugins=None, memory_backer=None, permissions_backer=None, mode=None, options=None,
                 add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default', **kwargs):
        if kwargs:
            l.warning("Unused keyword arguments passed to SimState: %s", " ".join(kwargs))
        super(SimState, self).__init__()
        self.project = project

        # Arch
        if self._is_java_jni_project:
            self._arch = { "soot" : project.arch,
                           "vex"  : project.simos.native_simos.arch }
            # This flag indicates whether the current ip is a native address or
            # a soot address descriptor.
            # Note: We cannot solely rely on the ip to make that decsision,
            #       because the registers (storing the ip) are part of the
            #       plugins that are getting toggled (=> mutual dependence).
            self.ip_is_soot_addr = False
        else:
            self._arch = arch if arch is not None else project.arch.copy() if project is not None else None
            if type(self._arch) is str:
                self._arch = archinfo.arch_from_id(self._arch)

        # the options
        if options is None:
            if mode is None:
                l.warning("SimState defaulting to symbolic mode.")
                mode = "symbolic"
            options = o.modes[mode]

        if isinstance(options, (set, list)):
            options = SimStateOptions(options)
        if add_options is not None:
            options |= add_options
        if remove_options is not None:
            options -= remove_options
        self._options = options
        self.mode = mode

        if plugin_preset is not None:
            self.use_plugin_preset(plugin_preset)

        if plugins is not None:
            for n,p in plugins.items():
                self.register_plugin(n, p, inhibit_init=True)
            for p in plugins.values():
                p.init_state()

        if not self.has_plugin('memory'):
            # We don't set the memory endness because, unlike registers, it's hard to understand
            # which endness the data should be read.

            # If they didn't provide us with either a memory plugin or a plugin preset to use,
            # we have no choice but to use the 'default' plugin preset.
            if self.plugin_preset is None:
                self.use_plugin_preset('default')

            # Determine memory backend
            if self._is_java_project and not self._is_java_jni_project:
                sim_memory_cls = self.plugin_preset.request_plugin('javavm_memory')
                sim_memory = sim_memory_cls(memory_id='mem')

            elif o.ABSTRACT_MEMORY in self.options:
                # We use SimAbstractMemory in static mode.
                # Convert memory_backer into 'global' region.
                if memory_backer is not None:
                    memory_backer = {'global': memory_backer}

                # TODO: support permissions backer in SimAbstractMemory
                sim_memory_cls = self.plugin_preset.request_plugin('abs_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem')

            elif o.FAST_MEMORY in self.options:
                sim_memory_cls = self.plugin_preset.request_plugin('fast_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem')

            else:
                sim_memory_cls = self.plugin_preset.request_plugin('sym_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem',
                                            permissions_backer=permissions_backer)

            # Add memory plugin
            if not self._is_java_jni_project:
                self.register_plugin('memory', sim_memory)

            else:
                # In case of the JavaVM with JNI support, we add two `memory` plugins; one for modeling the
                # native memory and another one for the JavaVM memory.
                native_sim_memory = sim_memory
                javavm_sim_memory_cls = self.plugin_preset.request_plugin('javavm_memory')
                javavm_sim_memory = javavm_sim_memory_cls(memory_id='mem')
                self.register_plugin('memory_soot', javavm_sim_memory)
                self.register_plugin('memory_vex', native_sim_memory)

        if not self.has_plugin('registers'):
            # Same as for 'memory' plugin.
            if self.plugin_preset is None:
                self.use_plugin_preset('default')

            # Get register endness
            if self._is_java_jni_project:
                register_endness = self._arch['vex'].register_endness
            else:
                register_endness = self.arch.register_endness

            # Determine register backend
            if self._is_java_project and not self._is_java_jni_project:
                sim_registers_cls = self.plugin_preset.request_plugin('keyvalue_memory')
                sim_registers = sim_registers_cls(memory_id='reg')

            elif o.FAST_REGISTERS in self.options:
                sim_registers_cls = self.plugin_preset.request_plugin('fast_memory')
                sim_registers = sim_registers_cls(memory_id="reg", endness=register_endness)
            else:
                sim_registers_cls = self.plugin_preset.request_plugin('sym_memory')
                sim_registers = sim_registers_cls(memory_id="reg", endness=register_endness)

            # Add registers plugin
            if not self._is_java_jni_project:
                self.register_plugin('registers', sim_registers)

            else:
                # Analog to memory, we add two registers plugins
                native_sim_registers = sim_registers
                javavm_sim_registers_cls = self.plugin_preset.request_plugin('keyvalue_memory')
                javavm_sim_registers = javavm_sim_registers_cls(memory_id='reg')
                self.register_plugin('registers_soot', javavm_sim_registers)
                self.register_plugin('registers_vex', native_sim_registers)

        # OS name
        self.os_name = os_name

        # This is used in static mode as we don't have any constraints there
        self._satisfiable = True

        self.uninitialized_access_handler = None
        self._special_memory_filler = special_memory_filler

        # this is a global condition, applied to all added constraints, memory reads, etc
        self._global_condition = None
        self.ip_constraints = []
Exemplo n.º 51
0
    def __init__(self, binary, is_main_bin=False, compatible_with=None, filetype='unknown', **kwargs):
        """
        :param binary:          The path to the binary to load
        :param is_main_bin:     Whether this binary should be loaded as the main executable
        :param compatible_with: An optional Backend object to force compatibility with
        :param filetype:        The format of the file to load
        """
        # Unfold the kwargs and convert them to class attributes
        # TODO: do we need to do this anymore?
        for k,v in kwargs.iteritems():
            setattr(self, k, v)

        if hasattr(binary, 'seek') and hasattr(binary, 'read'):
            self.binary = None
            self.binary_stream = binary
        else:
            self.binary = binary
            try:
                self.binary_stream = open(binary, 'rb')
            except IOError:
                self.binary_stream = None
        self.is_main_bin = is_main_bin
        self._entry = None
        self.segments = [] # List of segments
        self.sections = []      # List of sections
        self.sections_map = {}  # Mapping from section name to section
        self.symbols_by_addr = {}
        self.imports = {}
        self.resolved_imports = []
        self.relocs = []
        self.irelatives = []    # list of tuples (resolver, destination), dest w/o rebase
        self.jmprel = {}
        self.arch = None
        self.filetype = filetype
        self.os = 'windows' if self.filetype == 'pe' else 'unix'
        self.compatible_with = compatible_with
        self._symbol_cache = {}
        self.aslr = kwargs['aslr'] if 'aslr' in kwargs else False

        self.rebase_addr_symbolic = 0
        # These are set by cle, and should not be overriden manually
        self.rebase_addr = 0 # not to be set manually - used by CLE
        self.tls_module_id = None

        self.deps = []           # Needed shared objects (libraries dependencies)
        self.linking = None # Dynamic or static linking
        self.requested_base = None
        self.pic = False
        self.execstack = False

        # Custom options
        self._custom_entry_point = kwargs.get('custom_entry_point', None)
        self.provides = None

        self.memory = None

        custom_arch = kwargs.get('custom_arch', None)
        if custom_arch is None:
            self.arch = None
        elif isinstance(custom_arch, str):
            self.set_arch(archinfo.arch_from_id(custom_arch))
        elif isinstance(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch)
        elif isinstance(custom_arch, type) and issubclass(custom_arch, archinfo.Arch):
            self.set_arch(custom_arch())
        else:
            raise CLEError("Bad parameter: custom_arch=%s" % custom_arch)
Exemplo n.º 52
0
    def __init__(self, thing,
                 default_analysis_mode=None,
                 ignore_functions=None,
                 use_sim_procedures=True,
                 exclude_sim_procedures_func=None,
                 exclude_sim_procedures_list=(),
                 arch=None, simos=None,
                 load_options=None,
                 translation_cache=True,
                 support_selfmodifying_code=False,
                 store_function=None,
                 load_function=None,
                 analyses_preset=None,
                 concrete_target=None,
                 engines_preset=None,
                 **kwargs):

        # Step 1: Load the binary

        if load_options is None: load_options = {}

        load_options.update(kwargs)
        if arch is not None:
            load_options.update({'arch': arch})
        if isinstance(thing, cle.Loader):
            if load_options:
                l.warning("You provided CLE options to angr but you also provided a completed cle.Loader object!")
            self.loader = thing
            self.filename = self.loader.main_object.binary
        elif hasattr(thing, 'read') and hasattr(thing, 'seek'):
            l.info("Loading binary from stream")
            self.filename = None
            self.loader = cle.Loader(thing, **load_options)
        elif not isinstance(thing, str) or not os.path.exists(thing) or not os.path.isfile(thing):
            raise Exception("Not a valid binary file: %s" % repr(thing))
        else:
            # use angr's loader, provided by cle
            l.info("Loading binary %s", thing)
            self.filename = thing
            self.loader = cle.Loader(self.filename, concrete_target=concrete_target, **load_options)

        # Step 2: determine its CPU architecture, ideally falling back to CLE's guess
        if isinstance(arch, str):
            self.arch = archinfo.arch_from_id(arch)  # may raise ArchError, let the user see this
        elif isinstance(arch, archinfo.Arch):
            self.arch = arch
        elif arch is None:
            self.arch = self.loader.main_object.arch
        else:
            raise ValueError("Invalid arch specification.")

        # Step 3: Set some defaults and set the public and private properties
        if not default_analysis_mode:
            default_analysis_mode = 'symbolic'
        if not ignore_functions:
            ignore_functions = []

        if isinstance(exclude_sim_procedures_func, types.LambdaType):
            l.warning("Passing a lambda type as the exclude_sim_procedures_func argument to "
                      "Project causes the resulting object to be un-serializable.")

        self._sim_procedures = {}

        self.concrete_target = concrete_target

        # It doesn't make any sense to have auto_load_libs
        # if you have the concrete target, let's warn the user about this.
        if self.concrete_target and load_options.get('auto_load_libs', None):

            l.critical("Incompatible options selected for this project, please disable auto_load_libs if "
                       "you want to use a concrete target.")
            raise Exception("Incompatible options for the project")

        if self.concrete_target and self.arch.name not in ['X86', 'AMD64']:
            l.critical("Concrete execution does not support yet the selected architecture. Aborting.")
            raise Exception("Incompatible options for the project")

        self._default_analysis_mode = default_analysis_mode
        self._exclude_sim_procedures_func = exclude_sim_procedures_func
        self._exclude_sim_procedures_list = exclude_sim_procedures_list
        self._should_use_sim_procedures = use_sim_procedures
        self._ignore_functions = ignore_functions
        self._support_selfmodifying_code = support_selfmodifying_code
        self._translation_cache = translation_cache
        self._executing = False # this is a flag for the convenience API, exec() and terminate_execution() below
        self._is_java_project = None
        self._is_java_jni_project = None

        if self._support_selfmodifying_code:
            if self._translation_cache is True:
                self._translation_cache = False
                l.warning("Disabling IRSB translation cache because support for self-modifying code is enabled.")

        self.entry = self.loader.main_object.entry
        self.storage = defaultdict(list)
        self.store_function = store_function or self._store
        self.load_function = load_function or self._load

        # Step 4: Set up the project's plugin hubs
        # Step 4.1: Engines. Get the preset from the loader, from the arch, or use the default.
        engines = EngineHub(self)
        if engines_preset is not None:
            engines.use_plugin_preset(engines_preset)
        elif self.loader.main_object.engine_preset is not None:
            try:
                engines.use_plugin_preset(self.loader.main_object.engine_preset)
            except AngrNoPluginError:
                raise ValueError("The CLE loader asked to use a engine preset: %s" % \
                        self.loader.main_object.engine_preset)
        else:
            try:
                engines.use_plugin_preset(self.arch.name)
            except AngrNoPluginError:
                engines.use_plugin_preset('default')

        self.engines = engines
        self.factory = AngrObjectFactory(self)

        # Step 4.2: Analyses
        self.analyses = AnalysesHub(self)
        self.analyses.use_plugin_preset(analyses_preset if analyses_preset is not None else 'default')

        # Step 4.3: ...etc
        self.kb = KnowledgeBase(self, self.loader.main_object)

        # Step 5: determine the guest OS
        if isinstance(simos, type) and issubclass(simos, SimOS):
            self.simos = simos(self) #pylint:disable=invalid-name
        elif isinstance(simos, str):
            self.simos = os_mapping[simos](self)
        elif simos is None:
            self.simos = os_mapping[self.loader.main_object.os](self)
        else:
            raise ValueError("Invalid OS specification or non-matching architecture.")

        # Step 6: Register simprocedures as appropriate for library functions
        if isinstance(self.arch, ArchSoot) and self.simos.is_javavm_with_jni_support:
            # If we execute a Java archive that includes native JNI libraries,
            # we need to use the arch of the native simos for all (native) sim
            # procedures.
            sim_proc_arch = self.simos.native_arch
        else:
            sim_proc_arch = self.arch
        for obj in self.loader.initial_load_objects:
            self._register_object(obj, sim_proc_arch)

        # Step 7: Run OS-specific configuration
        self.simos.configure_project()
Exemplo n.º 53
0
def _regs_to_offsets(arch_name, regs):
    offsets = set()
    arch = archinfo.arch_from_id(arch_name)
    for r in regs:
        offsets.add(arch.registers[r][0])
    return offsets
Exemplo n.º 54
0
Arquivo: elf.py Projeto: quoscient/cle
    def __init__(self, binary, **kwargs):
        super(ELF, self).__init__(binary, **kwargs)

        patch_undo = None
        try:
            self.reader = elffile.ELFFile(self.binary_stream)
        except ELFError:
            self.binary_stream.seek(5)
            ty = self.binary_stream.read(1)
            if ty not in ('\1', '\2'):
                raise CLECompatibilityError

            patch_data = (0x20, '\0\0\0\0') if ty == '\1' else (0x28, '\0\0\0\0\0\0\0\0')
            self.binary_stream.seek(patch_data[0])
            patch_undo = (patch_data[0], self.binary_stream.read(len(patch_data[1])))
            self.binary_stream = PatchedStream(self.binary_stream, [patch_data])
            l.error("PyReadELF couldn't load this file. Trying again without section headers...")

            try:
                self.reader = elffile.ELFFile(self.binary_stream)
            except ELFError:
                raise CLECompatibilityError

        # Get an appropriate archinfo.Arch for this binary, unless the user specified one
        if self.arch is None:
            arch_str = self.reader['e_machine']
            if arch_str == 'ARM':
                if self.reader.header.e_flags & 0x200:
                    self.set_arch(archinfo.ArchARMEL('Iend_LE' if self.reader.little_endian else 'Iend_BE'))
                elif self.reader.header.e_flags & 0x400:
                    self.set_arch(archinfo.ArchARMHF('Iend_LE' if self.reader.little_endian else 'Iend_BE'))
            else:
                self.set_arch(archinfo.arch_from_id(arch_str,
                                                'le' if self.reader.little_endian else 'be',
                                                self.reader.elfclass))

        self.strtab = None
        self.dynsym = None
        self.hashtable = None

        self._dynamic = {}
        self.deps = []
        self.rela_type = None

        self._inits_extracted = False
        self._preinit_arr = []
        self._init_func = None
        self._init_arr = []
        self._fini_func = None
        self._fini_arr = []
        self._nullsymbol = Symbol(self, '', 0, 0, None, 'STT_NOTYPE', 0)

        self._symbol_cache = {}
        self.symbols_by_addr = {}
        self.demangled_names = {}
        self.imports = {}
        self.resolved_imports = []

        self.relocs = []
        self.jmprel = {}

        self._entry = self.reader.header.e_entry
        self.pic = self.reader.header.e_type == 'ET_DYN'

        self.tls_used = False
        self.tls_module_id = None
        self.tls_block_offset = None
        self.tls_block_size = None
        self.tls_tdata_start = None
        self.tls_tdata_size = None

        self.__parsed_reloc_tables = set()

        self.__register_segments()
        self.__register_sections()

        # call the methods defined by MetaELF
        self._ppc64_abiv1_entry_fix()
        self._load_plt()

        self._populate_demangled_names()

        if patch_undo is not None:
            self.memory.write_bytes(self.get_min_addr() + patch_undo[0], patch_undo[1])
Exemplo n.º 55
0
    def __init__(self, thing,
                 default_analysis_mode=None,
                 ignore_functions=None,
                 use_sim_procedures=True,
                 exclude_sim_procedures_func=None,
                 exclude_sim_procedures_list=(),
                 arch=None, simos=None,
                 load_options=None,
                 translation_cache=True,
                 support_selfmodifying_code=False,
                 **kwargs):

        # Step 1: Load the binary
        if load_options is None: load_options = {}
        load_options.update(kwargs)

        if isinstance(thing, cle.Loader):
            if load_options:
                l.warning("You provided CLE options to angr but you also provided a completed cle.Loader object!")
            self.loader = thing
            self.filename = self.loader.main_object.binary
        elif hasattr(thing, 'read') and hasattr(thing, 'seek'):
            l.info("Loading binary from stream")
            self.filename = None
            self.loader = cle.Loader(thing, **load_options)
        elif not isinstance(thing, (unicode, str)) or not os.path.exists(thing) or not os.path.isfile(thing):
            raise Exception("Not a valid binary file: %s" % repr(thing))
        else:
            # use angr's loader, provided by cle
            l.info("Loading binary %s", thing)
            self.filename = thing
            self.loader = cle.Loader(self.filename, **load_options)

        # Step 2: determine its CPU architecture, ideally falling back to CLE's guess
        if isinstance(arch, str):
            self.arch = archinfo.arch_from_id(arch)  # may raise ArchError, let the user see this
        elif isinstance(arch, archinfo.Arch):
            self.arch = arch
        elif arch is None:
            self.arch = self.loader.main_object.arch
        else:
            raise ValueError("Invalid arch specification.")

        # Step 3: Set some defaults and set the public and private properties
        if not default_analysis_mode:
            default_analysis_mode = 'symbolic'
        if not ignore_functions:
            ignore_functions = []

        if isinstance(exclude_sim_procedures_func, types.LambdaType):
            l.warning("Passing a lambda type as the exclude_sim_procedures_func argument to Project causes the resulting object to be un-serializable.")

        self._sim_procedures = {}
        self._default_analysis_mode = default_analysis_mode
        self._exclude_sim_procedures_func = exclude_sim_procedures_func
        self._exclude_sim_procedures_list = exclude_sim_procedures_list
        self._should_use_sim_procedures = use_sim_procedures
        self._support_selfmodifying_code = support_selfmodifying_code
        self._ignore_functions = ignore_functions
        self._executing = False # this is a flag for the convenience API, exec() and terminate_execution() below

        if self._support_selfmodifying_code:
            if translation_cache is True:
                translation_cache = False
                l.warning("Disabling IRSB translation cache because support for self-modifying code is enabled.")

        # Look up the default engine.
        engine_cls = get_default_engine(type(self.loader.main_object))
        if not engine_cls:
            raise AngrError("No engine associated with loader %s" % str(type(self.loader.main_object)))
        engine = engine_cls(
                stop_points=self._sim_procedures,
                use_cache=translation_cache,
                support_selfmodifying_code=support_selfmodifying_code)
        procedure_engine = SimEngineProcedure()
        hook_engine = SimEngineHook(self)
        failure_engine = SimEngineFailure(self)
        syscall_engine = SimEngineSyscall(self)
        unicorn_engine = SimEngineUnicorn(self._sim_procedures)

        self.entry = self.loader.main_object.entry
        self.factory = AngrObjectFactory(
                self,
                engine,
                procedure_engine,
                [failure_engine, syscall_engine, hook_engine, unicorn_engine, engine])
        self.analyses = Analyses(self)
        self.surveyors = Surveyors(self)
        self.kb = KnowledgeBase(self, self.loader.main_object)

        if self.filename is not None:
            projects[self.filename] = self

        # Step 4: determine the guest OS
        if isinstance(simos, type) and issubclass(simos, SimOS):
            self._simos = simos(self) #pylint:disable=invalid-name
        elif simos is None:
            self._simos = os_mapping[self.loader.main_object.os](self)
        else:
            raise ValueError("Invalid OS specification or non-matching architecture.")

        # Step 5: Register simprocedures as appropriate for library functions
        for obj in self.loader.initial_load_objects:
            self._register_object(obj)

        # Step 6: Run OS-specific configuration
        self._simos.configure_project()
Exemplo n.º 56
0
    def __init__(self, project=None, arch=None, plugins=None, memory_backer=None, permissions_backer=None, mode=None, options=None,
                 add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default'):
        super(SimState, self).__init__()
        self.project = project
        self.arch = arch if arch is not None else project.arch.copy() if project is not None else None

        if type(self.arch) is str:
            self.arch = arch_from_id(self.arch)

        # the options
        if options is None:
            if mode is None:
                l.warning("SimState defaulting to symbolic mode.")
                mode = "symbolic"
            options = o.modes[mode]

        if isinstance(options, (set, list)):
            options = SimStateOptions(options)
        if add_options is not None:
            options |= add_options
        if remove_options is not None:
            options -= remove_options
        self._options = options
        self.mode = mode

        if plugin_preset is not None:
            self.use_plugin_preset(plugin_preset)

        if plugins is not None:
            for n,p in plugins.iteritems():
                self.register_plugin(n, p, inhibit_init=True)
            for p in plugins.itervalues():
                p.init_state()

        if not self.has_plugin('memory'):
            # We don't set the memory endness because, unlike registers, it's hard to understand
            # which endness the data should be read.

            # If they didn't provide us with either a memory plugin or a plugin preset to use,
            # we have no choice but to use the 'default' plugin preset.
            if self.plugin_preset is None:
                self.use_plugin_preset('default')

            if o.ABSTRACT_MEMORY in self.options:
                # We use SimAbstractMemory in static mode.
                # Convert memory_backer into 'global' region.
                if memory_backer is not None:
                    memory_backer = {'global': memory_backer}

                # TODO: support permissions backer in SimAbstractMemory
                sim_memory_cls = self.plugin_preset.request_plugin('abs_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem')

            elif o.FAST_MEMORY in self.options:
                sim_memory_cls = self.plugin_preset.request_plugin('fast_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem')

            else:
                sim_memory_cls = self.plugin_preset.request_plugin('sym_memory')
                sim_memory = sim_memory_cls(memory_backer=memory_backer, memory_id='mem',
                                            permissions_backer=permissions_backer)

            self.register_plugin('memory', sim_memory)

        if not self.has_plugin('registers'):

            # Same as for 'memory' plugin.
            if self.plugin_preset is None:
                self.use_plugin_preset('default')

            if o.FAST_REGISTERS in self.options:
                sim_registers_cls = self.plugin_preset.request_plugin('fast_memory')
                sim_registers = sim_registers_cls(memory_id="reg", endness=self.arch.register_endness)
            else:
                sim_registers_cls = self.plugin_preset.request_plugin('sym_memory')
                sim_registers = sim_registers_cls(memory_id="reg", endness=self.arch.register_endness)

            self.register_plugin('registers', sim_registers)

        # OS name
        self.os_name = os_name

        # This is used in static mode as we don't have any constraints there
        self._satisfiable = True

        # states are big, so let's give them UUIDs for ANA right away to avoid
        # extra pickling
        self.make_uuid()

        self.uninitialized_access_handler = None
        self._special_memory_filler = special_memory_filler

        # this is a global condition, applied to all added constraints, memory reads, etc
        self._global_condition = None
        self.ip_constraints = []
Exemplo n.º 57
0
  def Iop_Add64(self, left, right): return utils.mask(left + right)
  def Iop_Add32(self, left, right): return utils.mask(left + right, 32)
  def Iop_Add8(self, left, right):  return utils.mask(left + right, 8)

  def Iop_Sub64(self, left, right): return utils.mask(left - right)
  def Iop_Sub32(self, left, right): return utils.mask(left - right, 32)

  def Iop_Shl64(self, left, right): return utils.mask(left << right)
  def Iop_Shl32(self, left, right): return utils.mask(left << right, 32)

  def Iop_CmpEQ64(self, left, right): return 1 if utils.mask(left, 64) == utils.mask(right, 64) else 0
  def Iop_CmpEQ32(self, left, right): return 1 if utils.mask(left, 32) == utils.mask(right, 32) else 0

  def Iop_CmpNE64(self, left, right): return 1 if utils.mask(left, 64) != utils.mask(right, 64) else 0
  def Iop_CmpNE32(self, left, right): return 1 if utils.mask(left, 32) != utils.mask(right, 32) else 0

if __name__ == "__main__":
  import sys
  if len(sys.argv) < 3:
    print "Usage: classifier.py architecture filename [-v]"
    sys.exit(1)

  arch = archinfo.arch_from_id(sys.argv[1]).__class__
  code = utils.get_contents(sys.argv[2])

  classifier = GadgetClassifier(arch, log_level = logging.DEBUG if len(sys.argv) > 3 else logging.WARNING)
  gadgets = classifier.create_gadgets_from_instructions(code, 0x40000)
  for g in gadgets:
    print g
Exemplo n.º 58
0
def test_ctype_tolower_loc():
    '''
    test_ctype_locale.test_ctype_tolower_loc

    int32_t * * __ctype_tolower_loc(void);

    Description:
    The __ctype_tolower_loc() function shall return a pointer into an array of
    characters in the current locale that contains lower case equivalents for
    each character in the current character set. The array shall contain a total
    of 384 characters, and can be indexed with any signed or unsigned char (i.e.
    with an index value between -128 and 255). If the application is
    multithreaded, the array shall be local to the current thread.

    This interface is not in the source standard; it is only in the binary
    standard.

    Return Value:
    The __ctype_tolower_loc() function shall return a pointer to the array of
    characters to be used for the ctype() family of functions (see <ctype.h>).
    '''
    # Just load a binary so that we can do the initialization steps from
    # libc_start_main
    bin_path = os.path.join(test_location, '../../binaries/tests/x86_64/ctype_tolower_loc')

    ctype_tolower_loc = lambda state, arguments: simuvex.SimProcedures['libc.so.6']['__ctype_tolower_loc'](FAKE_ADDR, archinfo.arch_from_id('AMD64')).execute(state, arguments=arguments)

    b = angr.Project(bin_path)
    p = b.factory.full_init_state()
    pg = b.factory.path_group(p)

    # Find main located at 0x400596 to let libc_start_main do its thing
    main = pg.explore(find=0x400596)

    state = main.found[0].state
    tolower_loc_array_ptr = ctype_tolower_loc(state, []).ret_expr
    table_ptr = state.memory.load(tolower_loc_array_ptr, state.arch.bits/8, endness=state.arch.memory_endness)

    result = ''
    for i in range(-128, 256):
        result += "%d->0x%x\n" % (i, state.se.any_int(state.memory.load(table_ptr + (i*4),
                                                                        4,
                                                                        endness=state.arch.memory_endness)))

    # Check output of compiled C program that uses ctype_tolower_loc()
    output = subprocess.check_output(bin_path, shell=True)
    nose.tools.assert_equal(result, output)