class App(object): """ this class describes an app """ def __init__(self, app_path, output_dir=None): """ create a App instance :param app_path: local file path of app :return: """ assert app_path is not None self.logger = logging.getLogger(self.__class__.__name__) self.app_path = app_path self.output_dir = output_dir if output_dir is not None: if not os.path.isdir(output_dir): os.makedirs(output_dir) from androguard.core.bytecodes.apk import APK self.apk = APK(self.app_path) self.package_name = self.apk.get_package() self.main_activity = self.apk.get_main_activity() self.permissions = self.apk.get_permissions() self.activities = self.apk.get_activities() self.possible_broadcasts = self.get_possible_broadcasts() self.dumpsys_main_activity = None self.hashes = self.get_hashes() def get_package_name(self): """ get package name of current app :return: """ return self.package_name def get_main_activity(self): """ get package name of current app :return: """ if self.main_activity is not None: return self.main_activity else: self.logger.warning("Cannot get main activity from manifest. Using dumpsys result instead.") return self.dumpsys_main_activity def get_start_intent(self): """ get an intent to start the app :return: Intent """ package_name = self.get_package_name() if self.get_main_activity(): package_name += "/%s" % self.get_main_activity() return Intent(suffix=package_name) def get_start_with_profiling_intent(self, trace_file, sampling=None): """ get an intent to start the app with profiling :return: Intent """ package_name = self.get_package_name() if self.get_main_activity(): package_name += "/%s" % self.get_main_activity() if sampling is not None: return Intent(prefix="start --start-profiler %s --sampling %d" % (trace_file, sampling), suffix=package_name) else: return Intent(prefix="start --start-profiler %s" % trace_file, suffix=package_name) def get_stop_intent(self): """ get an intent to stop the app :return: Intent """ package_name = self.get_package_name() return Intent(prefix="force-stop", suffix=package_name) def get_possible_broadcasts(self): possible_broadcasts = set() for receiver in self.apk.get_receivers(): intent_filters = self.apk.get_intent_filters('receiver', receiver) actions = intent_filters['action'] if 'action' in intent_filters else [] categories = intent_filters['category'] if 'category' in intent_filters else [] categories.append(None) for action in actions: for category in categories: intent = Intent(prefix='broadcast', action=action, category=category) possible_broadcasts.add(intent) return possible_broadcasts def get_hashes(self, block_size=2 ** 8): """ Calculate MD5,SHA-1, SHA-256 hashes of APK input file @param block_size: """ md5 = hashlib.md5() sha1 = hashlib.sha1() sha256 = hashlib.sha256() f = open(self.app_path, 'rb') while True: data = f.read(block_size) if not data: break md5.update(data) sha1.update(data) sha256.update(data) return [md5.hexdigest(), sha1.hexdigest(), sha256.hexdigest()]
def check(indicators, path, verbose=False): """ Check an APK with given indicators Returns True/False, string (explanation of the discovery) """ m = hashlib.sha256() with open(path, 'rb') as f: data = f.read() m.update(data) res = search(m.hexdigest(), indicators['sha256'], 'value') if verbose: print("SHA256: {}".format(m.hexdigest())) if res: if verbose: print("Known Stalkerware hash: {}".format(res)) return True, "Known Stalkerware hash: {}".format(res) else: if verbose: print("App hash not in the indicator database") apk = APK(path) res = search(apk.get_package(), indicators['appids'], 'package') if verbose: print("Package id: {}".format(apk.get_package())) if res: if verbose: print("Known stalkerware package id: {}".format(res)) return True, "Known stalkerware package id: {}".format(res) else: if verbose: print("Package id not in the indicators") if len(apk.get_certificates()) > 0: cert = apk.get_certificates()[0] sha1 = cert.sha1_fingerprint.replace(' ', '') if verbose: print("Certificate: {}".format(sha1)) res = search(sha1, indicators['certificates'], 'certificate') if res: if verbose: print("Known Stalkerware certificate: {}".format(res)) return True, "Known Stalkerware certificate: {}".format(res) else: if verbose: print("Certificate not in the indicators") else: if verbose: print("No certificate in this APK") if 'yara' in indicators: for dex in apk.get_all_dex(): res = indicators['yara'].match(data=dex) if len(res) > 0: if verbose: print("Matches yara rules {}".format(res[0])) return True, "Yara rule {}".format(res[0]) else: if verbose: print("Does not match any yara rules") return False, ""
def testAPKManifest(self): from androguard.core.bytecodes.apk import APK a = APK("examples/android/TestsAndroguard/bin/TestActivity.apk", testzip=True) self.assertEqual(a.get_app_name(), "TestsAndroguardApplication") self.assertEqual(a.get_app_icon(), "res/drawable-hdpi/icon.png") self.assertEqual(a.get_app_icon(max_dpi=120), "res/drawable-ldpi/icon.png") self.assertEqual(a.get_app_icon(max_dpi=160), "res/drawable-mdpi/icon.png") self.assertEqual(a.get_app_icon(max_dpi=240), "res/drawable-hdpi/icon.png") self.assertIsNone(a.get_app_icon(max_dpi=1)) self.assertEqual(a.get_main_activity(), "tests.androguard.TestActivity") self.assertEqual(a.get_package(), "tests.androguard") self.assertEqual(a.get_androidversion_code(), '1') self.assertEqual(a.get_androidversion_name(), "1.0") self.assertEqual(a.get_min_sdk_version(), "9") self.assertEqual(a.get_target_sdk_version(), "16") self.assertIsNone(a.get_max_sdk_version()) self.assertEqual(a.get_permissions(), []) self.assertEqual(a.get_declared_permissions(), []) self.assertTrue(a.is_valid_APK())
class App(object): def __init__(self, app_path, root_path, app_name): print("Root path:"+root_path) assert app_path is not None self.logger = logging.getLogger(self.__class__.__name__) self.app_path = app_path from androguard.core.bytecodes.apk import APK self.apk = APK(self.app_path) self.package_name = self.apk.get_package() self.main_activity = self.apk.get_main_activity() self.permissions = self.apk.get_permissions() self.activities = self.apk.get_activities() if app_name is not None: self.app_name = app_name else: self.app_name = self.apk.get_app_name() print("Main activity:"+self.main_activity) print("Package name:"+self.package_name) self.output_path=root_path+self.package_name def get_package_name(self): """ get package name of current app :return: """ return self.package_name
def get_apk_info(f, root=None): """ 获取apk信息 :param root: :param f: :return: """ if root: apk_path = os.path.join(root, f) else: apk_path = os.path.join(download_dir, f) apk_info = [] try: apk = APK(apk_path) if apk.is_valid_APK(): apk_info.append(f) apk_info.append(get_file_md5(apk_path)) apk_info.append(apk.get_app_name()) apk_info.append(apk.get_package()) apk_info.append(get_cert_md5(apk)) apk_info.append(apk.get_androidversion_name()) except Exception as e: print(f + ' ->>', e) return apk_info
def get_apk_info(self): apk = APK(self.apk_file) app_icon_file = apk.get_app_icon() app_icon_data = apk.get_file(app_icon_file) size = (256, 256) buffered = BytesIO() im = Image.open(BytesIO(app_icon_data)) im = im.resize(size, Image.ANTIALIAS) im.save(buffered, "PNG") app_icon_b64 = "data:image/png;base64," + base64.b64encode( buffered.getvalue()).decode('utf-8') self.package_name = apk.get_package() self.app_name = apk.get_app_name() self.report_saver.package_name = self.package_name self.report_saver.app_name = self.app_name self.report_saver.version = apk.get_androidversion_code() self.report_saver.app_icon = app_icon_b64 permission_parser = PermissionParser(mode='groups') permission_values = permission_parser.transform( apk.get_permissions()).flatten().tolist() permission_labels = permission_parser.labels() self.report_saver.permissions_actual = { permission_labels[i]: bool(v) for i, v in enumerate(permission_values) }
def testFrameworkResAPK(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/lineageos_nexus5_framework-res.apk") self.assertEqual(a.get_app_name(), 'Android System') self.assertEqual(a.get_package(), 'android')
def perform_analysis(self): if self.apk_file and os.path.exists(self.apk_file): try: apk = APK(self.apk_file) except Exception, ex: print ex return self.permissions = apk.get_permissions() # duplicate permissions check if (len(self.permissions) != len(set(self.permissions))): self.permission_duplicate = True # remove duplicate permissions self.permissions = list(set(self.permissions)) # uses-features features_name = apk.get_elements('uses-feature', 'android:name') if len(features_name) > 0: package_name = apk.get_package() features_used = apk.get_elements('uses-feature', 'android:required') for i in xrange(len(features_name)): if features_name[i] != '': if(features_used[i] != '%s.false' % package_name): self.features.append(features_name[i]) self.features = list(set(self.features))
def testAPKPermissions(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) self.assertEqual(a.get_package(), "a2dp.Vol") self.assertListEqual( sorted(a.get_permissions()), sorted([ "android.permission.RECEIVE_BOOT_COMPLETED", "android.permission.CHANGE_WIFI_STATE", "android.permission.ACCESS_WIFI_STATE", "android.permission.KILL_BACKGROUND_PROCESSES", "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN", "com.android.launcher.permission.READ_SETTINGS", "android.permission.RECEIVE_SMS", "android.permission.MODIFY_AUDIO_SETTINGS", "android.permission.READ_CONTACTS", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_PHONE_STATE", "android.permission.BROADCAST_STICKY", "android.permission.GET_ACCOUNTS" ]))
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError( "Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() # manifest["permissions"]=a.get_details_permissions_new() manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() # manifest["receivers_actions"]=a.get__extended_receivers() manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest # apkinfo["certificate"] = a.get_certificate() static_calls = {} if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = self.get_methods(vmx) static_calls[ "is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code( vmx) static_calls[ "is_reflection_code"] = analysis.is_reflection_code( vmx) # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx) # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx) # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx) # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx) # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx) else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"]: return from androguard.core.bytecodes.apk import APK from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import uVMAnalysis from androguard.core.analysis import analysis f = File(self.task["target"]) if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() # manifest["permissions"]=a.get_details_permissions_new() manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() # manifest["receivers_actions"]=a.get__extended_receivers() manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest # apkinfo["certificate"] = a.get_certificate() static_calls = {} if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = self.get_methods(vmx) static_calls["is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx) static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx) # static_calls["dynamic_method_calls"]= analysis.get_show_DynCode(vmx) # static_calls["reflection_method_calls"]= analysis.get_show_ReflectionCode(vmx) # static_calls["permissions_method_calls"]= analysis.get_show_Permissions(vmx) # static_calls["crypto_method_calls"]= analysis.get_show_CryptoCode(vmx) # static_calls["native_method_calls"]= analysis.get_show_NativeMethods(vmx) else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, zipfile.BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def run(self): """Run Google play unofficial python api the get the google play information @return: list of google play features """ self.key = "googleplay" googleplay = {} if not HAVE_GOOGLEPLAY: log.error("Unable to import the GooglePlay library, has it been " "installed properly?") return if "file" not in self.task["category"]: return f = File(self.task["target"]) if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) android_id = self.options.get("android_id") google_login = self.options.get("google_login") google_password = self.options.get("google_password") # auth_token = self.options.get("auth_token", None) if not android_id and not google_login and not google_password: raise CuckooProcessingError("Google Play Credentials not configured, skip") try: a = APK(self.file_path) if a.is_valid_APK(): package = a.get_package() # Connect api = GooglePlayAPI(android_id) api.login(google_login, google_password, None) # Get the version code and the offer type from the app details app_data = api.details(package) app_detail = app_data.docV2.details.appDetails if not app_detail.installationSize: return googleplay googleplay["title"] = app_detail.title googleplay["app_category"] = app_detail.appCategory._values googleplay["version_code"] = app_detail.versionCode googleplay["app_type"] = app_detail.appType googleplay["content_rating"] = app_detail.contentRating googleplay["developer_email"] = app_detail.developerEmail googleplay["developer_name"] = app_detail.developerName googleplay["developer_website"] = app_detail.developerWebsite googleplay["installation_size"] = app_detail.installationSize googleplay["num_downloads"] = app_detail.numDownloads googleplay["upload_date"] = app_detail.uploadDate googleplay["permissions"] = app_detail.permission._values except (IOError, OSError, zipfile.BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return googleplay
def androsign_main(args_apk, args_hash, args_all, show): from androguard.core.bytecodes.apk import APK from androguard.util import get_certificate_name_string import hashlib import traceback from colorama import Fore, Style from asn1crypto import x509 # Keep the list of hash functions in sync with cli/entry_points.py:sign hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args_hash.lower() not in hashfunctions: print("Hash function {} not supported!" .format(args_hash.lower()), file=sys.stderr) print("Use one of {}" .format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args_apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) certs = set(a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if show: x509_cert = x509.Certificate.load(cert) print("Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print("Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print("Valid not before:", x509_cert['tbs_certificate']['validity']['not_before'].native) print("Valid not after:", x509_cert['tbs_certificate']['validity']['not_after'].native) if not args_all: print("{} {}".format(args_hash.lower(), hashfunctions[args_hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args_apk) > 1: print()
def install_app_and_install_frida(app_path): app = APK(app_path) package_name = app.get_package() logger.info("Start ADB") adb = ADB() logger.info("Install APP") adb.install_app(app_path) logger.info("Frida Initialize") push_and_start_frida_server(adb) return package_name
def parse_apk(apk_path): apk = APK(apk_path) package = apk.get_package() version_code = apk.get_androidversion_code() version_name = apk.get_androidversion_name() tmp_icon = save_icon(apk, package) return {"version_code": version_code, "version_name": version_name, "tmp_icon": tmp_icon, "package": package}
def main(): parser = get_parser() args = parser.parse_args() hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args.hash.lower() not in hashfunctions: print("Hash function {} not supported!".format(args.hash.lower()), file=sys.stderr) print("Use one of {}".format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args.apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) certs = set(a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if args.show: x509_cert = x509.Certificate.load(cert) print("Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print("Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print("Valid not before:", x509_cert['tbs_certificate']['validity']['not_before'].native) print("Valid not after:", x509_cert['tbs_certificate']['validity']['not_after'].native) if not args.all: print("{} {}".format(args.hash.lower(), hashfunctions[args.hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args.apk) > 1: print()
def __edit_text_analyse__(self, a: apk.APK, d: DalvikVMFormat, dx: Analysis): # load keywords with open( os.path.join(os.path.dirname(__file__), "assets" + os.path.sep + 'pii_keywords.txt'), 'r') as file: keywords: [str] = file.read().splitlines(False) # parse flowdroid results folder = os.path.join(os.path.dirname(__file__), "results" + os.path.sep + "flowdroid") file_name = a.get_filename().split(os.path.sep)[-1][:-4] fd_path = os.path.join(folder, file_name + ".xml") self.leak_id_names: [str] = [] if not os.path.exists(fd_path): print("Flowdroid result doesn't exist") return resource_list = self.__analyse_flowdroid_result__(fd_path) resource_ids = [] for s_id, s_method, s_statement, sink_method, sink_statement in resource_list: resource_ids.append(s_id) # find Resource class package_name = a.get_package() package_name = package_name.replace(".", "/") cls: ClassDefItem = d.get_class("L" + package_name + "/R$id;") # find resource id if cls is None: print("This application doesn't have an R class") return fields: [EncodedField] = cls.get_fields() # match ids with keywords for field in fields: field: EncodedField = field value: EncodedValue = field.get_init_value() # resource id -> resource name the_value = str(value.get_value()) field_name = field.get_name() if the_value in resource_ids and field_name in keywords: self.leak_id_names.append(field_name)
class StaticAnalysis: def __init__(self): print "Static Analysis" self.apk = None def load_apk(self, apk): if apk is not None and os.path.isfile(apk): self.apk = APK(apk) else: raise IOError("{0} could not be loaded".format(apk)) def get_apk_package(self): try: return self.apk.get_package() except Exception, e: raise e
def get_apk_entry(self): """Get the entry point for this APK. The entry point is denoted by a package and main activity name.""" logging.getLogger("androguard.axml").setLevel(logging.WARNING) logging.getLogger("androguard.core.api_specific_resources").setLevel( logging.WARNING) filetype = self.get_type() if "Zip archive data" not in filetype and "Java archive data" not in filetype: return "", "" from androguard.core.bytecodes.apk import APK try: a = APK(self.file_path) if not a.is_valid_APK(): return "", "" package = a.get_package() if not package: log.warning("Unable to find the main package, this analysis " "will probably fail.") return "", "" main_activity = a.get_main_activity() if main_activity: log.debug("Picked package %s and main activity %s.", package, main_activity) return package, main_activity activities = a.get_activities() for activity in activities: if "main" in activity or "start" in activity: log.debug( "Choosing package %s and main activity due to " "its name %s.", package, activity) return package, activity if activities and activities[0]: log.debug("Picked package %s and the first activity %s.", package, activities[0]) return package, activities[0] except Exception as e: log.warning("Error extracting package and main activity: %s.", e) return "", ""
def retrieve_content_from_apk(self): a = APK(self.filename) package_name = a.get_package() resources = a.get_android_resources() # .get_strings_resources() self.client_id = resources.get_string(package_name, "PSA_API_CLIENT_ID_PROD")[1] self.client_secret = resources.get_string( package_name, "PSA_API_CLIENT_SECRET_PROD")[1] self.host_brandid_prod = resources.get_string(package_name, "HOST_BRANDID_PROD")[1] self.culture = self.__get_cultures_code( a.get_file("res/raw/cultures.json"), self.country_code) ## Get Customer id self.site_code = BRAND[package_name][ "brand_code"] + "_" + self.country_code + "_ESP" pfx_cert = a.get_file("assets/MWPMYMA1.pfx") save_key_to_pem(pfx_cert, b"y5Y2my5B")
def extract_apk_permisson(name,category): path = '/media/新加卷/begin_android_english/'+category+'/'+name+'.apk' try: apk=APK(path) if apk.is_valid_APK(): package=apk.get_package() permissions=apk.get_permissions() # clean repeat permission simple_permissions=set() for p in permissions: p=p.split('.')[-1] if PERMISSIONS.has_key(p): simple_permissions.add(p) insert_sql='insert into apk_permission(package,category' attrs=',' for permission in simple_permissions: attrs=attrs+permission+',' attrs=attrs.rstrip(',') values="values ('%s','%s',"%(package,category) for i in range(len(simple_permissions)): values=values+'1,' values=values.rstrip(',') values=values+')' insert_sql=insert_sql+attrs+') '+values #print insert_sql db.insert(insert_sql) print ('analysis %s'%(path)) else: print('%s is not valid apk'%(path)) except: etype, evalue, tracebackObj = sys.exc_info()[:3] print ('apk:%s errortype:%s errorvalue:%s'%(path,etype,evalue)) finally: sql = "update apk set state = 0 where package='%s'"%name print sql db1.update(sql) print 1
def main(): parser = get_parser() args = parser.parse_args() hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args.hash.lower() not in hashfunctions: print("Hash function {} not supported!".format(args.hash.lower()), file=sys.stderr) print("Use one of {}".format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args.apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) certs = set(a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if not args.all: print("{} {}".format(args.hash.lower(), hashfunctions[args.hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args.apk) > 1: print()
def install_app_and_install_frida(app_path): """ Install app and Frida script Parameters ---------- app_path Returns ------- """ app = APK(app_path) package_name = app.get_package() logger.info("Start ADB") adb = ADB() logger.info("Install APP") adb.install_app(app_path) logger.info("Frida Initialize") push_and_start_frida_server(adb) return package_name
def get_apk_entry(self): """Get the entry point for this APK. The entry point is denoted by a package and main activity name.""" filetype = self.get_type() if "Zip archive data" not in filetype and "Java archive data" not in filetype: return "", "" from androguard.core.bytecodes.apk import APK try: a = APK(self.file_path) if not a.is_valid_APK(): return "", "" package = a.get_package() if not package: log.warning("Unable to find the main package, this analysis " "will probably fail.") return "", "" main_activity = a.get_main_activity() if main_activity: log.debug("Picked package %s and main activity %s.", package, main_activity) return package, main_activity activities = a.get_activities() for activity in activities: if "main" in activity or "start" in activity: log.debug("Choosing package %s and main activity due to " "its name %s.", package, activity) return package, activity if activities and activities[0]: log.debug("Picked package %s and the first activity %s.", package, activities[0]) return package, activities[0] except Exception as e: log.warning("Error extracting package and main activity: %s.", e) return "", ""
def get_apk_info(self): apk = APK(self.apk_file) app_icon_file = apk.get_app_icon() app_icon_data = apk.get_file(app_icon_file) size = (256, 256) buffered = BytesIO() im = Image.open(BytesIO(app_icon_data)) im = im.resize(size, Image.ANTIALIAS) im.save(buffered, "PNG") app_icon_b64 = "data:image/png;base64," + base64.b64encode( buffered.getvalue()).decode('utf-8') self.package_name = apk.get_package() self.app_name = apk.get_app_name() self.report_saver.package_name = self.package_name self.report_saver.app_name = self.app_name self.report_saver.version = apk.get_androidversion_code() self.report_saver.app_icon = app_icon_b64
def testAPKPermissions(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) self.assertEqual(a.get_package(), "a2dp.Vol") self.assertListEqual(sorted(a.get_permissions()), sorted(["android.permission.RECEIVE_BOOT_COMPLETED", "android.permission.CHANGE_WIFI_STATE", "android.permission.ACCESS_WIFI_STATE", "android.permission.KILL_BACKGROUND_PROCESSES", "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN", "com.android.launcher.permission.READ_SETTINGS", "android.permission.RECEIVE_SMS", "android.permission.MODIFY_AUDIO_SETTINGS", "android.permission.READ_CONTACTS", "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_PHONE_STATE", "android.permission.BROADCAST_STICKY", "android.permission.GET_ACCOUNTS"]))
def install_app_and_install_frida(app_path, is_google_emulator: bool = False): """ Install app and Frida script Parameters ---------- app_path Returns ------- """ app = APK(app_path) package_name = app.get_package() logger.info("[*] Start ADB") adb = ADB() logger.info(f"[*] Install App {package_name}") adb.install_app(app_path) logger.info("[*] Frida Initialization") if not is_google_emulator: push_and_start_frida_server(adb) else: push_and_start_frida_server_google_emulator(adb) return package_name
class Run(Lobotomy): def __init__(self, ROOT_DIR): Lobotomy.__init__(self) self.ROOT_DIR = ROOT_DIR self.t = Terminal() self.logger = Logger() self.util = Util() self.apk = None self.package = None self.vm = None self.vmx = None self.gmx = None self.components = None self.dex = None self.strings = None self.permissions = None self.permissions_details = None self.files = None self.attack_surface = None def _cmd_completer(self, name, text, line, begidx, endidx): fn = getattr(self, 'do_'+name) if not hasattr(fn.im_func, "_expected_args"): return [] a = [arg for arg in fn.im_func._expected_args if arg.startswith(text)] return a def find_dex(self): """ Return True is classes.dex is found within the target APK. Args: None Returns: None """ if self.files: for f in self.files: if "classes" in f: return True break def process_vm(self, apk=False, dex=False): """ Process the application's classes.dex Args: param1 = boolean param2 = boolean Results: None """ try: if apk: # Make sure the APK contains a classes.dex file if self.find_dex(): self.dex = self.apk.get_dex() if self.dex: self.logger.log("info", "Loading classes.dex ...") from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import VMAnalysis from androguard.core.analysis.ganalysis import GVMAnalysis # Create a DalvikVMFormat instance ... # In this case self.dex will be a file type self.vm = DalvikVMFormat(self.dex) if self.vm: print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n")) self.logger.log("info", "Analyzing classes.dex ...") # Analyze the DalvikVMFormat instance and return # analysis instances of VMAnalysis and GVMAnalysis self.vmx = VMAnalysis(self.vm) self.gmx = GVMAnalysis(self.vmx, None) if self.vmx and self.gmx: print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n")) # Set the analysis properties on the # DalvikVMFormat instance self.vm.set_vmanalysis(self.vmx) self.vm.set_gvmanalysis(self.gmx) # Generate xref(s) and dref(s) self.vm.create_xref() self.vm.create_dref() return else: CommandError("process_vm : Cannot analyze VM instance (!)") return else: CommandError("process_vm : Cannot load VM instance (!)") return else: CommandError("process_vm : classes.dex not found (!)") return if dex: if self.dex: from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import VMAnalysis from androguard.core.analysis.ganalysis import GVMAnalysis # Analyze the DalvikVMFormat instance and return # analysis instances of VMAnalysis and GVMAnalysis self.vm = DalvikVMFormat(self.util.read(self.dex)) if self.vm: print(self.t.yellow("\n\t--> Loaded {} (!)\n" .format(self.dex .split("/")[-1]))) self.logger.log("info", "Analyzing {} ..." .format(self.dex .split("/")[-1])) # Set the analysis properties on the # DalvikVMFormat instance self.vmx = VMAnalysis(self.vm) self.gmx = GVMAnalysis(self.vmx, None) if self.vmx and self.gmx: print(self.t.yellow("\n\t--> Analyzed {} (!)\n" .format(self.dex .split("/")[-1]))) # Set the analysis properties on the # DalvikVMFormat instance self.vm.set_vmanalysis(self.vmx) self.vm.set_gvmanalysis(self.gmx) # Generate xref(s) and dref(s) self.vm.create_xref() self.vm.create_dref() return else: CommandError("process_vm :" + "Cannot analyze VM instance (!)") return else: CommandError("process_vm :" + "Cannot load VM instance (!)") return else: CommandError("process_vm : classes.dex not found (!)") return except Exception as e: CommandError("process_vm : {}".format(e)) def complete_operate(self, *args): return self._cmd_completer("operate", *args) @cmd_arguments(["apk", "dex"]) def do_operate(self, *args): """ := operate apk path_to_apk := operate dex path_to_classes.dex """ # Locals arg0 = args[0].split(" ")[0] arg1 = args[0].split(" ")[1] try: if arg0 == "apk": if arg1: self.logger.log("info", "Loading : {} ..." .format(arg1.split("/")[-1])) from androguard.core.bytecodes.apk import APK self.apk = APK(arg1) if self.apk: print(self.t.yellow("\n\t--> Loaded : {} (!)\n" .format(arg1.split("/")[-1]))) self.package = self.apk.get_package() from core.brains.apk.components import Components # Load activies, services, broadcast receivers, and # content providers self.components = Components(self.apk) self.components.enumerate_components() self.permissions = self.apk.get_permissions() self.files = self.apk.get_files() self.files_type = self.apk.get_files_types() # Process DVM self.process_vm(apk=True) else: CommandError("APK not loaded (!)") elif arg0 == "dex": if arg1: self.logger.log("info", "Loading : {} ..." .format(arg1.split("/")[-1])) self.dex = arg1 self.process_vm(dex=True) except ImportError as e: CommandError("operate : {}".format(e)) def complete_surgical(self, *args): return self._cmd_completer("surgical", *args) def do_surgical(self, *args): """ := surgical """ try: if self.vm and self.vmx: from .surgical import Run run = Run(self.vm, self.vmx) run.prompt = self.t.yellow("(surgical) ") run.ruler = self.t.yellow("-") run.cmdloop() else: CommandError("classes.dex not loaded (!)") except Exception as e: CommandError("surgical : {}".format(e)) def complete_attacksurface(self, *args): return self._cmd_completer("attacksurface", *args) def do_attacksurface(self, *args): """ := attacksurface """ try: if self.apk and self.components: self.logger.log("info", "Loading attacksurface module ...") from core.brains.apk.attacksurface import AttackSurface self.attack_surface = AttackSurface(self.apk, self.components) self.attack_surface.run() # Helps with visual spacing after the results are printed print("\n") except ImportError as e: CommandError("attacksurface : {}".format(e)) def complete_permissions(self, *args): return self._cmd_completer("permissions", *args) @cmd_arguments(["list"]) def do_permissions(self, *args): """ := permissions list """ # Locals arg0 = args[0] try: if self.permissions: if args[0] == "list": self.logger.log("info", "Loading permissions ... \n") for p in self.permissions: print(self.t.yellow("\t--> {}".format(p))) print("\n") else: CommandError("Permissions not found (!)") except Exception as e: CommandError("permissions : {}".format(e)) def complete_binja(self, *args): return self._cmd_completer("binja", *args) def do_binja(self, *args): """ := binja """ try: from .binja import Run run = Run(self.files, self.apk) run.prompt = self.t.cyan("(binja) ") run.ruler = self.t.cyan("-") run.cmdloop() except Exception as e: CommandError("binja : {}".format(e)) def complete_files(self, *args): return self._cmd_completer("files", *args) @cmd_arguments(["all", "assets", "libs", "res"]) def do_files(self, *args): """ := files all := files assets := files libs := files res """ # Locals arg0 = args[0] try: if self.files: if arg0 == "assets": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("assets"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif arg0 == "libs": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("lib"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif arg0 == "res": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("res"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif arg0 == "all": self.logger.log("info", "Loading files ... \n") for f in self.files: print(self.t.yellow("\t--> {}".format(f))) print("\n") else: CommandError("Files not populated (!)") except Exception as e: CommandError("files : {}".format(e)) def complete_strings(self, *args): return self._cmd_completer("strings", *args) @cmd_arguments(["list", "search"]) def do_strings(self, *args): """ List and search for strings found in classes.dex := strings list := strings search """ # Locals arg0 = args[0] strings = None try: if arg0 == "list": if self.vm: strings = self.vm.get_strings() if strings: for s in strings: print(self.t.cyan("--> {}".format(s.encode("utf-8", errors="ignore")))) else: CommandError("Strings not found (!)") else: CommandError("classes.dex not loaded (!)") elif arg0 == "search": if self.vm: strings = self.vm.get_strings() if strings: target = raw_input(self.t.yellow("\n\t--> Enter string : ")) for s in strings: if target in s: print(self.t.cyan("\t\t --> {}".format(s.encode("utf-8", errors="ignore")))) print("\n") else: CommandError("Strings not found (!)") else: CommandError("classes.dex not loaded (!)") except Exception as e: CommandError("strings : {}".format(e)) def complete_components(self, *args): return self._cmd_completer("components", *args) @cmd_arguments(["list"]) def do_components(self, *args): """ := components list """ # Locals arg0 = args[0] try: if arg0 == "list": if self.apk: self.logger.log("info", "Enumerating components ...\n") if self.components.activities: for a in self.components.activities: print(self.t.yellow("\t--> activity : {}" .format(a))) print("\n") if self.components.services: for s in self.components.services: print(self.t.yellow("\t--> service : {}" .format(s))) print("\n") if self.components.receivers: for r in self.components.receivers: print(self.t.yellow("\t--> receiver : {}" .format(r))) print("\n") if self.components.providers: for r in self.components.providers: print(self.t.yellow("\t--> provider : {}" .format(s))) print("\n") else: CommandError("APK not loaded (!)") except Exception as e: CommandError("components : {}".format(e)) def complete_interact(self, *args): return self._cmd_completer("interact", *args) def do_interact(self, *args): """ Drop into an interactive IPython session. := interact """ try: if self.vm and self.vmx: from core.brains.interact.interact import Interact i = Interact(self.vm, self.vmx) i.run() else: CommandError("classes.dex not loaded (!)") except Exception as e: CommandError("interact : {}".format(e.message)) def complete_class_tree(self, *args): return self._cmd_completer("class_tree", *args) def do_class_tree(self, *args): """ := class_tree """ try: if self.vm: for c in self.vm.get_classes(): # We don't care about Android support classes or resource # classes if c.name.startswith("Landroid") or \ c.name.split("/")[-1].startswith("R"): continue print("\n") print(self.t.yellow("\t--> class : {} {}".format(c.get_access_flags_string(), c.name))) for f in c.get_fields(): print(self.t.white("\t\t--> field : {} {} {}".format(f.get_access_flags_string(), f.get_descriptor(), f.name))) for m in c.get_methods(): print(self.t.cyan("\t\t\t--> method : {} {} {}".format(m.get_access_flags_string(), m.name, m.get_descriptor()))) print("\n") else: CommandError("class_tree : classes.dex not loaded (!)") except Exception as e: CommandError("class_tree : {}".format(e)) def complete_native(self, *args): return self._cmd_completer("native", *args) def do_native(self, *args): """ := native """ # Locals native_methods = list() try: if self.vm: for method in self.vm.get_methods(): if method.get_access_flags() & 0x100: native_methods.append((method.get_class_name(), method.get_name())) if native_methods: print("\n") for n in native_methods: print(self.t.cyan("\t--> {} : {}".format(n[0], n[1]))) print("\n") else: self.logger.log("info", "class_tree : classes.dex not loaded (!)") except Exception as e: CommandError("native : {}".format(e)) def complete_ui(self, *args): return self._cmd_completer("ui", *args) def do_ui(self, *args): """ := ui """ try: if self.vm and self.vmx: from core.brains.ui.terminal import TerminalApp ui = TerminalApp(self.vm, self.vmx) ui.run() except Exception as e: CommandError("ui : {}".format(e)) def complete_macro(self, *args): return self._cmd_completer("macro", *args) def do_macro(self, args): """ := macro """ # Locals directory_items = None macro = path.join(self.ROOT_DIR, "macro") selection = None apk_path = None json = None try: print("\n") directory_items = listdir(macro) for i, item in enumerate(directory_items): print(self.t.cyan("\t--> [{}] {}" .format(i, item))) print("\n") selection = raw_input(self.t.yellow("[{}] Select config : ".format(datetime.now()))) try: index = int(selection) except ValueError: index = -1 print("\n") if selection: for i, item in enumerate(directory_items): if selection == item or i == index: selection = item break with open("".join([macro, "/", selection]), "rb") as config: # Load the config as JSON json = loads(config.read()) if json: for k, v in json.items(): if k == "apk": if v: apk_path = str(v) # Call operate() with the path to apk self.do_operate("apk {}" .format(apk_path)) return else: CommandError("macro : Path to APK not found in {}" .format(selection)) else: CommandError("macro : Error loading {} as JSON" .format(selection)) except Exception as e: CommandError("macro : {}".format(e))
def main(): parser = get_parser() args = parser.parse_args() hashfunctions = dict( md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args.hash.lower() not in hashfunctions: print("Hash function {} not supported!".format(args.hash.lower()), file=sys.stderr) print("Use one of {}".format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args.apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) certs = set( a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if args.show: x509_cert = x509.Certificate.load(cert) print( "Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print( "Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print( "Valid not before:", x509_cert['tbs_certificate'] ['validity']['not_before'].native) print( "Valid not after:", x509_cert['tbs_certificate'] ['validity']['not_after'].native) if not args.all: print("{} {}".format( args.hash.lower(), hashfunctions[args.hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args.apk) > 1: print()
def get_package_name(apk_path): """ Extract the package name of an APK """ a = APK(apk_path) return a.get_package(), a.get_androidversion_code()
encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption())) current_dir = os.getcwd() script_dir = dir_path = os.path.dirname(os.path.realpath(__file__)) if sys.version_info < (3, 6): raise RuntimeError("This application requires Python 3.6+") if not argv[1].endswith(".apk"): print("No apk given") sys.exit(1) print("APK loading...") a = APK(argv[1]) package_name = a.get_package() resources = a.get_android_resources() # .get_strings_resources() client_id = resources.get_string(package_name, "PSA_API_CLIENT_ID_PROD")[1] client_secret = resources.get_string(package_name, "PSA_API_CLIENT_SECRET_PROD")[1] HOST_BRANDID_PROD = resources.get_string(package_name, "HOST_BRANDID_PROD")[1] pfx_cert = a.get_file("assets/MWPMYMA1.pfx") REMOTE_REFRESH_TOKEN = None print("APK loaded !") client_email = input(f"{BRAND[package_name]['app_name']} email: ") client_password = getpass(f"{BRAND[package_name]['app_name']} password: "******"What is your country code ? (ex: FR, GB, DE, ES...)\n") ## Get Customer id
class XAPK: def __init__(self, folder): self.folder = Path(folder) for x in self.folder.glob('*.apk'): self.apk_src = Path(x) break for x in self.folder.glob('*.obb'): self.obb_src = Path(x) break self.apk = APK(self.apk_src) self.manifest = self.make_manifest() self.icon = self.apk.get_file(self.apk.get_app_icon()) def make_manifest(self): apk_size = self.apk_src.stat().st_size if self.obb_src: obb_size = self.obb_src.stat().st_size else: obb_size = 0 total_size = apk_size + obb_size filename = self.apk.get_filename() manifest = {} manifest['xapk_version'] = 1 manifest['package_name'] = self.apk.get_package() manifest['name'] = self.apk.get_app_name() # manifest['locales_name'] = {} # TODO manifest['version_code'] = self.apk.get_androidversion_code() manifest['version_name'] = self.apk.get_androidversion_name() manifest['min_sdk_version'] = self.apk.get_min_sdk_version() manifest['target_sdk_version'] = self.apk.get_target_sdk_version() manifest['permissions'] = self.apk.get_declared_permissions() manifest['total_size'] = total_size manifest['expansions'] = [] if obb_size: main_obb = {} main_obb[ 'file'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format( **manifest) main_obb['install_location'] = 'EXTERNAL_STORAGE' main_obb[ 'install_path'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format( **manifest) manifest['expansions'].push(main_obb) return manifest def save(self): self.name = '{package_name}_v{version_name}.xapk'.format( **self.manifest) zip_path = self.folder.joinpath(self.name) zip_dir = tempfile.mkdtemp() try: print('copying apk to temp directory...') apk_name = '{package_name}.apk'.format(**self.manifest) apk_src = self.apk_src.resolve() apk_dest = PurePath(zip_dir).joinpath(apk_name) shutil.copy2(apk_src, apk_dest) print('apk: OK') if self.manifest.get('expansions'): print('copying obb to temp directory...') obb_name = self.manifest['expansions'][0]['install_path'] obb_src = self.obb_src.resolve() obb_dest = PurePath(zip_dir).joinpath(obb_name) os.makedirs(Path(obb_dest).parent, exist_ok=True) shutil.copy2(obb_src, obb_dest) print('obb: OK') else: print('no obb found') print('creating icon in temp directory...') icon = self.icon icon_dest = PurePath(zip_dir).joinpath('icon.png') with open(icon_dest, 'wb') as iconfile: iconfile.write(icon) print('icon: OK') print('creating manifest in temp directory...') manifest_dest = PurePath(zip_dir).joinpath('manifest.json') with open(manifest_dest, 'w') as manifestfile: s = json.dumps(self.manifest, separators=(':', ',')) manifestfile.write(s) print('manifest: OK') print('creating xapk archive...') with zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED) as zfd: for root, dirs, files in os.walk(zip_dir): for f in files: filename = os.path.join(root, f) zfd.write(filename, os.path.relpath(filename, zip_dir)) print('xapk: OK') finally: print('cleaning up temp directory...') shutil.rmtree(zip_dir) print('cleanup: OK')
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() apkinfo["hidden_payload"] = [] for file in apkinfo["files"]: if self.file_type_check(file): apkinfo["hidden_payload"].append(file) apkinfo["files_flaged"] = self.files_name_map manifest["permissions"]= get_permissions(a) manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() manifest["receivers_actions"] = get_extended_receivers(a) manifest["providers"] = a.get_providers() manifest["libraries"] = a.get_libraries() apkinfo["manifest"] = manifest apkinfo["icon"] = get_apk_icon(self.file_path) certificate = get_certificate(self.file_path) if certificate: apkinfo["certificate"] = certificate #vm = DalvikVMFormat(a.get_dex()) #strings = vm.get_strings() strings = self._get_strings(self.file_path) apkinfo["interesting_strings"] = find_strings(strings) apkinfo["dex_strings"] = strings static_calls = {} if self.options.decompilation: if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = uVMAnalysis(vm) static_calls["all_methods"] = get_methods(vmx) static_calls["is_native_code"] = analysis.is_native_code(vmx) static_calls["is_dynamic_code"] = analysis.is_dyn_code(vmx) static_calls["is_reflection_code"] = analysis.is_reflection_code(vmx) static_calls["is_crypto_code"] = is_crypto_code(vmx) static_calls["dynamic_method_calls"] = get_show_DynCode(vmx) static_calls["reflection_method_calls"] = get_show_ReflectionCode(vmx) static_calls["permissions_method_calls"] = get_show_Permissions(vmx) static_calls["crypto_method_calls"] = get_show_CryptoCode(vmx) static_calls["native_method_calls"] = get_show_NativeMethods(vmx) classes = list() for cls in vm.get_classes(): classes.append(cls.name) static_calls["classes"] = classes else: log.warning("Dex size bigger than: %s", self.options.decompilation_threshold) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo
def main(options, args): if options.emulator is None or options.file is None or options.policy is None: sys.exit('please confirm the parameters are correct') emulator = options.emulator apk_path = options.file policy = options.policy device = Device(emulator) if options.install: stevedore.install_apk(apk_path, device) if not os.path.isdir(LOGS): os.mkdir(LOGS) sha256 = hashlib.sha256() sha256.update(open(apk_path).read()) sha256sum = sha256.hexdigest() log_file = os.path.join(LOGS, sha256sum + '.log') if not os.path.isfile(log_file): #print 'writing log file into %s' % log_file try: apk = APK(apk_path) except Exception as ex: return False, ex if not apk.is_valid_APK(): return False, 'It is not a valid apk' activities = [] for act in apk.get_activities(): if not filtered(act, FILTERED_ACTIVITY): activities.append(act) services = apk.get_services() receivers = [] for rec in apk.get_receivers(): if not filtered(rec, FILTERED_BROADCAST): receivers.append(rec) package_name = apk.get_package() #write to log file with open(log_file, 'w') as fout: fout.write('package_name=' + package_name + '\n') fout.write('activity=' + ' '.join(activities) + '\n') fout.write('service=' + ' '.join(services) + '\n') fout.write('receiver=' + ' '.join(receivers) + '\n') else: #print 'reading log file from %s' % log_file with open(log_file, 'r') as fin: for line in fin.readlines(): if line.startswith('package_name='): package_name = line.replace('package_name=', '') elif line.startswith('activity='): activities = line.replace('activity=', '').split() elif line.startswith('service='): services = line.replace('service=', '').split() elif line.startswith('receiver='): receivers = line.replace('receiver=', '').split() if policy == 'random': policy = ['broadcast', 'listener', 'launcher', 'service', 'receiver'][random.randint(0, 4)] if policy == 'broadcast': actions = IntentEvent.get_intent_actions() if len(actions) > 0: selected = actions[random.randint(0, len(actions) - 1)] intent = IntentEvent(action=selected, package_name=package_name) intent.execute(device) elif policy == 'listener': if emulator.startswith('emulator'): listener_type = ['sms', 'gsm', 'rotate', 'volume'][random.randint(0, 3)] listener = ListenerEvent(listener_type) listener.execute(device) else: listener_type = ['sms', 'rotate', 'volume'][random.randint(0, 2)] if listener_type == 'sms': intent = IntentEvent( action='android.provider.Telephony.SMS_RECEIVED' ) #, package_name=package_name) intent.execute(device) else: listener = ListenerEvent(listener_type) listener.execute(device) elif policy == 'launcher': if len(activities) > 0: selected = activities[random.randint(0, len(activities) - 1)] launcher = LauncherEvent(package_name, selected) launcher.execute(device) elif policy == 'service': if len(services) > 0: selected = services[random.randint(0, len(services) - 1)] service = ServiceEvent(package_name, selected) service.execute(device) if random.randint(0, 1) == 1: import time time.sleep(3) service = ServiceEvent(package_name=package_name, service_name=selected, stop=True) service.execute(device) elif policy == 'receiver': if len(receivers) > 0: selected = receivers[random.randint(0, len(receivers) - 1)] receiver = ReceiverEvent(package_name, selected) receiver.execute(device)
class Run(Lobotomy): def __init__(self): Lobotomy.__init__(self) self.t = Terminal() self.logger = Logger() self.util = Util() self.apk = None self.package = None self.vm = None self.vmx = None self.gmx = None self.components = None self.dex = None self.strings = None self.permissions = None self.permissions_details = None self.files = None self.attack_surface = None def find_dex(self): """ Return True is classes.dex is found within the target APK. Args: None Returns: None """ if self.files: for f in self.files: if "classes" in f: return True break def process_vm(self): """ Process the application's classes.dex Args: None Results: None """ # Make sure classes.dex exists if self.find_dex(): self.dex = self.apk.get_dex() # Analyze classes.dex # TODO Throw in a progress bar, this can take awhile if self.dex: self.logger.log("info", "Loading classes.dex ...") from androguard.core.bytecodes.dvm import DalvikVMFormat from androguard.core.analysis.analysis import VMAnalysis from androguard.core.analysis.ganalysis import GVMAnalysis # Create a new virtual machine instance self.vm = DalvikVMFormat(self.dex) if self.vm: print(self.t.yellow("\n\t--> Loaded classes.dex (!)\n")) self.logger.log("info", "Analyzing classes.dex ...") # Analyze the virtual machine instance self.vmx = VMAnalysis(self.vm) self.gmx = GVMAnalysis(self.vmx, None) if self.vmx and self.gmx: print(self.t.yellow("\n\t--> Analyzed classes.dex (!)\n")) self.vm.set_vmanalysis(self.vmx) self.vm.set_gvmanalysis(self.gmx) # Generate xref(s) self.vm.create_xref() self.vm.create_dref() else: CommandError("Cannot analyze VM instance (!)") else: CommandError("Cannot load VM instance (!)") else: CommandError("classes.dex not found (!)") def do_operate(self, args): """ := operate apk path_to_apk := operate dex path_to_classes.dex """ try: if args.split()[0] == "apk": if args.split()[1]: self.logger.log("info", "Loading : {} ...".format(args.split()[1].split("/")[-1])) from androguard.core.bytecodes.apk import APK self.apk = APK(args.split()[1]) if self.apk: print(self.t.yellow("\n\t--> Loaded : {} (!)\n".format(args.split()[1].split("/")[-1]))) self.package = self.apk.get_package() from core.brains.apk.components import Components # Load activies, services, broadcast receivers, and # content providers self.components = Components(self.apk) self.components.enumerate_components() self.permissions = self.apk.get_permissions() self.files = self.apk.get_files() self.files_type = self.apk.get_files_types() # Process virtual machine self.process_vm() else: CommandError("APK not loaded (!)") else: CommandError("Unkown command (!)") except ImportError as e: CommandError(e.message) except IndexError as e: CommandError("Not enough arguments (!)") def do_surgical(self, args): """ := surgical """ try: if self.vm and self.vmx: from .surgical import Run run = Run(self.vm, self.vmx) run.prompt = self.t.yellow("(surgical) ") run.ruler = self.t.yellow("-") run.cmdloop() else: CommandError("classes.dex not loaded (!)") except Exception as e: CommandError(e.message) def do_attacksurface(self, args): """ := attacksurface """ try: if self.apk and self.components: self.logger.log("info", "Loading attacksurface module ...") from core.brains.apk.attacksurface import AttackSurface self.attack_surface = AttackSurface(self.apk, self.components) self.attack_surface.run() except ImportError as e: CommandError(e.message) def do_permissions(self, args): """ := permissions list """ try: if self.permissions: if args.split()[0] == "list": self.logger.log("info", "Loading permissions ... \n") for p in self.permissions: print(self.t.yellow("\t--> {}".format(p))) print("\n") else: CommandError("Permissions not found (!)") except Exception as e: CommandError(e.message) def do_files(self, args): """ := files all := files assets := files libs := files res """ try: if self.files: if args.split()[0]: if args.split()[0] == "assets": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("assets"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif args.split()[0] == "libs": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("lib"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif args.split()[0] == "res": self.logger.log("info", "Loading files ... \n") for f in self.files: if f.startswith("res"): print(self.t.yellow("\t--> {}".format(f))) print("\n") elif args.split()[0] == "all": self.logger.log("info", "Loading files ... \n") for f in self.files: print(self.t.yellow("\t--> {}".format(f))) print("\n") else: CommandError("Files not populated (!)") except Exception as e: CommandError(e.message) def do_strings(self, args): """ List and search for strings found in classes.dex := strings list := strings search """ # Locals strings = None try: if args.split()[0] == "list": if self.vm: strings = self.vm.get_strings() if strings: for s in strings: print(self.t.cyan("--> {}".format(s.encode("utf-8")))) else: CommandError("Strings not found (!)") else: CommandError("classes.dex not loaded (!)") elif args.split()[0] == "search": if self.vm: strings = self.vm.get_strings() if strings: target = raw_input(self.t.yellow("\n\t--> Enter string : \n")) for s in strings: if target in s: print(self.t.cyan("\t\t --> {}".format(s))) print("\n") else: CommandError("Strings not found (!)") else: CommandError("classes.dex not loaded (!)") else: CommandError("Command not found (!)") except Exception as e: # We might be see an exception like this: # 'utf8' codec can't decode byte 0xc0 in position 0: invalid start byte raise e CommandError(e.message) def do_components(self, args): """ := components list """ try: if args.split()[0] == "list": if self.apk: self.logger.log("info", "Enumerating components ...\n") if self.components.activities: for a in self.components.activities: print(self.t.yellow("\t--> activity : {}".format(a))) print("\n") if self.components.services: for s in self.components.services: print(self.t.yellow("\t--> service : {}".format(s))) print("\n") if self.components.receivers: for r in self.components.receivers: print(self.t.yellow("\t--> receiver : {}".format(s))) print("\n") if self.components.providers: for r in self.components.providers: print(self.t.yellow("\t--> provider : {}".format(s))) print("\n") else: CommandError("APK not loaded (!)") else: CommandError("Command not found (!)") except Exception as e: CommandError(e.message) def do_interact(self, args): """ Drop into an interactive IPython session. := interact """ try: if self.vm and self.vmx: from core.brains.interact.interact import Interact i = Interact(self.vm, self.vmx) i.run() else: CommandError("classes.dex not loaded (!)") except Exception as e: CommandError(e.message) def do_macro(self, args): """ """ return
def androsign_main(args_apk, args_hash, args_all, show): from androguard.core.bytecodes.apk import APK from androguard.util import get_certificate_name_string import hashlib import binascii import traceback from colorama import Fore, Style from asn1crypto import x509, keys from oscrypto import asymmetric # Keep the list of hash functions in sync with cli/entry_points.py:sign hashfunctions = dict(md5=hashlib.md5, sha1=hashlib.sha1, sha256=hashlib.sha256, sha512=hashlib.sha512, ) if args_hash.lower() not in hashfunctions: print("Hash function {} not supported!" .format(args_hash.lower()), file=sys.stderr) print("Use one of {}" .format(", ".join(hashfunctions.keys())), file=sys.stderr) sys.exit(1) for path in args_apk: try: a = APK(path) print("{}, package: '{}'".format(os.path.basename(path), a.get_package())) print("Is signed v1: {}".format(a.is_signed_v1())) print("Is signed v2: {}".format(a.is_signed_v2())) print("Is signed v3: {}".format(a.is_signed_v3())) certs = set(a.get_certificates_der_v3() + a.get_certificates_der_v2() + [a.get_certificate_der(x) for x in a.get_signature_names()]) pkeys = set(a.get_public_keys_der_v3() + a.get_public_keys_der_v2()) if len(certs) > 0: print("Found {} unique certificates".format(len(certs))) for cert in certs: if show: x509_cert = x509.Certificate.load(cert) print("Issuer:", get_certificate_name_string(x509_cert.issuer, short=True)) print("Subject:", get_certificate_name_string(x509_cert.subject, short=True)) print("Serial Number:", hex(x509_cert.serial_number)) print("Hash Algorithm:", x509_cert.hash_algo) print("Signature Algorithm:", x509_cert.signature_algo) print("Valid not before:", x509_cert['tbs_certificate']['validity']['not_before'].native) print("Valid not after:", x509_cert['tbs_certificate']['validity']['not_after'].native) if not args_all: print("{} {}".format(args_hash.lower(), hashfunctions[args_hash.lower()](cert).hexdigest())) else: for k, v in hashfunctions.items(): print("{} {}".format(k, v(cert).hexdigest())) print() if len(certs) > 0: print("Found {} unique public keys associated with the certs".format(len(pkeys))) for public_key in pkeys: if show: x509_public_key = asymmetric.load_public_key(public_key) print("PublicKey Algorithm:", x509_public_key.algorithm) print("Bit Size:", x509_public_key.bit_size) print("Fingerprint:", binascii.hexlify(x509_public_key.fingerprint)) try: print("Hash Algorithm:", hash_algo(x509_public_key)) except ValueError as ve: # RSA pkey does not have an hash algorithm pass print() except: print(Fore.RED + "Error in {}".format(os.path.basename(path)) + Style.RESET_ALL, file=sys.stderr) traceback.print_exc(file=sys.stderr) if len(args_apk) > 1: print()
class App(object): """ this class describes an app """ def __init__(self, app_path, output_dir=None): """ create a App instance :param app_path: local file path of app :return: """ assert app_path is not None self.logger = logging.getLogger(self.__class__.__name__) self.app_path = app_path self.output_dir = output_dir if output_dir is not None: if not os.path.isdir(output_dir): os.makedirs(output_dir) from androguard.core.bytecodes.apk import APK self.apk = APK(self.app_path) self.package_name = self.apk.get_package() self.main_activity = self.apk.get_main_activity() self.permissions = self.apk.get_permissions() self.activities = self.apk.get_activities() self.possible_broadcasts = self.get_possible_broadcasts() self.dumpsys_main_activity = None self.hashes = self.get_hashes() def get_package_name(self): """ get package name of current app :return: """ return self.package_name def get_main_activity(self): """ get package name of current app :return: """ if self.main_activity is not None: return self.main_activity else: self.logger.warning( "Cannot get main activity from manifest. Using dumpsys result instead." ) return self.dumpsys_main_activity def get_start_intent(self): """ get an intent to start the app :return: Intent """ package_name = self.get_package_name() if self.get_main_activity(): package_name += "/%s" % self.get_main_activity() return Intent(suffix=package_name) def get_start_with_profiling_intent(self, trace_file, sampling=None): """ get an intent to start the app with profiling :return: Intent """ package_name = self.get_package_name() if self.get_main_activity(): package_name += "/%s" % self.get_main_activity() if sampling is not None: return Intent(prefix="start --start-profiler %s --sampling %d" % (trace_file, sampling), suffix=package_name) else: return Intent(prefix="start --start-profiler %s" % trace_file, suffix=package_name) def get_stop_intent(self): """ get an intent to stop the app :return: Intent """ package_name = self.get_package_name() return Intent(prefix="force-stop", suffix=package_name) def get_possible_broadcasts(self): possible_broadcasts = set() for receiver in self.apk.get_receivers(): intent_filters = self.apk.get_intent_filters('receiver', receiver) actions = intent_filters[ 'action'] if 'action' in intent_filters else [] categories = intent_filters[ 'category'] if 'category' in intent_filters else [] categories.append(None) for action in actions: for category in categories: intent = Intent(prefix='broadcast', action=action, category=category) possible_broadcasts.add(intent) return possible_broadcasts def get_hashes(self, block_size=2**8): """ Calculate MD5,SHA-1, SHA-256 hashes of APK input file @param block_size: """ md5 = hashlib.md5() sha1 = hashlib.sha1() sha256 = hashlib.sha256() f = open(self.app_path, 'rb') while True: data = f.read(block_size) if not data: break md5.update(data) sha1.update(data) sha256.update(data) return [md5.hexdigest(), sha1.hexdigest(), sha256.hexdigest()]
def reverse(nameApk): # doc file config with open(config_file, "r+") as f: dataConfig = json.load(f) maxLabelsNum = dataConfig['maxLabelsNum'] # Label tong hop # with open(LabelsNum_file, "r+") as file_LabeslNum: # LABELSNUMANDTEXT = json.load(file_LabeslNum) # Load Android API packages and classes global API_PACKAGES_LIST, API_CLASSES_LIST, API_SYSTEM_COMMANDS ############################################################ # READING PACKAGES, CLASSES AND SYSTEM COMMANDS ############################################################ package_file = load_file(str(package_index_file)) API_PACKAGES_LIST = [x.strip() for x in package_file] class_file = load_file(str(classes_index_file)) API_CLASSES_LIST = [x.strip() for x in class_file] commands_file = load_file(str(system_commands_file)) API_SYSTEM_COMMANDS = [x.strip() for x in commands_file] static_analysis_dict = collections.OrderedDict() try: analyze_apk = os.path.join(TEMP,nameApk) # Getting the name of the folder that contains all apks and folders with apks base_folder = TEMP.split("/")[-1] apk_filename = join_dir(base_folder, analyze_apk.replace(TEMP, '')) apk_filename = apk_filename.replace("//", "/") apk_name_no_extensions = "".join(apk_filename.split("/")[-1].split(".")[:-1]) # export to monggoDB # if os.path.isfile(join_dir(output_folder, apk_filename.split("/")[-1].replace('.apk', '-analysis.json'))): # database[apk_filename.replace('.apk', '')] = json.load( # open(join_dir(output_folder, apk_filename.split("/")[-1]. # replace('.apk', '-analysis.json')))) # continue pre_static_dict = collections.OrderedDict() pre_static_dict['Filename'] = apk_filename hasher_md5 = hashlib.md5() hasher_sha256 = hashlib.sha256() hasher_sha1 = hashlib.sha1() with open(analyze_apk, 'rb') as afile: buf = afile.read() hasher_md5.update(buf) hasher_sha256.update(buf) hasher_sha1.update(buf) md5 = hasher_md5.hexdigest() sha256 = hasher_sha256.hexdigest() sha1 = hasher_sha1.hexdigest() pre_static_dict["md5"] = md5 pre_static_dict["sha256"] = sha256 pre_static_dict["sha1"] = sha1 """ if label is not None: pre_static_dict["Label"] = label else: pre_static_dict["Label"] = "/".join(apk_filename.split("/")[:-1]) """ pre_static_dict["VT_positives"] = None apk_Oject = APK(analyze_apk) # get package name static_analysis_dict['Package_name'] = apk_Oject.get_package() # get Permission static_analysis_dict['Permissions'] = apk_Oject.get_permissions() # Activities try: list_activities = apk_Oject.get_activities() except UnicodeEncodeError: list_activities = [] # get Main ACtivity static_analysis_dict['Main_activity'] = apk_Oject.get_main_activity() # Receivers try: list_receivers = apk_Oject.get_receivers() except UnicodeEncodeError: list_receivers = [] # Services try: list_services = apk_Oject.get_services() except UnicodeEncodeError: list_services = [] # API calls and Strings list_smali_api_calls, list_smali_strings = read_strings_and_apicalls(analyze_apk, API_PACKAGES_LIST, API_CLASSES_LIST) for api_call in list_smali_api_calls.keys(): new_api_call = '.'.join(api_call.split(".")[:-1]) if new_api_call in list_smali_api_calls.keys(): list_smali_api_calls[new_api_call] = list_smali_api_calls[new_api_call] + list_smali_api_calls[ api_call] else: list_smali_api_calls[new_api_call] = list_smali_api_calls[api_call] del list_smali_api_calls[api_call] static_analysis_dict['API_calls'] = list_smali_api_calls static_analysis_dict['Strings'] = Counter(filter(None, list_smali_strings)) # API packages API_packages_dict = collections.OrderedDict() android_list_packages_lenghts = [len(x.split(".")) for x in API_PACKAGES_LIST] list_api_calls_keys = list_smali_api_calls.keys() for api_call in list_api_calls_keys: score = 0 package_chosen = None for i, package in enumerate(API_PACKAGES_LIST): len_package = android_list_packages_lenghts[i] if api_call.startswith(package) and len_package > score: score = len_package package_chosen = package if package_chosen is not None: if not package_chosen in API_packages_dict.keys(): API_packages_dict[package_chosen] = list_smali_api_calls[api_call] else: API_packages_dict[package_chosen] += list_smali_api_calls[api_call] static_analysis_dict['API_packages'] = API_packages_dict # Intents try: static_analysis_dict['Intents'] = intents_analysis(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml')) except: static_analysis_dict['Intents'] = {'Failed to extract intents': 0} # Intents of activities intents_activities = collections.OrderedDict() for activity in list_activities: intents_activities[activity] = check_for_intents(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), activity, 'activity') static_analysis_dict['Activities'] = intents_activities # Intents of services intents_services = collections.OrderedDict() for service in list_services: intents_services[service] = check_for_intents(join_dir(analyze_apk.replace('.apk', ''), 'AndroidManifest.xml'), service, 'service') static_analysis_dict['Services'] = intents_services # Intents of receivers intents_receivers = collections.OrderedDict() for intent in list_receivers: intents_receivers[intent] = check_for_intents(join_dir(analyze_apk.replace('.apk', '/'), 'AndroidManifest.xml'), intent, 'receiver') static_analysis_dict['Receivers'] = intents_receivers static_analysis_dict['Receivers'] = intents_receivers apk_total_analysis = collections.OrderedDict([("Pre_static_analysis", pre_static_dict), ("Static_analysis", static_analysis_dict)]) # # save_as_json(apk_total_analysis, output_name=join_dir(output_folder, apk_name_no_extensions + # "-analysis.json")) row = standardData(pre_static_dict, static_analysis_dict) csvFileClient = open(DataCSVClient + md5 + '.csv', 'w+', newline='') writer = csv.writer(csvFileClient, delimiter=',') writer.writerow(row) csvFileClient.close() delAPk(analyze_apk) if checkMerge(DataCSVClient, dataConfig['mergeCSV']): mergeCSV() return md5, apk_total_analysis except Exception as e: print('Exception: ', e) return 'Error', 'No features'
def run(self): """Run androguard to extract static android information @return: list of static features """ self.key = "apkinfo" apkinfo = {} if "file" not in self.task["category"] or not HAVE_ANDROGUARD: return f = File(self.task["target"]) #if f.get_name().endswith((".zip", ".apk")) or "zip" in f.get_type(): if not os.path.exists(self.file_path): raise CuckooProcessingError("Sample file doesn't exist: \"%s\"" % self.file_path) try: a = APK(self.file_path) if a.is_valid_APK(): manifest = {} apkinfo["files"] = self._apk_files(a) manifest["package"] = a.get_package() apkinfo["hidden_payload"] = [] for file in apkinfo["files"]: if self.file_type_check(file): apkinfo["hidden_payload"].append(file) apkinfo["files_flaged"] = self.files_name_map manifest["permissions"] = get_permissions(a) manifest["main_activity"] = a.get_main_activity() manifest["activities"] = a.get_activities() manifest["services"] = a.get_services() manifest["receivers"] = a.get_receivers() manifest["receivers_actions"] = get_extended_receivers(a) manifest["providers"] = a.get_providers() manifest["libraries"] = list(a.get_libraries()) apkinfo["manifest"] = manifest apkinfo["icon"] = get_apk_icon(self.file_path) certificate = get_certificate(self.file_path) if certificate: apkinfo["certificate"] = certificate #vm = DalvikVMFormat(a.get_dex()) #strings = vm.get_strings() strings = self._get_strings(self.file_path) apkinfo["interesting_strings"] = find_strings(strings) apkinfo["dex_strings"] = strings static_calls = {} if self.options.decompilation: if self.check_size(apkinfo["files"]): vm = DalvikVMFormat(a.get_dex()) vmx = Analysis(vm) vmx.create_xref() static_calls["all_methods"] = get_methods(vmx) static_calls[ "permissions_method_calls"] = get_show_Permissions( vmx) static_calls[ "native_method_calls"] = get_show_NativeMethods( vmx) static_calls["is_native_code"] = bool( static_calls["native_method_calls"] ) # True if not empty, False if empty static_calls[ "dynamic_method_calls"] = get_show_DynCode(vmx) static_calls["is_dynamic_code"] = bool( static_calls["dynamic_method_calls"]) static_calls[ "reflection_method_calls"] = get_show_ReflectionCode( vmx) static_calls["is_reflection_code"] = bool( static_calls["reflection_method_calls"]) static_calls[ "crypto_method_calls"] = get_show_CryptoCode(vmx) static_calls["is_crypto_code"] = bool( static_calls["crypto_method_calls"]) classes = list() for cls in vm.get_classes(): classes.append(cls.name) static_calls["classes"] = classes else: log.warning( "Aborted decompilation, static extraction of calls not perforemd", ) apkinfo["static_method_calls"] = static_calls except (IOError, OSError, BadZipfile) as e: raise CuckooProcessingError("Error opening file %s" % e) return apkinfo