Esempio n. 1
0
def search_methods(args: list) -> None:
    """
        Searches the current Android application for a class method.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: android hooking search methods <name> (optional: <package-filter>)', bold=True)
        return

    search = args[0]
    class_filter = args[1] if len(clean_argument_flags(args)) > 1 else None
    found = 0

    if not class_filter:
        click.secho('Warning, searching all classes may take some time and in some cases, '
                    'crash the target application.', fg='yellow')
        if not click.confirm('Continue?'):
            return

    api = state_connection.get_api()

    # get the classes we have
    classes = api.android_hooking_get_classes()
    click.secho('Found {0} classes, searching methods (this may take some time)...'.format(len(classes)), dim=True)
    if class_filter:
        click.secho('Filtering classes with {0}'.format(class_filter), dim=True)

    # loop the classes and check the methods
    for class_name in sorted(classes):
        if class_filter and class_filter.lower() not in class_name.lower():
            continue

        try:

            for method in api.android_hooking_get_class_methods(class_name):
                # get only the raw method, minus returns, throws and args
                method = method.split('(')[0].split(' ')[-1]
                if search.lower() in method.lower():
                    click.secho(method)
                    found += 1

        except frida.core.RPCException as e:
            click.secho('Enumerating methods for class \'{0}\' failed with: {1}'.format(class_name, e), fg='red',
                        dim=True)
            click.secho('Ignoring error and continuing search...', dim=True)

    click.secho('\nFound {0} methods'.format(found), bold=True)
Esempio n. 2
0
def search_class(args: list) -> None:
    """
        Searches the currently loaded classes for a class.
        Note that Java classes are only loaded when they are used, 
        so if you don't get results, the class might not have been used yet.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: android hooking search classes <name>', bold=True)
        return

    click.secho(
        'Note that Java classes are only loaded when they are used,'
        ' so if the expected class has not been found, it might not have been loaded yet.',
        fg='yellow')

    search = args[0]
    found = 0

    api = state_connection.get_api()
    classes = api.android_hooking_get_classes()

    # print the enumerated classes
    for class_name in sorted(classes):

        if search.lower() in class_name.lower():
            click.secho(class_name)
            found += 1

    click.secho('\nFound {0} classes'.format(found), bold=True)
Esempio n. 3
0
def show_android_class_methods(args: list = None) -> None:
    """
        Shows the methods available on an Android class.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho('Usage: android hooking list class_methods <class name>',
                    bold=True)
        return

    class_name = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(android_hook('hooking/list-class-methods'),
                              class_name=class_name)

    runner.run()
    response = runner.get_last_message()

    if not response.is_successful():
        click.secho('Failed to list class methods with error: {0}'.format(
            response.error_reason),
                    fg='red')
        return None

    # print the enumerated classes
    for class_name in sorted(response.data):
        click.secho(class_name)

    click.secho('\nFound {0} method(s)'.format(len(response.data)), bold=True)
Esempio n. 4
0
def search_class(args: list) -> None:
    """
        Searching for Objective-C classes in the current
        application by name.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: ios hooking search classes <name>', bold=True)
        return

    search = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(ios_hook('hooking/search-class'), search=search)
    runner.run()

    response = runner.get_last_message()

    if not response.is_successful():
        click.secho('Failed to search for classes with error: {0}'.format(response.error_reason), fg='red')
        return None

    if response.data:

        # dump the classes to screen
        for classname in response.data:
            click.secho(classname)

        click.secho('\nFound {0} classes'.format(len(response.data)), bold=True)

    else:
        click.secho('No classes found')
Esempio n. 5
0
def watch_class(args: list) -> None:
    """
        Watches for invocations of all methods in an Android
        Java class. All overloads for methods found are also watched.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho(
            'Usage: android hooking watch class <class> '
            '(eg: com.example.test)',
            bold=True)
        return

    target_class = args[0]

    api = state_connection.get_api()

    if '*' in target_class:
        classes = api.android_hooking_get_classes()
        for class_name in fnmatch.filter(classes, target_class):
            api.android_hooking_watch_class(class_name)
    else:
        api.android_hooking_watch_class(target_class)
Esempio n. 6
0
def search_class(args: list) -> None:
    """
        Searches the current Android application for instances
        of a class.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: android hooking search classes <name>', bold=True)
        return

    search = args[0]
    found = 0

    api = state_connection.get_api()
    classes = api.android_hooking_get_classes()

    # print the enumerated classes
    for class_name in sorted(classes):

        if search.lower() in class_name.lower():
            click.secho(class_name)
            found += 1

    click.secho('\nFound {0} classes'.format(found), bold=True)
Esempio n. 7
0
def watch_class_method(args: list) -> None:
    """
        Watches for invocations of an Android Java class method.
        All overloads for the same method are also watched.

        Optionally, this method will dump the watched methods arguments,
        backtrace as well as return value.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho((
            'Usage: android hooking watch class_method <fully qualified class method> '
            '(eg: com.example.test.dologin) '
            '(optional: --dump-args) '
            '(optional: --dump-backtrace) '
            '(optional: --dump-return)'),
                    bold=True)
        return

    fully_qualified_class = args[0]

    api = state_connection.get_api()
    api.android_hooking_watch_method(fully_qualified_class,
                                     _should_dump_args(args),
                                     _should_dump_backtrace(args),
                                     _should_dump_return_value(args))

    return
Esempio n. 8
0
def watch_class(args: list) -> None:
    """
        Watches for invocations of all methods in an Android
        Java class. All overloads for methods found are also watched.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho(
            'Usage: android hooking watch class <class> '
            '(eg: com.example.test) '
            '(optional: --dump-args) '
            '(optional: --dump-backtrace) '
            '(optional: --dump-return)',
            bold=True)
        return

    target_class = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(android_hook('hooking/watch-class-methods'),
                              target_class=target_class,
                              dump_args=_should_dump_args(args),
                              dump_return=_should_dump_return_value(args),
                              dump_backtrace=_should_dump_backtrace(args))

    runner.run_as_job(name='watch-java-class', args=args)
Esempio n. 9
0
def watch_class_method(args: list) -> None:
    """
        Watches for invocations of an Android Java class method.
        All overloads for the same method are also watched.

        Optionally, this method will dump the watched methods arguments,
        backtrace as well as return value.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho(
            ('Usage: android hooking watch class_method <class> <method> '
             '(eg: com.example.test dologin) '
             '(optional: --dump-args) '
             '(optional: --dump-backtrace) '
             '(optional: --dump-return)'),
            bold=True)
        return

    target_class = args[0]
    target_method = args[1]

    runner = FridaRunner()

    runner.set_hook_with_data(android_hook('hooking/watch-method'),
                              target_class=target_class,
                              target_method=target_method,
                              dump_args=_should_dump_args(args),
                              dump_return=_should_dump_return_value(args),
                              dump_backtrace=_should_dump_backtrace(args))

    runner.run_as_job(name='watch-java-method', args=args)
Esempio n. 10
0
def set_method_return_value(args: list = None) -> None:
    """
        Sets a Java methods return value to a specified boolean.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho(
            ('Usage: android hooking set return_value '
             '"<fully qualified class>" (eg: "com.example.test") '
             '"<method (with overload if needed)>" (eg: see help for details) '
             '<true/false>'),
            bold=True)
        return

    class_name = args[0]
    method_name = args[1].replace('\'', '"')  # fun!
    retval = args[2]

    runner = FridaRunner()
    runner.set_hook_with_data(android_hook('hooking/set-return'),
                              class_name=class_name,
                              method_name=method_name,
                              retval=retval)

    runner.run_as_job(name='set-return-value', args=args)
Esempio n. 11
0
def search_method(args: list) -> None:
    """
        Search for Objective-C methods by name.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: ios hooking search methods <name>', bold=True)
        return

    search = args[0]

    api = state_connection.get_api()
    methods = api.ios_hooking_search_methods(search)

    if len(methods) > 0:

        # filter the methods for the search
        for method in methods:
            click.secho(method)

        click.secho('\nFound {0} methods'.format(len(methods)), bold=True)

    else:
        click.secho('No methods found')
Esempio n. 12
0
def search_class(args: list) -> None:
    """
        Searching for Objective-C classes in the current
        application by name.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: ios hooking search classes <name>', bold=True)
        return

    search = args[0]

    api = state_connection.get_api()
    classes = api.ios_hooking_get_classes(search)
    found_classes = 0

    if len(classes) > 0:

        # filter the classes for the search
        for classname in classes:

            if search.lower() in classname.lower():
                click.secho(classname)
                found_classes += 1

        click.secho('\nFound {0} classes'.format(found_classes), bold=True)

    else:
        click.secho('No classes found')
Esempio n. 13
0
def watch_class_method(args: list) -> None:
    """
        Watches for invocations of an Android Java class method.
        All overloads for the same method are also watched.

        Optionally, this method will dump the watched methods arguments,
        backtrace as well as return value.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho((
            'Usage: android hooking watch class_method <fully qualified class method> '
            '<optional overload> '
            '(optional: --dump-args) '
            '(optional: --dump-backtrace) '
            '(optional: --dump-return)'),
                    bold=True)
        return

    fully_qualified_class = args[0]
    overload_filter = args[1].replace(
        ' ', '') if (len(args) > 1 and '--' not in args[1]) else None

    api = state_connection.get_api()
    api.android_hooking_watch_method(fully_qualified_class, overload_filter,
                                     _should_dump_args(args),
                                     _should_dump_backtrace(args),
                                     _should_dump_return_value(args))

    return
Esempio n. 14
0
def search_method(args: list) -> None:
    """
        Search for Objective-C methods by name.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: ios hooking search methods <name>', bold=True)
        return

    search = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(ios_hook('hooking/search-method'), search=search)
    runner.run()

    response = runner.get_last_message()

    if not response.is_successful():
        click.secho('Failed to search for methods with error: {0}'.format(response.error_reason), fg='red')
        return None

    if response.data:

        # dump the methods to screen
        for method in response.data:
            click.secho(method)

        click.secho('\nFound {0} methods'.format(len(response.data)), bold=True)

    else:
        click.secho('No methods found')
Esempio n. 15
0
def show_ios_class_methods(args: list) -> None:
    """
        Displays the methods available in a class.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho('Usage: ios hooking list class_methods <class name> (--include-parents)', bold=True)
        return

    classname = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(
        ios_hook('hooking/list-class-methods'), classname=classname,
        include_parents=_should_include_parent_methods(args))

    runner.run()
    response = runner.get_last_message()

    if not response.is_successful():
        click.secho('Failed to list classes with error: {0}'.format(response.error_reason), fg='red')
        return None

    # dump the methods to screen
    for method in response.data:
        click.secho(method)
Esempio n. 16
0
def watch_class_methods_var_returns(args: list) -> None:
    """
        Starts an objection jon that hooks into a specific all classes
        and methods and reports on invocations when specifi
        args and return values reached.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho(('Usage: ios hooking watch var_and_returns <classPattern> <methodPattern> <argsPattern> <returnPattern> (eg: Controller login [email protected] false) '
                     '(optional: --dump-backtrace) '
                     '(optional: --dump-args) '
                     '(optional: --dump-return)'), bold=True)
        return

    classes_Pattern = args[0]
    methods_Pattern = args[1]
    args_Pattern = args[2]
    returns_Pattern = args[3]

    runner = FridaRunner()
    runner.set_hook_with_data(ios_hook('hooking/watch-class-methods-var-returns'),
                              classes_Pattern=classes_Pattern,
                              methods_Pattern=methods_Pattern,
                              args_Pattern=args_Pattern,
                              returns_Pattern=returns_Pattern,
                              dump_backtrace=_should_dump_backtrace(args),
                              dump_args=_should_dump_args(args),
                              dump_return=_should_dump_return_value(args))

    runner.run_as_job(name='watch-class-methods-var-returns', args=args)
Esempio n. 17
0
def watch_class_method(args: list) -> None:
    """
        Starts an objection jon that hooks into a specific class method
        and reports on invocations.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho(('Usage: ios hooking watch method <selector> (eg: -[ClassName methodName:]) '
                     '(optional: --dump-backtrace) '
                     '(optional: --dump-args) '
                     '(optional: --dump-return)'), bold=True)
        return

    selector = args[0]
    argument_count = selector.count(':')

    runner = FridaRunner()
    runner.set_hook_with_data(ios_hook('hooking/watch-method'), selector=selector,
                              argument_count=argument_count,
                              dump_backtrace=_should_dump_backtrace(args),
                              dump_args=_should_dump_args(args),
                              dump_return=_should_dump_return_value(args))

    runner.run_as_job(name='watch-method', args=args)
Esempio n. 18
0
def set_method_return_value(args: list = None) -> None:
    """
        Sets a Java methods return value to a specified boolean.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho((
            'Usage: android hooking set return_value '
            '"<fully qualified class method>" "<optional overload>" (eg: "com.example.test.doLogin") '
            '<true/false>'),
                    bold=True)
        return

    # make sure we got a true/false
    if args[-1].lower() not in ('true', 'false'):
        click.secho('Return value must be set to either true or false',
                    bold=True)
        return

    class_name = args[0].replace('\'', '"')  # fun!

    # check if we got an overload
    overload_filter = args[1] if len(args) == 3 else None
    retval = True if _string_is_true(args[-1]) else False

    api = state_connection.get_api()
    api.android_hooking_set_method_return(class_name,
                                          overload_filter.replace(' ', ''),
                                          retval)
Esempio n. 19
0
def show_ios_class_methods(args: list) -> None:
    """
        Displays the methods available in a class.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho(
            'Usage: ios hooking list class_methods <class name> (--include-parents)',
            bold=True)
        return

    classname = args[0]

    api = state_connection.get_api()
    methods = api.ios_hooking_get_class_methods(
        classname, _should_include_parent_methods(args))

    if len(methods) > 0:

        # dump the methods to screen
        for method in methods:
            click.secho(method)

        click.secho('\nFound {0} methods'.format(len(methods)), bold=True)

    else:
        click.secho('No class / methods found')
Esempio n. 20
0
def launch_activity(args: list) -> None:
    """
        Launches an activity class using an Android Intent

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: android intent launch_activity <activity_class>',
                    bold=True)
        return

    intent_class = args[0]

    api = state_connection.get_api()
    api.android_intent_start_activity(intent_class)
Esempio n. 21
0
def watch_class(args: list) -> None:
    """
        Starts an objection job that hooks into all of the methods
        available in a class and reports on invocations.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho('Usage: ios hooking watch class <class_name> (--include-parents)', bold=True)
        return

    class_name = args[0]

    api = state_connection.get_api()
    api.ios_hooking_watch_class(class_name)
Esempio n. 22
0
def set_method_return_value(args: list) -> None:
    """
        Make an Objective-C method return a specific boolean
        value, always.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho('Usage: ios hooking set_method_return "<selector>" (eg: "-[ClassName methodName:]") <true/false>',
                    bold=True)
        return

    selector = args[0]
    retval = args[1]

    api = state_connection.get_api()
    api.ios_hooking_set_return_value(selector, _string_is_true(retval))
Esempio n. 23
0
def set_method_return_value(args: list = None) -> None:
    """
        Sets a Java methods return value to a specified boolean.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho(('Usage: android hooking set return_value '
                     '"<fully qualified class method (with overload if needed)>" (eg: "com.example.test.doLogin") '
                     '<true/false>'),
                    bold=True)
        return

    class_name = args[0].replace('\'', '"')  # fun!
    retval = True if _string_is_true(args[1]) else False

    api = state_connection.get_api()
    api.android_hooking_set_method_return(class_name, retval)
Esempio n. 24
0
def watch_class(args: list) -> None:
    """
        Starts an objection job that hooks into all of the methods
        available in a class and reports on invocations.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho('Usage: ios hooking watch class <class_name> (--include-parents)', bold=True)
        return

    class_name = args[0]

    runner = FridaRunner()
    runner.set_hook_with_data(
        ios_hook('hooking/watch-class-methods'),
        class_name=class_name, include_parents=_should_include_parent_methods(args))

    runner.run_as_job(name='watch-class-methods', args=args)
Esempio n. 25
0
def launch_activity(args: list) -> None:
    """
        Launches an activity class using an Android Intent

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 1:
        click.secho('Usage: android intent launch_activity <activity_class>',
                    bold=True)
        return

    intent_class = args[0]

    click.secho('Launching Activity: {0}...'.format(intent_class), dim=True)
    runner = FridaRunner()
    runner.set_hook_with_data(android_hook('intent/start-activity'),
                              intent_class=intent_class)
    runner.run()

    click.secho('Launched: {0}'.format(intent_class), fg='green')
Esempio n. 26
0
def show_android_class_methods(args: list = None) -> None:
    """
        Shows the methods available on an Android class.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho('Usage: android hooking list class_methods <class name>', bold=True)
        return

    class_name = args[0]

    api = state_connection.get_api()
    methods = api.android_hooking_get_class_methods(class_name)

    # print the enumerated classes
    for class_name in sorted(methods):
        click.secho(class_name)

    click.secho('\nFound {0} method(s)'.format(len(methods)), bold=True)
Esempio n. 27
0
def set_method_return_value(args: list) -> None:
    """
        Make an Objective-C method return a specific boolean
        value, always.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) < 2:
        click.secho('Usage: ios hooking set_method_return "<selector>" (eg: "-[ClassName methodName:]") <true/false>',
                    bold=True)
        return

    selector = args[0]
    retval = args[1]

    runner = FridaRunner()
    runner.set_hook_with_data(
        ios_hook('hooking/set-return'), selector=selector, retval=_string_is_true(retval))

    runner.run_as_job(name='set-return-value', args=args)
Esempio n. 28
0
def var_class(args: list) -> None:

    if len(clean_argument_flags(args)) < 2:
        click.secho(('Usage: android hooking watch var <class> <var> '
                     '(eg: com.example.test [email protected]) '
                     '(optional: --dump-args) '
                     '(optional: --dump-backtrace) '
                     '(optional: --dump-return)'),
                    bold=True)
        return

    search_class = args[0]
    search_var = args[1]
    runner = FridaRunner()

    runner.set_hook_with_data(android_hook('hooking/var-class'),
                              search_class=search_class,
                              search_var=search_var,
                              dump_args=_should_dump_args(args),
                              dump_return=_should_dump_return_value(args),
                              dump_backtrace=_should_dump_backtrace(args))

    runner.run_as_job(name='watch-java-var', args=args)
Esempio n. 29
0
def watch_class_method(args: list) -> None:
    """
        Starts an objection jon that hooks into a specific class method
        and reports on invocations.

        :param args:
        :return:
    """

    if len(clean_argument_flags(args)) <= 0:
        click.secho(('Usage: ios hooking watch method <selector> (eg: -[ClassName methodName:]) '
                     '(optional: --dump-backtrace) '
                     '(optional: --dump-args) '
                     '(optional: --dump-return)'), bold=True)
        return

    selector = args[0]

    api = state_connection.get_api()
    api.ios_hooking_watch_method(selector,
                                 _should_dump_args(args),
                                 _should_dump_backtrace(args),
                                 _should_dump_return_value(args))
 def test_cleans_argument_lists_with_flags(self):
     result = clean_argument_flags(['foo', '--bar'])
     self.assertEqual(result, ['foo'])