def disassemble_apks(malware_samples, work_dir, proc_number=6, verbose=True): """ disassemble apks :param malware_samples: list of malware sample paths :param work_dir: directory for conducting disassembly :param verbose: print the info on the shell :return: True if perform does successfully, False if not """ pool = multiprocessing.Pool(int(proc_number)) pbar = progressbar_wrapper.ProgressBar() process_results = [] for i, path in enumerate(malware_samples): src = path dst = os.path.join(work_dir, os.path.splitext(os.path.basename(path))[0]) if os.path.exists(dst): shutil.rmtree(dst) process_results = pool.apply_async( _disassemble_apk, args=[src, dst, verbose], callback=pbar.CallbackForProgressBar) pool.close() if process_results: pbar.DisplayProgressBar(process_results, len(malware_samples), type='hour') pool.join() for file_name, res in pbar.TotalResults: sys.stdout.write("Disassemble: " + file_name + " result: {0}.\n".format(res)) return 0
def GetApkData(ApkFileList, saveDir, ProcessNumber=4): ''' Get Apk data dictionary for all Apk files under ApkDirectoryPath and store them in ApkDirectoryPath Used for next step's classification :param list ApkDirectoryPaths: absolute path of the directories contained Apk files ''' if len(ApkFileList) <= 0: return ''' Change current working directory to import the mapping ''' PMap = AxplorerMapping() pool = multiprocessing.Pool(int(ProcessNumber)) ProcessingResults = [] ScheduledTasks = [] ProgressBar = progressbar_wrapper.ProgressBar() if not os.path.exists(saveDir): os.mkdir(saveDir) for i, ApkFile in enumerate(ApkFileList): if not os.path.exists(os.path.join(saveDir, os.path.splitext(os.path.basename(ApkFile))[0] + ".data")): # ProcessingDataForGetApkData(ApkDirectoryPath, ApkFile, PMap) ApkDirectoryPath = os.path.split(ApkFile)[0] ScheduledTasks.append(ApkFile) ProcessingResults = pool.apply_async(ProcessingDataForGetApkData, args=(ApkDirectoryPath, ApkFile, PMap, saveDir), callback=ProgressBar.CallbackForProgressBar) pool.close() if (ProcessingResults): ProgressBar.DisplayProgressBar(ProcessingResults, len(ScheduledTasks), type="hour") pool.join() return
def modify_disassembly(pristine_apk_paths, decomp_file_dir, meta_instrs, proc_number=6, verbose=True): """ modify the apk's disassembly according to the corresponding meta_instrs :param pristine_apk_paths: pristine apk paths :param decomp_file_dir: the corresponding disassembled folder named by the apk name :param meta_instrs: the corresponding instructions for modification :param save_dir: directory for saving the adversarial apks :param verbose: print the details :return: True if this method performs thoroughly, otherwise False """ pool = multiprocessing.Pool(int(proc_number)) # unparallel # for i, apk_path in enumerate(pristine_apk_paths): # _morpher_wrapper([apk_path, decomp_file_dir, meta_instrs[i], verbose]) processing_results = [] processing_result = None scheduled_tasks = [] progrss_bar = progressbar_wrapper.ProgressBar() for i, apk_path in enumerate(pristine_apk_paths): scheduled_tasks.append(apk_path) processing_result = pool.apply_async( _morpher, args=(apk_path, decomp_file_dir, meta_instrs[i], verbose), callback=progrss_bar.CallbackForProgressBar) processing_results.append(processing_result) pool.close() if (processing_result): progrss_bar.DisplayProgressBar(processing_result, len(scheduled_tasks), type='hour') for i, res in enumerate(processing_results): if res is None: continue _flag, invalid_instructions = res.get() if _flag: print("Modifications are done") if len(invalid_instructions) > 0: logger.warning("Not all instructons are performed.\n") logger.info("\t" + '\n'.join(invalid_instructions) + '\n') else: print("Modify disassembly files failed.") pool.join() # good for getting exceptions return True