示例#1
0
文件: memory.py 项目: iamahuman/angr
    def _resolve_location_name(self, name, is_write=False):

        # Delayed load so SimMemory does not rely on SimEngines
        from ..engines.vex.ccall import _get_flags

        if self.category == 'reg':
            if self.state.arch.name in ('X86', 'AMD64'):
                if name in stn_map:
                    return (((stn_map[name] + self.load('ftop')) & 7) << 3) + self.state.arch.registers['fpu_regs'][0], 8
                elif name in tag_map:
                    return ((tag_map[name] + self.load('ftop')) & 7) + self.state.arch.registers['fpu_tags'][0], 1
                elif name in ('flags', 'eflags', 'rflags'):
                    # we tweak the state to convert the vex condition registers into the flags register
                    if not is_write: # this work doesn't need to be done if we're just gonna overwrite it
                        self.store('cc_dep1', _get_flags(self.state)[0]) # TODO: can constraints be added by this?
                    self.store('cc_op', 0) # OP_COPY
                    return self.state.arch.registers['cc_dep1'][0], self.state.arch.bytes
            if is_arm_arch(self.state.arch):
                if name == 'flags':
                    if not is_write:
                        self.store('cc_dep1', _get_flags(self.state)[0])
                    self.store('cc_op', 0)
                    return self.state.arch.registers['cc_dep1'][0], self.state.arch.bytes

            return self.state.arch.registers[name]
        elif name[0] == '*':
            return self.state.registers.load(name[1:]), None
        else:
            raise SimMemoryError("Trying to address memory with a register name.")
示例#2
0
    def _resolve_location_name(self, name, is_write=False):

        # Delayed load so SimMemory does not rely on SimEngines
        from angr.engines.vex.claripy.ccall import _get_flags

        if self.category == 'reg':
            if self.state.arch.name in ('X86', 'AMD64'):
                if name in stn_map:
                    return (((stn_map[name] + self.load('ftop')) & 7) << 3) + self.state.arch.registers['fpu_regs'][0], 8
                elif name in tag_map:
                    return ((tag_map[name] + self.load('ftop')) & 7) + self.state.arch.registers['fpu_tags'][0], 1
                elif name in ('flags', 'eflags', 'rflags'):
                    # we tweak the state to convert the vex condition registers into the flags register
                    if not is_write: # this work doesn't need to be done if we're just gonna overwrite it
                        self.store('cc_dep1', _get_flags(self.state))
                    self.store('cc_op', 0) # OP_COPY
                    return self.state.arch.registers['cc_dep1'][0], self.state.arch.bytes
            if is_arm_arch(self.state.arch):
                if name == 'flags':
                    if not is_write:
                        self.store('cc_dep1', _get_flags(self.state))
                    self.store('cc_op', 0)
                    return self.state.arch.registers['cc_dep1'][0], self.state.arch.bytes

            return self.state.arch.registers[name]
        elif name[0] == '*':
            return self.state.registers.load(name[1:]), None
        else:
            raise SimMemoryError("Trying to address memory with a register name.")
示例#3
0
文件: labels.py 项目: ufo2011/angr
    def __init__(self, kb):
        self._kb = kb
        self._labels = {}
        self._reverse_labels = {}

        is_arm = is_arm_arch(kb._project.arch)
        for obj in kb._project.loader.all_objects:
            for v in obj.symbols:
                if is_arm and v.name in {"$d", "$t", "$a"}:
                    continue
                if v.name and not v.is_import and v.type not in {
                        cle.SymbolType.TYPE_OTHER,
                }:
                    self._labels[v.rebased_addr] = v.name
                    self._reverse_labels[v.name] = v.rebased_addr
            try:
                for v, k in obj.plt.items():
                    self._labels[k] = v
            except AttributeError:
                pass

        # Artificial labels for the entry point
        entry = kb._project.loader.main_object.entry
        if entry not in self._labels:
            lbl = "_start"
            self._labels[entry] = self.get_unique_label(lbl)
示例#4
0
 def __getitem__(self, ident) -> CFGModel:
     if ident not in self.cfgs:
         if self._kb is not None and self._kb._project is not None:
             is_arm = is_arm_arch(self._kb._project.arch)
         else:
             is_arm = False
         self.cfgs[ident] = CFGModel(ident, cfg_manager=self, is_arm=is_arm)
     return self.cfgs[ident]
示例#5
0
文件: view.py 项目: ohyeah521/angr-1
 def __dir__(self):
     if self.state.arch.name in ('X86', 'AMD64'):
         return list(self.state.arch.registers.keys()) + [
             'st%d' % n for n in range(8)
         ] + ['tag%d' % n
              for n in range(8)] + ['flags', 'eflags', 'rflags']
     elif is_arm_arch(self.state.arch):
         return list(self.state.arch.registers.keys()) + ['flags']
     return self.state.arch.registers.keys()
示例#6
0
def decode_instruction(arch, instr):
    # this is clearly architecture specific

    arch_name = arch.name
    if arch_name == 'MIPS32' and once('mips-instruction-groups'):
        l.warning(
            'Your version of capstone does not support MIPS instruction groups.'
        )

    insn_info = None

    info = INS_GROUP_INFO.get(arch_name, None)
    if info is not None:
        for group in instr.insn.insn.groups:
            insn_info = info.get(group, None)
            if insn_info is not None:
                break

    if insn_info is None:
        info = INS_INFO.get(arch_name, None)
        if info is not None:
            insn_info = info.get(instr.insn.insn.id, None)

    if insn_info is None:
        return

    instr.type = insn_info

    if instr.type in ('call', 'branch'):
        # determine if this is a direct or indirect call/branch
        if arch_name in ('X86', 'AMD64'):
            last_operand = instr.insn.operands[-1]
            if last_operand.type == cs.x86.X86_OP_IMM:
                instr.branch_type = 'direct'
            else:
                instr.branch_type = 'indirect'
            instr.branch_target_operand = len(instr.insn.operands) - 1

        elif is_arm_arch(arch):
            last_operand = instr.insn.operands[-1]
            if last_operand.type == cs.arm.ARM_OP_IMM:
                instr.branch_type = 'direct'
            else:
                instr.branch_type = 'indirect'
            instr.branch_target_operand = len(instr.insn.operands) - 1

        elif arch_name == 'MIPS32':
            # check the last operand
            last_operand = instr.insn.operands[-1]
            if last_operand.type == cs.mips.MIPS_OP_REG:
                instr.branch_type = 'indirect'
            else:
                instr.branch_type = 'direct'
            instr.branch_target_operand = len(instr.insn.operands) - 1
示例#7
0
    def _is_sane_register_variable(self,
                                   variable: SimRegisterVariable) -> bool:
        """
        Filters all registers that are surly not members of function arguments.
        This can be seen as a workaround, since VariableRecoveryFast sometimes gives input variables of cc_ndep (which
        is a VEX-specific register) :-(

        :param variable: The variable to test.
        :return:         True if it is an acceptable function argument, False otherwise.
        :rtype:          bool
        """

        arch = self.project.arch

        if arch.name == 'AARCH64':
            return 16 <= variable.reg < 80  # x0-x7

        elif arch.name == 'AMD64':
            return (24 <= variable.reg < 40 or  # rcx, rdx
                    64 <= variable.reg < 104  # rsi, rdi, r8, r9, r10
                    )
            # 224 <= variable.reg < 480)  # xmm0-xmm7

        elif is_arm_arch(arch):
            return 8 <= variable.reg < 24  # r0-r3

        elif arch.name == 'MIPS32':
            return 24 <= variable.reg < 40  # a0-a3

        elif arch.name == 'MIPS64':
            return 48 <= variable.reg < 80 or 112 <= variable.reg < 208  # a0-a3 or t4-t7

        elif arch.name == 'PPC32':
            return 28 <= variable.reg < 60  # r3-r10

        elif arch.name == 'X86':
            return (8 <= variable.reg < 24 or  # eax, ebx, ecx, edx
                    160 <= variable.reg < 288)  # xmm0-xmm7

        else:
            l.critical('Unsupported architecture %s.', arch.name)
            return True
示例#8
0
    def _handle_Get(self, expr):
        reg_offset = expr.offset
        reg_size = expr.result_size(self.tyenv) // 8

        # because of how VEX implements MOVCC and MOVCS instructions in ARM THUMB mode, we need to skip the register
        # read if the immediate next instruction is an WrTmp(ITE).
        #
        # MOVCC           R3, #0
        #
        #    46 | ------ IMark(0xfeca2, 2, 1) ------
        #    47 | t299 = CmpLT32U(t8,0x00010000)
        #    48 | t143 = GET:I32(r3)      <-   this read does not exist
        #    49 | t300 = ITE(t299,0x00000000,t143)
        #    50 | PUT(r3) = t300
        #    51 | PUT(pc) = 0x000feca5
        if is_arm_arch(self.arch) and (self.ins_addr & 1) == 1:
            if self.stmt_idx < len(self.block.vex.statements) - 1:
                next_stmt = self.block.vex.statements[self.stmt_idx + 1]
                if isinstance(next_stmt, pyvex.IRStmt.WrTmp) and isinstance(
                        next_stmt.data, pyvex.IRExpr.ITE):
                    return RichR(self.state.top(reg_size * 8))

        return self._read_from_register(reg_offset, reg_size, expr=expr)
示例#9
0
    def _is_sane_register_variable(self, variable):
        """
        Filters all registers that are surly not members of function arguments.
        This can be seen as a workaround, since VariableRecoveryFast sometimes gives input variables of cc_ndep (which
        is a VEX-specific register) :-(

        :param SimRegisterVariable variable: The variable to test.
        :return:                             True if it is an acceptable function argument, False otherwise.
        :rtype:                              bool
        """

        arch = self.project.arch

        if arch.name == 'AARCH64':
            return 16 <= variable.reg < 80  # x0-x7

        elif arch.name == 'AMD64':
            return (24 <= variable.reg < 40 or  # rcx, rdx
                    64 <= variable.reg < 104 or  # rsi, rdi, r8, r9, r10
                    224 <= variable.reg < 480)  # xmm0-xmm7

        elif is_arm_arch(arch):
            return 8 <= variable.reg < 24  # r0-r3

        elif arch.name == 'MIPS32':
            return 24 <= variable.reg < 40  # a0-a3

        elif arch.name == 'PPC32':
            return 28 <= variable.reg < 60  # r3-r10

        elif arch.name == 'X86':
            return (8 <= variable.reg < 24 or  # eax, ebx, ecx, edx
                    160 <= variable.reg < 288)  # xmm0-xmm7

        else:
            l.critical('Unsupported architecture %s.', arch.name)
            return True
示例#10
0
文件: view.py 项目: iamahuman/angr
 def __dir__(self):
     if self.state.arch.name in ('X86', 'AMD64'):
         return list(self.state.arch.registers.keys()) + ['st%d' % n for n in range(8)] + ['tag%d' % n for n in range(8)] + ['flags', 'eflags', 'rflags']
     elif is_arm_arch(self.state.arch):
         return self.state.arch.registers.keys() + ['flags']
     return self.state.arch.registers.keys()
示例#11
0
文件: flirt.py 项目: ufo2011/angr
    def __init__(self, sig: Optional[Union[FlirtSignature, str]] = None):

        self._is_arm = is_arm_arch(self.project.arch)
        self._all_suggestions: Dict[str, Dict[str, Dict[int, str]]] = {}
        self._suggestions: Dict[int, str] = {}
        self.matched_suggestions: Dict[str, Tuple[FlirtSignature,
                                                  Dict[int, str]]] = {}
        self._temporary_sig = False

        if sig:
            if isinstance(sig, str):
                # this is a file path
                sig = FlirtSignature(self.project.arch.name.lower(),
                                     self.project.simos.name.lower(),
                                     "Temporary", sig, None)

                self.signatures = [sig]
                self._temporary_sig = True

        else:
            if not FLIRT_SIGNATURES_BY_ARCH:
                raise RuntimeError(
                    "No FLIRT signatures exist. Please load FLIRT signatures by calling "
                    "load_signatures() before running FlirtAnalysis.")

            # determine all signatures to match against strings in mapped memory regions
            mem_regions = [
                self.project.loader.memory.load(seg.vaddr, seg.memsize)
                for seg in self.project.loader.main_object.segments
                if seg.filesize > 0 and seg.memsize > 0
            ]

            self.signatures = list(self._find_hits_by_strings(mem_regions))
            _l.debug("Identified %d signatures to apply.",
                     len(self.signatures))

        path_to_sig: Dict[str, FlirtSignature] = {}
        for sig_ in self.signatures:
            self._match_all_against_one_signature(sig_)
            if sig_.sig_name not in self._all_suggestions:
                self._all_suggestions[sig_.sig_name] = {}
            path_to_sig[sig_.sig_path] = sig_
            self._all_suggestions[sig_.sig_name][
                sig_.sig_path] = self._suggestions
            self._suggestions = {}

        for lib, sig_to_suggestions in self._all_suggestions.items():
            max_suggestions = None
            max_suggestion_sig_path = None
            for sig_, suggestion in sig_to_suggestions.items():
                _l.debug("Signature %s has %d function name suggestions.",
                         sig_, len(suggestion))
                if max_suggestions is None or len(
                        suggestion) > max_suggestions:
                    max_suggestion_sig_path = sig_
                    max_suggestions = len(suggestion)

            if max_suggestion_sig_path is not None:
                sig_ = path_to_sig.get(max_suggestion_sig_path, None)
                _l.info("Applying FLIRT signature %s for library %s.", sig_,
                        lib)
                self._apply_changes(
                    sig_.sig_name if not self._temporary_sig else None,
                    sig_to_suggestions[max_suggestion_sig_path])
                self.matched_suggestions[lib] = (
                    sig_, sig_to_suggestions[max_suggestion_sig_path])