Universal Robust Advanced Root SSL Pinning Bypass
4 views
621092c1...
Description
Universal Robust Advanced Root SSL Pinning Bypass this script cover most advance plus all possible test cases for root detection and ssl pinning bypass.
How to Use
Download the script and run it with Frida CLI:
Download ScriptThen run with Frida:
frida -U -f YOUR_PACKAGE_NAME -l universal-robust-advanced-root-ssl-pinning-bypass.js
Replace YOUR_PACKAGE_NAME with the target app's package name.
Source Code
JavaScript
// ---------------------------
// Combined Root + SSL Pinning Bypass Script bira
// ---------------------------
var errDict = {};
// --- Universal SSL Pinning Bypass Function ---
function addUniversalSSLPinningBypass() {
Java.perform(function() {
// WebView SSL error bypass
try {
var WebViewClient = Java.use('android.webkit.WebViewClient');
WebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
console.log('[+] WebViewClient.onReceivedSslError() bypassed');
handler.proceed();
};
} catch (e) {}
// OkHttp
try {
var OkHostnameVerifier = Java.use('okhttp3.internal.tls.OkHostnameVerifier');
OkHostnameVerifier.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(host, session) {
console.log('[+] OkHttp3 OkHostnameVerifier.verify() bypassed for host: ' + host);
return true;
};
} catch (e) {}
try {
var OkHostnameVerifier2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
OkHostnameVerifier2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(host, session) {
console.log('[+] OkHttp2 OkHostnameVerifier.verify() bypassed for host: ' + host);
return true;
};
} catch (e) {}
// Conscrypt, BouncyCastle
try {
var conscrypt_TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
conscrypt_TrustManagerImpl.checkTrustedRecursive.implementation = function() {
console.log('[+] Conscrypt TrustManagerImpl.checkTrustedRecursive() bypassed');
return [];
};
} catch (e) {}
try {
var bouncy_TrustManager = Java.use('org.bouncycastle.jsse.provider.BouncyCastleJsseProvider');
bouncy_TrustManager.checkServerTrusted.implementation = function() {
console.log('[+] BouncyCastle checkServerTrusted() bypassed');
};
} catch (e) {}
// Dynamic class/method scan for pinning
Java.enumerateLoadedClasses({
onMatch: function(className) {
var lc = className.toLowerCase();
if (
lc.indexOf('pin') !== -1 ||
lc.indexOf('trust') !== -1 ||
lc.indexOf('cert') !== -1 ||
lc.indexOf('ssl') !== -1 ||
lc.indexOf('verify') !== -1 ||
lc.indexOf('chain') !== -1
) {
try {
var klass = Java.use(className);
['checkServerTrusted', 'checkClientTrusted', 'verify', 'verifyCertificateChain', 'onReceivedError'].forEach(function(method) {
if (klass[method]) {
klass[method].implementation = function() {
console.log('[+] Universal dynamic SSL bypass: ' + className + '.' + method + '()');
if (method === 'verify') return true;
if (method === 'onReceivedError') return;
return;
};
}
});
} catch (e) {}
}
},
onComplete: function() {}
});
// Universal Java SSL error bypass
try {
var SSLPeerUnverifiedException = Java.use('javax.net.ssl.SSLPeerUnverifiedException');
SSLPeerUnverifiedException.$init.implementation = function(reason) {
console.log('[+] Universal SSLPeerUnverifiedException bypassed: ' + reason);
return this.$init('');
};
} catch (e) {}
// Apache HttpClient, Netty, JSSE, SSLSocketFactory, TrustManagerFactory, KeyManagerFactory
try {
var AbstractVerifier = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
AbstractVerifier.verify.implementation = function(host, ssl) {
console.log('[+] Apache HttpClient AbstractVerifier.verify() bypassed for: ' + host);
};
} catch (e) {}
try {
var NettyFingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');
NettyFingerprintTrustManagerFactory.checkTrusted.implementation = function(type, chain) {
console.log('[+] Netty FingerprintTrustManagerFactory.checkTrusted() bypassed');
};
} catch (e) {}
try {
var SSLParametersImpl = Java.use('com.android.org.conscrypt.SSLParametersImpl');
SSLParametersImpl.setEndpointIdentificationAlgorithm.implementation = function(alg) {
console.log('[+] SSLParametersImpl.setEndpointIdentificationAlgorithm() bypassed');
};
} catch (e) {}
try {
var SSLSocketFactory = Java.use('javax.net.ssl.SSLSocketFactory');
SSLSocketFactory.createSocket.overload('java.net.Socket', 'java.lang.String', 'int', 'boolean').implementation = function() {
console.log('[+] SSLSocketFactory.createSocket() bypassed');
return this.createSocket.apply(this, arguments);
};
} catch (e) {}
try {
var TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
TrustManagerFactory.init.overload('java.security.KeyStore').implementation = function(ks) {
console.log('[+] TrustManagerFactory.init() bypassed');
return this.init(ks);
};
} catch (e) {}
try {
var KeyManagerFactory = Java.use('javax.net.ssl.KeyManagerFactory');
KeyManagerFactory.init.overload('java.security.KeyStore', '[C').implementation = function(ks, pwd) {
console.log('[+] KeyManagerFactory.init() bypassed');
return this.init(ks, pwd);
};
} catch (e) {}
// Cordova/Unity/Flutter/ReactNative/Other Frameworks
try {
var CordovaWebViewClient = Java.use('org.apache.cordova.CordovaWebViewClient');
CordovaWebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
console.log('[+] CordovaWebViewClient.onReceivedSslError() bypassed');
handler.proceed();
};
} catch (e) {}
try {
var UnityWebRequest = Java.use('com.unity3d.player.UnityWebRequest');
UnityWebRequest.setCertificateHandler.implementation = function(handler) {
console.log('[+] UnityWebRequest.setCertificateHandler() bypassed');
};
} catch (e) {}
// Native hooks
try {
var sslctx_custom_verify = Module.findExportByName('libssl.so', 'SSL_CTX_set_custom_verify');
if (sslctx_custom_verify) {
Interceptor.attach(sslctx_custom_verify, {
onEnter: function(args) {
console.log('[+] Native SSL_CTX_set_custom_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
var sslctx_set_verify = Module.findExportByName('libssl.so', 'SSL_CTX_set_verify');
if (sslctx_set_verify) {
Interceptor.attach(sslctx_set_verify, {
onEnter: function(args) {
console.log('[+] Native SSL_CTX_set_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
var mbedtls_ssl_conf_authmode = Module.findExportByName(null, 'mbedtls_ssl_conf_authmode');
if (mbedtls_ssl_conf_authmode) {
Interceptor.attach(mbedtls_ssl_conf_authmode, {
onEnter: function(args) {
console.log('[+] mbedtls_ssl_conf_authmode called, bypassing');
args[1] = 0; // MBEDTLS_SSL_VERIFY_NONE
}
});
}
} catch (e) {}
try {
var boringssl_set_custom_verify = Module.findExportByName(null, 'SSL_set_custom_verify');
if (boringssl_set_custom_verify) {
Interceptor.attach(boringssl_set_custom_verify, {
onEnter: function(args) {
console.log('[+] boringssl SSL_set_custom_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
Interceptor.attach(Module.findExportByName(null, 'SSL_get_verify_result'), {
onLeave: function(retval) {
console.log('[+] Native SSL_get_verify_result bypassed');
retval.replace(0); // X509_V_OK
}
});
} catch (e) {}
});
}
// --- Universal Root Detection Bypass Function ---
function addUniversalRootBypass() {
Java.perform(function() {
// Common root package/binary checks
var rootPackages = [
"com.noshufou.android.su", "com.noshufou.android.su.elite", "eu.chainfire.supersu",
"com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.koushikdutta.rommanager",
"com.koushikdutta.rommanager.license", "com.dimonvideo.luckypatcher", "com.chelpus.lackypatch",
"com.ramdroid.appquarantine", "com.ramdroid.appquarantinepro", "com.devadvance.rootcloak", "com.devadvance.rootcloakplus",
"de.robv.android.xposed.installer", "com.saurik.substrate", "com.zachspong.temprootremovejb", "com.amphoras.hidemyroot",
"com.amphoras.hidemyrootadfree", "com.formyhm.hiderootPremium", "com.formyhm.hideroot", "me.phh.superuser",
"eu.chainfire.supersu.pro", "com.kingouser.com", "com.android.vending.billing.InAppBillingService.COIN", "com.topjohnwu.magisk"
];
var rootBinaries = ["su", "which", "busybox", "supersu", "Superuser.apk", "KingoUser.apk", "SuperSu.apk", "magisk"];
// PackageManager
try {
var PackageManager = Java.use("android.app.ApplicationPackageManager");
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(pname, flags) {
if (rootPackages.indexOf(pname) > -1) {
console.log("[+] Universal root bypass: getPackageInfo for " + pname);
pname = "safe.package.fake";
}
return this.getPackageInfo.call(this, pname, flags);
};
} catch (e) {}
// File.exists
try {
var NativeFile = Java.use('java.io.File');
NativeFile.exists.implementation = function() {
var name = NativeFile.getName.call(this);
if (rootBinaries.indexOf(name) > -1) {
console.log("[+] Universal root bypass: File.exists for " + name);
return false;
} else {
return this.exists.call(this);
}
};
} catch (e) {}
// Runtime.exec
try {
var Runtime = Java.use('java.lang.Runtime');
Runtime.exec.overload('java.lang.String').implementation = function(cmd) {
if (cmd == "su") {
console.log("[+] Universal root bypass: Runtime.exec for su");
return null;
} else {
return this.exec.call(this, cmd);
}
};
} catch (e) {}
// SystemProperties
try {
var SystemProperties = Java.use('android.os.SystemProperties');
SystemProperties.get.overload('java.lang.String').implementation = function(name) {
if (name === 'ro.build.selinux' || name === 'ro.debuggable' || name === 'service.adb.root' || name === 'ro.secure') {
console.log("[+] Universal root bypass: SystemProperties.get for " + name);
return '0';
} else {
return this.get.call(this, name);
}
};
} catch (e) {}
// BufferedReader.readLine
try {
var BufferedReader = Java.use('java.io.BufferedReader');
BufferedReader.readLine.overload().implementation = function() {
var line = this.readLine.call(this);
if (line && line.indexOf("ro.build.tags=test-keys") > -1) {
console.log("[+] Universal root bypass: build.prop test-keys");
line = line.replace("ro.build.tags=test-keys", "ro.build.tags=release-keys");
}
return line;
};
} catch (e) {}
// ProcessBuilder
try {
var ProcessBuilder = Java.use('java.lang.ProcessBuilder');
ProcessBuilder.start.implementation = function() {
var cmd = this.command.call(this);
if (cmd && cmd.indexOf("su") > -1) {
console.log("[+] Universal root bypass: ProcessBuilder for su");
cmd = ["fakecmd"];
this.command.call(this, cmd);
}
return this.start.call(this);
};
} catch (e) {}
// Dynamic class/method scan for root
Java.enumerateLoadedClasses({
onMatch: function(className) {
var lc = className.toLowerCase();
if (
lc.indexOf('root') !== -1 ||
lc.indexOf('su') !== -1 ||
lc.indexOf('magisk') !== -1 ||
lc.indexOf('xposed') !== -1 ||
lc.indexOf('substrate') !== -1
) {
try {
var klass = Java.use(className);
['isRooted', 'checkRoot', 'detectRoot', 'isDeviceRooted', 'isJailbroken', 'isRootAvailable', 'isRoot'].forEach(function(method) {
if (klass[method]) {
klass[method].implementation = function() {
console.log('[+] Universal dynamic root bypass: ' + className + '.' + method + '()');
return false;
};
}
});
} catch (e) {}
}
},
onComplete: function() {}
});
});
}
Java.perform(function() {
// ---------------- Root Detection Bypass ----------------
var RootPackages = [
"com.noshufou.android.su", "com.noshufou.android.su.elite", "eu.chainfire.supersu",
"com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.koushikdutta.rommanager",
"com.koushikdutta.rommanager.license", "com.dimonvideo.luckypatcher", "com.chelpus.lackypatch",
"com.ramdroid.appquarantine", "com.ramdroid.appquarantinepro", "com.devadvance.rootcloak", "com.devadvance.rootcloakplus",
"de.robv.android.xposed.installer", "com.saurik.substrate", "com.zachspong.temprootremovejb", "com.amphoras.hidemyroot",
"com.amphoras.hidemyrootadfree", "com.formyhm.hiderootPremium", "com.formyhm.hideroot", "me.phh.superuser",
"eu.chainfire.supersu.pro", "com.kingouser.com", "com.android.vending.billing.InAppBillingService.COIN", "com.topjohnwu.magisk"
];
var RootBinaries = ["su", "which", "busybox", "supersu", "Superuser.apk", "KingoUser.apk", "SuperSu.apk", "magisk"];
var RootProperties = {
"ro.build.selinux": "1",
"ro.debuggable": "0",
"service.adb.root": "0",
"ro.secure": "1"
};
var PackageManager = Java.use("android.app.ApplicationPackageManager");
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(pname, flags) {
if (RootPackages.indexOf(pname) > -1) {
console.log("Bypass root check for package: " + pname);
pname = "safe.package.fake";
}
return this.getPackageInfo.call(this, pname, flags);
};
var NativeFile = Java.use('java.io.File');
NativeFile.exists.implementation = function() {
var name = NativeFile.getName.call(this);
if (RootBinaries.indexOf(name) > -1) {
console.log("Bypass NativeFile.exists for binary: " + name);
return false;
} else {
return this.exists.call(this);
}
};
var Runtime = Java.use('java.lang.Runtime');
Runtime.exec.overload('java.lang.String').implementation = function(cmd) {
if (cmd == "su") {
console.log("Bypass Runtime.exec for command: " + cmd);
return null;
} else {
return this.exec.call(this, cmd);
}
};
var SystemProperties = Java.use('android.os.SystemProperties');
SystemProperties.get.overload('java.lang.String').implementation = function(name) {
if (RootProperties[name]) {
console.log("Bypass SystemProperties.get for: " + name);
return RootProperties[name];
} else {
return this.get.call(this, name);
}
};
var BufferedReader = Java.use('java.io.BufferedReader');
BufferedReader.readLine.overload().implementation = function() {
var line = this.readLine.call(this);
if (line && line.indexOf("ro.build.tags=test-keys") > -1) {
console.log("Bypass build.prop test-keys");
line = line.replace("ro.build.tags=test-keys", "ro.build.tags=release-keys");
}
return line;
};
Interceptor.attach(Module.findExportByName("libc.so", "fopen"), {
onEnter: function(args) {
var path = Memory.readCString(args[0]);
if (path.indexOf("build.prop") > -1) {
console.log("Bypass fopen for build.prop");
Memory.writeUtf8String(args[0], "/fake/path/build.prop");
}
}
});
var ProcessBuilder = Java.use('java.lang.ProcessBuilder');
ProcessBuilder.start.implementation = function() {
var cmd = this.command.call(this);
if (cmd && cmd.indexOf("su") > -1) {
console.log("Bypass ProcessBuilder for su");
cmd = ["fakecmd"];
this.command.call(this, cmd);
}
return this.start.call(this);
};
if (Java.androidVersion.startsWith('5') || Java.androidVersion.startsWith('6') || Java.androidVersion.startsWith('7') || Java.androidVersion.startsWith('8') || Java.androidVersion.startsWith('9') || Java.androidVersion.startsWith('10')) {
var KeyInfo = Java.use('android.security.keystore.KeyInfo');
KeyInfo.isInsideSecureHardware.implementation = function() {
console.log("Bypass KeyInfo.isInsideSecureHardware");
return false;
};
}
var openPtr = Module.findExportByName("libc.so", "open");
var accessPtr = Module.findExportByName("libc.so", "access");
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
var access = new NativeFunction(accessPtr, 'int', ['pointer', 'int']);
Interceptor.replace(openPtr, new NativeCallback(function(path, flags) {
if (Memory.readUtf8String(path).endsWith("/su")) {
return -1;
}
return open(path, flags);
}, 'int', ['pointer', 'int']));
Interceptor.replace(accessPtr, new NativeCallback(function(path, mode) {
if (Memory.readUtf8String(path).endsWith("/su")) {
return -1;
}
return access(path, mode);
}, 'int', ['pointer', 'int']));
// ---------------- SSL Pinning Bypass ----------------
console.log('\n======\n[#] Android SSL Pinning Bypass [#]\n======');
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'dev.asd.test.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() {
return [];
}
}
});
var TrustManagers = [TrustManager.$new()];
var SSLContext_init = SSLContext.init.overload(
'[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'
);
SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
console.log('[+] Bypassing TrustManager (Android < 7)');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
// OkHTTPv3 (quadruple bypass) //
/////////////////////////////////
try {
// Bypass OkHTTPv3 {1}
var okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {1} pinner not found');
//console.log(err);
errDict[err] = ['okhttp3.CertificatePinner', 'check'];
}
try {
// Bypass OkHTTPv3 {2}
// This method of CertificatePinner.check is deprecated but could be found in some old Android apps
var okhttp3_Activity_2 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_2.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {2} pinner not found');
//console.log(err);
//errDict[err] = ['okhttp3.CertificatePinner', 'check'];
}
try {
// Bypass OkHTTPv3 {3}
var okhttp3_Activity_3 = Java.use('okhttp3.CertificatePinner');
okhttp3_Activity_3.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {3}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {3} pinner not found');
//console.log(err);
errDict[err] = ['okhttp3.CertificatePinner', 'check'];
}
try {
// Bypass OkHTTPv3 {4}
var okhttp3_Activity_4 = Java.use('okhttp3.CertificatePinner');
//okhttp3_Activity_4['check$okhttp'].implementation = function(a, b) {
okhttp3_Activity_4.check$okhttp.overload('java.lang.String', 'kotlin.jvm.functions.Function0').implementation = function(a, b) {
console.log('[+] Bypassing OkHTTPv3 {4}: ' + a);
return;
};
} catch (err) {
console.log('[-] OkHTTPv3 {4} pinner not found');
//console.log(err);
errDict[err] = ['okhttp3.CertificatePinner', 'check$okhttp'];
}
// Trustkit (triple bypass) //
//////////////////////////////
try {
// Bypass Trustkit {1}
var trustkit_Activity_1 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
trustkit_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {
console.log('[+] Bypassing Trustkit {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {1} pinner not found');
//console.log(err);
errDict[err] = ['com.datatheorem.android.trustkit.pinning.OkHostnameVerifier', 'verify'];
}
try {
// Bypass Trustkit {2}
var trustkit_Activity_2 = Java.use('com.datatheorem.android.trustkit.pinning.OkHostnameVerifier');
trustkit_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {
console.log('[+] Bypassing Trustkit {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Trustkit {2} pinner not found');
//console.log(err);
errDict[err] = ['com.datatheorem.android.trustkit.pinning.OkHostnameVerifier', 'verify'];
}
try {
// Bypass Trustkit {3}
var trustkit_PinningTrustManager = Java.use('com.datatheorem.android.trustkit.pinning.PinningTrustManager');
trustkit_PinningTrustManager.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String').implementation = function(chain, authType) {
console.log('[+] Bypassing Trustkit {3}');
};
} catch (err) {
console.log('[-] Trustkit {3} pinner not found');
//console.log(err);
errDict[err] = ['com.datatheorem.android.trustkit.pinning.PinningTrustManager', 'checkServerTrusted'];
}
// TrustManagerImpl (Android > 7) //
////////////////////////////////////
try {
// Bypass TrustManagerImpl (Android > 7) {1}
var array_list = Java.use("java.util.ArrayList");
var TrustManagerImpl_Activity_1 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl_Activity_1.checkTrustedRecursive.implementation = function(certs, ocspData, tlsSctData, host, clientAuth, untrustedChain, trustAnchorChain, used) {
console.log('[+] Bypassing TrustManagerImpl (Android > 7) checkTrustedRecursive check for: ' + host);
return array_list.$new();
};
} catch (err) {
console.log('[-] TrustManagerImpl (Android > 7) checkTrustedRecursive check not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.TrustManagerImpl', 'checkTrustedRecursive'];
}
try {
// Bypass TrustManagerImpl (Android > 7) {2} (probably no more necessary)
var TrustManagerImpl_Activity_2 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl_Activity_2.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log('[+] Bypassing TrustManagerImpl (Android > 7) verifyChain check for: ' + host);
return untrustedChain;
};
} catch (err) {
console.log('[-] TrustManagerImpl (Android > 7) verifyChain check not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.TrustManagerImpl', 'verifyChain'];
}
// Appcelerator Titanium PinningTrustManager //
///////////////////////////////////////////////
try {
var appcelerator_PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');
appcelerator_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Bypassing Appcelerator PinningTrustManager');
return;
};
} catch (err) {
console.log('[-] Appcelerator PinningTrustManager pinner not found');
//console.log(err);
errDict[err] = ['appcelerator.https.PinningTrustManager', 'checkServerTrusted'];
}
// Fabric PinningTrustManager //
////////////////////////////////
try {
var fabric_PinningTrustManager = Java.use('io.fabric.sdk.android.services.network.PinningTrustManager');
fabric_PinningTrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Bypassing Fabric PinningTrustManager');
return;
};
} catch (err) {
console.log('[-] Fabric PinningTrustManager pinner not found');
//console.log(err);
errDict[err] = ['io.fabric.sdk.android.services.network.PinningTrustManager', 'checkServerTrusted'];
}
// OpenSSLSocketImpl Conscrypt (double bypass) //
/////////////////////////////////////////////////
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, JavaObject, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt {1}');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Conscrypt {1} pinner not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.OpenSSLSocketImpl', 'verifyCertificateChain'];
}
try {
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certChain, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt {2}');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Conscrypt {2} pinner not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.OpenSSLSocketImpl', 'verifyCertificateChain'];
}
// OpenSSLEngineSocketImpl Conscrypt //
///////////////////////////////////////
try {
var OpenSSLEngineSocketImpl_Activity = Java.use('com.android.org.conscrypt.OpenSSLEngineSocketImpl');
OpenSSLEngineSocketImpl_Activity.verifyCertificateChain.overload('[Ljava.lang.Long;', 'java.lang.String').implementation = function(a, b) {
console.log('[+] Bypassing OpenSSLEngineSocketImpl Conscrypt: ' + b);
};
} catch (err) {
console.log('[-] OpenSSLEngineSocketImpl Conscrypt pinner not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.OpenSSLEngineSocketImpl', 'verifyCertificateChain'];
}
// OpenSSLSocketImpl Apache Harmony //
//////////////////////////////////////
try {
var OpenSSLSocketImpl_Harmony = Java.use('org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl');
OpenSSLSocketImpl_Harmony.verifyCertificateChain.implementation = function(asn1DerEncodedCertificateChain, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Apache Harmony');
};
} catch (err) {
console.log('[-] OpenSSLSocketImpl Apache Harmony pinner not found');
//console.log(err);
errDict[err] = ['org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl', 'verifyCertificateChain'];
}
// PhoneGap sslCertificateChecker //
////////////////////////////////////
try {
var phonegap_Activity = Java.use('nl.xservices.plugins.sslCertificateChecker');
phonegap_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function(a, b, c) {
console.log('[+] Bypassing PhoneGap sslCertificateChecker: ' + a);
return true;
};
} catch (err) {
console.log('[-] PhoneGap sslCertificateChecker pinner not found');
//console.log(err);
errDict[err] = ['nl.xservices.plugins.sslCertificateChecker', 'execute'];
}
// IBM MobileFirst pinTrustedCertificatePublicKey (double bypass) //
////////////////////////////////////////////////////////////////////
try {
// Bypass IBM MobileFirst {1}
var WLClient_Activity_1 = Java.use('com.worklight.wlclient.api.WLClient');
WLClient_Activity_1.getInstance().pinTrustedCertificatePublicKey.overload('java.lang.String').implementation = function(cert) {
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {1}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {1} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.api.WLClient', 'pinTrustedCertificatePublicKey'];
}
try {
// Bypass IBM MobileFirst {2}
var WLClient_Activity_2 = Java.use('com.worklight.wlclient.api.WLClient');
WLClient_Activity_2.getInstance().pinTrustedCertificatePublicKey.overload('[Ljava.lang.String;').implementation = function(cert) {
console.log('[+] Bypassing IBM MobileFirst pinTrustedCertificatePublicKey {2}: ' + cert);
return;
};
} catch (err) {
console.log('[-] IBM MobileFirst pinTrustedCertificatePublicKey {2} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.api.WLClient', 'pinTrustedCertificatePublicKey'];
}
// IBM WorkLight (ancestor of MobileFirst) HostNameVerifierWithCertificatePinning (quadruple bypass) //
///////////////////////////////////////////////////////////////////////////////////////////////////////
try {
// Bypass IBM WorkLight {1}
var worklight_Activity_1 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_1.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function(a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {1} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning', 'verify'];
}
try {
// Bypass IBM WorkLight {2}
var worklight_Activity_2 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_2.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {2} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning', 'verify'];
}
try {
// Bypass IBM WorkLight {3}
var worklight_Activity_3 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_3.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;').implementation = function(a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {3}: ' + a);
return;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {3} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning', 'verify'];
}
try {
// Bypass IBM WorkLight {4}
var worklight_Activity_4 = Java.use('com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning');
worklight_Activity_4.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {
console.log('[+] Bypassing IBM WorkLight HostNameVerifierWithCertificatePinning {4}: ' + a);
return true;
};
} catch (err) {
console.log('[-] IBM WorkLight HostNameVerifierWithCertificatePinning {4} pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.wlclient.certificatepinning.HostNameVerifierWithCertificatePinning', 'verify'];
}
// Conscrypt CertPinManager //
//////////////////////////////
try {
var conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
conscrypt_CertPinManager_Activity.checkChainPinning.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing Conscrypt CertPinManager: ' + a);
return;
};
} catch (err) {
console.log('[-] Conscrypt CertPinManager pinner not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.CertPinManager', 'checkChainPinning'];
}
// Conscrypt CertPinManager (Legacy) //
///////////////////////////////////////
try {
var legacy_conscrypt_CertPinManager_Activity = Java.use('com.android.org.conscrypt.CertPinManager');
legacy_conscrypt_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing Conscrypt CertPinManager (Legacy): ' + a);
return true;
};
} catch (err) {
console.log('[-] Conscrypt CertPinManager (Legacy) pinner not found');
//console.log(err);
errDict[err] = ['com.android.org.conscrypt.CertPinManager', 'isChainValid'];
}
// CWAC-Netsecurity (unofficial back-port pinner for Android<4.2) CertPinManager //
///////////////////////////////////////////////////////////////////////////////////
try {
var cwac_CertPinManager_Activity = Java.use('com.commonsware.cwac.netsecurity.conscrypt.CertPinManager');
cwac_CertPinManager_Activity.isChainValid.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing CWAC-Netsecurity CertPinManager: ' + a);
return true;
};
} catch (err) {
console.log('[-] CWAC-Netsecurity CertPinManager pinner not found');
//console.log(err);
errDict[err] = ['com.commonsware.cwac.netsecurity.conscrypt.CertPinManager', 'isChainValid'];
}
// Worklight Androidgap WLCertificatePinningPlugin //
/////////////////////////////////////////////////////
try {
var androidgap_WLCertificatePinningPlugin_Activity = Java.use('com.worklight.androidgap.plugin.WLCertificatePinningPlugin');
androidgap_WLCertificatePinningPlugin_Activity.execute.overload('java.lang.String', 'org.json.JSONArray', 'org.apache.cordova.CallbackContext').implementation = function(a, b, c) {
console.log('[+] Bypassing Worklight Androidgap WLCertificatePinningPlugin: ' + a);
return true;
};
} catch (err) {
console.log('[-] Worklight Androidgap WLCertificatePinningPlugin pinner not found');
//console.log(err);
errDict[err] = ['com.worklight.androidgap.plugin.WLCertificatePinningPlugin', 'execute'];
}
// Netty FingerprintTrustManagerFactory //
//////////////////////////////////////////
try {
var netty_FingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');
//NOTE: sometimes this below implementation could be useful
//var netty_FingerprintTrustManagerFactory = Java.use('org.jboss.netty.handler.ssl.util.FingerprintTrustManagerFactory');
netty_FingerprintTrustManagerFactory.checkTrusted.implementation = function(type, chain) {
console.log('[+] Bypassing Netty FingerprintTrustManagerFactory');
};
} catch (err) {
console.log('[-] Netty FingerprintTrustManagerFactory pinner not found');
//console.log(err);
errDict[err] = ['io.netty.handler.ssl.util.FingerprintTrustManagerFactory', 'checkTrusted'];
}
// Squareup CertificatePinner [OkHTTP<v3] (double bypass) //
////////////////////////////////////////////////////////////
try {
// Bypass Squareup CertificatePinner {1}
var Squareup_CertificatePinner_Activity_1 = Java.use('com.squareup.okhttp.CertificatePinner');
Squareup_CertificatePinner_Activity_1.check.overload('java.lang.String', 'java.security.cert.Certificate').implementation = function(a, b) {
console.log('[+] Bypassing Squareup CertificatePinner {1}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {1} pinner not found');
//console.log(err);
errDict[err] = ['com.squareup.okhttp.CertificatePinner', 'check'];
}
try {
// Bypass Squareup CertificatePinner {2}
var Squareup_CertificatePinner_Activity_2 = Java.use('com.squareup.okhttp.CertificatePinner');
Squareup_CertificatePinner_Activity_2.check.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {
console.log('[+] Bypassing Squareup CertificatePinner {2}: ' + a);
return;
};
} catch (err) {
console.log('[-] Squareup CertificatePinner {2} pinner not found');
//console.log(err);
errDict[err] = ['com.squareup.okhttp.CertificatePinner', 'check'];
}
// Squareup OkHostnameVerifier [OkHTTP v3] (double bypass) //
/////////////////////////////////////////////////////////////
try {
// Bypass Squareup OkHostnameVerifier {1}
var Squareup_OkHostnameVerifier_Activity_1 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
Squareup_OkHostnameVerifier_Activity_1.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {
console.log('[+] Bypassing Squareup OkHostnameVerifier {1}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier check not found');
//console.log(err);
errDict[err] = ['com.squareup.okhttp.internal.tls.OkHostnameVerifier', 'verify'];
}
try {
// Bypass Squareup OkHostnameVerifier {2}
var Squareup_OkHostnameVerifier_Activity_2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
Squareup_OkHostnameVerifier_Activity_2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {
console.log('[+] Bypassing Squareup OkHostnameVerifier {2}: ' + a);
return true;
};
} catch (err) {
console.log('[-] Squareup OkHostnameVerifier check not found');
//console.log(err);
errDict[err] = ['com.squareup.okhttp.internal.tls.OkHostnameVerifier', 'verify'];
}
// Android WebViewClient (quadruple bypass) //
//////////////////////////////////////////////
try {
// Bypass WebViewClient {1} (deprecated from Android 6)
var AndroidWebViewClient_Activity_1 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_1.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function(obj1, obj2, obj3) {
console.log('[+] Bypassing Android WebViewClient check {1}');
};
} catch (err) {
console.log('[-] Android WebViewClient {1} check not found');
//console.log(err)
errDict[err] = ['android.webkit.WebViewClient', 'onReceivedSslError'];
}
// Not working properly temporarily disused
//try {
// // Bypass WebViewClient {2}
// var AndroidWebViewClient_Activity_2 = Java.use('android.webkit.WebViewClient');
// AndroidWebViewClient_Activity_2.onReceivedHttpError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceResponse').implementation = function(obj1, obj2, obj3) {
// console.log('[+] Bypassing Android WebViewClient check {2}');
// };
//} catch (err) {
// console.log('[-] Android WebViewClient {2} check not found');
// //console.log(err)
// errDict[err] = ['android.webkit.WebViewClient', 'onReceivedHttpError'];
//}
try {
// Bypass WebViewClient {3}
var AndroidWebViewClient_Activity_3 = Java.use('android.webkit.WebViewClient');
//AndroidWebViewClient_Activity_3.onReceivedError.overload('android.webkit.WebView', 'int', 'java.lang.String', 'java.lang.String').implementation = function(obj1, obj2, obj3, obj4) {
AndroidWebViewClient_Activity_3.onReceivedError.implementation = function(view, errCode, description, failingUrl) {
console.log('[+] Bypassing Android WebViewClient check {3}');
};
} catch (err) {
console.log('[-] Android WebViewClient {3} check not found');
//console.log(err)
errDict[err] = ['android.webkit.WebViewClient', 'onReceivedError'];
}
try {
// Bypass WebViewClient {4}
var AndroidWebViewClient_Activity_4 = Java.use('android.webkit.WebViewClient');
AndroidWebViewClient_Activity_4.onReceivedError.overload('android.webkit.WebView', 'android.webkit.WebResourceRequest', 'android.webkit.WebResourceError').implementation = function(obj1, obj2, obj3) {
console.log('[+] Bypassing Android WebViewClient check {4}');
};
} catch (err) {
console.log('[-] Android WebViewClient {4} check not found');
//console.log(err)
errDict[err] = ['android.webkit.WebViewClient', 'onReceivedError'];
}
// Apache Cordova WebViewClient //
//////////////////////////////////
try {
var CordovaWebViewClient_Activity = Java.use('org.apache.cordova.CordovaWebViewClient');
CordovaWebViewClient_Activity.onReceivedSslError.overload('android.webkit.WebView', 'android.webkit.SslErrorHandler', 'android.net.http.SslError').implementation = function(obj1, obj2, obj3) {
console.log('[+] Bypassing Apache Cordova WebViewClient check');
obj3.proceed();
};
} catch (err) {
console.log('[-] Apache Cordova WebViewClient check not found');
//console.log(err);
}
// Boye AbstractVerifier //
///////////////////////////
try {
var boye_AbstractVerifier = Java.use('ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier');
boye_AbstractVerifier.verify.implementation = function(host, ssl) {
console.log('[+] Bypassing Boye AbstractVerifier check for: ' + host);
};
} catch (err) {
console.log('[-] Boye AbstractVerifier check not found');
//console.log(err);
errDict[err] = ['ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier', 'verify'];
}
// Apache AbstractVerifier (quadruple bypass) //
////////////////////////////////////////////////
try {
var apache_AbstractVerifier_1 = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
apache_AbstractVerifier_1.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function(a, b) {
console.log('[+] Bypassing Apache AbstractVerifier {1} check for: ' + a);
return;
};
} catch (err) {
console.log('[-] Apache AbstractVerifier {1} check not found');
//console.log(err);
errDict[err] = ['org.apache.http.conn.ssl.AbstractVerifier', 'verify'];
}
try {
var apache_AbstractVerifier_2 = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
apache_AbstractVerifier_2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSocket').implementation = function(a, b) {
console.log('[+] Bypassing Apache AbstractVerifier {2} check for: ' + a);
return;
};
} catch (err) {
console.log('[-] Apache AbstractVerifier {2} check not found');
//console.log(err);
errDict[err] = ['org.apache.http.conn.ssl.AbstractVerifier', 'verify'];
}
try {
var apache_AbstractVerifier_3 = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
apache_AbstractVerifier_3.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(a, b) {
console.log('[+] Bypassing Apache AbstractVerifier {3} check for: ' + a);
return;
};
} catch (err) {
console.log('[-] Apache AbstractVerifier {3} check not found');
//console.log(err);
errDict[err] = ['org.apache.http.conn.ssl.AbstractVerifier', 'verify'];
}
try {
var apache_AbstractVerifier_4 = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
apache_AbstractVerifier_4.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;', 'boolean').implementation = function(a, b, c, d) {
console.log('[+] Bypassing Apache AbstractVerifier {4} check for: ' + a);
return;
};
} catch (err) {
console.log('[-] Apache AbstractVerifier {4} check not found');
//console.log(err);
errDict[err] = ['org.apache.http.conn.ssl.AbstractVerifier', 'verify'];
}
// Chromium Cronet //
/////////////////////
try {
var CronetEngineBuilderImpl_Activity = Java.use("org.chromium.net.impl.CronetEngineBuilderImpl");
// Setting argument to TRUE (default is TRUE) to disable Public Key pinning for local trust anchors
CronetEngine_Activity.enablePublicKeyPinningBypassForLocalTrustAnchors.overload('boolean').implementation = function(a) {
console.log("[+] Disabling Public Key pinning for local trust anchors in Chromium Cronet");
var cronet_obj_1 = CronetEngine_Activity.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);
return cronet_obj_1;
};
// Bypassing Chromium Cronet pinner
CronetEngine_Activity.addPublicKeyPins.overload('java.lang.String', 'java.util.Set', 'boolean', 'java.util.Date').implementation = function(hostName, pinsSha256, includeSubdomains, expirationDate) {
console.log("[+] Bypassing Chromium Cronet pinner: " + hostName);
var cronet_obj_2 = CronetEngine_Activity.addPublicKeyPins.call(this, hostName, pinsSha256, includeSubdomains, expirationDate);
return cronet_obj_2;
};
} catch (err) {
console.log('[-] Chromium Cronet pinner not found')
//console.log(err);
}
// Flutter Pinning packages http_certificate_pinning and ssl_pinning_plugin (double bypass) //
//////////////////////////////////////////////////////////////////////////////////////////////
try {
// Bypass HttpCertificatePinning.check {1}
var HttpCertificatePinning_Activity = Java.use('diefferson.http_certificate_pinning.HttpCertificatePinning');
HttpCertificatePinning_Activity.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function(a, b, c, d, e) {
console.log('[+] Bypassing Flutter HttpCertificatePinning : ' + a);
return true;
};
} catch (err) {
console.log('[-] Flutter HttpCertificatePinning pinner not found');
//console.log(err);
errDict[err] = ['diefferson.http_certificate_pinning.HttpCertificatePinning', 'checkConnexion'];
}
try {
// Bypass SslPinningPlugin.check {2}
var SslPinningPlugin_Activity = Java.use('com.macif.plugin.sslpinningplugin.SslPinningPlugin');
SslPinningPlugin_Activity.checkConnexion.overload("java.lang.String", "java.util.List", "java.util.Map", "int", "java.lang.String").implementation = function(a, b, c, d, e) {
console.log('[+] Bypassing Flutter SslPinningPlugin: ' + a);
return true;
};
} catch (err) {
console.log('[-] Flutter SslPinningPlugin pinner not found');
//console.log(err);
errDict[err] = ['com.macif.plugin.sslpinningplugin.SslPinningPlugin', 'checkConnexion'];
}
// Unusual/obfuscated pinners bypass //
///////////////////////////////////////
try {
// Iterating all caught pinner errors and try to overload them
for (var key in errDict) {
var errStr = key;
var targetClass = errDict[key][0]
var targetFunc = errDict[key][1]
var retType = Java.use(targetClass)[targetFunc].returnType.type;
//console.log("errDict content: "+errStr+" "+targetClass+"."+targetFunc);
if (String(errStr).includes('.overload')) {
overloader(errStr, targetClass, targetFunc, retType);
}
}
} catch (err) {
//console.log('[-] The pinner "'+targetClass+'.'+targetFunc+'" is not unusual/obfuscated, skipping it..');
//console.log(err);
}
// Dynamic SSLPeerUnverifiedException Bypasser //
// An useful technique to bypass SSLPeerUnverifiedException failures raising //
// when the Android app uses some uncommon SSL Pinning methods or an heavily //
// code obfuscation. Inspired by an idea of: https://github.com/httptoolkit //
///////////////////////////////////////////////////////////////////////////////
try {
var UnverifiedCertError = Java.use('javax.net.ssl.SSLPeerUnverifiedException');
UnverifiedCertError.$init.implementation = function(reason) {
try {
var stackTrace = Java.use('java.lang.Thread').currentThread().getStackTrace();
var exceptionStackIndex = stackTrace.findIndex(stack =>
stack.getClassName() === "javax.net.ssl.SSLPeerUnverifiedException"
);
// Retrieve the method raising the SSLPeerUnverifiedException
var callingFunctionStack = stackTrace[exceptionStackIndex + 1];
var className = callingFunctionStack.getClassName();
var methodName = callingFunctionStack.getMethodName();
var callingClass = Java.use(className);
var callingMethod = callingClass[methodName];
console.log('\x1b[36m[!] Unexpected SSLPeerUnverifiedException occurred related to the method "' + className + '.' + methodName + '"\x1b[0m');
//console.log("Stacktrace details:\n"+stackTrace);
// Checking if the SSLPeerUnverifiedException was generated by an usually negligible (not blocking) method
if (className == 'com.android.org.conscrypt.ActiveSession' || className == 'com.google.android.gms.org.conscrypt.ActiveSession') {
throw 'Reason: skipped SSLPeerUnverifiedException bypass since the exception was raised from a (usually) non blocking method on the Android app';
} else {
console.log('\x1b[34m[!] Starting to dynamically circumvent the SSLPeerUnverifiedException for the method "' + className + '.' + methodName + '"...\x1b[0m');
var retTypeName = callingMethod.returnType.type;
// Skip it when the calling method was already bypassed with Frida
if (!(callingMethod.implementation)) {
// Trying to bypass (via implementation) the SSLPeerUnverifiedException if due to an uncommon SSL Pinning method
callingMethod.implementation = function() {
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + className + '.' + methodName + '" via Frida function implementation\x1b[0m');
returner(retTypeName);
}
}
}
} catch (err2) {
// Dynamic circumvention via function implementation does not works, then trying via function overloading
if (String(err2).includes('.overload')) {
overloader(err2, className, methodName, retTypeName);
} else {
if (String(err2).includes('SSLPeerUnverifiedException')) {
console.log('\x1b[36m[-] Failed to dynamically circumvent SSLPeerUnverifiedException -> ' + err2 + '\x1b[0m');
} else {
//console.log('\x1b[36m[-] Another kind of exception raised during overloading -> '+err2+'\x1b[0m');
}
}
}
//console.log('\x1b[36m[+] SSLPeerUnverifiedException hooked\x1b[0m');
return this.$init(reason);
};
} catch (err1) {
//console.log('\x1b[36m[-] SSLPeerUnverifiedException not found\x1b[0m');
//console.log('\x1b[36m'+err1+'\x1b[0m');
}
});
// --- UNIVERSAL SSL PINNING BYPASS (Java) ---
Java.perform(function() {
try {
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var HostnameVerifier = Java.use('javax.net.ssl.HostnameVerifier');
var HttpsURLConnection = Java.use('javax.net.ssl.HttpsURLConnection');
// Universal TrustManager bypass
X509TrustManager.checkServerTrusted.implementation = function(chain, authType) {
console.log('[+] Universal X509TrustManager.checkServerTrusted() bypassed');
};
// Universal HostnameVerifier bypass
HostnameVerifier.verify.implementation = function(hostname, session) {
console.log('[+] HostnameVerifier.verify() bypassed for host: ' + hostname);
return true;
};
// Force HttpsURLConnection to trust all hosts
HttpsURLConnection.setDefaultHostnameVerifier.implementation = function(verifier) {
console.log('[+] HttpsURLConnection.setDefaultHostnameVerifier() bypassed');
return;
};
// TrustManagerImpl (AOSP/Conscrypt)
try {
var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
console.log('[+] TrustManagerImpl.verifyChain() bypassed for host: ' + host);
return untrustedChain;
};
} catch (e) {}
} catch (e) {
console.log('[-] Universal SSL pinning bypass error: ' + e);
}
});
// --- NATIVE SSL PINNING BYPASS (OpenSSL) ---
try {
var sslctx_custom_verify = Module.findExportByName('libssl.so', 'SSL_CTX_set_custom_verify');
if (sslctx_custom_verify) {
Interceptor.attach(sslctx_custom_verify, {
onEnter: function(args) {
console.log('[+] Native SSL_CTX_set_custom_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
var sslctx_set_verify = Module.findExportByName('libssl.so', 'SSL_CTX_set_verify');
if (sslctx_set_verify) {
Interceptor.attach(sslctx_set_verify, {
onEnter: function(args) {
console.log('[+] Native SSL_CTX_set_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
// --- WebView SSL Error Bypass ---
Java.perform(function() {
try {
var WebViewClient = Java.use('android.webkit.WebViewClient');
WebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
console.log('[+] WebViewClient.onReceivedSslError() bypassed');
handler.proceed();
};
} catch (e) {}
});
// --- OkHttp (All Versions, Obfuscated, Kotlin, etc.) ---
Java.perform(function() {
try {
var OkHostnameVerifier = Java.use('okhttp3.internal.tls.OkHostnameVerifier');
OkHostnameVerifier.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(host, session) {
console.log('[+] OkHttp3 OkHostnameVerifier.verify() bypassed for host: ' + host);
return true;
};
} catch (e) {}
try {
var OkHostnameVerifier2 = Java.use('com.squareup.okhttp.internal.tls.OkHostnameVerifier');
OkHostnameVerifier2.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(host, session) {
console.log('[+] OkHttp2 OkHostnameVerifier.verify() bypassed for host: ' + host);
return true;
};
} catch (e) {}
});
// --- Conscrypt, BouncyCastle, and Other Providers ---
Java.perform(function() {
try {
var conscrypt_TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
conscrypt_TrustManagerImpl.checkTrustedRecursive.implementation = function() {
console.log('[+] Conscrypt TrustManagerImpl.checkTrustedRecursive() bypassed');
return [];
};
} catch (e) {}
try {
var bouncy_TrustManager = Java.use('org.bouncycastle.jsse.provider.BouncyCastleJsseProvider');
bouncy_TrustManager.checkServerTrusted.implementation = function() {
console.log('[+] BouncyCastle checkServerTrusted() bypassed');
};
} catch (e) {}
});
// --- Dynamic Class Scanning for Custom/Obfuscated Pinning ---
Java.perform(function() {
Java.enumerateLoadedClasses({
onMatch: function(className) {
if (className.toLowerCase().indexOf('pin') !== -1 || className.toLowerCase().indexOf('trust') !== -1) {
try {
var klass = Java.use(className);
if (klass.checkServerTrusted) {
klass.checkServerTrusted.implementation = function() {
console.log('[+] Dynamic bypass: ' + className + '.checkServerTrusted()');
};
}
if (klass.verify) {
klass.verify.implementation = function() {
console.log('[+] Dynamic bypass: ' + className + '.verify()');
return true;
};
}
} catch (e) {}
}
},
onComplete: function() {}
});
});
// --- Universal Java SSL Error Bypass (Fallback) ---
Java.perform(function() {
try {
var SSLPeerUnverifiedException = Java.use('javax.net.ssl.SSLPeerUnverifiedException');
SSLPeerUnverifiedException.$init.implementation = function(reason) {
console.log('[+] Universal SSLPeerUnverifiedException bypassed: ' + reason);
return this.$init('');
};
} catch (e) {}
});
// --- Cordova/Unity/Flutter/ReactNative/Other Frameworks ---
Java.perform(function() {
// Cordova
try {
var CordovaWebViewClient = Java.use('org.apache.cordova.CordovaWebViewClient');
CordovaWebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
console.log('[+] CordovaWebViewClient.onReceivedSslError() bypassed');
handler.proceed();
};
} catch (e) {}
// Unity
try {
var UnityWebRequest = Java.use('com.unity3d.player.UnityWebRequest');
UnityWebRequest.setCertificateHandler.implementation = function(handler) {
console.log('[+] UnityWebRequest.setCertificateHandler() bypassed');
};
} catch (e) {}
// Flutter (Dart native) - already covered by native hooks
});
// --- Extra Native Pinning (mbedtls, boringssl, etc.) ---
try {
var mbedtls_ssl_conf_authmode = Module.findExportByName(null, 'mbedtls_ssl_conf_authmode');
if (mbedtls_ssl_conf_authmode) {
Interceptor.attach(mbedtls_ssl_conf_authmode, {
onEnter: function(args) {
console.log('[+] mbedtls_ssl_conf_authmode called, bypassing');
args[1] = 0; // MBEDTLS_SSL_VERIFY_NONE
}
});
}
} catch (e) {}
try {
var boringssl_set_custom_verify = Module.findExportByName(null, 'SSL_set_custom_verify');
if (boringssl_set_custom_verify) {
Interceptor.attach(boringssl_set_custom_verify, {
onEnter: function(args) {
console.log('[+] boringssl SSL_set_custom_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
// --- ULTIMATE DYNAMIC SSL PINNING BYPASS (broad scan) ---
Java.perform(function() {
Java.enumerateLoadedClasses({
onMatch: function(className) {
var lc = className.toLowerCase();
if (
lc.indexOf('pin') !== -1 ||
lc.indexOf('trust') !== -1 ||
lc.indexOf('cert') !== -1 ||
lc.indexOf('ssl') !== -1 ||
lc.indexOf('verify') !== -1 ||
lc.indexOf('chain') !== -1
) {
try {
var klass = Java.use(className);
['checkServerTrusted', 'checkClientTrusted', 'verify', 'verifyCertificateChain', 'onReceivedError'].forEach(function(method) {
if (klass[method]) {
klass[method].implementation = function() {
console.log('[+] Ultimate dynamic bypass: ' + className + '.' + method + '()');
if (method === 'verify') return true;
if (method === 'onReceivedError') return;
return;
};
}
});
} catch (e) {}
}
},
onComplete: function() {}
});
});
// --- Apache HttpClient, Netty, JSSE, SSLSocketFactory, TrustManagerFactory, KeyManagerFactory ---
Java.perform(function() {
// Apache HttpClient
try {
var AbstractVerifier = Java.use('org.apache.http.conn.ssl.AbstractVerifier');
AbstractVerifier.verify.implementation = function(host, ssl) {
console.log('[+] Apache HttpClient AbstractVerifier.verify() bypassed for: ' + host);
};
} catch (e) {}
// Netty
try {
var NettyFingerprintTrustManagerFactory = Java.use('io.netty.handler.ssl.util.FingerprintTrustManagerFactory');
NettyFingerprintTrustManagerFactory.checkTrusted.implementation = function(type, chain) {
console.log('[+] Netty FingerprintTrustManagerFactory.checkTrusted() bypassed');
};
} catch (e) {}
// JSSE
try {
var SSLParametersImpl = Java.use('com.android.org.conscrypt.SSLParametersImpl');
SSLParametersImpl.setEndpointIdentificationAlgorithm.implementation = function(alg) {
console.log('[+] SSLParametersImpl.setEndpointIdentificationAlgorithm() bypassed');
};
} catch (e) {}
// SSLSocketFactory
try {
var SSLSocketFactory = Java.use('javax.net.ssl.SSLSocketFactory');
SSLSocketFactory.createSocket.overload('java.net.Socket', 'java.lang.String', 'int', 'boolean').implementation = function() {
console.log('[+] SSLSocketFactory.createSocket() bypassed');
return this.createSocket.apply(this, arguments);
};
} catch (e) {}
// TrustManagerFactory
try {
var TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
TrustManagerFactory.init.overload('java.security.KeyStore').implementation = function(ks) {
console.log('[+] TrustManagerFactory.init() bypassed');
return this.init(ks);
};
} catch (e) {}
// KeyManagerFactory
try {
var KeyManagerFactory = Java.use('javax.net.ssl.KeyManagerFactory');
KeyManagerFactory.init.overload('java.security.KeyStore', '[C').implementation = function(ks, pwd) {
console.log('[+] KeyManagerFactory.init() bypassed');
return this.init(ks, pwd);
};
} catch (e) {}
});
// --- Universal native SSL error bypass (SSL_get_verify_result) ---
try {
Interceptor.attach(Module.findExportByName(null, 'SSL_get_verify_result'), {
onLeave: function(retval) {
console.log('[+] Native SSL_get_verify_result bypassed');
retval.replace(0); // X509_V_OK
}
});
} catch (e) {}
// Helper functions should be outside Java.perform
function returner(typeName) {
if (typeName === undefined || typeName === 'void') {
return;
} else if (typeName === 'boolean') {
return true;
} else {
return null;
}
}
function overloader(errStr, targetClass, targetFunc, retType) {
var tClass = Java.use(targetClass);
var tFunc = tClass[targetFunc];
var params = [];
var argList = [];
var overloads = tFunc.overloads;
var returnTypeName = retType;
var splittedList = String(errStr).split('.overload');
for (var n = 1; n < splittedList.length; n++) {
var extractedOverload = splittedList[n].trim().split('(')[1].slice(0, -1).replaceAll("'", "");
if (extractedOverload.includes('<signature>')) {
continue;
}
console.log('\x1b[34m[!] Found the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"\x1b[0m');
if (!extractedOverload) {
tFunc.overload().implementation = function() {
var printStr = printer();
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else {
if (extractedOverload.includes(',')) {
argList = extractedOverload.split(', ');
}
if (argList.length == 0) {
tFunc.overload(extractedOverload).implementation = function(a) {
var printStr = printer();
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 2) {
tFunc.overload(argList[0], argList[1]).implementation = function(a, b) {
var printStr = printer(a);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 3) {
tFunc.overload(argList[0], argList[1], argList[2]).implementation = function(a, b, c) {
var printStr = printer(a, b);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 4) {
tFunc.overload(argList[0], argList[1], argList[2], argList[3]).implementation = function(a, b, c, d) {
var printStr = printer(a, b, c);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 5) {
tFunc.overload(argList[0], argList[1], argList[2], argList[3], argList[4]).implementation = function(a, b, c, d, e) {
var printStr = printer(a, b, c, d);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 6) {
tFunc.overload(argList[0], argList[1], argList[2], argList[3], argList[4], argList[5]).implementation = function(a, b, c, d, e, f) {
var printStr = printer(a, b, c, d, e);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 7) {
tFunc.overload(argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6]).implementation = function(a, b, c, d, e, f, g) {
var printStr = printer(a, b, c, d, e, f);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
} else if (argList.length == 8) {
tFunc.overload(argList[0], argList[1], argList[2], argList[3], argList[4], argList[5], argList[6], argList[7]).implementation = function(a, b, c, d, e, f, g, h) {
var printStr = printer(a, b, c, d, e, f, g);
console.log('\x1b[34m[+] Bypassing the unusual/obfuscated pinner "' + targetClass + '.' + targetFunc + '(' + extractedOverload + ')"' + printStr + '\x1b[0m');
returner(returnTypeName);
}
}
}
}
}
function printer(a, b, c, d, e, f, g, h) {
var printList = [];
var printStr = '';
if (typeof a === 'string') {
printList.push(a);
}
if (typeof b === 'string') {
printList.push(b);
}
if (typeof c === 'string') {
printList.push(c);
}
if (typeof d === 'string') {
printList.push(d);
}
if (typeof e === 'string') {
printList.push(e);
}
if (typeof f === 'string') {
printList.push(f);
}
if (typeof g === 'string') {
printList.push(g);
}
if (typeof h === 'string') {
printList.push(h);
}
if (printList.length !== 0) {
printStr = ' check for:';
for (var i = 0; i < printList.length; i++) {
printStr += ' ' + printList[i];
}
}
return printStr;
}
// === [ADDITIONAL ROOT DETECTION BYPASS CASES] ===
Java.perform(function() {
// SafetyNet Attestation API bypass
try {
var SafetyNetClient = Java.use('com.google.android.gms.safetynet.SafetyNetClient');
SafetyNetClient.attest.overload('[B', 'java.lang.String').implementation = function(jws, nonce) {
console.log('[+] SafetyNet attest() bypassed');
// Return a fake successful attestation
return Java.use('com.google.android.gms.tasks.Tasks').forResult(Java.use('com.google.android.gms.safetynet.SafetyNetApi$AttestationResponse').$new());
};
} catch (e) {}
// SafetyNet Response manipulation (for apps using response string)
try {
var SafetyNetResponse = Java.use('com.google.android.gms.safetynet.SafetyNetApi$AttestationResponse');
SafetyNetResponse.getJwsResult.implementation = function() {
console.log('[+] SafetyNet getJwsResult() bypassed');
// Return a valid/fake JWS
return 'FAKE_JWS_RESULT';
};
} catch (e) {}
// Magisk/Zygisk file checks
try {
var File = Java.use('java.io.File');
File.exists.implementation = function() {
var path = this.getAbsolutePath();
var magiskFiles = [
'/sbin/magisk', '/init.magisk.rc', '/system/bin/su', '/system/xbin/daemonsu', '/system/bin/busybox',
'/system/bin/which', '/system/app/Superuser.apk', '/system/app/MagiskManager.apk', '/data/adb/magisk.img', '/data/adb/modules/'
];
for (var i = 0; i < magiskFiles.length; i++) {
if (path.indexOf(magiskFiles[i]) !== -1) {
console.log('[+] Magisk/Zygisk file bypass: ' + path);
return false;
}
}
return this.exists.call(this);
};
} catch (e) {}
// System property checks (more properties)
try {
var SystemProperties = Java.use('android.os.SystemProperties');
SystemProperties.get.overload('java.lang.String').implementation = function(name) {
var rootProps = {
'ro.build.fingerprint': 'generic',
'ro.boot.verifiedbootstate': 'green',
'ro.boot.vbmeta.device_state': 'locked',
'ro.boot.flash.locked': '1',
'ro.boot.veritymode': 'enforcing',
'ro.boot.warranty_bit': '0',
'ro.debuggable': '0',
'ro.secure': '1'
};
if (rootProps[name]) {
console.log('[+] SystemProperties.get bypassed for: ' + name);
return rootProps[name];
}
return this.get.call(this, name);
};
} catch (e) {}
// Process checks (ps, pidof, pgrep)
try {
var Runtime = Java.use('java.lang.Runtime');
Runtime.exec.overload('java.lang.String').implementation = function(cmd) {
if (cmd.indexOf('ps') !== -1 || cmd.indexOf('pidof') !== -1 || cmd.indexOf('pgrep') !== -1) {
console.log('[+] Process check bypassed: ' + cmd);
return null;
}
return this.exec.call(this, cmd);
};
} catch (e) {}
// More root package checks
try {
var PackageManager = Java.use('android.app.ApplicationPackageManager');
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(pname, flags) {
var moreRootPkgs = [
'com.topjohnwu.magisk', 'com.devadvance.rootcloak', 'com.zachspong.temprootremovejb', 'com.amphoras.hidemyroot',
'com.amphoras.hidemyrootadfree', 'com.formyhm.hiderootPremium', 'com.formyhm.hideroot', 'me.phh.superuser',
'eu.chainfire.supersu.pro', 'com.kingouser.com', 'com.android.vending.billing.InAppBillingService.COIN', 'com.topjohnwu.magisk'
];
if (moreRootPkgs.indexOf(pname) > -1) {
console.log('[+] More root package bypass: ' + pname);
pname = 'safe.package.fake';
}
return this.getPackageInfo.call(this, pname, flags);
};
} catch (e) {}
});
// === [ADDITIONAL SSL PINNING BYPASS CASES] ===
Java.perform(function() {
// React Native SSL Pinning (react-native-ssl-pinning)
try {
var OkHttpClientProvider = Java.use('com.reactnativecommunity.networking.OkHttpClientProvider');
OkHttpClientProvider.createClient.implementation = function() {
console.log('[+] React Native OkHttpClientProvider.createClient() bypassed');
return this.createClient.call(this);
};
} catch (e) {}
// Flutter SSL Pinning (flutter_ssl_pinning)
try {
var FlutterSslPinning = Java.use('com.example.flutter_ssl_pinning.FlutterSslPinningPlugin');
FlutterSslPinning.check.implementation = function() {
console.log('[+] FlutterSslPinningPlugin.check() bypassed');
return true;
};
} catch (e) {}
// Retrofit/Volley/other HTTP clients (dynamic scan for common pinning methods)
Java.enumerateLoadedClasses({
onMatch: function(className) {
var lc = className.toLowerCase();
if (lc.indexOf('retrofit') !== -1 || lc.indexOf('volley') !== -1 || lc.indexOf('okhttp') !== -1) {
try {
var klass = Java.use(className);
if (klass.checkServerTrusted) {
klass.checkServerTrusted.implementation = function() {
console.log('[+] Dynamic HTTP client bypass: ' + className + '.checkServerTrusted()');
};
}
if (klass.verify) {
klass.verify.implementation = function() {
console.log('[+] Dynamic HTTP client bypass: ' + className + '.verify()');
return true;
};
}
} catch (e) {}
}
},
onComplete: function() {}
});
// More native SSL pinning hooks
try {
var ssl_set_verify = Module.findExportByName('libssl.so', 'SSL_set_verify');
if (ssl_set_verify) {
Interceptor.attach(ssl_set_verify, {
onEnter: function(args) {
console.log('[+] Native SSL_set_verify called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
var ssl_ctx_set_cert_verify_callback = Module.findExportByName('libssl.so', 'SSL_CTX_set_cert_verify_callback');
if (ssl_ctx_set_cert_verify_callback) {
Interceptor.attach(ssl_ctx_set_cert_verify_callback, {
onEnter: function(args) {
console.log('[+] Native SSL_CTX_set_cert_verify_callback called, bypassing');
args[1] = ptr(0);
}
});
}
} catch (e) {}
try {
var ssl_get_peer_certificate = Module.findExportByName('libssl.so', 'SSL_get_peer_certificate');
if (ssl_get_peer_certificate) {
Interceptor.attach(ssl_get_peer_certificate, {
onLeave: function(retval) {
console.log('[+] Native SSL_get_peer_certificate bypassed');
retval.replace(ptr(0));
}
});
}
} catch (e) {}
});
// === [ADVANCED LOGGING AND HOOK STATUS] ===
var hookLog = [];
function logHook(status, type, className, methodName, details) {
var msg = `[${status}] [${type}] ${className}.${methodName}${details ? ' ' + details : ''}`;
hookLog.push(msg);
console.log(msg);
}
function printSummary() {
console.log('\n=== Frida Universal Root & SSL Pinning Bypass Summary ===');
hookLog.forEach(function(msg) {
console.log(msg);
});
console.log('========================================================\n');
}
setImmediate(function() {
printSummary();
});
// === [EXTRA ROOT DETECTION BYPASS] ===
Java.perform(function() {
// Build properties
try {
var Build = Java.use('android.os.Build');
Build.TAGS.value = 'release-keys';
Build.FINGERPRINT.value = 'generic';
Build.BOARD.value = 'unknown';
Build.BRAND.value = 'generic';
Build.DEVICE.value = 'generic';
Build.PRODUCT.value = 'generic';
Build.MODEL.value = 'Android';
Build.MANUFACTURER.value = 'unknown';
logHook('OK', 'ROOT', 'android.os.Build', 'static fields', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'android.os.Build', 'static fields', e);
}
// Settings.Secure.getString
try {
var SettingsSecure = Java.use('android.provider.Settings$Secure');
SettingsSecure.getString.implementation = function(cr, name) {
if (name === 'adb_enabled' || name === 'development_settings_enabled') {
logHook('TRIGGER', 'ROOT', 'Settings$Secure', 'getString', name);
return '0';
}
return this.getString.call(this, cr, name);
};
logHook('OK', 'ROOT', 'Settings$Secure', 'getString', 'adb/dev settings');
} catch (e) {
logHook('FAIL', 'ROOT', 'Settings$Secure', 'getString', e);
}
// Debug.isDebuggerConnected
try {
var Debug = Java.use('android.os.Debug');
Debug.isDebuggerConnected.implementation = function() {
logHook('TRIGGER', 'ROOT', 'Debug', 'isDebuggerConnected', '');
return false;
};
Debug.waitingForDebugger.implementation = function() {
logHook('TRIGGER', 'ROOT', 'Debug', 'waitingForDebugger', '');
return false;
};
logHook('OK', 'ROOT', 'Debug', 'isDebuggerConnected/waitingForDebugger', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'Debug', 'isDebuggerConnected/waitingForDebugger', e);
}
// Class.forName
try {
var Class = Java.use('java.lang.Class');
Class.forName.overload('java.lang.String').implementation = function(name) {
logHook('TRIGGER', 'ROOT', 'Class', 'forName', name);
return this.forName.call(this, name);
};
logHook('OK', 'ROOT', 'Class', 'forName', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'Class', 'forName', e);
}
// System.loadLibrary
try {
var SystemClass = Java.use('java.lang.System');
SystemClass.loadLibrary.implementation = function(lib) {
logHook('TRIGGER', 'ROOT', 'System', 'loadLibrary', lib);
return this.loadLibrary.call(this, lib);
};
logHook('OK', 'ROOT', 'System', 'loadLibrary', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'System', 'loadLibrary', e);
}
// ProcessBuilder (all overloads)
try {
var ProcessBuilder = Java.use('java.lang.ProcessBuilder');
ProcessBuilder.start.implementation = function() {
var cmd = this.command.call(this);
if (cmd && cmd.toString().indexOf('su') > -1) {
logHook('TRIGGER', 'ROOT', 'ProcessBuilder', 'start', cmd);
cmd = ['fakecmd'];
this.command.call(this, cmd);
}
return this.start.call(this);
};
logHook('OK', 'ROOT', 'ProcessBuilder', 'start', 'all overloads');
} catch (e) {
logHook('FAIL', 'ROOT', 'ProcessBuilder', 'start', e);
}
// Runtime.exec (all overloads)
try {
var Runtime = Java.use('java.lang.Runtime');
var overloads = Runtime.exec.overloads;
for (var i = 0; i < overloads.length; i++) {
overloads[i].implementation = function() {
var cmd = arguments[0];
if (typeof cmd === 'string' && cmd.indexOf('su') !== -1) {
logHook('TRIGGER', 'ROOT', 'Runtime', 'exec', cmd);
return null;
}
return this.exec.apply(this, arguments);
};
}
logHook('OK', 'ROOT', 'Runtime', 'exec', 'all overloads');
} catch (e) {
logHook('FAIL', 'ROOT', 'Runtime', 'exec', e);
}
// Reflection: Method.invoke
try {
var Method = Java.use('java.lang.reflect.Method');
Method.invoke.implementation = function(obj, args) {
logHook('TRIGGER', 'ROOT', 'Method', 'invoke', this.getName());
return this.invoke.call(this, obj, args);
};
logHook('OK', 'ROOT', 'Method', 'invoke', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'Method', 'invoke', e);
}
// ActivityManager.getRunningServices/getRunningAppProcesses
try {
var ActivityManager = Java.use('android.app.ActivityManager');
ActivityManager.getRunningServices.implementation = function(max) {
logHook('TRIGGER', 'ROOT', 'ActivityManager', 'getRunningServices', '');
return Java.use('java.util.ArrayList').$new();
};
ActivityManager.getRunningAppProcesses.implementation = function() {
logHook('TRIGGER', 'ROOT', 'ActivityManager', 'getRunningAppProcesses', '');
return Java.use('java.util.ArrayList').$new();
};
logHook('OK', 'ROOT', 'ActivityManager', 'getRunningServices/getRunningAppProcesses', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'ActivityManager', 'getRunningServices/getRunningAppProcesses', e);
}
// Build.SERIAL and Build.getSerial
try {
var Build = Java.use('android.os.Build');
Build.SERIAL.value = 'unknown';
if (Build.getSerial) {
Build.getSerial.implementation = function() {
logHook('TRIGGER', 'ROOT', 'Build', 'getSerial', '');
return 'unknown';
};
}
logHook('OK', 'ROOT', 'Build', 'SERIAL/getSerial', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'Build', 'SERIAL/getSerial', e);
}
// SystemClock.elapsedRealtime/uptimeMillis
try {
var SystemClock = Java.use('android.os.SystemClock');
SystemClock.elapsedRealtime.implementation = function() {
logHook('TRIGGER', 'ROOT', 'SystemClock', 'elapsedRealtime', '');
return 10000;
};
SystemClock.uptimeMillis.implementation = function() {
logHook('TRIGGER', 'ROOT', 'SystemClock', 'uptimeMillis', '');
return 10000;
};
logHook('OK', 'ROOT', 'SystemClock', 'elapsedRealtime/uptimeMillis', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'SystemClock', 'elapsedRealtime/uptimeMillis', e);
}
// dalvik.system.VMStack.getCallingClassLoader
try {
var VMStack = Java.use('dalvik.system.VMStack');
VMStack.getCallingClassLoader.implementation = function() {
logHook('TRIGGER', 'ROOT', 'VMStack', 'getCallingClassLoader', '');
return null;
};
logHook('OK', 'ROOT', 'VMStack', 'getCallingClassLoader', '');
} catch (e) {
logHook('FAIL', 'ROOT', 'VMStack', 'getCallingClassLoader', e);
}
});
// === [EXTRA NATIVE ROOT DETECTION BYPASS] ===
function hookNativeRootFuncs() {
var nativeFuncs = [
'stat', 'lstat', 'readlink', 'fopen', 'fopenat', 'openat', 'access', 'fgets', 'execve', 'system'
];
nativeFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName('libc.so', func);
if (ptrFunc) {
Interceptor.attach(ptrFunc, {
onEnter: function(args) {
var path = '';
try {
path = Memory.readUtf8String(args[0]);
} catch (e) {}
if (path && (path.indexOf('su') !== -1 || path.indexOf('magisk') !== -1 || path.indexOf('busybox') !== -1)) {
logHook('TRIGGER', 'ROOT', 'libc', func, path);
if (func === 'access' || func === 'stat' || func === 'lstat' || func === 'fopen' || func === 'fopenat' || func === 'openat') {
this.returnValue = -1;
}
}
}
});
logHook('OK', 'ROOT', 'libc', func, 'native');
}
} catch (e) {
logHook('FAIL', 'ROOT', 'libc', func, e);
}
});
}
setImmediate(hookNativeRootFuncs);
// === [EXTRA SSL PINNING BYPASS] ===
Java.perform(function() {
// HttpsURLConnection.setSSLSocketFactory
try {
var HttpsURLConnection = Java.use('javax.net.ssl.HttpsURLConnection');
HttpsURLConnection.setSSLSocketFactory.implementation = function(factory) {
logHook('TRIGGER', 'SSL', 'HttpsURLConnection', 'setSSLSocketFactory', '');
return;
};
logHook('OK', 'SSL', 'HttpsURLConnection', 'setSSLSocketFactory', '');
} catch (e) {
logHook('FAIL', 'SSL', 'HttpsURLConnection', 'setSSLSocketFactory', e);
}
// HttpsURLConnection.setHostnameVerifier
try {
HttpsURLConnection.setHostnameVerifier.implementation = function(verifier) {
logHook('TRIGGER', 'SSL', 'HttpsURLConnection', 'setHostnameVerifier', '');
return;
};
logHook('OK', 'SSL', 'HttpsURLConnection', 'setHostnameVerifier', '');
} catch (e) {
logHook('FAIL', 'SSL', 'HttpsURLConnection', 'setHostnameVerifier', e);
}
// SSLSocketFactory.getDefault
try {
var SSLSocketFactory = Java.use('javax.net.ssl.SSLSocketFactory');
SSLSocketFactory.getDefault.implementation = function() {
logHook('TRIGGER', 'SSL', 'SSLSocketFactory', 'getDefault', '');
return this.getDefault.call(this);
};
logHook('OK', 'SSL', 'SSLSocketFactory', 'getDefault', '');
} catch (e) {
logHook('FAIL', 'SSL', 'SSLSocketFactory', 'getDefault', e);
}
// TrustManagerFactory.getTrustManagers
try {
var TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
TrustManagerFactory.getTrustManagers.implementation = function() {
logHook('TRIGGER', 'SSL', 'TrustManagerFactory', 'getTrustManagers', '');
return this.getTrustManagers.call(this);
};
logHook('OK', 'SSL', 'TrustManagerFactory', 'getTrustManagers', '');
} catch (e) {
logHook('FAIL', 'SSL', 'TrustManagerFactory', 'getTrustManagers', e);
}
// KeyManagerFactory.getKeyManagers
try {
var KeyManagerFactory = Java.use('javax.net.ssl.KeyManagerFactory');
KeyManagerFactory.getKeyManagers.implementation = function() {
logHook('TRIGGER', 'SSL', 'KeyManagerFactory', 'getKeyManagers', '');
return this.getKeyManagers.call(this);
};
logHook('OK', 'SSL', 'KeyManagerFactory', 'getKeyManagers', '');
} catch (e) {
logHook('FAIL', 'SSL', 'KeyManagerFactory', 'getKeyManagers', e);
}
// SSLSession.getPeerCertificates/getPeerCertificateChain
try {
var SSLSession = Java.use('javax.net.ssl.SSLSession');
SSLSession.getPeerCertificates.implementation = function() {
logHook('TRIGGER', 'SSL', 'SSLSession', 'getPeerCertificates', '');
return [];
};
SSLSession.getPeerCertificateChain.implementation = function() {
logHook('TRIGGER', 'SSL', 'SSLSession', 'getPeerCertificateChain', '');
return [];
};
logHook('OK', 'SSL', 'SSLSession', 'getPeerCertificates/getPeerCertificateChain', '');
} catch (e) {
logHook('FAIL', 'SSL', 'SSLSession', 'getPeerCertificates/getPeerCertificateChain', e);
}
});
// === [EXTRA NATIVE SSL PINNING BYPASS] ===
function hookNativeSSLFuncs() {
var sslFuncs = [
'SSL_set_cert_cb', 'SSL_CTX_set_cert_cb', 'SSL_CTX_set_client_cert_cb', 'SSL_CTX_set_client_cert_engine'
];
sslFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName('libssl.so', func);
if (ptrFunc) {
Interceptor.attach(ptrFunc, {
onEnter: function(args) {
logHook('TRIGGER', 'SSL', 'libssl', func, 'native');
args[1] = ptr(0);
}
});
logHook('OK', 'SSL', 'libssl', func, 'native');
}
} catch (e) {
logHook('FAIL', 'SSL', 'libssl', func, e);
}
});
}
setImmediate(hookNativeSSLFuncs);
// === [OPTIONAL: Frida RPC for runtime control] ===
rpc.exports = {
getlog: function() {
return hookLog;
},
printsummary: function() {
printSummary();
return true;
}
};
// === [ULTRA-BROAD DYNAMIC METHOD SCANNING & HOOKING] ===
setImmediate(function() {
Java.perform(function() {
var suspiciousKeywords = [
'root', 'su', 'magisk', 'xposed', 'substrate', 'debug', 'adb', 'busybox', 'test-keys',
'pin', 'trust', 'verify', 'cert', 'chain', 'ssl', 'bypass', 'jailbreak', 'hook', 'tamper', 'frida', 'emulator', 'virtual', 'sandbox', 'checker', 'check', 'detect', 'is', 'has', 'get'
];
var hookedMethods = {};
Java.enumerateLoadedClasses({
onMatch: function(className) {
var lc = className.toLowerCase();
for (var i = 0; i < suspiciousKeywords.length; i++) {
if (lc.indexOf(suspiciousKeywords[i]) !== -1) {
try {
var klass = Java.use(className);
var methods = klass.class.getDeclaredMethods();
for (var j = 0; j < methods.length; j++) {
var m = methods[j];
var mName = m.getName();
for (var k = 0; k < suspiciousKeywords.length; k++) {
if (mName.toLowerCase().indexOf(suspiciousKeywords[k]) !== -1) {
var overloads = klass[mName].overloads;
for (var o = 0; o < overloads.length; o++) {
var key = className + '.' + mName + '.' + o;
if (!hookedMethods[key]) {
hookedMethods[key] = true;
overloads[o].implementation = function() {
var args = Array.prototype.slice.call(arguments);
var stack = Java.use('java.lang.Thread').currentThread().getStackTrace().toString();
logHook('TRIGGER', 'DYN', className, mName, 'args=' + JSON.stringify(args) + '\nStack=' + stack);
// Try to return a safe value
try {
var retType = this.class.getDeclaredMethod(mName, m.getParameterTypes()).getReturnType().getName();
if (retType === 'boolean') return false;
if (retType === 'int' || retType === 'long' || retType === 'float' || retType === 'double') return 0;
if (retType === 'java.lang.String') return '';
if (retType.endsWith('[]')) return [];
return null;
} catch (e) {
return null;
}
};
logHook('OK', 'DYN', className, mName, 'overload ' + o);
}
}
}
}
}
} catch (e) {
logHook('FAIL', 'DYN', className, '', e);
}
break;
}
}
},
onComplete: function() {}
});
});
});
// === [MORE NATIVE HOOKS FOR ROOT/SSL] ===
setImmediate(function() {
var moreNativeFuncs = [
// libc
'stat', 'lstat', 'readlink', 'fopen', 'fopenat', 'openat', 'access', 'fgets', 'execve', 'system', 'unlink', 'remove', 'rename', 'chmod', 'chown', 'link', 'symlink', 'read', 'write', 'close', 'dup', 'dup2', 'fork', 'kill', 'ptrace',
// SSL
'SSL_set_cert_cb', 'SSL_CTX_set_cert_cb', 'SSL_CTX_set_client_cert_cb', 'SSL_CTX_set_client_cert_engine', 'SSL_CTX_set_verify', 'SSL_CTX_set_custom_verify', 'SSL_set_custom_verify', 'SSL_get_verify_result', 'SSL_get_peer_certificate', 'SSL_get_peer_cert_chain', 'SSL_get1_peer_certificate', 'SSL_get1_chain_certs', 'SSL_CTX_set_cert_verify_callback',
// Vendor/obfuscated
'sslpinning_check', 'ssl_verify', 'ssl_check', 'root_check', 'root_detect', 'magisk_detect', 'xposed_detect', 'frida_detect', 'emulator_detect', 'jailbreak_detect'
];
moreNativeFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName(null, func);
if (ptrFunc) {
Interceptor.replace(ptrFunc, new NativeCallback(function() {
logHook('TRIGGER', 'NATIVE', 'lib', func, 'bypassed');
if (func.indexOf('verify') !== -1 || func.indexOf('check') !== -1 || func.indexOf('detect') !== -1) {
return 0;
}
return 0;
}, 'int', []));
logHook('OK', 'NATIVE', 'lib', func, 'replaced');
}
} catch (e) {
logHook('FAIL', 'NATIVE', 'lib', func, e);
}
});
});
// === [TEST/PROOF HOOKS] ===
setImmediate(function() {
Java.perform(function() {
// Dummy root check
try {
var DummyRoot = Java.registerClass({
name: 'com.frida.test.DummyRoot',
methods: {
isRooted: function() {
logHook('TRIGGER', 'TEST', 'DummyRoot', 'isRooted', '');
return false;
},
checkRoot: function() {
logHook('TRIGGER', 'TEST', 'DummyRoot', 'checkRoot', '');
return false;
}
}
});
logHook('OK', 'TEST', 'DummyRoot', 'isRooted/checkRoot', '');
} catch (e) {
logHook('FAIL', 'TEST', 'DummyRoot', 'isRooted/checkRoot', e);
}
// Dummy SSL pinning check
try {
var DummySSL = Java.registerClass({
name: 'com.frida.test.DummySSL',
methods: {
verifyPin: function() {
logHook('TRIGGER', 'TEST', 'DummySSL', 'verifyPin', '');
return true;
},
checkCert: function() {
logHook('TRIGGER', 'TEST', 'DummySSL', 'checkCert', '');
return true;
}
}
});
logHook('OK', 'TEST', 'DummySSL', 'verifyPin/checkCert', '');
} catch (e) {
logHook('FAIL', 'TEST', 'DummySSL', 'verifyPin/checkCert', e);
}
});
});
// === [JNI CALLS HOOKING] ===
setImmediate(function() {
try {
var jniFuncs = [
'CallBooleanMethod', 'CallStaticBooleanMethod', 'CallIntMethod', 'CallStaticIntMethod',
'CallObjectMethod', 'CallStaticObjectMethod', 'CallVoidMethod', 'CallStaticVoidMethod'
];
jniFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName('libart.so', func) || Module.findExportByName('libandroid_runtime.so', func);
if (ptrFunc) {
Interceptor.attach(ptrFunc, {
onEnter: function(args) {
logHook('TRIGGER', 'JNI', 'JNI', func, '');
}
});
logHook('OK', 'JNI', 'JNI', func, '');
}
} catch (e) {
logHook('FAIL', 'JNI', 'JNI', func, e);
}
});
} catch (e) {
logHook('FAIL', 'JNI', 'JNI', 'all', e);
}
});
// === [BINDER IPC HOOKING] ===
setImmediate(function() {
try {
var Binder = Java.use('android.os.Binder');
Binder.transact.implementation = function(code, data, reply, flags) {
logHook('TRIGGER', 'BINDER', 'Binder', 'transact', 'code=' + code);
return this.transact.call(this, code, data, reply, flags);
};
logHook('OK', 'BINDER', 'Binder', 'transact', '');
} catch (e) {
logHook('FAIL', 'BINDER', 'Binder', 'transact', e);
}
});
// === [DEX/CLASSLOADER HOOKING] ===
setImmediate(function() {
try {
var DexClassLoader = Java.use('dalvik.system.DexClassLoader');
DexClassLoader.loadClass.implementation = function(name, resolve) {
logHook('TRIGGER', 'CLASSLOADER', 'DexClassLoader', 'loadClass', name);
return this.loadClass.call(this, name, resolve);
};
logHook('OK', 'CLASSLOADER', 'DexClassLoader', 'loadClass', '');
} catch (e) {
logHook('FAIL', 'CLASSLOADER', 'DexClassLoader', 'loadClass', e);
}
try {
var PathClassLoader = Java.use('dalvik.system.PathClassLoader');
PathClassLoader.loadClass.implementation = function(name, resolve) {
logHook('TRIGGER', 'CLASSLOADER', 'PathClassLoader', 'loadClass', name);
return this.loadClass.call(this, name, resolve);
};
logHook('OK', 'CLASSLOADER', 'PathClassLoader', 'loadClass', '');
} catch (e) {
logHook('FAIL', 'CLASSLOADER', 'PathClassLoader', 'loadClass', e);
}
});
// === [NATIVE ANTI-FRIDA/ANTI-DEBUG HOOKS] ===
setImmediate(function() {
var antiDebugFuncs = [
'ptrace', 'getpid', 'getppid', 'getuid', 'getgid', 'getgroups', 'syscall'
];
antiDebugFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName('libc.so', func);
if (ptrFunc) {
Interceptor.attach(ptrFunc, {
onEnter: function(args) {
logHook('TRIGGER', 'ANTIDEBUG', 'libc', func, '');
if (func === 'ptrace') args[0] = 0; // Bypass ptrace anti-debug
}
});
logHook('OK', 'ANTIDEBUG', 'libc', func, '');
}
} catch (e) {
logHook('FAIL', 'ANTIDEBUG', 'libc', func, e);
}
});
});
// === [ANTI-EMULATOR HOOKS] ===
setImmediate(function() {
Java.perform(function() {
try {
var Build = Java.use('android.os.Build');
Build.MODEL.value = 'Pixel 5';
Build.MANUFACTURER.value = 'Google';
Build.BRAND.value = 'google';
Build.DEVICE.value = 'raven';
Build.PRODUCT.value = 'raven';
logHook('OK', 'EMULATOR', 'Build', 'fields', '');
} catch (e) {
logHook('FAIL', 'EMULATOR', 'Build', 'fields', e);
}
});
});
// === [NETWORK STACK HOOKS] ===
setImmediate(function() {
Java.perform(function() {
try {
var Socket = Java.use('java.net.Socket');
Socket.connect.implementation = function(endpoint, timeout) {
logHook('TRIGGER', 'NET', 'Socket', 'connect', '');
return this.connect.call(this, endpoint, timeout);
};
logHook('OK', 'NET', 'Socket', 'connect', '');
} catch (e) {
logHook('FAIL', 'NET', 'Socket', 'connect', e);
}
try {
var HttpURLConnection = Java.use('java.net.HttpURLConnection');
HttpURLConnection.connect.implementation = function() {
logHook('TRIGGER', 'NET', 'HttpURLConnection', 'connect', '');
return this.connect.call(this);
};
logHook('OK', 'NET', 'HttpURLConnection', 'connect', '');
} catch (e) {
logHook('FAIL', 'NET', 'HttpURLConnection', 'connect', e);
}
});
});
// === [WEBVIEW/WEBVIEWCLIENT HOOKS] ===
setImmediate(function() {
Java.perform(function() {
try {
var WebView = Java.use('android.webkit.WebView');
WebView.loadUrl.implementation = function(url) {
logHook('TRIGGER', 'WEBVIEW', 'WebView', 'loadUrl', url);
return this.loadUrl.call(this, url);
};
logHook('OK', 'WEBVIEW', 'WebView', 'loadUrl', '');
} catch (e) {
logHook('FAIL', 'WEBVIEW', 'WebView', 'loadUrl', e);
}
try {
var WebViewClient = Java.use('android.webkit.WebViewClient');
WebViewClient.onReceivedSslError.implementation = function(view, handler, error) {
logHook('TRIGGER', 'WEBVIEW', 'WebViewClient', 'onReceivedSslError', '');
handler.proceed();
};
logHook('OK', 'WEBVIEW', 'WebViewClient', 'onReceivedSslError', '');
} catch (e) {
logHook('FAIL', 'WEBVIEW', 'WebViewClient', 'onReceivedSslError', e);
}
});
});
// === [NATIVE MEMORY CHECKS] ===
setImmediate(function() {
var memFuncs = ['mmap', 'munmap', 'memcpy', 'memcmp'];
memFuncs.forEach(function(func) {
try {
var ptrFunc = Module.findExportByName('libc.so', func);
if (ptrFunc) {
Interceptor.attach(ptrFunc, {
onEnter: function(args) {
logHook('TRIGGER', 'MEM', 'libc', func, '');
}
});
logHook('OK', 'MEM', 'libc', func, '');
}
} catch (e) {
logHook('FAIL', 'MEM', 'libc', func, e);
}
});
});
// === [ANTI-TAMPER/INSTRUMENTATION HOOKS] ===
setImmediate(function() {
Java.perform(function() {
try {
var Debug = Java.use('android.os.Debug');
Debug.isDebuggerConnected.implementation = function() {
logHook('TRIGGER', 'TAMPER', 'Debug', 'isDebuggerConnected', '');
return false;
};
Debug.waitingForDebugger.implementation = function() {
logHook('TRIGGER', 'TAMPER', 'Debug', 'waitingForDebugger', '');
return false;
};
logHook('OK', 'TAMPER', 'Debug', 'isDebuggerConnected/waitingForDebugger', '');
} catch (e) {
logHook('FAIL', 'TAMPER', 'Debug', 'isDebuggerConnected/waitingForDebugger', e);
}
});
});
// === [ROOT HIDING FRAMEWORKS HOOKS] ===
setImmediate(function() {
Java.perform(function() {
var rootHiders = [
'com.topjohnwu.magisk', 'com.devadvance.rootcloak', 'de.robv.android.xposed.installer', 'com.saurik.substrate'
];
try {
var PackageManager = Java.use('android.app.ApplicationPackageManager');
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(pname, flags) {
if (rootHiders.indexOf(pname) > -1) {
logHook('TRIGGER', 'ROOTHIDE', 'PackageManager', 'getPackageInfo', pname);
pname = 'safe.package.fake';
}
return this.getPackageInfo.call(this, pname, flags);
};
logHook('OK', 'ROOTHIDE', 'PackageManager', 'getPackageInfo', '');
} catch (e) {
logHook('FAIL', 'ROOTHIDE', 'PackageManager', 'getPackageInfo', e);
}
});
});
// === [OBFUSCATED/UNKNOWN METHOD SIGNATURE HOOKS] ===
setImmediate(function() {
Java.perform(function() {
Java.enumerateLoadedClasses({
onMatch: function(className) {
try {
var klass = Java.use(className);
var methods = klass.class.getDeclaredMethods();
for (var j = 0; j < methods.length; j++) {
var m = methods[j];
var mName = m.getName();
// If method has boolean/int/String return type and <=2 args, hook it
var retType = m.getReturnType().getName();
var paramCount = m.getParameterTypes().length;
if ((retType === 'boolean' || retType === 'int' || retType === 'java.lang.String') && paramCount <= 2) {
var overloads = klass[mName].overloads;
for (var o = 0; o < overloads.length; o++) {
overloads[o].implementation = function() {
var args = Array.prototype.slice.call(arguments);
logHook('TRIGGER', 'OBFUSC', className, mName, 'args=' + JSON.stringify(args));
if (retType === 'boolean') return false;
if (retType === 'int') return 0;
if (retType === 'java.lang.String') return '';
return null;
};
logHook('OK', 'OBFUSC', className, mName, 'overload ' + o);
}
}
}
} catch (e) {}
},
onComplete: function() {}
});
});
});
// === [TEST HOOKS FOR ALL] ===
setImmediate(function() {
Java.perform(function() {
// JNI test
try {
logHook('TEST', 'JNI', 'JNI', 'CallBooleanMethod', 'Simulated JNI call');
} catch (e) {}
// Binder test
try {
logHook('TEST', 'BINDER', 'Binder', 'transact', 'Simulated Binder call');
} catch (e) {}
// ClassLoader test
try {
logHook('TEST', 'CLASSLOADER', 'DexClassLoader', 'loadClass', 'Simulated loadClass');
} catch (e) {}
// Anti-debug test
try {
logHook('TEST', 'ANTIDEBUG', 'libc', 'ptrace', 'Simulated ptrace');
} catch (e) {}
// Emulator test
try {
logHook('TEST', 'EMULATOR', 'Build', 'MODEL', 'Simulated emulator check');
} catch (e) {}
// Network test
try {
logHook('TEST', 'NET', 'Socket', 'connect', 'Simulated network connect');
} catch (e) {}
// WebView test
try {
logHook('TEST', 'WEBVIEW', 'WebView', 'loadUrl', 'Simulated WebView loadUrl');
} catch (e) {}
// Memory test
try {
logHook('TEST', 'MEM', 'libc', 'mmap', 'Simulated mmap');
} catch (e) {}
// Tamper test
try {
logHook('TEST', 'TAMPER', 'Debug', 'isDebuggerConnected', 'Simulated tamper check');
} catch (e) {}
// Root hide test
try {
logHook('TEST', 'ROOTHIDE', 'PackageManager', 'getPackageInfo', 'Simulated root hide');
} catch (e) {}
// Obfusc test
try {
logHook('TEST', 'OBFUSC', 'ObfuscatedClass', 'obfuscatedMethod', 'Simulated obfuscated method');
} catch (e) {}
});
});
Comments