def addDEY(self, filename, data, dx=None): """ Add an ODEX file to the session and run the analysis """ digest = hashlib.sha256(data).hexdigest() log.debug("add DEY:%s" % digest) d = DalvikOdexVMFormat(data) log.debug("added DEY:%s" % digest) self.analyzed_files[filename].append(digest) self.analyzed_digest[digest] = filename self.analyzed_dex[digest] = d if self.export_ipython: d.create_python_export() if dx is None: dx = Analysis() dx.add(d) dx.create_xref() for d in dx.vms: # TODO: allow different decompiler here! d.set_decompiler(DecompilerDAD(d, dx)) d.set_vmanalysis(dx) self.analyzed_vms[digest] = dx return digest, d, dx
def run(self): unique_apis = [] for apk in self.apks_list: try: with ZipFile(apk) as zipfile: # find .dex files inside apk dexes = [dex for dex in zipfile.namelist() if dex.endswith('.dex')] dx = Analysis() # analyze every .dex for dex in dexes: with zipfile.open(dex) as dexfile: d = DalvikVMFormat(dexfile.read()) dx.add(d) # creates cross references between classes, methods, etc. for all the .dex dx.create_xref() # extracting android apis apis = self.get_api_calls(dx) not_unique = unique_apis + apis unique_apis = list(np.unique(not_unique)) print('Process %d: %.1f%%' % (self.process_id, ((self.apks_list.index(apk) + 1) / self.total_apks) * 100)) except BadZipfile as e: print('Bad zip file =========> %s' % apk) except Exception as e: print('\n%s\n%s\n' % (apk, e)) self.queue.put(unique_apis) print('----------------> Process %d is done!' % self.process_id)
def AnalyzeAPK(_file, session=None, raw=False): """ Analyze an android application and setup all stuff for a more quickly analysis! If session is None, no session is used at all. This is the default behaviour. If you like to continue your work later, it might be a good idea to use a session. A default session can be created by using :meth:`~get_default_session`. :param _file: the filename of the android application or a buffer which represents the application :type _file: string (for filename) or bytes (for raw) :param session: A session (default: None) :param raw: boolean if raw bytes are supplied instead of a filename :rtype: return the :class:`~androguard.core.bytecodes.apk.APK`, list of :class:`~androguard.core.bytecodes.dvm.DalvikVMFormat`, and :class:`~androguard.core.analysis.analysis.Analysis` objects """ log.debug("AnalyzeAPK") if session: log.debug("Using existing session {}".format(session)) if raw: data = _file filename = hashlib.md5(_file).hexdigest() else: with open(_file, "rb") as fd: data = fd.read() filename = _file digest = session.add(filename, data) return session.get_objects_apk(filename, digest) else: log.debug("Analysing without session") a = APK(_file, raw=raw) # FIXME: probably it is not necessary to keep all DalvikVMFormats, as # they are already part of Analysis. But when using sessions, it works # this way... d = [] dx = Analysis() for dex in a.get_all_dex(): df = DalvikVMFormat(dex, using_api=a.get_target_sdk_version()) dx.add(df) d.append(df) df.set_decompiler(decompiler.DecompilerDAD(d, dx)) dx.create_xref() return a, d, dx
def addDEX(self, filename, data, dx=None, postpone_xref=False): """ Add a DEX file to the Session and run analysis. :param filename: the (file)name of the DEX file :param data: binary data of the dex file :param dx: an existing Analysis Object (optional) :param postpone_xref: True if no xref shall be created, and will be called manually :return: A tuple of SHA256 Hash, DalvikVMFormat Object and Analysis object """ digest = hashlib.sha256(data).hexdigest() log.debug("add DEX:%s" % digest) log.debug("Parsing format ...") d = DalvikVMFormat(data) log.debug("added DEX:%s" % digest) self.analyzed_files[filename].append(digest) self.analyzed_digest[digest] = filename self.analyzed_dex[digest] = d if dx is None: dx = Analysis() dx.add(d) if not postpone_xref: dx.create_xref() # TODO: If multidex: this will called many times per dex, even if already set for d in dx.vms: # TODO: allow different decompiler here! d.set_decompiler(DecompilerDAD(d, dx)) d.set_vmanalysis(dx) self.analyzed_vms[digest] = dx if self.export_ipython: log.debug("Exporting in ipython") d.create_python_export() return digest, d, dx
def addDEX(self, filename, data, dx=None): """ Add a DEX file to the Session and run analysis. :param filename: the (file)name of the DEX file :param data: binary data of the dex file :param dx: an existing Analysis Object (optional) :return: A tuple of SHA256 Hash, DalvikVMFormat Object and Analysis object """ digest = hashlib.sha256(data).hexdigest() log.debug("add DEX:%s" % digest) log.debug("Parsing format ...") d = DalvikVMFormat(data) log.debug("added DEX:%s" % digest) self.analyzed_files[filename].append(digest) self.analyzed_digest[digest] = filename self.analyzed_dex[digest] = d if dx is None: dx = Analysis() dx.add(d) dx.create_xref() # TODO: If multidex: this will called many times per dex, even if already set for d in dx.vms: # TODO: allow different decompiler here! d.set_decompiler(DecompilerDAD(d, dx)) d.set_vmanalysis(dx) self.analyzed_vms[digest] = dx if self.export_ipython: log.debug("Exporting in ipython") d.create_python_export() return digest, d, dx
def analyze(path_to_apk): logging.info("Starting analysis...") app_to_analyze = AnalyzedApk() try: a, d, dx = invoke_androguard(path_to_apk) except zipfile.BadZipFile: # File is invalid -> we need a unique dummy name for the app to generate a valid json file hasher = hashlib.md5() with open(path_to_apk, "rb") as apk: buf = apk.read() hasher.update(buf) app_to_analyze.app_name = "error" app_to_analyze.package_name = hasher.hexdigest() app_to_analyze.error = True return app_to_analyze app_to_analyze = init_basic_infos(a, app_to_analyze) app_to_analyze = filter_target_sdk(a, app_to_analyze) app_to_analyze = filter_manifest_permission_requests(a, app_to_analyze) if app_to_analyze.error: logging.critical( "Error during extraction of basic infos, maybe the app is obfuscated!" ) exit(42) if not app_to_analyze.is_analyzable(): logging.error( "App is not analyzable, skipping request and usage analysis") return app_to_analyze # Prepare analysis instance analysis = Analysis() for vm in d: analysis.add(vm) logging.info("Creating XREFs...") analysis.create_xref() main_activities = list( map(lambda act: act.replace(".", "/"), a.get_main_activities())) app_to_analyze = run_request_analysis(app_to_analyze, a, analysis, main_activities) try: app_to_analyze = run_usage_analysis(app_to_analyze, analysis) except: traceback.print_exc(file=sys.stdout) logging.info( "An error occurred during usage analysis. " + "Still continuing, hoping that the request analysis is valuable..." ) app_to_analyze.error = True logging.info("Finished analysis...") return app_to_analyze
# apk_path = "./baidu.apk" apk_path = "./app-debug.apk" print("[*] Begin") a = apk.APK(apk_path) f_path = apk_path+"-JavascriptInterface"+".java" f2_path = apk_path+"-JavascriptInterface-list"+".txt" f3_path = apk_path+"-method-list"+".txt" dvm = DalvikVMFormat(a.get_dex()) print("[*] DalvikVMFormat Finish!") dx = Analysis() dx.add(dvm) dvm.set_decompiler(decompiler.DecompilerDAD(dvm, dx)) print("[*] Analysis Finish!") savedStdout = sys.stdout with open(f_path, 'w+') as file: sys.stdout = file f2 = open(f2_path, 'w+') f3 = open(f3_path, 'w+') for adi in dvm.map_list.get_item_type("TYPE_ANNOTATIONS_DIRECTORY_ITEM"): if adi.get_method_annotations() == []: continue
def main(): for path in samples(): print(path) logging.error("Processing" + path) tests_apk = [ "is_valid_APK", "get_filename", "get_app_name", "get_app_icon", "get_package", "get_androidversion_code", "get_androidversion_name", "get_files", "get_files_types", "get_files_crc32", "get_files_information", "get_raw", "get_dex", "get_all_dex", "get_main_activity", "get_activities", "get_services", "get_receivers", "get_providers", "get_permissions", "get_details_permissions", "get_requested_aosp_permissions", "get_requested_aosp_permissions_details", "get_requested_third_party_permissions", "get_declared_permissions", "get_declared_permissions_details", "get_max_sdk_version", "get_min_sdk_version", "get_target_sdk_version", "get_libraries", "get_android_manifest_axml", "get_android_manifest_xml", "get_android_resources", "get_signature_name", "get_signature_names", "get_signature", "get_signatures" ] tests_dex = [ "get_api_version", "get_classes_def_item", "get_methods_id_item", "get_fields_id_item", "get_codes_item", "get_string_data_item", "get_debug_info_item", "get_header_item", "get_class_manager", "show", # "save", # FIXME broken "get_classes_names", "get_classes", "get_all_fields", "get_fields", "get_methods", "get_len_methods", "get_strings", "get_format_type", "create_python_export", "get_BRANCH_DVM_OPCODES", "get_determineNext", "get_determineException", "print_classes_hierarchy", "list_classes_hierarchy", "get_format" ] try: # Testing APK a = APK(path) for t in tests_apk: print(t) x = getattr(a, t) try: x() except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {}".format(path, t)) # Testing DEX dx = Analysis() for dex in a.get_all_dex(): d = DalvikVMFormat(dex) dx.add(d) # Test decompilation for c in d.get_classes(): for m in c.get_methods(): mx = dx.get_method(m) ms = DvMethod(mx) try: ms.process(doAST=True) except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {} .. {}".format( path, c.get_name(), m.get_name())) ms2 = DvMethod(mx) try: ms2.process(doAST=False) except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {} .. {}".format( path, c.get_name(), m.get_name())) # DEX tests for t in tests_dex: print(t) x = getattr(d, t) try: x() except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {}".format(path, t)) # Analysis Tests try: dx.create_xref() except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {} at Analysis".format(path, t)) # MethodAnalysis tests for m in dx.methods.values(): for bb in m.get_basic_blocks(): try: list(bb.get_instructions()) except Exception as aaa: print(aaa) traceback.print_exc() print(path, aaa, file=sys.stderr) logging.exception("{} .. {} at BasicBlock {}".format( path, t, m)) except KeyboardInterrupt: raise except FileNotFoundError: pass except Exception as e: print(e) traceback.print_exc() print(path, e, file=sys.stderr) logging.exception(path)