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)
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)
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)
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')
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)
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)
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
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)
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)
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)
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')
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')
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
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')
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)
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)
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)
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)
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')
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)
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)
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))
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)
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)
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')
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)
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)
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)
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'])