Commands (via USB)
Show all the applications of the device
Starts the Frida Gadget
frida -U APP_NAME
frida -U -l SCRIPT.js APP_NAME
Tracing native APIs (partial method name with wildcards allowed)
frida-trace -U APP_NAME -i "METHOD_NAME"$
Tracing Objective-C metods (partial method and class name with wildcards allowed)
$ frida-trace -U APP_NAME -m "-[CLASS_NAME METHOD_NAME]"
Execute Objective-C commands from terminal
frida -q -U APP_NAME -e "COMMAND"
Get instance object
var instance = ObjC.chooseSync(ObjC.classes.CLASS_NAME);
Dump the entire view hierarchy of a window
w = ObjC.classes.UIWindow.keyWindow() desc = w.recursiveDescription().toString()
Application installation path
Mapping each instance variable name to its current value
Call method (inside onEnter or onLeave)
var obj = new ObjC.Object(arg); obj.METHOD_NAME();
Print class and method
this._className = ObjC.Object(args).toString(); this._methodName = ObjC.selectorAsString(args); console.log('Detected call to:'); console.log(' ' + this._className + ' --> ' + this._methodName);
Modify return value
The following scripts can be found in my Github Trelis24
Python script that given a script and a app bundle, it starts the app, inject de script and resume the execution.
Search for classes
- If no strings are specified in “search_class” array, the script will print all the classes.
- If one or more strings are specified in “search_class array”, the script will only print classes which contains the strings in their name.
Search for methods
- If no strings are specified in “search_class” nor “search_method” arrays, the script will print the methods of all the classes (frida server might stop running if there are a lot of classes).
- If one or more strings are specified in “search_class array”, the script will print the methods of the classes which contains the strings in their name.
- If one or more strings are specified in “search_method” array, the script will print the classes which contains the strings in the name of one or more of their methods.
- If one or more strings are specified in “search_method” and “search_class” array, the script will print only the classes and methods that meet with the search criteria.
Hooks into methods
- Given one or more classes in “search_class”, it hooks into all their methods.
- Given one or more methods in “search_method”, it hooks into all methods of any classes that meet with the search criteria.
- Given a class and a method, it hooks into the method of this class.
- Neither class nor method full name is needed in order to hook. If a partial string is given, the script will hook into all the methods that have the string in their name.
Replace methods return values
- Given an especific class, method and value it replaces the return value of the method.
- Method format: for example: “- isJailbroken:”
- Data must be in the same array position (classNmes, methodNames, returnValues). For example: [‘class1’,’class2’][‘method1’,’method2’][‘retvalue1’,’retvalue2’]
- If returnValues of a method is left empty, the method will be hooken but the script will not modify the return value.
In this section, I will use DVIA iOS application in order to show how can frida and my scripts be used. Specifically I will analise jailbreak detection test 1. The objective is to bypass the jailbreak detection control.
List applications. The ones with a PID are currently active:
With frida-trace, hooking into all methods whose name has the substring “jail”:
With frida-trace, hooking into all methods of the class JailbreakDetectionVC:
With frida-trace, hooking into an specific method an class:
In order to detect which methods are called, one way is to hook into all methods of a class. In the following image you can see how the view was loaded first and then the method “jailbreakTest1Tapped:” and “isJailbroken” are called:
Of course, in the device the following message is shown:
Due to the jailbreak detection control only shows an alert text box and it does not terminate the application execution, I will execute the scripts via terminal. Otherwise, I would have used the python script in order to inject the scripts before the applications terminates.
First of all, you should look for classes of your interest. In this example, I have looked for the string “jail” (find_classes.js):
var search_class = ['jail'];
The only class with the substring “jail” is “JailbreakDetectionVC”:
An other way to find classes is to look into their methods. The only drawback is that depending of the string, a lot of results can be found. I have looked for the string “jail” in the methods (find_methods.js):
var search_class = ['']; var search_method = ['jail'];
The class “JailbreakDetectionVC” is in the list, however there are a lot more classes I am not interested in:
Now that I have detected the class, let’s print all its methods (find_methods.js):
var search_class = ['JailbreakDetectionVC']; var search_method = [''];
There are a total of 7 methods:
Now that I know the class, I can hook into the methods in order to understand how are they called (hooking.js):
var search_class = ['JailbreakDetectionVC']; var search_method = ['']; ... onEnter: ... //print_arguments(args);
In the code below, I have commented the line “print_arguments(args);”, which prints the arguments send into the methods, because it prints information not needed for this example.
After the script execution, it shows:
- Calls “jailbreakTest1Tapped:”
- Calls “isJailbroken”
- “isJailbroken” returns 0x1
- “jailbreakTest1Tapped:” returns 0x1035a9d10
I can deduce that “isJailbroken” might be de method which checks if the device is jailbroken due to it returns a “false”. However, if you want to be sure, static analysis can always be done. Check my post about bypassing Jailbreak with IDA.
Finally, I will try to replace the return value of “isJailbroken” so it always returns “false” (replace.js):
var classNames = ['JailbreakDetectionVC']; var methodNames = ['- isJailbroken']; var returnValues = ['0x0'];
The script hooks into the method. When isJailbroken returns the 0x1, frida intercepts it, changes the value to 0x0 and resume the execution:
After changing the return value from 0x1 to 0x0, the alert textbox is: