def get_apk(self, _hash, **kwargs): ''' Get the `EAndroApk` from `_hash`. Parameters ---------- _hash : str Hash of the .apk (sha256) Raises ------ DatabaseLoadException NoFile If the file is not present. Returns ------- EAndroApk Apk constructed from raw data and meta infos. ''' try: gridfs = self.__apk_coll log.info("getting apk: %s from mongodb ...", _hash) gridfs_obj = gridfs.get(_hash) # get raw .apk apk_zipfile = gridfs_obj.read() # get apk meta infos apk_meta = gridfs_obj.metadata package_name, version_name, path, _hash, import_date, tag = apk_meta[RESOBJ_APK_META_PACKAGE_NAME], apk_meta[RESOBJ_APK_META_VERSION_NAME], apk_meta[RESOBJ_APK_META_PATH], apk_meta[RESOBJ_APK_META_HASH], apk_meta[RESOBJ_APK_META_IMPORT_DATE], apk_meta[RESOBJ_APK_META_TAG] # use to hold apk meta infos fast_apk = FastApk(package_name, version_name, path, _hash, import_date, tag) eandro_apk = AnalyzeUtil.open_apk(apk_zipfile, fast_apk, raw = True) log.info("got apk") return eandro_apk except NoFile: raise except PyMongoError as e: raise DatabaseLoadException(self, content = "Apk (hash=%s)" % _hash, caused_by = e), None, sys.exc_info()[2]
def get_imported_apks(self, hashes=None, package_names=None, tags=None, **kwargs): order_by = kwargs.get('order_by', TABLE_APK_IMPORT_KEY_PACKAGE_NAME) # prevent sql injection if not order_by in TABLE_APK_IMPORT_KEYS: raise ValueError("Sort key has to be in %s, is: %s" % (TABLE_APK_IMPORT_KEYS, order_by)) ascending = kwargs.get("ascending", True) sort_direction = 'ASC' if ascending else 'DESC' try: SQL_STMT = 'SELECT * FROM %s ' % TABLE_APK_IMPORT # create temporary database to store many values and have them later in the IN clause available with self.conn as _conn: c = _conn.cursor() c.execute("DROP TABLE IF EXISTS data_helper") c.execute("CREATE TEMPORARY TABLE data_helper (value TEXT)") INSERT_HELPER_STMT = "INSERT INTO data_helper VALUES (?)" DYN_IN_STMT = 'WHERE %s IN (SELECT * FROM data_helper)' args = () if hashes is not None: args = tuple(hashes) SQL_STMT += DYN_IN_STMT % TABLE_APK_IMPORT_KEY_HASH elif package_names is not None: args = tuple(package_names) SQL_STMT += DYN_IN_STMT % TABLE_APK_IMPORT_KEY_PACKAGE_NAME elif tags is not None: args = tuple(tags) SQL_STMT += DYN_IN_STMT % TABLE_APK_IMPORT_KEY_TAG # insert values into temporary table but only if `hashes` or `package_names` has been supplied # otherwise return all apks if args: # executemany needs iterable<tuple> INSERT_ARGS = ((a, ) for a in args) c.executemany(INSERT_HELPER_STMT, INSERT_ARGS) # sort by package names and version SQL_STMT += ' ORDER BY %s COLLATE NOCASE %s, %s' % ( order_by, sort_direction, TABLE_APK_IMPORT_KEY_PACKAGE_NAME) # get apks c = self.conn.cursor().execute(SQL_STMT) # treat cursor as iterator for apk_dict in c: yield FastApk( apk_dict[TABLE_APK_IMPORT_KEY_PACKAGE_NAME], apk_dict[TABLE_APK_IMPORT_KEY_VERSION_NAME], path=apk_dict[TABLE_APK_IMPORT_KEY_PATH], _hash=apk_dict[TABLE_APK_IMPORT_KEY_HASH], import_date=apk_dict[TABLE_APK_IMPORT_KEY_IMPORT_DATE], tag=apk_dict[TABLE_APK_IMPORT_KEY_TAG], size_app_code=apk_dict[TABLE_APK_IMPORT_KEY_SIZE_APP_CODE], build_date=apk_dict.get(TABLE_APK_IMPORT_KEY_BUILD_DATE)) except (sqlite3.Error, KeyError) as e: data = "all apks" if hashes is not None: data = ', '.join(hashes) elif package_names is not None: data = ', '.join(package_names) raise ImportQueryError(DatabaseLoadException( self, data, e)), None, sys.exc_info()[2]
''' if key in res_dict or register_key: func(res_dict, key, value) else: raise KeyNotRegisteredError(key, *categories) if __name__ == '__main__': from androlyze.model.android.apk.FastApk import FastApk from datetime import datetime # we will link the `ResultObject` to an `Apk` to see it's meta information # but we don't need to link against any `Apk` ! apk = FastApk("com.foo.bar", "1.0", "/", "some hash", datetime.utcnow(), tag="exploitable") res = ResultObject(apk) res.register_bool_keys(["check1", "check2"]) # register enumeration keys res.register_enum_keys( ["activities", "content providers", "broadcast receivers", "services"], "components") # this shows how you can abstract categories, in this example into a tuple # the important point is that you need to unpack it with "*" ! ROOT_CAT = ("apkinfo", "listings") res.register_keys(["files"], *ROOT_CAT)