def fast_load_from_io(file_like_object=None, apk_file_path=None, calculate_hash=True): ''' Load a FastApk from file-like object or path by unzipping only the manifest file and calculating the hash. Parameters ---------- file_like_object : file-like-object, optional (default is None) A file-like obj that points to the apk. If non given, try to open a file_like_object from the given `apk_file_path`. apk_file_path: str, optional (default is "not set") Path of apk calculate_hash : bool If true calculate the hash. This means the file has be to loaded completely into memory. If False, the hash will be calculated the first time it gets retrieved. Returns ------- apk: FastApk Raises ------ CouldNotOpenApk If the apk file could not be opened CouldNotReadManifest If the manifest file could not be read ''' from androguard.core.bytecodes import apk as androapk from androguard.patch import zipfile # apk will be loaded from `flo` variable flo = file_like_object # indicates if file has been opened from path file_open_from_path = False # no file_like_object given, open file from path if file_like_object is None and isinstance(apk_file_path, str): try: flo = open(apk_file_path, "rb") file_open_from_path = True except IOError as e: flo.close() raise CouldNotOpenApk(apk_file_path, e), None, sys.exc_info()[2] # if file path not set, show at least that it's not seen in the exceptions if apk_file_path is None: apk_file_path = "not set" # load apk into memory and calculate hash if option set flo.seek(0) _hash = None if calculate_hash: data = flo.read() # calculate hash _hash = Util.sha256(data) flo.seek(0) try: if zipfile.is_zipfile(flo): z = zipfile.ZipFile(flo) # only read manifest from zip file binary_manifest = z.read(MANIFEST_FILENAME) ap = androapk.AXMLPrinter(binary_manifest) dom = minidom.parseString(ap.get_buff()) manifest_tag = dom.getElementsByTagName(MANIFEST_TAG_NAME) # check that manifest tag is available if len(manifest_tag) > 0: # get size of uncompresses .dex file size_app_code = z.getinfo(COMPILED_APP_CODE).file_size # get build date (last timestamp of classes.dex in zipfile) build_date = datetime( # use tuple from zipfile and pass the unpacked content to the constructor *z.getinfo(COMPILED_APP_CODE).date_time) manifest_items = manifest_tag[0].attributes # use the namespace to ignore wrong prefixes like "ns0" version_name = manifest_items.getNamedItemNS( MANIFEST_NS, MANIFEST_VERSION_NAME).nodeValue package = manifest_items.getNamedItem( MANIFEST_PACKAGE).nodeValue return FastApk(package, version_name, path=apk_file_path, _hash=_hash, size_app_code=size_app_code, build_date=build_date) raise CouldNotOpenManifest(apk_file_path), None, sys.exc_info()[2] except Exception as e: raise CouldNotOpenApk(apk_file_path, caused_by=e), None, sys.exc_info()[2] finally: # close file if manually opened from path if file_open_from_path: flo.close()
def fast_load_from_io(file_like_object = None, apk_file_path = None, calculate_hash = True): ''' Load a FastApk from file-like object or path by unzipping only the manifest file and calculating the hash. Parameters ---------- file_like_object : file-like-object, optional (default is None) A file-like obj that points to the apk. If non given, try to open a file_like_object from the given `apk_file_path`. apk_file_path: str, optional (default is "not set") Path of apk calculate_hash : bool If true calculate the hash. This means the file has be to loaded completely into memory. If False, the hash will be calculated the first time it gets retrieved. Returns ------- apk: FastApk Raises ------ CouldNotOpenApk If the apk file could not be opened CouldNotReadManifest If the manifest file could not be read ''' from androguard.core.bytecodes import apk as androapk from androguard.patch import zipfile # apk will be loaded from `flo` variable flo = file_like_object # indicates if file has been opened from path file_open_from_path = False # no file_like_object given, open file from path if file_like_object is None and isinstance(apk_file_path, str): try: flo = open(apk_file_path, "rb") file_open_from_path = True except IOError as e: flo.close() raise CouldNotOpenApk(apk_file_path, e), None, sys.exc_info()[2] # if file path not set, show at least that it's not seen in the exceptions if apk_file_path is None: apk_file_path = "not set" # load apk into memory and calculate hash if option set flo.seek(0) _hash = None if calculate_hash: data = flo.read() # calculate hash _hash = Util.sha256(data) flo.seek(0) try: if zipfile.is_zipfile(flo): z = zipfile.ZipFile(flo) # only read manifest from zip file binary_manifest = z.read(MANIFEST_FILENAME) ap = androapk.AXMLPrinter(binary_manifest) dom = minidom.parseString(ap.get_buff()) manifest_tag = dom.getElementsByTagName(MANIFEST_TAG_NAME) # check that manifest tag is available if len(manifest_tag) > 0: # get size of uncompresses .dex file size_app_code = z.getinfo(COMPILED_APP_CODE).file_size # get build date (last timestamp of classes.dex in zipfile) build_date = datetime( # use tuple from zipfile and pass the unpacked content to the constructor *z.getinfo(COMPILED_APP_CODE).date_time ) manifest_items = manifest_tag[0].attributes # use the namespace to ignore wrong prefixes like "ns0" version_name = manifest_items.getNamedItemNS(MANIFEST_NS, MANIFEST_VERSION_NAME).nodeValue package = manifest_items.getNamedItem(MANIFEST_PACKAGE).nodeValue return FastApk(package, version_name, path = apk_file_path, _hash = _hash, size_app_code = size_app_code, build_date = build_date) raise CouldNotOpenManifest(apk_file_path), None, sys.exc_info()[2] except Exception as e: raise CouldNotOpenApk(apk_file_path, caused_by = e), None, sys.exc_info()[2] finally: # close file if manually opened from path if file_open_from_path: flo.close()
def androguard_load_from_io(file_like_object=None, apk_file_path=None, calculate_hash=True): ''' Load a FastApk from file-like object or path by using `androgaurd`. Parameters ---------- file_like_object : file-like-object, optional (default is None) A file-like obj that points to the apk. If non given, try to open a file_like_object from the given `apk_file_path`. apk_file_path: str, optional (default is "not set") Path of apk calculate_hash : bool If true calculate the hash. This means the file has be to loaded completely into memory. If False, the hash will be calculated the first time it gets retrieved. Returns ------- apk: FastApk Raises ------ CouldNotOpenApk If the apk file could not be opened ''' # prevent circular import from androlyze.analyze import AnalyzeUtil # apk will be loaded from `flo` variable flo = file_like_object # indicates if file has been opened from path file_open_from_path = False # no file_like_object given, open file from path if file_like_object is None and isinstance(apk_file_path, str): try: flo = open(apk_file_path, "rb") file_open_from_path = True except IOError as e: flo.close() raise CouldNotOpenApk(apk_file_path, e), None, sys.exc_info()[2] # if file path not set, show at least that it's not seen in the exceptions if apk_file_path is None: apk_file_path = "not set" # load apk into memory and calculate hash if option set flo.seek(0) _hash = None data = flo.read() if calculate_hash: # calculate hash _hash = Util.sha256(data) flo.seek(0) apk = AnalyzeUtil.open_apk(data, raw=True, path=apk_file_path) if file_open_from_path: flo.close() if apk is not None: try: return FastApk.load_from_eandroapk(apk) except KeyError: pass # could not open apk -> raise error raise CouldNotOpenApk(file_path=apk_file_path)
def androguard_load_from_io(file_like_object = None, apk_file_path = None, calculate_hash = True): ''' Load a FastApk from file-like object or path by using `androgaurd`. Parameters ---------- file_like_object : file-like-object, optional (default is None) A file-like obj that points to the apk. If non given, try to open a file_like_object from the given `apk_file_path`. apk_file_path: str, optional (default is "not set") Path of apk calculate_hash : bool If true calculate the hash. This means the file has be to loaded completely into memory. If False, the hash will be calculated the first time it gets retrieved. Returns ------- apk: FastApk Raises ------ CouldNotOpenApk If the apk file could not be opened ''' # prevent circular import from androlyze.analyze import AnalyzeUtil # apk will be loaded from `flo` variable flo = file_like_object # indicates if file has been opened from path file_open_from_path = False # no file_like_object given, open file from path if file_like_object is None and isinstance(apk_file_path, str): try: flo = open(apk_file_path, "rb") file_open_from_path = True except IOError as e: flo.close() raise CouldNotOpenApk(apk_file_path, e), None, sys.exc_info()[2] # if file path not set, show at least that it's not seen in the exceptions if apk_file_path is None: apk_file_path = "not set" # load apk into memory and calculate hash if option set flo.seek(0) _hash = None data = flo.read() if calculate_hash: # calculate hash _hash = Util.sha256(data) flo.seek(0) apk = AnalyzeUtil.open_apk(data, raw = True, path = apk_file_path) if file_open_from_path: flo.close() if apk is not None: try: return FastApk.load_from_eandroapk(apk) except KeyError: pass # could not open apk -> raise error raise CouldNotOpenApk(file_path = apk_file_path)