Example #1
0
    def function_check(self, function):
        """
        Check if the specific function returns any value outside of the predefined scope.

        :param angr.knowledge.Function function: The function to check.
        :return: True if the policy is respected, False otherwise.
        :rtype: bool
        """

        if function.addr != self.function_address:
            # skip this function
            raise PolicySkipFunctionNotice()

        # the temporary knowledge base
        tmp_kb = KnowledgeBase(self.project, self.project.loader.main_bin)

        cfg = self.project.analyses.CFGAccurate(
            starts=(function.addr, ),
            keep_state=True,
            call_depth=0,
            kb=tmp_kb,
        )

        # generate the data dependence graph on the function
        dep_graph = self.project.analyses.DataDependencyAnalysis(cfg,
                                                                 kb=tmp_kb)

        # perform a return value analysis
        ret_val = self.project.analyses.ReturnValueAnalysis(
            function, dep_graph)

        result = True

        # check the return values
        for r in ret_val.return_values:  # type: ConstantReturnValue
            if r.value not in self.return_values:
                l.warning(
                    'Policy violation: return value %s not found in predefined set of return values specified by '
                    'the policy.', r.value)
                cr = CheckResult(self,
                                 False,
                                 function=function,
                                 unexpected_value=r.value)
                self._add_result(cr)
                result = False

                if self._failfast:
                    return result

        if result is True:
            cr = CheckResult(self, True, function=function)
            self._add_result(cr)

        return True
Example #2
0
    def _analyze(self):

        # Generate a CFG of the current function with the base graph
        cfg = self.project.analyses.CFGAccurate(
            kb=KnowledgeBase(self.project, self.project.loader.main_object),
            starts=(self.function.addr, ),
            keep_state=True,
            base_graph=self.function.graph,
            iropt_level=0,
        )

        self.ddg = self.project.analyses.DDG(cfg)
    def _get_new_kb_with_cfgs_and_functions(project, kb):
        new_kb = KnowledgeBase(project)

        new_kb.cfgs = kb.cfgs.copy()
        new_kb.functions = kb.functions.copy()
        new_kb.labels = kb.labels.copy()
        new_kb.resolved_indirect_jumps = kb.resolved_indirect_jumps.copy()
        new_kb.unresolved_indirect_jumps = kb.unresolved_indirect_jumps.copy()

        return new_kb
    def function_check(self, function):

        if isinstance(function, (int, long)):
            function = self.kb.functions.get(function, None)

        if function is None:
            # the function is not found
            raise FunctionNotFoundError(
                'The function specified is not found. Please make sure the function you '
                'specified is correct, and the correct knowledge base with function '
                'information is passed in.')

        # create a temporary knowledgebase so that the new CFG does not overwrite the existing global CFG
        tmp_kb = KnowledgeBase(self.project, self.kb.obj)

        # create an accurate control flow graph for this function
        cfg = self.project.analyses.CFGAccurate(kb=tmp_kb, base_graph=function)

        import ipdb
        ipdb.set_trace()
    def function_check(self, function):
        """


        :param angr.knowledge.Function function: The function to be checked against.
        :return: True if the policy is respected, False otherwise.
        :rtype: bool
        """

        if function.returning is False:
            l.warning('Function %#x does not return.', function.addr)
            return True

        # find all places where the function is called

        cfg = self._fast_cfg

        function_node = cfg.get_any_node(function.addr)

        if not function_node:
            # the function is not found
            l.warning('Function %#x is not found in the control flow graph.',
                      function.addr)
            return True

        # find all predecessors, which are callers to this function
        predecessors = cfg.get_all_predecessors(function_node)

        if not predecessors:
            # the function is not called from anywhere, or we cannot resolve the caller
            l.warning(
                'Function %#x is not called by any node throughout the control flow graph.',
                function.addr)
            return True

        # for each function that the caller is in, generate a data dependency graph
        for pred in predecessors:  # type: angr.analyses.cfg_node.CFGNode
            func_addr = pred.function_address

            if func_addr is None:
                continue

            caller_func = cfg.functions.get(
                func_addr, None)  # type: angr.knowledge.Function
            if caller_func is None:
                continue

            tmp_kb = KnowledgeBase(self.project, self.project.loader.main_bin)
            caller_func_cfg = self.project.analyses.CFGAccurate(
                call_depth=0,
                base_graph=caller_func.graph,
                keep_state=True,
            )
            dep_graph = self.project.analyses.DataDependencyAnalysis(
                caller_func_cfg,
                kb=tmp_kb,
            )

            # analyze on dep_graph
            ret_val_reg = ReturnValueAnalysis.RETURN_VALUE_REGISTERS[
                self.project.arch.name]
            ret_val_reg_offset, ret_val_reg_size = self.project.arch.registers[
                ret_val_reg]
            ret_var = SimRegisterVariable(ret_val_reg_offset,
                                          ret_val_reg_size * 8)

            # return site
            return_site_addr = pred.addr + pred.size

            ret_var_def = ProgramVariable(ret_var,
                                          CodeLocation(return_site_addr, -1))
            # TODO: add return value nodes in DataDependencyAnalysis

            consumers = dep_graph.find_consumers(ret_var_def)

            if not consumers:
                l.warning(
                    'Return value of function %#x is not checked at calling site %#x.',
                    function.addr, pred.addr)
                return False

        return True