def main(instrumented_app_dir): """ Test one apk :param instrumented_app_dir: The instrumentation folder of the app | apk file path for closed-source app """ host_system = platform.system() if host_system == "Darwin": print "Running on Mac OS" settings.TIMEOUT_CMD = "gtimeout" elif host_system == "Linux": print "Running on Linux" else: print "Runnning on unknown OS" package_name, apk_path = get_package_name(instrumented_app_dir) # for css subjects if instrumented_app_dir.endswith(".apk"): instrumented_app_dir += "_output" os.system("mkdir " + instrumented_app_dir) print "### Working on apk:", package_name # get emulator device print "Preparing devices ..." emulator.boot_devices() emulator.prepare_motifcore() emulator.clean_sdcard() # log the devices devices = emulator.get_devices() # static analysis if settings.ENABLE_STRING_SEEDING: output_dir = None if instrumented_app_dir.endswith(".apk_output"): output_dir = instrumented_app_dir else: output_dir = instrumented_app_dir + "/bin" static_analyser.decode_apk(apk_path, output_dir) # will use dummy 0 if disabled for device in devices: decoded_dir = None if instrumented_app_dir.endswith(".apk_output"): decoded_dir = instrumented_app_dir + "/" + apk_path.split("/")[-1].split(".apk")[0] else: decoded_dir = instrumented_app_dir + "/bin/" + apk_path.split("/")[-1].split(".apk")[0] static_analyser.upload_string_xml(device, decoded_dir, package_name) os.system("adb -s " + device + " shell rm /mnt/sdcard/bugreport.crash") os.system("adb -s " + device + " uninstall " + package_name) os.system("adb -s " + device + " install " + apk_path) # intermediate should be in app folder os.system("rm -rf " + instrumented_app_dir + "/intermediate") os.system("mkdir " + instrumented_app_dir + "/intermediate") os.system("rm -rf " + instrumented_app_dir + "/crashes") os.system("mkdir " + instrumented_app_dir + "/crashes") os.system("rm -rf " + instrumented_app_dir + "/coverages") os.system("mkdir " + instrumented_app_dir + "/coverages") # generate initial population print "### Initialising population ...." population = toolbox.population(n=settings.POPULATION_SIZE, apk_dir=instrumented_app_dir, package_name=package_name) print "### Individual Lengths: " for indi in population: for seq in indi: print len(seq), print "" history.update(population) # hof = tools.HallOfFame(6) # pareto front can be large, there is a similarity option parameter hof = tools.ParetoFront() stats = tools.Statistics(lambda ind: ind.fitness.values) # axis = 0, the numpy.mean will return an array of results stats.register("avg", numpy.mean, axis=0) stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) stats.register("pop_fitness", return_as_is) # evolve print "\n\n\n### Start to Evolve" population, logbook = eaMuPlusLambdaParallel.evolve(population, toolbox, settings.POPULATION_SIZE, settings.OFFSPRING_SIZE, cxpb=settings.CXPB, mutpb=settings.MUTPB, ngen=settings.GENERATION, apk_dir=instrumented_app_dir, package_name=package_name, stats=stats, halloffame=hof, verbose=True) # persistent logbook_file = open(instrumented_app_dir + "/intermediate/logbook.pickle", 'wb') pickle.dump(logbook, logbook_file) logbook_file.close() hof_file = open(instrumented_app_dir + "/intermediate/hof.pickle", 'wb') pickle.dump(hof, hof_file) hof_file.close() history_file = open(instrumented_app_dir + "/intermediate/history.pickle", 'wb') pickle.dump(history, history_file) history_file.close() # draw graph two_d_line.plot(logbook, 0, instrumented_app_dir) two_d_line.plot(logbook, 1, instrumented_app_dir) two_d_line.plot(logbook, 2, instrumented_app_dir)
def main(instrumented_app_dir): """ Test one apk :param instrumented_app_dir: The instrumentation folder of the app | apk file path for closed-source app """ host_system = platform.system() if host_system == "Darwin": print "Running on Mac OS" settings.TIMEOUT_CMD = "gtimeout" elif host_system == "Linux": print "Running on Linux" else: print "Runnning on unknown OS" package_name, apk_path = get_package_name(instrumented_app_dir) # check if an interrupted run available if settings.IGNORE_INTERRUPTED_RUNS: resume = False else: interrupted_output_dir = find_interrupted_run(instrumented_app_dir) resume = interrupted_output_dir is not None if not resume: # for css subjects if instrumented_app_dir.endswith(".apk"): instrumented_app_dir += "_output" i = 1 tmp = instrumented_app_dir # avoid deleting output folder while os.path.isdir(tmp): tmp = instrumented_app_dir + "_" + str(i) i += 1 instrumented_app_dir = tmp os.system("mkdir " + instrumented_app_dir) else: instrumented_app_dir = interrupted_output_dir print "### Working on apk:", package_name # get emulator device print "Preparing devices ..." if settings.USE_REAL_DEVICE: real_device.adb_root() # real_device.prepare_motifcore() devices = real_device.get_devices() else: # emulator.boot_genymotion_devices() emulator.boot_devices(wipe_data=True) emulator.prepare_motifcore() emulator.clean_sdcard() # log the devices devices = emulator.get_devices() # static analysis if settings.ENABLE_STRING_SEEDING: if ".apk_output" in instrumented_app_dir: output_dir = instrumented_app_dir else: output_dir = instrumented_app_dir + "/bin" static_analyser.decode_apk(apk_path, output_dir) # will use dummy 0 if disabled for device in devices: if ".apk_output" in instrumented_app_dir: decoded_dir = instrumented_app_dir + "/" + apk_path.split("/")[-1].split(".apk")[0] else: decoded_dir = instrumented_app_dir + "/bin/" + apk_path.split("/")[-1].split(".apk")[0] static_analyser.upload_string_xml(device, decoded_dir, package_name) os.system("adb -s " + device + " shell rm /mnt/sdcard/bugreport.crash") # os.system("adb -s " + device + " uninstall " + package_name) os.system("adb -s " + device + " install " + apk_path) stats = tools.Statistics(lambda ind: ind.fitness.values) # axis = 0, the numpy.mean will return an array of results stats.register("avg", numpy.mean, axis=0) stats.register("std", numpy.std, axis=0) stats.register("min", numpy.min, axis=0) stats.register("max", numpy.max, axis=0) stats.register("pop_fitness", return_as_is) # facebook_login(devices, package_name) if not resume: # intermediate should be in app folder os.system("rm -rf " + instrumented_app_dir + "/intermediate") os.system("mkdir " + instrumented_app_dir + "/intermediate") os.system("rm -rf " + instrumented_app_dir + "/crashes") os.system("mkdir " + instrumented_app_dir + "/crashes") os.system("rm -rf " + instrumented_app_dir + "/coverages") os.system("mkdir " + instrumented_app_dir + "/coverages") # generate initial population print "### Initialising population ...." n = settings.POPULATION_SIZE if settings.DIVERSE_INITIAL_POP: n = n * 2 population = toolbox.population(n=n, apk_dir=instrumented_app_dir, package_name=package_name) if settings.DIVERSE_INITIAL_POP: population = select_most_diverse(population, settings.POPULATION_SIZE) print "### Individual Lengths: " for indi in population: for seq in indi: print len(seq), print "" history.update(population) # hof = tools.HallOfFame(6) # pareto front can be large, there is a similarity option parameter hof = tools.ParetoFront() logbook = tools.Logbook() logbook.header = ['gen', 'nevals'] + ( stats.fields if stats else []) else: logbook, population, hof = eaMuPlusLambdaParallel.load_files(instrumented_app_dir) # evolve print "\n\n\n### Start to Evolve" population, logbook = eaMuPlusLambdaParallel.evolve(logbook, population, toolbox, settings.POPULATION_SIZE, settings.OFFSPRING_SIZE, cxpb=settings.CXPB, mutpb=settings.MUTPB, ngen=settings.GENERATION, apk_dir=instrumented_app_dir, package_name=package_name, stats=stats, halloffame=hof, verbose=True, resume=resume) # persistent logbook_file = open(instrumented_app_dir + "/intermediate/logbook.pickle", 'wb') pickle.dump(logbook, logbook_file) logbook_file.close() hof_file = open(instrumented_app_dir + "/intermediate/hof.pickle", 'wb') pickle.dump(hof, hof_file) hof_file.close() history_file = open(instrumented_app_dir + "/intermediate/history.pickle", 'wb') pickle.dump(history, history_file) history_file.close() draw_graphs(logbook, instrumented_app_dir) # draw history network # history_network.plot(history, instrumented_app_dir) # emulator.shutdown_genymotion_devices() emulator.destroy_devices() os.system( 'cd ' + instrumented_app_dir + '/intermediate && pdfunite obj_0.pdf obj_1.pdf obj_2.pdf hv_standard.pdf proportion_pareto_optimal.pdf population_diameter.pdf rel_diameter.pdf population_diversity.pdf pconnec.pdf sing.pdf hvconnec.pdf avgconnec.pdf nconnec.pdf lconnec.pdf kconnec.pdf summary.pdf')
def evolve(logbook, population, toolbox, mu, lambda_, cxpb, mutpb, ngen, apk_dir, package_name, stats=None, halloffame=None, verbose=__debug__, resume=False): start_gen = 0 if not resume: # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in population if not ind.fitness.valid] # fitnesses = toolbox.map(toolbox.evaluate, invalid_ind) # for ind, fit in zip(invalid_ind, fitnesses): # ind.fitness.values = fit evaluate_in_parallel(toolbox.evaluate, invalid_ind, apk_dir, package_name, 0) # discard invalid population individual for i in range(len(population) - 1, -1, -1): if not population[i].fitness.valid: del population[i] record = stats.compile(population) if stats is not None else {} if halloffame is not None: halloffame.update(population) record['hof_size'] = len(halloffame) # run metric algorithms record = calc_metrics(toolbox, population, record) logbook.record(gen=0, nevals=len(invalid_ind), **record) if verbose: print logbook.stream save_files(logbook, population, halloffame, apk_dir) else: start_gen = logbook.select('gen')[-1] print 'Resuming at generation ' + str(start_gen + 1) # Begin the generational process for gen in range(start_gen + 1, ngen + 1): apply_diversity_action = settings.RE_RANDOMIZE and low_diversity(logbook) if apply_diversity_action: offspring = toolbox.population(n=settings.OFFSPRING_SIZE, apk_dir=apk_dir, package_name=package_name) else: offspring = varOr(population, toolbox, lambda_, cxpb, mutpb) # Evaluate the individuals with an invalid fitness invalid_ind = [ind for ind in offspring if not ind.fitness.valid] # check memory usage, reboot if needed if psutil.virtual_memory().percent > 90: emulator.destroy_devices() time.sleep(2) emulator.boot_devices() # this function will eval and match each invalid_ind to its fitness # fitness is invalid if it contains no values evaluate_in_parallel(toolbox.evaluate, invalid_ind, apk_dir, package_name, gen) if settings.DEBUG: for indi in invalid_ind: print indi.fitness.values # discard invalid offspring individual for i in range(len(offspring) - 1, -1, -1): if not offspring[i].fitness.valid: print "### Warning: Invalid Fitness" del offspring[i] # Update the hall of fame with the generated individuals print "### Updating Hall of Fame ..." if halloffame is not None: halloffame.update(offspring) len(halloffame) # assert fitness invalid_ind_post = [ind for ind in population + offspring if not ind.fitness.valid] print "### assert len(invalid_ind) == 0, len = ", len(invalid_ind_post) assert len(invalid_ind_post) == 0 # Select the next generation population if apply_diversity_action: population[:] = toolbox.select_most_diverse(population + offspring, mu) elif settings.INCLUDE_MOST_DIVERSE: pareto_front = toolbox.select(population + offspring, mu) most_diverse = toolbox.select_most_diverse(population + offspring, mu) diff = [] selected = [] diff.extend(x for x in most_diverse if x not in pareto_front) for i, ind in enumerate(diff): if i < mu * settings.PROPORTION_DIVERSE_IND: selected.append(ind) while len(selected) < mu: selected.append(pareto_front.pop(0)) population[:] = selected else: population[:] = toolbox.select(population + offspring, mu) # Update the statistics with the new population record = stats.compile(population) if stats is not None else {} # run metric algorithms record = calc_metrics(toolbox, population, record) record['hv_hof'] = ndm.hypervolume(halloffame.items) record['hv_size'] = len(halloffame) logbook.record(gen=gen, nevals=len(invalid_ind), **record) if verbose: print logbook.stream # in case interrupted save_files(logbook, population, halloffame, apk_dir) return population, logbook