def _profile_libs(dex_files, jar_files, output_folder="profiles", processes=None, overwrite=False): # Convert jar file to dex file for f in jar_files: dex_file_path = path.join(path.dirname(f), path.basename(f)[:-4] + ".dex") if not path.exists(dex_file_path): LOGGER.info("Converting %s to %s ...", path.basename(f), path.basename(dex_file_path)) cmd = "{} -o {} {}".format(DEX2JAR_PATH, dex_file_path, f) try: subprocess.check_output(cmd, shell=True) LOGGER.info("Converted") dex_files.append(dex_file_path) except: LOGGER.error("Conversion failed") continue if dex_files: profiler.parallel_profiling_binaries(dex_files, output_folder, "lib", processes=processes, overwrite=overwrite)
def profile_binaries(base_path=None, file_paths=None, output_folder='profiles', processes=None, overwrite=False): """Profile app/library binaries to JSON files. Must provide either `base_path` or `file_paths`. Args: base_path (str, optional): Defaults to None. The folder that contains app/library binaries. file_paths (list, optional): Defaults to None. The list of app/library binaries. output_folder (str, optional): Defaults to 'profiles'. The folder to store profiles. processes (int, optional): Defaults to None. The number of processes to use. If processes is None then the number returned by cpu_count() is used. overwrite (bool, optional): Defaults to False. Should LibID overwrite the output file if it exists? """ apk_files = [] dex_files = [] jar_files = [] aar_files = [] if not file_paths: if base_path: apk_files = glob2.glob(path.join(base_path, "**/*.apk")) dex_files = glob2.glob(path.join(base_path, "**/*.dex")) jar_files = glob2.glob(path.join(base_path, "**/*.jar")) aar_files = glob2.glob(path.join(base_path, "**/*.aar")) else: LOGGER.error("No valid folder or file path provided.") else: for f in file_paths: if f[-4:] == '.apk': apk_files.append(f) elif f[-4:] == '.dex': dex_files.append(f) elif f[-4:] == '.jar': jar_files.append(f) elif f[-4:] == '.aar': aar_files.append(f) else: LOGGER.error("Invalid file format {}".format(f)) _profile_apps( apk_files, output_folder=output_folder, processes=processes, overwrite=overwrite) _profile_libs( dex_files, jar_files, aar_files, output_folder=output_folder, processes=processes, overwrite=overwrite)
def _profiling_binary(profiling_info): (file_path, output_dir, profile_type, overwrite) = profiling_info name = path.splitext(path.basename(file_path))[0] + ".json" json_file_path = path.join(output_dir, profile_type, name) if overwrite or not path.exists(json_file_path): try: analyzer = LibAnalyzer(file_path) json_info = analyzer.get_classes_signatures_json_info( ) if profile_type == "app" else analyzer.get_lib_classes_signatures_json_info( ) write_to_json(json_file_path, json_info) LOGGER.info("The binary profile is stored at %s", json_file_path) except Exception, e: LOGGER.error("error: %s", e) return file_path
json_file_path = path.join(output_dir, profile_type, name) if overwrite or not path.exists(json_file_path): try: analyzer = LibAnalyzer(file_path) json_info = analyzer.get_classes_signatures_json_info( ) if profile_type == "app" else analyzer.get_lib_classes_signatures_json_info( ) write_to_json(json_file_path, json_info) LOGGER.info("The binary profile is stored at %s", json_file_path) except Exception, e: LOGGER.error("error: %s", e) return file_path else: LOGGER.error("The %s profile (%s) already exists. Use -w to overwrite", profile_type, json_file_path) return file_path def parallel_profiling_binaries(paths, output_folder, profile_type, processes=1, overwrite=False): """Profiling Android app/library binaries to JSON files. Args: paths (list): The list of binaries. output_folder (str): The folder to store profiles. profile_type (str): Either 'app' or 'lib'. processes (int, optional): Defaults to 1. The number of processes to use.