Ejemplo n.º 1
0
def native_activity_analysis(jnsaf_client, so_file, custom_entry_func_name,
                             native_ss_file, java_ss_file):
    """
    Do the analysis for pure native activity.

    :param JNSafClient jnsaf_client: JNSaf client
    :param so_file: so file
    :param custom_entry_func_name: Custom entry function name
    :param native_ss_file: native source and sink file path
    :param java_ss_file: java source and sink file path
    :return: total instructions: total execution instructions
    """

    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(so_file,
                           load_options={
                               'auto_load_libs': False,
                               'main_opts': {
                                   'custom_base_addr': 0x0
                               }
                           })
    ssm = SourceAndSinkManager(native_ss_file, java_ss_file)
    jni_method_signature = 'Landroid/app/NativeActivity;.onCreate:(Landroid/os/Bundle;)V'
    analysis_center = AnalysisCenter(jni_method_signature, jnsaf_client, ssm)
    env_method_model = EnvMethodModel()
    android_main_symbol = project.loader.main_object.get_symbol('android_main')
    if android_main_symbol:
        entry_func_symbol = android_main_symbol
    else:
        if custom_entry_func_name:
            entry_func_symbol = project.loader.main_object.get_symbol(
                custom_entry_func_name)
        else:
            entry_func_symbol = project.loader.main_object.get_symbol(
                'ANativeActivity_onCreate')

    if entry_func_symbol:
        if android_main_symbol:
            initial_state, native_activity_argument, initial_instructions = \
                env_method_model.hook_android_main_callbacks(project, analysis_center, entry_func_symbol)
        else:
            initial_state, native_activity_argument, initial_instructions = \
                env_method_model.hook_native_activity_direct_callbacks(project, analysis_center, entry_func_symbol)

        nativedroid_logger.info(entry_func_symbol.name)
        annotation_based_analysis = project.analyses.AnnotationBasedAnalysis(
            analysis_center, entry_func_symbol.rebased_addr, list(), True,
            (initial_state, native_activity_argument))
        sources, sinks = annotation_based_analysis.run()
        taint_analysis_report = \
            annotation_based_analysis.gen_taint_analysis_report(sources, sinks)
        print taint_analysis_report
        analysis_instructions = annotation_based_analysis.count_cfg_instructions(
        )
        total_instructions = initial_instructions + analysis_instructions
        nativedroid_logger.info('[Total Instructions] %s', total_instructions)
    else:
        total_instructions = 0
    return total_instructions
Ejemplo n.º 2
0
def get_dynamic_register_methods(so_file, jni_method_signature):
    """
    Get dynamically registered methods
    :param so_file: Binary path
    :param jni_method_signature: JNI method signature
    :return: dict
    """
    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(so_file, load_options={'main_opts': {'custom_base_addr': 0x0}})
    analysis_center = AnalysisCenter(jni_method_signature, None, None)
    return dynamic_register_resolve(project, analysis_center)
Ejemplo n.º 3
0
def get_dynamic_register_methods(so_file, jni_method_signature):
    """
    Get dynamically registered methods
    :param so_file: Binary path
    :param jni_method_signature: JNI method signature
    :return: dict
    """
    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(
        so_file, load_options={'main_opts': {
            'custom_base_addr': 0x0
        }})
    analysis_center = AnalysisCenter(jni_method_signature, None, None)
    return dynamic_register_resolve(project, analysis_center)
Ejemplo n.º 4
0
def native_activity_analysis(jnsaf_client, so_file, custom_entry_func_name, native_ss_file, java_ss_file):
    """
    Do the analysis for pure native activity.

    :param JNSafClient jnsaf_client: JNSaf client
    :param so_file: so file
    :param custom_entry_func_name: Custom entry function name
    :param native_ss_file: native source and sink file path
    :param java_ss_file: java source and sink file path
    :return: total instructions: total execution instructions
    """

    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(so_file, load_options={'auto_load_libs': False, 'main_opts': {'custom_base_addr': 0x0}})
    ssm = SourceAndSinkManager(native_ss_file, java_ss_file)
    jni_method_signature = 'Landroid/app/NativeActivity;.onCreate:(Landroid/os/Bundle;)V'
    analysis_center = AnalysisCenter(jni_method_signature, jnsaf_client, ssm)
    env_method_model = EnvMethodModel()
    android_main_symbol = project.loader.main_object.get_symbol('android_main')
    if android_main_symbol:
        entry_func_symbol = android_main_symbol
    else:
        if custom_entry_func_name:
            entry_func_symbol = project.loader.main_object.get_symbol(custom_entry_func_name)
        else:
            entry_func_symbol = project.loader.main_object.get_symbol('ANativeActivity_onCreate')

    if entry_func_symbol:
        if android_main_symbol:
            initial_state, native_activity_argument, initial_instructions = \
                env_method_model.hook_android_main_callbacks(project, analysis_center, entry_func_symbol)
        else:
            initial_state, native_activity_argument, initial_instructions = \
                env_method_model.hook_native_activity_direct_callbacks(project, analysis_center, entry_func_symbol)

        nativedroid_logger.info(entry_func_symbol.name)
        annotation_based_analysis = project.analyses.AnnotationBasedAnalysis(
            analysis_center, entry_func_symbol.rebased_addr, list(), True, (initial_state, native_activity_argument))
        sources, sinks = annotation_based_analysis.run()
        taint_analysis_report = \
            annotation_based_analysis.gen_taint_analysis_report(sources, sinks)
        print taint_analysis_report
        analysis_instructions = annotation_based_analysis.count_cfg_instructions()
        total_instructions = initial_instructions + analysis_instructions
        nativedroid_logger.info('[Total Instructions] %s', total_instructions)
    else:
        total_instructions = 0
    return total_instructions
Ejemplo n.º 5
0
def gen_summary(jnsaf_client, so_file, jni_method_name_or_address,
                jni_method_signature, jni_method_arguments, native_ss_file,
                java_ss_file):
    """
    Generate summary and taint tracking report based on annotation-based analysis.

    :param JNSafClient jnsaf_client: JNSaf client
    :param so_file: Binary path
    :param jni_method_name_or_address: JNI method name or func address
    :param jni_method_signature: JNI method signature
    :param jni_method_arguments: Arguments of JNI method
    :param native_ss_file: Native source and sink file path
    :param java_ss_file: Java source and sink file path
    :return: Taint analysis report, safsu_report and total execution instructions number
    :rtype: tuple
    """
    jni_native_interface.java_sas_file = java_ss_file
    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(
        so_file, load_options={'main_opts': {
            'custom_base_addr': 0x0
        }})
    ssm = SourceAndSinkManager(native_ss_file, java_ss_file)
    analysis_center = AnalysisCenter(jni_method_signature, jnsaf_client, ssm)
    if isinstance(jni_method_name_or_address, long):
        jni_method_addr = jni_method_name_or_address
    else:
        jni_method_symb = project.loader.main_object.get_symbol(
            jni_method_name_or_address)
        if jni_method_symb is None:
            nativedroid_logger.error(
                'Failed to resolve jni method address for %s',
                jni_method_name_or_address)
            return '', '`' + jni_method_signature + '`:;', 0
        else:
            jni_method_addr = jni_method_symb.rebased_addr
    annotation_based_analysis = project.analyses.AnnotationBasedAnalysis(
        analysis_center, jni_method_addr, jni_method_arguments, False)
    sources, sinks = annotation_based_analysis.run()
    taint_analysis_report = annotation_based_analysis.gen_taint_analysis_report(
        sources, sinks)
    safsu_report = annotation_based_analysis.gen_saf_summary_report()
    nativedroid_logger.info('[Taint Analysis]\n%s', taint_analysis_report)
    nativedroid_logger.info('[SafSu Analysis]\n%s', safsu_report)
    total_instructions = annotation_based_analysis.count_cfg_instructions()
    return taint_analysis_report, safsu_report, total_instructions
Ejemplo n.º 6
0
def gen_summary(jnsaf_client, so_file, jni_method_name_or_address, jni_method_signature, jni_method_arguments,
                native_ss_file, java_ss_file):
    """
    Generate summary and taint tracking report based on annotation-based analysis.

    :param JNSafClient jnsaf_client: JNSaf client
    :param so_file: Binary path
    :param jni_method_name_or_address: JNI method name or func address
    :param jni_method_signature: JNI method signature
    :param jni_method_arguments: Arguments of JNI method
    :param native_ss_file: Native source and sink file path
    :param java_ss_file: Java source and sink file path
    :return: Taint analysis report, safsu_report and total execution instructions number
    :rtype: tuple
    """
    jni_native_interface.java_sas_file = java_ss_file
    angr.register_analysis(AnnotationBasedAnalysis, 'AnnotationBasedAnalysis')
    project = angr.Project(so_file, load_options={'main_opts': {'custom_base_addr': 0x0}})
    ssm = SourceAndSinkManager(native_ss_file, java_ss_file)
    analysis_center = AnalysisCenter(jni_method_signature, jnsaf_client, ssm)
    if isinstance(jni_method_name_or_address, long):
        jni_method_addr = jni_method_name_or_address
    else:
        jni_method_symb = project.loader.main_object.get_symbol(jni_method_name_or_address)
        if jni_method_symb is None:
            nativedroid_logger.error('Failed to resolve jni method address for %s', jni_method_name_or_address)
            return '', '`' + jni_method_signature + '`:;', 0
        else:
            jni_method_addr = jni_method_symb.rebased_addr
    annotation_based_analysis = project.analyses.AnnotationBasedAnalysis(
        analysis_center, jni_method_addr, jni_method_arguments, False)
    sources, sinks = annotation_based_analysis.run()
    taint_analysis_report = annotation_based_analysis.gen_taint_analysis_report(sources, sinks)
    safsu_report = annotation_based_analysis.gen_saf_summary_report()
    nativedroid_logger.info('[Taint Analysis]\n%s', taint_analysis_report)
    nativedroid_logger.info('[SafSu Analysis]\n%s', safsu_report)
    total_instructions = annotation_based_analysis.count_cfg_instructions()
    return taint_analysis_report, safsu_report, total_instructions
Ejemplo n.º 7
0
def main():
    angr.register_analysis(UseAfterFree, 'UseAfterFree')

    # binary_name = "/media/sf_Documents/AEG/AEG/challenges/uaf/menu_uaf"
    # binary_name = "/media/sf_Documents/AEG/AEG/challenges/uaf/uaf"
    binary_name = "/media/sf_Documents/AEG/AEG/challenges/uaf/simple_uaf"
    # binary_name = "/media/sf_Documents/AEG/Zeratool/challenges/uaf/simple_uaf"
    #binary_name = "/media/sf_Documents/AEG/AEG/tests/how2heap_fastbin_dup/fastbin_dup.bin"
    allocator_path = "/media/sf_Documents/AEG/heaphopper/tests/libc-2.23/libc.so.6"
    libc_path = "/media/sf_Documents/AEG/heaphopper/tests/libc-2.23/libc.so.6"
    proj = angr.Project(
        binary_name,
        load_options={
            'ld_path':
            [os.path.dirname(allocator_path),
             os.path.dirname(libc_path)],
            'auto_load_libs':
            True
        })

    protectionDetector.getProperties(binary_name)
    detect = proj.analyses.UseAfterFree()
    detect.uaf_analysis()
Ejemplo n.º 8
0
                else:
                    raise NotImplementedError('Not implemented yet.')

        new_stmts = self.block.statements[::]

        new_stmts[-1] = Stmt.Call(last_stmt, last_stmt.target,
                                  calling_convention=func.calling_convention,
                                  prototype=func.prototype,
                                  args=args,
                                  **last_stmt.tags
                                  )

        new_block = self.block.copy()
        new_block.statements = new_stmts

        self.result_block = new_block

    def _get_call_target(self, stmt):
        """

        :param Stmt.Call stmt:
        :return:
        """

        if type(stmt.target) is Expr.Const:
            return stmt.target.value

        return None

register_analysis(CallSiteMaker, 'AILCallSiteMaker')
Ejemplo n.º 9
0
                        path.addr)
            if succ_base is not None:
                for succ_addr in ideal_successors:
                    forced_succ = succ_base.copy()
                    forced_succ.state.regs.ip = succ_addr
                    real_successors.append(forced_succ)

        return real_successors

    def complete(self, pg):
        return False


class AbortAtOtherFunctions(angr.exploration_techniques.ExplorationTechnique):
    """
    Another otiegnqwvk for clerical work
    """
    def __init__(self, cfg, func):
        super(AbortAtOtherFunctions, self).__init__()
        self.cfg = cfg
        self.func = func

    def filter(self, path):
        if path.addr != self.func and path.addr in self.cfg.functions:
            l.warning("Function %#x jumps into another function (%#x)",
                      self.func, path.addr)
            return 'finished'


angr.register_analysis(OffsetAnalysis, 'OffsetAnalysis')
Ejemplo n.º 10
0
                        for loc in common.str_find_all(read_bytes,
                                                       ret_instruction):
                            addrs.append(loc + segment.min_addr)
        except KeyError:
            l.warning("Key error with segment analysis")
            # try reading from state
            state = self.project.factory.entry_state()
            for segment in self.project.loader.main_object.segments:
                if segment.is_executable:
                    num_bytes = segment.max_addr - segment.min_addr

                    read_bytes = state.se.eval(state.memory.load(
                        segment.min_addr, num_bytes),
                                               cast_to=str)
                    for ret_instruction in ret_instructions:
                        for loc in common.str_find_all(read_bytes,
                                                       ret_instruction):
                            addrs.append(loc + segment.min_addr)

        return sorted(addrs)

    @staticmethod
    def _is_jumpkind_valid(jk):

        if jk in {'Ijk_Boring', 'Ijk_Call', 'Ijk_Ret'}:
            return True
        return False


register_analysis(ROP, 'ROP')
Ejemplo n.º 11
0
        defs = []
        for d in all_defs:  # type: ProgramVariable
            if not self._data_dep.find_consumers(
                    d) and not self._data_dep.find_killers(d):
                defs.append(d)

        if not defs:
            l.warning('Cannot find any definition for return value.')
            return

        return_values = []

        # trace each definition backwards
        for d in defs:
            sources = self._data_dep.find_sources(d)

            if not sources:
                # umm what's going on
                continue

            for s in sources:
                if isinstance(s.variable, SimConstantVariable):
                    return_values.append(ConstantReturnValue(s.variable.value))
                else:
                    return_values.append(UnknownReturnValue())

        self.return_values = return_values


register_analysis(ReturnValueAnalysis, 'ReturnValueAnalysis')
Ejemplo n.º 12
0
        ])

        for idx, stmt in enumerate(block.statements):
            if type(stmt) is Assignment:
                if type(stmt.dst) is Tmp:
                    if stmt.dst.tmp_idx not in used_tmp_indices:
                        continue

                # is it a dead virgin?
                if idx in dead_virgins_stmt_idx:
                    continue

                # is it an assignment to an artificial register?
                if type(
                        stmt.dst
                ) is Register and self.project.arch.is_artificial_register(
                        stmt.dst.reg_offset, stmt.dst.size):
                    continue

                if stmt.src == stmt.dst:
                    continue

            new_statements.append(stmt)

        new_block = block.copy()
        new_block.statements = new_statements
        return new_block


register_analysis(BlockSimplifier, 'AILBlockSimplifier')
Ejemplo n.º 13
0
        if isinstance(node, Block):
            block = node
            block_key = node.addr
            engine = self._engine_ail
        else:
            block = self.project.factory.block(node.addr,
                                               node.size,
                                               opt_level=0)
            block_key = node.addr
            engine = self._engine_vex

        state = input_state.copy()

        engine.process(state, block=block)

        self._node_iterations[block_key] += 1

        self._states[block_key] = state

        return True, state

    def _intra_analysis(self):
        pass

    def _post_analysis(self):
        pass


register_analysis(Propagator, "AILPropagator")
Ejemplo n.º 14
0
            block=block,
            track_tmps=True,
            observation_points=[(block.statements[-1].ins_addr, OP_AFTER)])

        used_tmp_indices = set(rd.one_result.tmp_uses.keys())
        dead_virgins = rd.one_result._dead_virgin_definitions
        dead_virgins_stmt_idx = set([
            d.codeloc.stmt_idx for d in dead_virgins
            if not isinstance(d.codeloc, ExternalCodeLocation)
        ])

        for idx, stmt in enumerate(block.statements):
            if type(stmt) is Assignment:
                if type(stmt.dst) is Tmp:
                    if stmt.dst.tmp_idx not in used_tmp_indices:
                        continue

                # is it a dead virgin?
                if idx in dead_virgins_stmt_idx:
                    continue

            new_statements.append(stmt)

        new_block = block.copy()
        new_block.statements = new_statements

        return new_block


register_analysis(Simplifier, 'AILSimplifier')
Ejemplo n.º 15
0
    def __init__(self, policies=None):
        """
        Constructor.

        :param iterable policies: A collection of policies to be registered with the policy manager.
        """

        self.policy_manager = PolicyManager(self.project, self.kb)

        if policies is not None:
            for policy in policies:
                self.policy_manager.register_policy(policy, policy.name)

    def check(self, functions=None):
        """
        Enforce the policy.

        :param iterable functions: A collection of functions to enforce all policies.
        :return: True if all policies are enforced, False otherwise
        :rtype: bool
        """

        if functions is None:
            functions = self.policy_manager.fast_cfg.functions.values()

        for function in functions:
            self.policy_manager.check_function(function)


register_analysis(StaticPolice, 'StaticPolice')