コード例 #1
0
def install_ape_and_make_snapshot(avd_name, force_snapshot=False):
    avd_list = get_avd_list()
    avd = next(avd for avd in avd_list if avd.name == avd_name)

    if avd.running:
        if not force_snapshot and APE_READY_SS in list_snapshots(
                serial=avd.serial):
            load_snapshot(APE_READY_SS, serial=avd.serial)
            return avd
        serial = avd.serial
    else:
        serial = emulator_run_and_wait(avd_name, snapshot=APE_READY_SS)

    if force_snapshot or APE_READY_SS not in list_snapshots(serial=serial):
        print(
            'No saved snapshot on the device, rebooting and making snapshot...'
        )
        kill_emulator(serial=serial)
        time.sleep(3)
        serial = emulator_run_and_wait(avd_name, wipe_data=True)
        print('Setup emulator...')
        emulator_setup(serial=serial)
        run_adb_cmd('push ape.jar {}'.format(APE_ROOT), serial=serial)
        save_snapshot(APE_READY_SS, serial=serial)
    avd.setRunning(serial)
    return avd
コード例 #2
0
 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)
         run_adb_cmd("shell rm -rf {}".format(directory), serial=serial)
コード例 #3
0
def fetch_result(output_dir, serial):
    ret = run_adb_cmd('shell ls /sdcard/', serial=serial)
    folders = []
    for line in ret.split('\n'):
        if line.startswith('sata-'):
            folders.append('/sdcard/{}'.format(line.rstrip()))
    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)
    for folder in folders:
        run_adb_cmd('pull {} {}'.format(folder, output_dir), serial=serial)
コード例 #4
0
def start_catcher(output_fname, serial = None):
    run_adb_cmd("logcat -c", serial = serial)

    with open(output_fname, 'wt') as f:
        try:
            run_adb_cmd("logcat art:I AndroidRuntime:E CrashAnrDetector:D ActivityManager:E SQLiteDatabase:E WindowManager:E ActivityThread:E Parcel:E *:F *:S",
                serial = serial,
                stdout_callback = lambda t:f.write("O: " + t + '\n'),
                stderr_callback = lambda t:f.write("E: " + t + '\n'))
        except RunCmdError as e:
            pass
コード例 #5
0
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)
コード例 #6
0
    def release_file(self, socketfd, fname):
        # This part could be called with gentle termination of the app (not SIGKILL)
        if socketfd not in self.connections:
            raise WrongConnectionState
        state, data = self.connections[socketfd]

        if state != STATE_RUNNING:
            raise WrongConnectionState

        print("{} release file {}".format(TAG, fname))
        run_adb_cmd("pull {} {}".format(fname, self.output_folder),
                serial=self.serial)
        run_adb_cmd("shell rm {}".format(fname),
                serial=self.serial)
コード例 #7
0
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)
コード例 #8
0
def run_mtserver(package_name, output_folder, serial=None):
    connections = Connections(package_name, serial, output_folder)

    kill_mtserver(serial)
    try:
        print('{} Start mtserver...'.format(TAG))
        out = run_adb_cmd('shell /data/local/tmp/mtserver server {}'  \
                .format(package_name),
            stdout_callback = connections.stdout_callback,
            stderr_callback = connections.stderr_callback,
            serial=serial)
    except WrongConnectionState:
        print('{} WrongConnectionState. Check follow log...'.format(TAG))
        for line in connections.log:
            print('{} {}'.format(TAG, line))

        kill_mtserver(serial)
    except KeyboardInterrupt:
        connections.clean_up('KeyboardInterrupt')
        raise
    except Exception as e:
        connections.clean_up('Exception {}'.format(e))
        raise

    connections.clean_up('Normal run_mtserver')
コード例 #9
0
def libart_check(libart_path, serial):
    # Check our target libart.so is installed
    # Since checking is done by its size, it may give wrong result.
    size1 = os.path.getsize(libart_path)
    output = run_adb_cmd("shell ls -l /system/lib/libart.so", serial=serial)
    size2 = int(output.split()[3])

    return size1 == size2
コード例 #10
0
def ape_task(avd_name, serial, package_name, output_dir, running_minutes,
             mt_is_running, mtdtarget_fname, target_all_thread, methodGuide):
    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

    mt_data_dir = os.path.join(output_dir, 'mt_data')
    if not os.path.isdir(mt_data_dir):
        os.makedirs(mt_data_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)
            run_adb_cmd("shell rm -rf {}".format(directory), serial=serial)

    print('ape_task(): Emulator[{}, {}] Running APE with package {}'.format(
        avd_name, serial, package_name))
    args = '-p {} --running-minutes {} --mt --mtdtarget {} --ape {} {}--countlim 2'.format(
        package_name, running_minutes, mtdtarget_fname,
        "target" if methodGuide else "sata",
        "--target-all-thread " if target_all_thread 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)
コード例 #11
0
    def close_connection(self, socketfd, prefix):
        if socketfd not in self.connections:
            raise WrongConnectionState

        state, data = self.connections[socketfd]
        if state == STATE_RUNNING:
            pid, prefix_ = data
            assert prefix == prefix_, (prefix, prefix_)

            prefix_local = os.path.join(self.output_folder, os.path.split(prefix)[1])

            # clean up given prefix
            print("{} close connection on {}".format(TAG, prefix_local))
            out = run_adb_cmd('shell ls {}*'.format(prefix),
                    serial=self.serial)
            if "No such file or directory" not in out:
                pulled_files = []
                for line in out.split():
                    if line == '':
                        break
                    fname = line.rstrip()
                    print("{} - pull and remove {}".format(TAG, fname))
                    try:
                        run_adb_cmd("pull {} {}".format(fname, self.output_folder),
                                serial=self.serial)
                        pulled_files.append(
                                os.path.join(self.output_folder,
                                os.path.split(fname)[1]))
                    except RunCmdError as e:
                        # @TODO How could it be happen?
                        print("{} - failed to pull and remove {}".format(TAG, fname), file=sys.stderr)
                        for file in pulled_files:
                            os.remove(file)
                        prefix_local = ""
                        break
                    run_adb_cmd("shell rm {}".format(fname),
                            serial=self.serial)
            del self.connections[socketfd]
            return prefix_local
        else:
            raise WrongConnectionState
コード例 #12
0
def run_ape(apk_path, avd_name, output_dir, running_minutes=1):
    package_name = get_package_name(apk_path)
    print('run_ape(): given apk_path {} avd_name {}'.format(
        apk_path, avd_name))
    avd = install_ape_and_make_snapshot(avd_name)
    try:
        install_package(apk_path, serial=avd.serial)
    except RuntimeError as e:
        print(e)
        return

    # run ape
    print('run_ape(): Emulator[{}, {}] Running APE with apk={}'.format(
        avd_name, avd.serial, apk_path))
    args = '-p {} --running-minutes {} --ape sata'.format(
        package_name, running_minutes)
    ret = run_adb_cmd('shell CLASSPATH={} {} {} {} {}'.format(
        os.path.join(APE_ROOT, 'ape.jar'), '/system/bin/app_process', APE_ROOT,
        'com.android.commands.monkey.Monkey', args),
                      serial=avd.serial)

    fetch_result(output_dir, avd.serial)
コード例 #13
0
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")
コード例 #14
0
def install_art_ape_mt(avd_name,
                       libart_path,
                       ape_jar_path,
                       mtserver_path,
                       force_clear=False):
    avd_list = get_avd_list()
    avd = next(avd for avd in avd_list if avd.name == avd_name)

    serial = None
    if not force_clear:  # use snapshot if it is possible
        if avd.running and ART_APE_MT_READY_SS in list_snapshots(
                serial=avd.serial):
            load_snapshot(ART_APE_MT_READY_SS, serial=avd.serial)
            time.sleep(3)
            assert libart_check(libart_path, serial=avd.serial)
            return avd
        serial = emulator_run_and_wait(avd_name,
                                       snapshot=ART_APE_MT_READY_SS,
                                       writable_system=True,
                                       ram_size_in_mb=4096,
                                       partition_size_in_mb=8192)

        if ART_APE_MT_READY_SS in list_snapshots(serial=serial):
            # now running
            avd.setRunning(serial)
            return avd
        print(
            "No saved snapshot on the device, rebooting and making snapshot..."
        )
        kill_emulator(serial=serial)
        time.sleep(3)
    elif avd.running:  # if force_clear, turn off running emulators
        kill_emulator(serial=avd.serial)
        time.sleep(3)

    serial = emulator_run_and_wait(avd_name,
                                   wipe_data=True,
                                   writable_system=True,
                                   ram_size_in_mb=4096,
                                   partition_size_in_mb=8192)

    print("Installing libart.so")
    run_adb_cmd("remount", serial=serial)
    run_adb_cmd("shell su root mount -o remount,rw /system", serial=serial)
    # run_adb_cmd("shell su root mount -o remount,rw rootfs /", serial=serial)
    # run_adb_cmd("shell su root chmod 777 /storage/sdcard", serial=serial)
    run_adb_cmd("push {} /sdcard/libart.so".format(libart_path), serial=serial)
    run_adb_cmd("shell su root mv /sdcard/libart.so /system/lib/libart.so",
                serial=serial)
    run_adb_cmd("shell su root chmod 644 /system/lib/libart.so", serial=serial)
    run_adb_cmd("shell su root chown root:root /system/lib/libart.so",
                serial=serial)
    run_adb_cmd("shell su root reboot", serial=serial)

    print("Wait for emulator")
    emulator_wait_for_boot(avd_name, r_fd=None, serial=serial)

    print("Setup emulator...")
    emulator_setup(serial=serial)

    print("Installing ape.jar")
    run_adb_cmd("push {} {}".format(ape_jar_path,
                                    os.path.join(TMP_LOCATION, "ape.jar")),
                serial=serial)

    print("Installing minitrace")
    run_adb_cmd("push {} {}".format(mtserver_path, TMP_LOCATION),
                serial=serial)

    save_snapshot(ART_APE_MT_READY_SS, serial=serial)
    assert libart_check(libart_path, serial=serial)
    avd.setRunning(serial)
    return avd
コード例 #15
0
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"
コード例 #16
0
def kill_mtserver(serial = None):
    pids = get_pids('/data/local/tmp/mtserver', serial=serial)
    for pid in pids:
        run_adb_cmd('shell kill {}'.format(pid), serial=serial)