Frida hooks (Android)
TL;DR: Frida injects a JavaScript engine into the target process and lets you replace Java/native methods at runtime — the fastest way to bypass root checks, SSL pinning and custom crypto.
What it is
Frida is a dynamic instrumentation toolkit. On Android, frida-server runs as root on the device and exposes a control channel; on the host, frida / frida-trace / a Python client attaches to a target process, loads a JS agent, and uses the Java and Interceptor APIs to intercept methods. For unrooted devices, frida-gadget is repackaged into the APK as a shared library that the app itself loads.
Preconditions / where it applies
- Rooted device with
frida-serverof matching arch + version, or repackaged APK embeddingfrida-gadget(see apk-reverse-tools) - USB or network reachability between host and device
- Target not employing aggressive apk-anti-debug / Frida detection — otherwise spawn paused and hook the detector first
Technique
Setup and discovery:
1
2
3
4
5
6
# Push the right frida-server to the device
adb push frida-server-16.x-android-arm64 /data/local/tmp/fs
adb shell "chmod 755 /data/local/tmp/fs && /data/local/tmp/fs &"
frida-ps -U # list running processes
frida -U -f com.victim --no-pause -l hook.js # spawn target with agent
Java hook — overriding a method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Java.perform(function () {
var Auth = Java.use('com.victim.security.Auth');
Auth.verifyToken.implementation = function (tok) {
console.log('[+] verifyToken called with: ' + tok);
return true; // bypass
};
// Print every overload of a noisy method
var Crypto = Java.use('com.victim.Crypto');
Crypto.encrypt.overloads.forEach(function (ov) {
ov.implementation = function () {
var out = ov.apply(this, arguments);
console.log('encrypt(' + JSON.stringify(arguments) + ') = ' + out);
return out;
};
});
});
Native hook — intercepting a JNI export or libc call:
1
2
3
4
5
6
7
8
var addr = Module.findExportByName('libnative.so', 'Java_com_victim_Native_check');
Interceptor.attach(addr, {
onEnter: function (args) { this.in = args[2].readCString(); },
onLeave: function (retval) {
console.log('check(' + this.in + ') = ' + retval);
retval.replace(ptr(1));
}
});
Common one-shots: dump every Java class (Java.enumerateLoadedClasses), trace constructors ($init), watch okhttp3.CertificatePinner.check for ssl-pinning-bypass, hook dalvik.system.DexClassLoader to capture decrypted DEX for apk-unpacking.
Useful companions:
frida-trace -U -j 'com.victim.*!*'— generate stub handlers for every method in a classobjection— Frida wrapper with one-line root/pinning bypass and memory dumpingr2frida— radare2 connected to a Frida session for live native debugging
Detection and defence
- Scan
/proc/self/mapsforfrida-agent/gum-js-loop, check ports 27042/27043 - Detect
gadgetlibrary by name; rename + early-load to evade - TLS pin server certs and verify with native code that hooks itself for integrity
- Layer with apk-anti-debug; assume any single check is defeated and combine many
- Server-side: short-lived tokens + Play Integrity binding so a hooked client cannot replay
References
- Frida docs — Android setup
- Frida JavaScript API —
Java,Interceptor,Memory - Objection — runtime mobile toolkit