def testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER']}, {'action': ['android.service.notification.NotificationListenerService']}, {'action': ['android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED'], 'category': ['android.intent.category.HOME']}, {'action': ['android.appwidget.action.APPWIDGET_UPDATE']}]) self.assertTrue(any(x != y for x, y in pairs))
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 testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': ['android.service.notification.NotificationListenerService'] }, { 'action': [ 'android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED' ], 'category': ['android.intent.category.HOME'] }, { 'action': ['android.appwidget.action.APPWIDGET_UPDATE'] }]) self.assertTrue(any(x != y for x, y in pairs))
def lim_features_categories(apk_filepath): try: apk = APK(apk_filepath) info = { 'declared permissions': sorted(apk.get_permissions()), 'activities': apk.get_activities(), 'services': apk.get_services(), 'intent filters': apk.get_intent_filters('receiver', ''), 'content providers': apk.get_providers(), 'broadcast receivers': apk.get_receivers(), 'hardware components': apk.get_features() } for category in info: info[category] = [ feature.replace(".", "_").lower() for feature in info[category] ] return info except: # We just do not process the APK pass
def testAPKIntentFilters(self): from androguard.core.bytecodes.apk import APK a = APK("examples/tests/a2dp.Vol_137.apk", testzip=True) activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': [ 'android.intent.action.BOOT_COMPLETED', 'android.intent.action.MY_PACKAGE_REPLACED' ], 'category': ['android.intent.category.HOME'] }, { 'action': ['android.appwidget.action.APPWIDGET_UPDATE'] }, { 'action': ['android.service.notification.NotificationListenerService'] }]) self.assertFalse(any(x != y for x, y in pairs)) a = APK("examples/tests/com.test.intent_filter.apk", testzip=True) activities = a.get_activities() activities = a.get_activities() receivers = a.get_receivers() services = a.get_services() filter_list = [] for i in activities: filters = a.get_intent_filters("activity", i) if len(filters) > 0: filter_list.append(filters) for i in receivers: filters = a.get_intent_filters("receiver", i) if len(filters) > 0: filter_list.append(filters) for i in services: filters = a.get_intent_filters("service", i) if len(filters) > 0: filter_list.append(filters) pairs = zip(filter_list, [{ 'action': ['android.intent.action.VIEW'], 'category': [ 'android.intent.category.APP_BROWSER', 'android.intent.category.DEFAULT', 'android.intent.category.BROWSABLE' ], 'data': [{ 'scheme': 'testscheme', 'host': 'testhost', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }] }, { 'action': ['android.intent.action.MAIN'], 'category': ['android.intent.category.LAUNCHER'] }, { 'action': ['android.intent.action.VIEW'], 'category': ['android.intent.category.DEFAULT', 'android.intent.category.BROWSABLE'], 'data': [{ 'scheme': 'testhost', 'host': 'testscheme', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }] }, { 'action': ['android.intent.action.RESPOND_VIA_MESSAGE'], 'data': [{ 'scheme': 'testhost', 'host': 'testscheme', 'port': '0301', 'path': '/testpath', 'pathPattern': 'testpattern', 'mimeType': 'text/html' }, { 'scheme': 'testscheme2', 'host': 'testhost2', 'port': '0301', 'path': '/testpath2', 'pathPattern': 'testpattern2', 'mimeType': 'image/png' }] }]) self.assertFalse(any(x != y for x, y in pairs))
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()]
class App(object): """ The class representing the application to be analyzed. """ def __init__(self, apk_path: str): self.logger = logging.getLogger('{0}.{1}'.format( __name__, self.__class__.__name__)) if not os.path.isfile(apk_path): raise FileNotFoundError( 'The input application file "{0}" was not found'.format( apk_path)) self.apk_path = apk_path self.apk = APK(self.apk_path) self.hashes = self.get_hashes() self.package_name = self.apk.get_package() self.main_activities = self.apk.get_main_activities() # This is the variable that holds the list of intents that should be used to start the app. Every # time an intent is used to start the app, the code should check if the intent is valid (it starts # an existing activity), if it's not valid then the intent should be removed from this list. self.start_intents = self.get_start_intents() self.permissions = self.apk.get_permissions() self.activities = self.apk.get_activities() self.possible_broadcasts = self.get_possible_broadcasts() def get_hashes(self, block_size=65536) -> List[str]: """ Calculate MD5, SHA1 and SHA256 hashes of the input application file. :param block_size: The size of the block used for the hash functions. :return: A list containing the MD5, SHA1 and SHA256 hashes of the input application file. """ md5_hash = hashlib.md5() sha1_hash = hashlib.sha1() sha256_hash = hashlib.sha256() with open(self.apk_path, 'rb') as filename: for chunk in iter(lambda: filename.read(block_size), b''): md5_hash.update(chunk) sha1_hash.update(chunk) sha256_hash.update(chunk) return [ md5_hash.hexdigest(), sha1_hash.hexdigest(), sha256_hash.hexdigest() ] def get_package_name(self) -> str: """ Get the package name of the current application. :return: The package name of the current application. """ return self.package_name def get_main_activities(self) -> List[str]: """ Get the main activities of the current application. :return: A list with the main activities of the current application. """ return self.main_activities def get_start_intents(self) -> List[Intent]: """ Get a list of intents to start the main activities of the current application. This method should be called only during initialization, after that use start_intents variable. :return: A list of intents to start the main activities of the current application. """ list_of_intents: List[Intent] = [] for activity in self.get_main_activities(): list_of_intents.append( Intent(suffix='{0}/{1}'.format(self.package_name, activity))) if list_of_intents: return list_of_intents raise RuntimeError( 'This application has no main activity that can be used') def get_stop_intent(self): """ Get an intent to stop the current application. :return: An intent to stop the current application. """ return Intent(prefix='force-stop', suffix=self.package_name) def get_possible_broadcasts(self) -> Set[Intent]: """ Get the intents to trigger the broadcast receivers in the current application. :return: A set with the intents to trigger the broadcast receivers in the current application. """ 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