コード例 #1
0
ファイル: pe.py プロジェクト: 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!")
コード例 #2
0
ファイル: s_state.py プロジェクト: extremecoders-re/simuvex
    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 = []
コード例 #3
0
ファイル: pe.py プロジェクト: 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
コード例 #4
0
ファイル: __init__.py プロジェクト: 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)
コード例 #5
0
ファイル: __init__.py プロジェクト: angriestalien/angr
    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
コード例 #6
0
ファイル: elf.py プロジェクト: pewpewsecure/cle
    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()
コード例 #7
0
ファイル: __init__.py プロジェクト: 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
コード例 #8
0
ファイル: __init__.py プロジェクト: angriestalien/angr
 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
コード例 #9
0
ファイル: absobj.py プロジェクト: aziem/cle
    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)
コード例 #10
0
ファイル: gadget.py プロジェクト: KurSh/rop_compiler
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
コード例 #11
0
ファイル: __init__.py プロジェクト: 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)
コード例 #12
0
ファイル: pe.py プロジェクト: 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())
コード例 #13
0
ファイル: elf.py プロジェクト: 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)
コード例 #14
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
                )
             ),
        ],
        '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
コード例 #15
0
ファイル: __init__.py プロジェクト: angriestalien/angr
    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)
コード例 #16
0
ファイル: pe.py プロジェクト: 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!')
コード例 #17
0
ファイル: test_lift.py プロジェクト: angr/pyvex
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
コード例 #18
0
ファイル: gadget.py プロジェクト: jamella/rop_compiler
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
コード例 #19
0
ファイル: classifier.py プロジェクト: KurSh/rop_compiler
  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
コード例 #20
0
ファイル: sim_state.py プロジェクト: mattrepl/angr
    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 = []
コード例 #21
0
ファイル: elf.py プロジェクト: 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()
コード例 #22
0
ファイル: project.py プロジェクト: extremecoders-re/angr
    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()
コード例 #23
0
ファイル: finder.py プロジェクト: KurSh/rop_compiler
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()

コード例 #24
0
ファイル: __init__.py プロジェクト: xybsoft/cle
    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)
コード例 #25
0
ファイル: sim_state.py プロジェクト: chen93/angr
    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 = []
コード例 #26
0
ファイル: elf.py プロジェクト: 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])
コード例 #27
0
ファイル: test_ctype_locale.py プロジェクト: SlivTaMere/angr
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)
コード例 #28
0
ファイル: backward_slice.py プロジェクト: 0xItx/angr
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
コード例 #29
0
ファイル: project.py プロジェクト: tiffanyb/angr
    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()
コード例 #30
0
ファイル: project.py プロジェクト: iamahuman/angr
    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()