Esempio n. 1
0
    def __init__(self, project, cfg=None, require_predecessors=True, only_find=None):
        self.project = project
        if cfg is not None:
            self._cfg = cfg
        else:
            self._cfg = project.analyses.CFGFast(resolve_indirect_jumps=True)
        self._runner = Runner(project, self._cfg)

        # only find if in this set
        self.only_find = only_find

        # reg list
        a = self.project.arch
        self._sp_reg = a.register_names[a.sp_offset]
        self._bp_reg = a.register_names[a.bp_offset]
        self._ip_reg = a.register_names[a.ip_offset]
        self._reg_list = a.default_symbolic_registers
        self._reg_list = filter(lambda r: r != self._sp_reg, self._reg_list)
        self._reg_list = filter(lambda r: r != self._ip_reg, self._reg_list)

        self.matches = dict()

        self.callsites = None
        self.inv_callsites = None
        self.func_info = dict()
        self.block_to_func = dict()

        self.map_callsites()

        if self._too_large():
            l.warning("Too large")
            return

        self.base_symbolic_state = rop_utils.make_symbolic_state(self.project, self._reg_list)
        self.base_symbolic_state.options.discard(simuvex.o.SUPPORT_FLOATING_POINT)
        self.base_symbolic_state.regs.bp = self.base_symbolic_state.se.BVS("sreg_" + "ebp" + "-", self.project.arch.bits)

        for f in self._cfg.functions.values():
            if f.is_syscall:
                continue
            if self.project.is_hooked(f.addr):
                continue

            # skip if no predecessors
            try:
                if require_predecessors and len(self._cfg.functions.callgraph.predecessors(f.addr)) == 0:
                    continue
            except NetworkXError:
                if require_predecessors:
                    continue

            # find the actual vars
            try:
                func_info = self.find_stack_vars_x86(f)
                self.func_info[f] = func_info
            except (SimEngineError, SimMemoryError) as ex:
                l.debug("angr translation error: %s", ex.message)
            except IdentifierException as e:
                l.debug("Identifier Exception: %s", e.message)
Esempio n. 2
0
    def do_trace(self, addr_trace, reverse_accesses,
                 func_info):  #pylint disable=unused-argument
        # get to the callsite
        from angrop import rop_utils

        s = rop_utils.make_symbolic_state(self.project,
                                          self._reg_list,
                                          stack_length=200)
        s.options.discard(options.AVOID_MULTIVALUED_WRITES)
        s.options.discard(options.AVOID_MULTIVALUED_READS)
        s.options.add(options.UNDER_CONSTRAINED_SYMEXEC)
        s.options.discard(options.LAZY_SOLVES)

        func_info = self.func_info[self.block_to_func[addr_trace[0]]]
        for i in range(func_info.frame_size / self.project.arch.bytes + 5):
            s.stack_push(s.se.BVS("var_" + hex(i), self.project.arch.bits))

        if func_info.bp_based:
            s.regs.bp = s.regs.sp + func_info.bp_sp_diff
        s.regs.ip = addr_trace[0]
        addr_trace = addr_trace[1:]
        simgr = self.project.factory.simulation_manager(
            s, save_unconstrained=True)
        while len(addr_trace) > 0:
            simgr.stashes['unconstrained'] = []
            simgr.step()
            stepped = False
            for ss in simgr.active:
                # todo could write symbolic data to pointers passed to functions
                if ss.history.jumpkind == "Ijk_Call":
                    ss.regs.eax = ss.se.BVS("unconstrained_ret_%#x" % ss.addr,
                                            ss.arch.bits)
                    ss.regs.ip = ss.stack_pop()
                    ss.history.jumpkind = "Ijk_Ret"
                if ss.addr == addr_trace[0]:
                    simgr.stashes['active'] = [ss]
                    stepped = True
                    break
            if not stepped:
                if len(simgr.unconstrained) > 0:
                    s = simgr.unconstrained[0]
                    if s.history.jumpkind == "Ijk_Call":
                        s.regs.eax = s.se.BVS("unconstrained_ret", s.arch.bits)
                        s.regs.ip = s.stack_pop()
                        s.history.jumpkind = "Ijk_Ret"
                    s.regs.ip = addr_trace[0]
                    simgr.stashes['active'] = [s]
                    stepped = True
            if not stepped:
                raise IdentifierException("could not get call args")
            addr_trace = addr_trace[1:]

        # step one last time to the call
        simgr.step()
        if len(simgr.active) == 0:
            IdentifierException("Didn't succeed call")
        return simgr.active[0]
Esempio n. 3
0
File: identify.py Progetto: axt/angr
    def do_trace(self, addr_trace, reverse_accesses, func_info): #pylint disable=unused-argument
        # get to the callsite
        from angrop import rop_utils

        s = rop_utils.make_symbolic_state(self.project, self._reg_list, stack_length=200)
        s.options.discard(options.AVOID_MULTIVALUED_WRITES)
        s.options.discard(options.AVOID_MULTIVALUED_READS)
        s.options.add(options.UNDER_CONSTRAINED_SYMEXEC)
        s.options.discard(options.LAZY_SOLVES)

        func_info = self.func_info[self.block_to_func[addr_trace[0]]]
        for i in range(func_info.frame_size/self.project.arch.bytes+5):
            s.stack_push(s.se.BVS("var_" + hex(i), self.project.arch.bits))

        if func_info.bp_based:
            s.regs.bp = s.regs.sp + func_info.bp_sp_diff
        s.regs.ip = addr_trace[0]
        addr_trace = addr_trace[1:]
        simgr = self.project.factory.simulation_manager(s, save_unconstrained=True)
        while len(addr_trace) > 0:
            simgr.stashes['unconstrained'] = []
            simgr.step()
            stepped = False
            for ss in simgr.active:
                # todo could write symbolic data to pointers passed to functions
                if ss.history.jumpkind == "Ijk_Call":
                    ss.regs.eax = ss.se.BVS("unconstrained_ret_%#x" % ss.addr, ss.arch.bits)
                    ss.regs.ip = ss.stack_pop()
                    ss.history.jumpkind = "Ijk_Ret"
                if ss.addr == addr_trace[0]:
                    simgr.stashes['active'] = [ss]
                    stepped = True
                    break
            if not stepped:
                if len(simgr.unconstrained) > 0:
                    s = simgr.unconstrained[0]
                    if s.history.jumpkind == "Ijk_Call":
                        s.regs.eax = s.se.BVS("unconstrained_ret", s.arch.bits)
                        s.regs.ip = s.stack_pop()
                        s.history.jumpkind = "Ijk_Ret"
                    s.regs.ip = addr_trace[0]
                    simgr.stashes['active'] = [s]
                    stepped = True
            if not stepped:
                raise IdentifierException("could not get call args")
            addr_trace = addr_trace[1:]

        # step one last time to the call
        simgr.step()
        if len(simgr.active) == 0:
            IdentifierException("Didn't succeed call")
        return simgr.active[0]
Esempio n. 4
0
    def do_trace(self, addr_trace, reverse_accesses, func_info):
        # get to the callsite
        s = rop_utils.make_symbolic_state(self.project,
                                          self._reg_list,
                                          stack_length=200)
        s.options.discard(simuvex.o.AVOID_MULTIVALUED_WRITES)
        s.options.discard(simuvex.o.AVOID_MULTIVALUED_READS)
        s.options.add(simuvex.o.UNDER_CONSTRAINED_SYMEXEC)
        s.options.discard(simuvex.o.LAZY_SOLVES)

        func_info = self.func_info[self.block_to_func[addr_trace[0]]]
        for i in range(func_info.frame_size / self.project.arch.bytes + 5):
            s.stack_push(s.se.BVS("var_" + hex(i), self.project.arch.bits))

        if func_info.bp_based:
            s.regs.bp = s.regs.sp + func_info.bp_sp_diff
        s.regs.ip = addr_trace[0]
        addr_trace = addr_trace[1:]
        p = self.project.factory.path(s)
        while len(addr_trace) > 0:
            p.step()
            stepped = False
            for ss in p.successors:
                # todo could write symbolic data to pointers passed to functions
                if ss.jumpkind == "Ijk_Call":
                    ss.state.regs.eax = ss.state.se.BVS(
                        "unconstrained_ret_%#x" % ss.addr, ss.state.arch.bits)
                    ss.state.regs.ip = ss.state.stack_pop()
                    ss.state.scratch.jumpkind = "Ijk_Ret"
                if ss.addr == addr_trace[0]:
                    p = ss
                    stepped = True
            if not stepped:
                if len(p.unconstrained_successors) > 0:
                    p = p.unconstrained_successors[0]
                    if p.jumpkind == "Ijk_Call":
                        p.state.regs.eax = p.state.se.BVS(
                            "unconstrained_ret_%#x" % p.addr,
                            p.state.arch.bits)
                        p.state.regs.ip = p.state.stack_pop()
                        p.state.scratch.jumpkind = "Ijk_Ret"
                    p.state.regs.ip = addr_trace[0]
                    stepped = True
            if not stepped:
                raise IdentifierException("could not get call args")
            addr_trace = addr_trace[1:]

        # step one last time to the call
        p.step()
        if len(p.successors) == 0:
            IdentifierException("Didn't succeed call")
        return p.successors[0]
Esempio n. 5
0
    def __init__(self, binary, crash=None):
        """
        :param binary: path to the binary which crashed
        :param crash: string of input which crashed the binary
        """

        self.binary = binary
        self.crash = crash

        # verify it actually crashes the binary
        r = tracer.Runner(self.binary, input=self.crash, record_stdout=True)
        if not r.crash_mode:
            raise CrashFuzzerException("input did not crash the binary")

        self.orig_stdout = r.stdout

        self.addr_ast = None
        try:
            self._p = angr.Project(self.binary)

            self.orig_regs = r.reg_vals
            s = rop_utils.make_symbolic_state(self._p,
                                              reg_list=CGC_GENERAL_REGS)
            self._reg_asts = dict()
            for r in CGC_GENERAL_REGS:
                ast = s.se.BVS(r, 32, explicit_name=True)
                self._reg_asts[r] = ast
                s.registers.store(r, ast)
            s.ip = self.orig_regs["eip"]
            p = self._p.factory.path(s)
            p.step(num_inst=1)
            all_succ = p.successors + p.unconstrained_successors
            if len(all_succ) == 0:
                raise CannotExploit("no successors")
            succ = all_succ[0]
            for a in succ.actions.hardcopy:
                if a.type == "mem" and a.action == "read":
                    dependencies = a.addr.ast.variables
                    self.addr_ast = a.addr.ast
                    self.reg_deps = dependencies | {"AST"}

            self.orig_regs = self._fix_reg_vals(self.orig_regs)

            l.debug("REG DEPS: %s", self.reg_deps)
        except CLEError as e:
            l.warning("CLEError: %s", e)
            pass

        if self.addr_ast is None:
            self.reg_deps = set(CGC_GENERAL_REGS)
            l.warning("couldn't find read addr depenency")

        self.pool = None
        self.byte_analysis = dict()
        self._bases = dict()
        self.skip_bytes = set()
        self.skip_sets = set()
        self.regs_to_numbers = dict()
        self.used_bytes = set()
        self.byte_translation_funcs = list()
        self.byte_translation_calls = dict()
        self._bit_patterns = dict()
        self._raw_payload = None
        self.output_leak_idx = None
        self.cgc_type = 2

        self.make_bases()
        self.run()
        self.post_filter()
        self.post_analysis()
Esempio n. 6
0
File: identify.py Progetto: axt/angr
    def __init__(self, cfg=None, require_predecessors=True, only_find=None):
        from angrop import rop_utils

        # self.project = project
        if not isinstance(self.project.loader.main_object, CGC):
            l.critical("The identifier currently works only on CGC binaries. Results may be completely unexpected.")

        if cfg is not None:
            self._cfg = cfg
        else:
            self._cfg = self.project.analyses.CFGFast(resolve_indirect_jumps=True)
        self._runner = Runner(self.project, self._cfg)

        # only find if in this set
        self.only_find = only_find

        # reg list
        a = self.project.arch
        self._sp_reg = a.register_names[a.sp_offset]
        self._bp_reg = a.register_names[a.bp_offset]
        self._ip_reg = a.register_names[a.ip_offset]
        self._reg_list = a.default_symbolic_registers
        self._reg_list = filter(lambda r: r != self._sp_reg, self._reg_list)
        self._reg_list = filter(lambda r: r != self._ip_reg, self._reg_list)

        self.matches = dict()

        self.callsites = None
        self.inv_callsites = None
        self.func_info = dict()
        self.block_to_func = dict()

        self.map_callsites()

        if self._too_large():
            l.warning("Too large")
            return

        self.base_symbolic_state = rop_utils.make_symbolic_state(self.project, self._reg_list)
        self.base_symbolic_state.options.discard(options.SUPPORT_FLOATING_POINT)
        self.base_symbolic_state.regs.bp = self.base_symbolic_state.se.BVS("sreg_" + "ebp" + "-", self.project.arch.bits)

        for f in self._cfg.functions.values():
            if f.is_syscall:
                continue
            if self.project.is_hooked(f.addr):
                continue

            # skip if no predecessors
            try:
                if require_predecessors and len(self._cfg.functions.callgraph.predecessors(f.addr)) == 0:
                    continue
            except NetworkXError:
                if require_predecessors:
                    continue

            # find the actual vars
            try:
                func_info = self.find_stack_vars_x86(f)
                self.func_info[f] = func_info
            except (SimEngineError, SimMemoryError) as e:
                l.debug("angr translation error: %s", e.message)
            except IdentifierException as e:
                l.debug("Identifier error: %s", e.message)
            except SimError as e:
                l.debug("Simulation error: %s", e.message)