Frida Cheatsheet

Installation (iOS/iPhone 6s)

To get Frida working on this device you need the specific package frida_17.7.0_iphoneos.deb, see https://github.com/frida/frida/releases.

# Install
scp frida_17.7.0_iphoneos-arm.deb [email protected]:/var/root/
ssh [email protected]
dpkg -i /var/root/frida_17.7.0_iphoneos-arm.deb

# Install via SSH (General alternative)
ssh root@<device-ip>
apt update
apt install re.frida.server

# Start frida-server
frida-server -l 0.0.0.0 &
# or explicitly:
/usr/sbin/frida-server -l 0.0.0.0

# Verify it's running
ps aux | grep frida

Process Enumeration

CommandDescription
frida-psList running processes on the local host.
frida-ps -UList processes on the connected USB device.
frida-ps -H <host:port>List processes on a remote device.
frida-ps -UaiList installed applications (Android/iOS).
frida-ps -UaList all installed applications.

Attaching & Execution

CommandDescription
frida -n <name>Attach to a process by name.
frida -p <pid>Attach to a process by PID.
frida -f <app_id>Spawn (launch) the application and attach immediately.
frida -U -f <app_id> -l script.jsSpawn app on USB device and load a script.
frida -n <name> -l hook_script.jsAttach to process and load a JavaScript file.
frida -n <name> -e "console.log('Hi')"Attach to process and execute inline JavaScript code.
frida -U -f <app_id> --no-pauseSpawn app and automatically resume execution (no pause).

Remote Debugging

CommandDescription
frida -H <host>:<port> -n <name>Attach to a process on a remote device.
frida -H 192.168.1.100:27042 -f com.appSpawn an app on a remote device via IP/Port.

CLI Utilities

CommandDescription
frida-traceTrace function calls (generates stubs handlers).
frida-discoverDiscover internal functions called by the app.
frida-killKill a specific session or process.
frida-ls-devicesList all connected Frida devices.

Resources:

From this code, we can notice that all constructor addresses are checked beforehand by the containsAddress function. Therefore, it makes this function a good hooking spot as it is executed before calling the constructor itself. One can use the native SDK of frida-gum to perform this action:

// Address of ImageLoader::containsAddress in /usr/lib/dyld
const uintptr_t containsAddress_ptr = ...;

// Setup hooks with gum_interceptor_attach
GumAttachReturn attach_ret = gum_interceptor_attach(
    listener_->interceptor,
    /* target */ reinterpret_cast<void*>(containsAddress_ptr),
    reinterpret_cast<GumInvocationListener*>(listener_),
    /* ID */ reinterpret_cast<void*>(containsAddress_ptr)
);
....
// Equivalent of onEnter in Javascript
void native_listener_on_enter(GumInvocationListener* listener, GumInvocationContext* ic) {
  const uintptr_t ctor_function_addr = ic->cpu_context->x[1];
  // Do stuff with ctor_function_addr
}
By hooking containsAddress(), we get the control before the execution of the constructors. It gives us the ability to perform the following actions that can help to identify the constructor involved in the crash:

Trace the constructors (see: constructors_trace.log)
Replace/disable a constructor (gum_interceptor_replace)
Detect the first constructor and hook the next ones (gum_interceptor_attach)
// Hook associated with ImageLoader::containsAddress
void native_listener_on_enter(GumInvocationListener* listener,
                              GumInvocationContext* ic) {
  static size_t CTOR_ID = 0;
  const uintptr_t ctor_function_addr = ic->cpu_context->x[1];
  std::string libname = module_from_addr(ctor_function_addr);
  if (libname == "NianticLabsPlugin" && CTOR_ID++ == 3) {
    const uintptr_t base_address = base_addr_from_ptr(ctor_function_addr);
    auto bin = LIEF::MachO::Parser::parse_from_memory(base_address);
    bin->write("/tmp/pokemongo_after_ctor.bin"); // /tmp on the iPhone
  }
}