Tools & Frameworks
Frida
Dynamic instrumentation toolkit for Android and iOS: hook functions, intercept calls, and modify app behavior at runtime without recompiling.
Documentation Index
Fetch the complete documentation index at: /llms.txt
Use this file to discover all available pages before exploring further.
Dynamic instrumentation toolkit for Android and iOS: hook functions, intercept calls, and modify app behavior at runtime without recompiling.
pip install frida-tools
frida --version
# Check device architecture
adb shell getprop ro.product.cpu.abi
# e.g. arm64-v8a, armeabi-v7a, x86_64
# Download matching frida-server from:
# https://github.com/frida/frida/releases
# File: frida-server-<version>-android-<arch>.xz
xz -d frida-server-*-android-arm64.xz
adb push frida-server-*-android-arm64 /data/local/tmp/frida-server
adb shell chmod +x /data/local/tmp/frida-server
# Start server (root required)
adb shell su -c "/data/local/tmp/frida-server &"
| Command | Description |
|---|---|
frida-ps -U | List processes on USB device |
frida-ps -Ua | List installed apps |
frida-ps -Uai | List apps with identifiers |
frida-trace -U -i "open" <pkg> | Trace native function calls |
frida -U -f <pkg> | Spawn app and attach |
frida -U -n <name> | Attach to running process by name |
frida -U -p <pid> | Attach by PID |
frida -U -f com.example.app --no-pause
frida -U -n "App Name"
frida -U -f com.example.app -l script.js --no-pause
Java.perform(function () {
var MainActivity = Java.use("com.example.app.MainActivity");
MainActivity.isUserLoggedIn.implementation = function () {
console.log("[*] isUserLoggedIn called — returning true");
return true;
};
});
Java.perform(function () {
var LoginActivity = Java.use("com.example.app.LoginActivity");
LoginActivity.checkCredentials.implementation = function (user, pass) {
console.log("[*] checkCredentials(" + user + ", " + pass + ")");
var result = this.checkCredentials(user, pass); // call original
console.log("[*] result: " + result);
return result;
};
});
Java.perform(function () {
var RootCheck = Java.use("com.example.app.RootCheck");
RootCheck.isRooted.implementation = function () {
return false; // always not rooted
};
});
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (className) {
if (className.includes("auth") || className.includes("Auth")) {
console.log(className);
}
},
onComplete: function () {}
});
});
Java.perform(function () {
// OkHttp3
try {
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function () {
console.log("[*] OkHttp3 CertificatePinner.check bypassed");
};
} catch (e) {}
// TrustManager — accept all certs
try {
var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
TrustManagerImpl.verifyChain.implementation = function () {
return arguments[0];
};
} catch (e) {}
// SSLContext
try {
var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
var SSLContext = Java.use("javax.net.ssl.SSLContext");
var TrustManager = Java.registerClass({
name: "com.frida.TrustManager",
implements: [X509TrustManager],
methods: {
checkClientTrusted: function (chain, authType) {},
checkServerTrusted: function (chain, authType) {},
getAcceptedIssuers: function () { return []; }
}
});
SSLContext.init.implementation = function (km, tm, sr) {
SSLContext.init.call(this, km, [TrustManager.$new()], sr);
};
} catch (e) {}
});
// Hook libc open()
Interceptor.attach(Module.findExportByName("libc.so", "open"), {
onEnter: function (args) {
console.log("[*] open: " + args[0].readUtf8String());
},
onLeave: function (retval) {
console.log("[*] open returned: " + retval);
}
});
// Read string from address
var ptr = ptr("0x12345678");
console.log(ptr.readUtf8String());
// Write value
Memory.writeByteArray(ptr, [0x01, 0x02, 0x03]);
frida --codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -U -f com.example.app