Frida: Complete Guide to Dynamic Application Instrumentation and Runtime Analysis Using Kali Linux

Frida: Complete Guide to Dynamic Application Instrumentation and Runtime Analysis Using Kali Linux

Frida is a world-class, open-source dynamic instrumentation toolkit that allows testers, reverse engineers, and developers to inject JavaScript (or Python-driven) snippets into running processes on Windows, macOS, GNU/Linux, iOS, Android, watchOS, tvOS, FreeBSD, and QNX. Rather than statically analyzing a compiled binary, Frida lets you observe and alter a program’s behavior while it is running, without needing to recompile or modify the original source code.

Frida operates through a client-server architecture:

In mobile security testing, Frida is used to:

How to Install

Install the Frida CLI tools on Kali Linux (client side):

# Install pip if not already present
sudo apt update
sudo apt install python3-pip -y

# Install frida-tools (includes frida, frida-ps, frida-trace, frida-discover,
# frida-ls-devices, frida-kill) plus the Python bindings
pip3 install frida-tools frida --break-system-packages

Verify installation and check the version:

$ frida --version
16.4.1

Install frida-server on a rooted Android device/emulator (server side):

# Determine your target device's CPU architecture
adb shell getprop ro.product.cpu.abi
# Example output: x86_64

# Download the matching frida-server release (version MUST match the client version)
wget https://github.com/frida/frida/releases/download/16.4.1/frida-server-16.4.1-android-x86_64.xz

# Extract
unxz frida-server-16.4.1-android-x86_64.xz
mv frida-server-16.4.1-android-x86_64 frida-server

# Push to the device and set permissions
adb root
adb push frida-server /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"

# Run the server in the background
adb shell "/data/local/tmp/frida-server &"

Confirm client-server connectivity:

$ frida-ps -U
  PID  Name
-----  ------------------
  412  Android System
 1091  Google Play Services
 2214  InsecureBankv2

Syntax

frida [options] target
frida-ps [options]
frida-trace [options] target
frida-discover [options] target
frida-ls-devices
frida-kill [options] target

All Command-Line Options

frida (main REPL/CLI):

OptionDescription
-U, --usbConnect to a USB device
-R, --remoteConnect to a remote frida-server
-D ID, --device IDConnect to a device with the given ID
-H HOST, --host HOSTConnect to remote frida-server on HOST
-f TARGET, --file TARGETSpawn the target application
-n NAME, --attach-name NAMEAttach by process name
-p PID, --attach-pid PIDAttach by process ID
-l SCRIPT, --load SCRIPTLoad a JavaScript file into the session
--debugEnable the Node.js compatible script debugger
--runtime {qjs|v8}Choose the JavaScript engine runtime
--no-pauseDo not pause spawned program at entry point
-o OUTPUT, --output OUTPUTWrite output to file instead of console
--versionShow the Frida version

frida-ps (list processes):

OptionDescription
-U, --usbConnect to a USB device
-UaList running applications on a USB device
-UaiList all installed applications (running or not) on a USB device
-D ID, --device IDConnect to a device with the given ID
-R, --remoteConnect to a remote frida-server

frida-trace (dynamic function call tracer) — Full List of Options:

OptionDescription
-D ID, --device IDConnect to device with the given ID
-U, --usbConnect to USB device
-R, --remoteConnect to remote frida-server
-H HOST, --host HOSTConnect to remote frida-server on HOST
-f TARGET, --file TARGETSpawn TARGET
-F, --attach-frontmostAttach to the frontmost application
-n NAME, --attach-name NAMEAttach to NAME
-N IDENTIFIER, --attach-identifier IDENTIFIERAttach to IDENTIFIER
-p PID, --attach-pid PIDAttach to PID
-W PATTERN, --await PATTERNAwait spawn matching PATTERN
--runtime {qjs|v8}Script runtime to use
--debugEnable the Node.js compatible script debugger
-I MODULE, --include-module MODULEInclude an entire MODULE
-X MODULE, --exclude-module MODULEExclude an entire MODULE
-i FUNCTION, --include FUNCTIONInclude [MODULE!]FUNCTION (glob)
-x FUNCTION, --exclude FUNCTIONExclude [MODULE!]FUNCTION (glob)
-a MODULE!OFFSET, --add MODULE!OFFSETTrace an unexported function by offset
-T, --include-importsInclude the program’s imports
-t MODULE, --include-module-imports MODULEInclude MODULE’s imports
-m OBJC_METHOD, --include-objc-method OBJC_METHODInclude an Objective-C method
-M OBJC_METHOD, --exclude-objc-method OBJC_METHODExclude an Objective-C method
-j JAVA_METHOD, --include-java-method JAVA_METHODInclude a Java method (e.g. '*!*certificate*/isu')
-J JAVA_METHOD, --exclude-java-method JAVA_METHODExclude a Java method
-s DEBUG_SYMBOL, --include-debug-symbol DEBUG_SYMBOLInclude a debug symbol
-q, --quietDo not format output messages
-d, --decorateAdd module name to generated onEnter log statements
-S PATH, --init-session PATHJavaScript file used to initialize the session
-P PARAMETERS_JSON, --parameters PARAMETERS_JSONPass JSON parameters exposed as global parameters
-o OUTPUT, --output OUTPUTDump messages to a file
-O FILE, --options-file FILERead additional CLI options from a text file
--ui-port UI_PORTTCP port to serve the frida-trace UI on
--squelch-crashDo not dump crash report to console
--versionShow version and exit

frida-ls-devices (list connected devices):

$ frida-ls-devices
Id                                    Type    Name
------------------------------------  ------  --------------
local                                 local   Local System
0216027d1d6d3a03                      usb     Pixel 6a

frida-kill (terminate a process on a device):

OptionDescription
-U, --usbConnect to USB device
-D ID, --device IDConnect to device with the given ID
-R, --remoteConnect to remote frida-server
targetProcess name or PID to kill

Basic Usage (Expected Output in Bash)

List running processes on a USB-connected device:

$ frida-ps -U
  PID  Name
-----  ------------------
  412  Android System
 2214  InsecureBankv2

Attach the REPL to a running application:

$ frida -U InsecureBankv2
     ____
    / _  |   Frida 16.4.1 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|   help      -> Displays the help system
   . . . .   object?   -> Display information about 'object'
   . . . .   exit/quit -> Exit
   . . . .
   . . . . Connected to Pixel 6a (id=0216027d1d6d3a03)
[Pixel 6a::InsecureBankv2]->

Practical Examples with Output

Example 1 — List all installed applications on the device (running or not):

$ frida-ps -Uai
  PID  Name              Identifier
-----  ----------------  -----------------------------------
 2214  InsecureBankv2    com.android.insecurebankv2
    -  DIVA              jakhar.aseem.diva
    -  Chrome            com.android.chrome

Example 2 — Spawn (launch) an app and attach immediately, pausing at entry:

$ frida -U -f com.android.insecurebankv2 --no-pause
Spawned `com.android.insecurebankv2`. Resuming main thread!
[Pixel 6a::com.android.insecurebankv2]->

Example 3 — Load a custom JavaScript hook script on attach:

$ frida -U -f com.android.insecurebankv2 -l ssl_bypass.js --no-pause
Spawned `com.android.insecurebankv2`. Resuming main thread!
[SSL Pinning Bypass] Hook installed on X509TrustManager
[Pixel 6a::com.android.insecurebankv2]->

Example 4 — Trace all Java methods containing “login” (case-insensitive, user classes only):

$ frida-trace -U -f com.android.insecurebankv2 --runtime=v8 -j '*!*login*/iu'
Instrumenting...
LoginActivity.onLoginClick: Auto-generated handler at "/handlers/__handlers__/LoginActivity_onLoginClick.js"
Started tracing 1 function. Press Ctrl+C to stop.
           /* TID 0x2a1e */
  1204 ms  LoginActivity.onLoginClick()

Example 5 — Trace native open* and read* functions in a running process by PID:

$ frida-trace -p 2214 -i "open*" -i "read*" -x "libc.so!*close*"
Instrumenting...
open: Auto-generated handler at "/handlers/libc.so/open.js"
read: Auto-generated handler at "/handlers/libc.so/read.js"
Started tracing 2 functions. Press Ctrl+C to stop.
           /* TID 0x2a20 */
  3011 ms  open(pathname="/data/data/com.android.insecurebankv2/databases/users.db", flags=0x2)
  3012 ms  read(fd=48, buf=0x7f3a1c2000, count=4096)

Example 6 — Trace with decorated output showing module names:

$ frida-trace -p 2214 --decorate -i "recv*" -i "send*"
Instrumenting...
Started tracing 6 functions. Press Ctrl+C to stop.
  8420 ms  send() [libc.so]
  8421 ms  recv() [libc.so]

Example 7 — Auto-discover interesting native functions in a running process:

$ frida-discover -U -p 2214
Discovering functions in InsecureBankv2...
Found 12 interesting functions.
See discover.sqlite for results.

Example 8 — List connected devices (local, USB, and remote):

$ frida-ls-devices
Id                                    Type    Name
------------------------------------  ------  --------------
local                                 local   Local System
0216027d1d6d3a03                      usb     Pixel 6a

Example 9 — Kill a running application on the target device:

$ frida-kill -U InsecureBankv2
$ frida-ps -U | grep InsecureBankv2

(No output — the process has been terminated.)

Example 10 — Trace an unexported native function by module offset:

$ frida-trace -p 2214 -a "libnative-lib.so!0x4793c"
Instrumenting...
sub_4793c: Auto-generated handler at "/handlers/libnative-lib.so/sub_4793c.js"
Started tracing 1 function. Press Ctrl+C to stop.
  9102 ms  sub_4793c()

Example 11 — Use -P to pass runtime JSON parameters into trace handlers:

$ frida-trace -p 2214 -i "AES_encrypt" -P '{"displayPid": true}'
Instrumenting...
Started tracing 1 function. Press Ctrl+C to stop.
  4501 ms  AES_encrypt() [libcrypto.so]
           Process ID: 2214

Example 12 — Attach to the frontmost (currently visible) app on the device:

$ frida -U -F
     ____
    / _  |   Frida 16.4.1 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |
   /_/ |_|
   . . . . Connected to Pixel 6a (id=0216027d1d6d3a03)
[Pixel 6a::Frontmost]->

Common Use Cases

Automation with Bash

The following script automates deploying frida-server to a connected device, verifying connectivity, and launching a trace session against a target package.

#!/bin/bash
# frida_setup_and_trace.sh - Deploy frida-server and start tracing a target app

FRIDA_VERSION="16.4.1"
TARGET_PACKAGE="com.android.insecurebankv2"
ARCH=$(adb shell getprop ro.product.cpu.abi | tr -d '\r')

echo "[*] Detected device architecture: $ARCH"

SERVER_FILE="frida-server-${FRIDA_VERSION}-android-${ARCH}"

if [ ! -f "${SERVER_FILE}" ]; then
    echo "[*] Downloading frida-server ${FRIDA_VERSION} for ${ARCH}..."
    wget -q "https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/${SERVER_FILE}.xz"
    unxz "${SERVER_FILE}.xz"
fi

echo "[*] Pushing frida-server to device..."
adb root > /dev/null 2>&1
adb push "${SERVER_FILE}" /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"

echo "[*] Starting frida-server on device..."
adb shell "/data/local/tmp/frida-server &"
sleep 2

echo "[*] Verifying connectivity..."
frida-ps -U > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "[+] frida-server is running and reachable."
else
    echo "[-] Could not reach frida-server."
    exit 1
fi

echo "[*] Launching trace session on ${TARGET_PACKAGE}..."
frida-trace -U -f "${TARGET_PACKAGE}" --runtime=v8 -j '*!*password*/iu' -j '*!*login*/iu'

Sample run:

$ chmod +x frida_setup_and_trace.sh
$ ./frida_setup_and_trace.sh
[*] Detected device architecture: x86_64
[*] Pushing frida-server to device...
[*] Starting frida-server on device...
[*] Verifying connectivity...
[+] frida-server is running and reachable.
[*] Launching trace session on com.android.insecurebankv2...
Instrumenting...
LoginActivity.checkPassword: Auto-generated handler at "/handlers/__handlers__/LoginActivity_checkPassword.js"
Started tracing 2 functions. Press Ctrl+C to stop.

Tips and Best Practices

Troubleshooting

ProblemCauseSolution
Failed to spawn: unable to connect to remote frida-serverfrida-server not running or version mismatchConfirm the server is running (`adb shell “ps -A
Failed to enumerate applications: permission deniedDevice not rooted or adb root not appliedEnsure the device is rooted and run adb root before pushing the server
App crashes immediately after hook is appliedHook logic references a class/method that doesn’t exist in this buildVerify class/method names via jadx decompiled source before writing the hook
frida: command not foundfrida-tools not installed or not in PATHRun pip3 install frida-tools --break-system-packages and confirm ~/.local/bin is on PATH
Unable to find process with name 'X'Process name typo or app not runningUse frida-ps -Ua to confirm the exact running process name first
Trace output extremely noisyOverly broad glob pattern (e.g., -i "*")Narrow the glob pattern and use -x to exclude noisy modules like libc.so
Connection works locally but not for a specific appApp uses Frida detection/anti-instrumentation checksUse Objection or a custom hook to patch Frida detection strings/signatures before attaching

References

Exit mobile version