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
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)
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)
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
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
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
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()
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')
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')
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')
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')
]) 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')
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")
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')
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')