def ape_task(avd_name, serial, package_name, output_dir, running_minutes, mt_is_running): sleep_cnt = 0 while mt_is_running.value == 0 and sleep_cnt < 30: time.sleep(1) sleep_cnt += 1 # Something wrong on mtserver, wait 30 seconds if sleep_cnt == 30: kill_mtserver(serial=serial) return print('ape_task(): Emulator[{}, {}] Running APE with package {}'.format( avd_name, serial, package_name)) args = '-p {} --running-minutes {} --mt --ape sata'.format( package_name, running_minutes) with open(os.path.join(output_dir, 'ape_stdout_stderr.txt'), 'wt') as f: ret = run_adb_cmd( 'shell CLASSPATH={} {} {} {} {}'.format( os.path.join(TMP_LOCATION, 'ape.jar'), '/system/bin/app_process', TMP_LOCATION, 'com.android.commands.monkey.Monkey', args), stdout_callback=lambda t: f.write(t + '\n'), stderr_callback=lambda t: f.write(t + '\n'), serial=serial, ) fetch_result(output_dir, serial)
def mt_task(package_name, serial, logging_flag, mt_is_running): def stdout_callback(line): if line.startswith('Server with uid'): mt_is_running.value += 1 print('Start mtserver...') run_adb_cmd('shell /data/local/tmp/mtserver server {} {}' \ .format(package_name, logging_flag), stdout_callback = stdout_callback, stderr_callback = stdout_callback, serial=serial) kill_mtserver(serial)
def run_ape_with_mt(apk_path, avd_name, libart_path, ape_jar_path, mtserver_path, ape_output_folder, mt_output_folder, running_minutes, force_clear): package_name = get_package_name(apk_path) print('run_ape_with_mt(): given apk_path {} avd_name {}'.format( apk_path, avd_name)) assert os.path.split(libart_path)[1] == 'libart.so' assert os.path.split(mtserver_path)[1] == 'mtserver' assert os.path.split(ape_jar_path)[1] == 'ape.jar' avd = install_art_ape_mt(avd_name, libart_path, ape_jar_path, mtserver_path, force_clear) try: install_package(apk_path, serial=avd.serial) except RuntimeError as e: print(e) return True kill_mtserver(serial=avd.serial) mt_is_running = Value('i', 0) mtserver_thread = threading.Thread(target=mt_task, args=(package_name, mt_output_folder, avd.serial, "20010107", mt_is_running)) apetask_thread = threading.Thread(target=ape_task, args=(avd_name, avd.serial, package_name, ape_output_folder, running_minutes, mt_is_running)) set_multiprocessing_mode() generate_catcher_thread(os.path.join(mt_output_folder, "logcat.txt"), serial=avd.serial) mtserver_thread.start() apetask_thread.start() apetask_thread.join() kill_mtserver(serial=avd.serial) mtserver_thread.join() kill_generated_logcat_processes() unset_multiprocessing_mode() if mt_is_running.value == 0: # It failed to run ape/mt print('run_ape_with_mt(): failed to run') return False return True
def ape_task(avd_name, serial, package_name, output_dir, running_minutes, mt_is_running, mtdtarget, no_guide): sleep_cnt = 0 while mt_is_running.value == 0 and sleep_cnt < 30: time.sleep(1) sleep_cnt += 1 # Something wrong on mtserver, wait 30 seconds if sleep_cnt == 30: kill_mtserver(serial=serial) return assert mtdtarget mt_data_dir = os.path.join(output_dir, 'mt_data') if not os.path.isdir(mt_data_dir): os.makedirs(mt_data_dir) if not os.path.isdir(output_dir): os.makedirs(output_dir) def ape_stdout_callback(line): f.write(line + '\n') if line.startswith("[APE_MT] mt data "): directory = line[len("[APE_MT] mt data "):] run_adb_cmd("pull {} {}".format(directory, mt_data_dir), serial=serial) print("callback: {} pulled into {}".format(directory, mt_data_dir)) run_adb_cmd("shell rm -rf {}".format(directory), serial=serial) run_adb_cmd("push {} {}".format(mtdtarget_fname, mtdtarget_destname), serial=serial) print('ape_task(): Emulator[{}, {}] Running APE with package {}'.format(avd_name, serial, package_name)) args = '-p {} --running-minutes {} --mt --mtdtarget {} {}--ape sata'.format(package_name, running_minutes, mtdtarget_destname, "--no-mtdguide " if no_guide else "") with open(os.path.join(output_dir, 'ape_stdout_stderr.txt'), 'wt') as f: ret = run_adb_cmd('shell CLASSPATH={} {} {} {} {}'.format( os.path.join(TMP_LOCATION, 'ape.jar'), '/system/bin/app_process', TMP_LOCATION, 'com.android.commands.monkey.Monkey', args), stdout_callback = ape_stdout_callback, stderr_callback = lambda t:f.write(t + '\n'), serial = serial, ) # pull ape results try: run_adb_cmd('shell rmdir /data/ape/mt_data', serial=serial) except RunCmdError as e: print(e.message, file=sys.stderr) ret = run_adb_cmd('pull /data/ape {}'.format(output_dir), serial=serial)
def mt_task(package_name, output_folder, serial, logging_flag, mt_is_running): connections = ConnectionsWithValue(package_name, serial, output_folder, mt_is_running) try: print('Start mtserver...') out = run_adb_cmd('shell /data/local/tmp/mtserver server {} {}' \ .format(package_name, logging_flag), stdout_callback = connections.stdout_callback, stderr_callback = connections.stderr_callback, serial=serial) except WrongConnectionState: print('CONNECTION: WrongConnectionState. Check follow log...') for line in connections.log: print(line) kill_mtserver(serial) except KeyboardInterrupt: connections.clean_up("KeyboardInterrupt") raise except Exception as e: connections.clean_up("Exception " + repr(e)) raise connections.clean_up("Normal")
def run_ape_with_mt(apk_path, avd_name, libart_path, ape_path, mtserver_path, output_dir, running_minutes, force_clear, methods, target_all_thread, methodGuide=True): package_name = get_package_name(apk_path) print('run_ape_with_mt(): given apk_path {} avd_name {}'.format( apk_path, avd_name)) assert os.path.split(libart_path)[1] == 'libart.so' assert os.path.split(mtserver_path)[1] == 'mtserver' assert os.path.split(ape_path)[1] == 'ape.jar' avd = install_art_ape_mt(avd_name, libart_path, ape_path, mtserver_path, force_clear) try: install_package(apk_path, serial=avd.serial) except RuntimeError as e: print(e) return "install" mtdtarget_fname = 'mtdtarget.txt' mtdtarget_emulpath = '/data/local/tmp/mtdtarget.txt' with open(mtdtarget_fname, 'wt') as f: for clsname, mtdname, signature in methods: f.write("%s\t%s\t%s\t1\n" % (clsname, mtdname, signature)) # 1: method enter run_adb_cmd("push {} {}".format(mtdtarget_fname, mtdtarget_emulpath), serial=avd.serial) kill_mtserver(serial=avd.serial) mt_is_running = Value('i', 0) mtserver_thread = threading.Thread(target=mt_task, args=(package_name, avd.serial, "00010180", mt_is_running)) apetask_thread = threading.Thread(target=ape_task, args=(avd_name, avd.serial, package_name, output_dir, running_minutes, mt_is_running, mtdtarget_emulpath, target_all_thread, methodGuide)) set_multiprocessing_mode() generate_catcher_thread(os.path.join(output_dir, "logcat.txt"), serial=avd.serial) mtserver_thread.start() apetask_thread.start() apetask_thread.join() kill_mtserver(serial=avd.serial) mtserver_thread.join() kill_generated_logcat_processes() unset_multiprocessing_mode() if mt_is_running.value == 0: # It failed to run ape/mt print('run_ape_with_mt(): failed to run') return "rerun" # feedback # 1. method is not found, then stop experiment this (apk, targeting methods) # 2. method is not called methods_registered_over_exp = [] # list of registered methods for each run logs = [] try: with open(os.path.join(output_dir, "logcat.txt"), 'rt') as f: cur_methods_registered = None lazy_methods = [] for line in f: ''' MiniTrace: TargetMethod %s:%s[%s] lazy MiniTrace: TargetMethod %s:%s[%s] registered MiniTrace: TargetMethod %s:%s[%s] registered lazily ''' if 'MiniTrace' not in line: continue line = line.rstrip() line = line[line.index('MiniTrace'):] if line.startswith("MiniTrace: connection success, received"): lazy_methods = [] if cur_methods_registered is not None: methods_registered_over_exp.append( cur_methods_registered) cur_methods_registered = [] logs.append(line) continue gp = re.match( r'MiniTrace: TargetMethod (.*):(.*)\[(.*)\] ([a-z ]+)', line) if gp: logs.append(line) clsname, mtdname, signature, status = gp.groups() if status == 'lazy': assert (clsname, mtdname, signature) in methods, (clsname, mtdname, signature, methods) lazy_methods.append((clsname, mtdname, signature)) elif status == 'registered': assert (clsname, mtdname, signature) in methods, (clsname, mtdname, signature, methods) cur_methods_registered.append( methods.index((clsname, mtdname, signature))) else: assert status == 'registered lazily', status assert clsname[0] == 'L' and clsname[-1] == ';', clsname clsname = clsname[1:-1] assert (clsname, mtdname, signature) in lazy_methods, (clsname, mtdname, signature, lazy_methods) cur_methods_registered.append( methods.index((clsname, mtdname, signature))) if cur_methods_registered is not None: methods_registered_over_exp.append(cur_methods_registered) except AssertionError as e: print("run_ape_with_mt(): Feedback - failed to register methods") print(methods_registered_over_exp) print('\n'.join(logs)) print(e) traceback.print_exc() return "unregistered" if all(executed == [] for executed in methods_registered_over_exp): print("run_ape_with_mt(): Feedback - failed to register any methods") return "unregistered" print('run_ape_with_mt(): methods registered...') print(methods_registered_over_exp) if not methodGuide: return "success" # 2. method is not called with open(os.path.join(output_dir, 'ape_stdout_stderr.txt'), 'rt') as logf: for line in logf: line = line.rstrip() if "met target" in line: return "success" return "notsearched"