Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection)
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
This page provides a practical workflow to regain dynamic analysis against Android apps that detect/root‑block instrumentation or enforce TLS pinning. It focuses on fast triage, common detections, and copy‑pasteable hooks/tactics to bypass them without repacking when possible.
Detection Surface (what apps check)
- Root checks: su binary, Magisk paths, getprop values, common root packages
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
- Native anti‑debug: ptrace(), syscalls, anti‑attach, breakpoints, inline hooks
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
Bypassing Anti-Frida Detection / Stealth Frida Servers
phantom-frida rebuilds Frida from source and applies ~90 patches so common Frida fingerprints disappear while the stock Frida protocol remains compatible (frida-tools can still connect). Target: apps that grep /proc (cmdline, maps, task comm, fd readlink), D-Bus service names, default ports, or exported symbols.
Phases:
- Source patches: global rename of
fridaidentifiers (server/agent/helper) and rebuilt helper DEX with a renamed Java package. - Targeted build/runtime patches: meson tweaks, memfd label changed to
jit-cache, SELinux labels (e.g.,frida_file) renamed, libc hooks onexit/signaldisabled to avoid hook-detectors. - Post-build rename: exported symbol
frida_agent_mainrenamed after the first compile (Vala emits it), requiring a second incremental build. - Binary hex patches: thread names (
gmain,gdbus,pool-spawner) replaced; optional sweep removes leftoverfrida/Fridastrings.
Detection vectors covered:
- Base (1–8): process name
frida-server, mappedlibfrida-agent.so, thread names, memfd label, exportedfrida_agent_main, SELinux labels, libc hook side-effects, and D-Bus servicere.frida.serverare renamed/neutralized. - Extended (9–16): change listening port (
--port), rename D-Bus interfaces/internal C symbols/GType names, temp paths like.frida/frida-, sweep binary strings, rename build-time defines and asset paths (libdir/frida). D-Bus interface names that are part of the wire protocol stay unchanged in base mode to avoid breaking stock clients.
Build/usage (Android arm64 example):
python3 build.py --version 17.7.2 --name myserver --port 27142 --extended --verify
adb push output/myserver-server-17.7.2-android-arm64 /data/local/tmp/myserver-server
adb shell chmod 755 /data/local/tmp/myserver-server
adb shell /data/local/tmp/myserver-server -D &
adb forward tcp:27142 tcp:27142
frida -H 127.0.0.1:27142 -f com.example.app
फ्लैग्स: --skip-build (patch only), --skip-clone, --arch, --ndk-path, --temp-fixes; WSL हेल्पर: wsl -d Ubuntu bash build-wsl.sh.
Step 1 — Quick win: hide root with Magisk DenyList
- Zygisk को सक्षम करें (Enable Zygisk in Magisk)
- DenyList सक्षम करें, लक्ष्य पैकेज जोड़ें
- रिबूट करें और फिर से परीक्षण करें
कई ऐप्स केवल स्पष्ट संकेतों (su/Magisk paths/getprop) की तलाश करते हैं। DenyList अक्सर सरल चेक्स को निष्प्रभावी कर देता है।
References:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
Play Integrity / Zygisk detections (post‑SafetyNet)
नए banking/ID apps रनटाइम चेक्स को Google Play Integrity (SafetyNet replacement) से जोड़ते हैं और यदि Zygisk स्वयं मौजूद हो तो वे क्रैश भी कर सकते हैं। त्वरित ट्रायाज सुझाव:
- अस्थायी रूप से Zygisk को डिसेबल करें (toggle off + reboot) और पुनः प्रयास करें; कुछ apps तब क्रैश हो जाते हैं जैसे ही Zygote injection लोड होता है।
- यदि attestation लॉगिन ब्लॉक करता है, तो Google Play Services को PlayIntegrityFix/Fork + TrickyStore से patch करें या केवल टेस्टिंग के समय ReZygisk/Zygisk‑Next का उपयोग करें। लक्ष्य को DenyList में रखें और उन LSPosed मॉड्यूल से बचें जो props को leak करते हैं।
- एक‑बार के रन के लिए, KernelSU/APatch का उपयोग करें (कोई Zygote injection नहीं) ताकि Zygisk heuristics के नीचे रहें, फिर Frida attach करें।
Step 2 — 30‑second Frida Codeshare tests
दीर्घ जांच से पहले सामान्य drop‑in scripts आज़माएँ:
- anti-root-bypass.js
- anti-frida-detection.js
- hide_frida_gum.js
Example:
frida -U -f com.example.app -l anti-frida-detection.js
ये आम तौर पर Java root/debug checks, process/service scans, और native ptrace() को stub करते हैं। हल्के सुरक्षा वाले apps पर उपयोगी; hardened targets के लिए tailored hooks की आवश्यकता हो सकती है।
- Codeshare: https://codeshare.frida.re/
Medusa (Frida framework) के साथ ऑटोमेट करें
Medusa 90+ ready-made modules प्रदान करता है, जैसे SSL unpinning, root/emulator detection bypass, HTTP comms logging, crypto key interception, और अन्य।
git clone https://github.com/Ch0pin/medusa
cd medusa
pip install -r requirements.txt
python medusa.py
# Example interactive workflow
show categories
use http_communications/multiple_unpinner
use root_detection/universal_root_detection_bypass
run com.target.app
Tip: Medusa तेज़ नतीजे पाने के लिए custom hooks लिखने से पहले बेहतरीन है। आप modules को भी cherry-pick करके उन्हें अपने scripts के साथ combine कर सकते हैं।
चरण 3 — init-time detectors को बाद में attach करके बायपास करें
कई detections केवल process spawn/onCreate() के दौरान ही चलते हैं। Spawn‑time injection (-f) या gadgets पकड़ लिए जाते हैं; UI लोड होने के बाद attach करने से यह बायपास हो सकता है।
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore # if using gadget
यदि यह काम करता है, तो session को स्थिर रखें और map और stub जांचों पर आगे बढ़ें।
Step 4 — Jadx और string hunting के माध्यम से detection logic को मैप करें
Jadx में Static triage keywords:
- “frida”, “gum”, “root”, “magisk”, “ptrace”, “su”, “getprop”, “debugger”
सामान्य Java पैटर्न:
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
सामान्य APIs जिनकी समीक्षा/hook करनी चाहिए:
- android.os.Debug.isDebuggerConnected
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
- java.lang.System.loadLibrary / System.load (native bridge)
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
- android.os.SystemProperties.get (root/emulator heuristics)
चरण 5 — Runtime stubbing with Frida (Java)
पुनपैकिंग किए बिना सुरक्षित मान लौटाने के लिए कस्टम गार्ड्स को ओवरराइड करें:
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
Checks.isFridaDetected.implementation = function () { return false; };
// Neutralize debugger checks
const Debug = Java.use('android.os.Debug');
Debug.isDebuggerConnected.implementation = function () { return false; };
// Example: kill ActivityManager scans
const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});
Triaging early crashes? मरने से ठीक पहले classes को dump करके संभावित detection namespaces ढूंढें:
Java.perform(() => {
Java.enumerateLoadedClasses({
onMatch: n => console.log(n),
onComplete: () => console.log('Done')
});
});
त्वरित root detection stub उदाहरण (लक्ष्य package/class नामों के अनुसार अनुकूलित करें):
Java.perform(() => {
try {
const RootChecker = Java.use('com.target.security.RootCheck');
RootChecker.isDeviceRooted.implementation = function () { return false; };
} catch (e) {}
});
संदिग्ध methods को log और neuter करके execution flow की पुष्टि करें:
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
Det.checkFrida.implementation = function () {
console.log('checkFrida() called');
return false;
};
});
Bypass emulator/VM detection (Java stubs)
सामान्य संकेत: Build.FINGERPRINT/MODEL/MANUFACTURER/HARDWARE में generic/goldfish/ranchu/sdk का होना; QEMU artifacts जैसे /dev/qemu_pipe, /dev/socket/qemud; default MAC 02:00:00:00:00:00; 10.0.2.x NAT; telephony/sensors की कमी।
Build fields की त्वरित spoofing:
Java.perform(function(){
var Build = Java.use('android.os.Build');
Build.MODEL.value = 'Pixel 7 Pro';
Build.MANUFACTURER.value = 'Google';
Build.BRAND.value = 'google';
Build.FINGERPRINT.value = 'google/panther/panther:14/UP1A.231105.003/1234567:user/release-keys';
});
फ़ाइल अस्तित्व जांच और पहचानकर्ताओं (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) के लिए स्टब जोड़ें ताकि वे वास्तविक मान लौटाएँ।
SSL pinning bypass quick hook (Java)
custom TrustManagers को निष्क्रिय करें और permissive SSL contexts को लागू कराएँ:
Java.perform(function(){
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
// No-op validations
X509TrustManager.checkClientTrusted.implementation = function(){ };
X509TrustManager.checkServerTrusted.implementation = function(){ };
// Force permissive TrustManagers
var TrustManagers = [ X509TrustManager.$new() ];
var SSLContextInit = SSLContext.init.overload('[Ljavax.net.ssl.KeyManager;','[Ljavax.net.ssl.TrustManager;','java.security.SecureRandom');
SSLContextInit.implementation = function(km, tm, sr){
return SSLContextInit.call(this, km, TrustManagers, sr);
};
});
Notes
- OkHttp के लिए विस्तारित करें: आवश्यकता के अनुसार okhttp3.CertificatePinner और HostnameVerifier को hook करें, या CodeShare से एक universal unpinning script का उपयोग करें।
- उदाहरण चलाएँ:
frida -U -f com.target.app -l ssl-bypass.js --no-pause
OkHttp4 / gRPC / Cronet pinning (2024+)
आधुनिक stacks नए APIs के अंदर pin करते हैं (OkHttp4+, gRPC over Cronet/BoringSSL). जब बेसिक SSLContext hook अटक जाए तो ये hooks जोड़ें:
Java.perform(() => {
try {
const Pinner = Java.use('okhttp3.CertificatePinner');
Pinner.check.overload('java.lang.String', 'java.util.List').implementation = function(){};
Pinner.check$okhttp.implementation = function(){};
} catch (e) {}
try {
const CronetB = Java.use('org.chromium.net.CronetEngine$Builder');
CronetB.enablePublicKeyPinningBypassForLocalTrustAnchors.overload('boolean').implementation = function(){ return this; };
CronetB.setPublicKeyPins.overload('java.lang.String', 'java.util.Set', 'boolean').implementation = function(){ return this; };
} catch (e) {}
});
यदि TLS अभी भी विफल हो रहा है, तो native पर जाएँ और Cronet/gRPC द्वारा उपयोग किए जाने वाले BoringSSL verification entry points को patch करें:
const customVerify = Module.findExportByName(null, 'SSL_CTX_set_custom_verify');
if (customVerify) {
Interceptor.attach(customVerify, {
onEnter(args){
// arg0 = SSL_CTX*, arg1 = mode, arg2 = callback
args[1] = ptr(0); // SSL_VERIFY_NONE
args[2] = NULL; // disable callback
}
});
}
चरण 6 — Java hooks विफल होने पर JNI/native ट्रेल का पालन करें
JNI entry points को ट्रेस करके native loaders और detection init का पता लगाएँ:
frida-trace -n com.example.app -i "JNI_OnLoad"
बंडल किए गए .so फ़ाइलों का त्वरित native triage:
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
Interactive/native reversing:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
उदाहरण: ptrace को निष्क्रिय करके सरल anti‑debug को libc में हराना:
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
Interceptor.replace(ptrace, new NativeCallback(function () {
return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}
यह भी देखें: Reversing Native Libraries
चरण 7 — Objection patching (embed gadget / strip basics)
जब आप runtime hooks के बजाय repacking को प्राथमिकता देते हैं, तो आज़माएँ:
objection patchapk --source app.apk
नोट:
- apktool की आवश्यकता है; बिल्ड समस्याओं से बचने के लिए आधिकारिक मार्गदर्शिका से नवीनतम संस्करण सुनिश्चित करें: https://apktool.org/docs/install
- Gadget injection instrumentation को root के बिना सक्षम करता है, लेकिन इसे मजबूत init‑time checks द्वारा अभी भी पकड़ा जा सकता है।
वैकल्पिक रूप से, Zygisk environments में मजबूत root hiding के लिए LSPosed modules और Shamiko जोड़ें, और child processes को कवर करने के लिए DenyList को curate करें।
पूर्ण वर्कफ़्लो के लिए, जिसमें script-mode Gadget configuration और अपने Frida 17+ agent को APK में bundling करना शामिल है, देखें:
Frida Tutorial — Self-contained agent + Gadget embedding
संदर्भ:
- Objection: https://github.com/sensepost/objection
Step 8 — Fallback: नेटवर्क दृश्यता के लिए TLS pinning को पैच करें
यदि instrumentation अवरुद्ध है, तो आप pinning को स्थैतिक रूप से हटाकर फिर भी ट्रैफ़िक का निरीक्षण कर सकते हैं:
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
- टूल: https://github.com/shroudedcode/apk-mitm
- नेटवर्क कॉन्फ़िग CA‑trust ट्रिक्स (और Android 7+ user CA trust) के लिए, देखें:
Make APK Accept CA Certificate
उपयोगी कमांड चीट‑शीट
# List processes and attach
frida-ps -Uai
frida -U -n com.example.app
# Spawn with a script (may trigger detectors)
frida -U -f com.example.app -l anti-frida-detection.js
# Trace native init
frida-trace -n com.example.app -i "JNI_OnLoad"
# Objection runtime
objection --gadget com.example.app explore
# Static TLS pinning removal
apk-mitm app.apk
Universal proxy forcing + TLS unpinning (HTTP Toolkit Frida hooks)
आधुनिक ऐप अक्सर सिस्टम प्रॉक्सी को अनदेखा करते हैं और पिनिंग की कई परतें लागू करते हैं (Java + native), जिससे user/system CAs स्थापित होने के बावजूद ट्रैफ़िक कैप्चर करना कठिन हो जाता है। एक व्यावहारिक तरीका यह है कि universal TLS unpinning को ready-made Frida hooks के माध्यम से proxy forcing के साथ मिलाया जाए, और सभी ट्रैफ़िक को mitmproxy/Burp के माध्यम से रूट किया जाए।
Workflow
- अपने होस्ट पर mitmproxy चलाएँ (या Burp)। सुनिश्चित करें कि डिवाइस होस्ट के IP/port तक पहुँच सकता है।
- HTTP Toolkit के समेकित Frida hooks लोड करें ताकि TLS को अनपिन किया जा सके और सामान्य स्टैक्स (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, आदि) में proxy उपयोग को ज़बरदस्ती लागू किया जा सके। यह CertificatePinner/TrustManager चेक्स को बायपास करता है और proxy selectors को ओवरराइड करता है, इसलिए ट्रैफ़िक हमेशा आपके proxy के जरिए भेजा जाता है भले ही ऐप स्पष्ट रूप से proxies को डिसेबल कर दे।
- Frida और hook script के साथ target app को स्टार्ट करें, और mitmproxy में requests को capture करें।
उदाहरण
# Device connected via ADB or over network (-U)
# See the repo for the exact script names & options
frida -U -f com.vendor.app \
-l ./android-unpinning-with-proxy.js \
--no-pause
# mitmproxy listening locally
mitmproxy -p 8080
नोट्स
- Combine with a system-wide proxy via
adb shell settings put global http_proxy <host>:<port>when possible. The Frida hooks will enforce proxy use even when apps bypass global settings. - This technique is ideal when you need to MITM mobile-to-IoT onboarding flows where pinning/proxy avoidance is common.
- Hooks: https://github.com/httptoolkit/frida-interception-and-unpinning
संदर्भ
- Reversing Android Apps: Bypassing Detection Like a Pro
- Frida Codeshare
- Objection
- apk-mitm
- Jadx
- Ghidra
- r2frida
- Apktool install guide
- Magisk
- Medusa (Android Frida framework)
- Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa
- phantom-frida (stealth Frida server builder)
- Frida OkHttp4 SSL pinning bypass script
- XDA guide to strong Play Integrity bypass (2025)
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।


