Android Studio mobile application penetration testing environment setup with Magisk root, Frida, and SSL bypass capabilities
---
name: androidstudio-app-pentest-environment
description: Android Studio mobile application penetration testing environment setup with Magisk root, Frida, and SSL bypass capabilities
triggers:
- set up android pentest environment
- configure android studio for app security testing
- install magisk on android emulator
- root android emulator for pentesting
- bypass ssl pinning on android
- setup frida for android app testing
- create rooted android virtual device
- configure android app security toolkit
---
# Android Studio App Pentest Environment Setup
> Skill by [ara.so](https://ara.so) — Security Skills collection.
Complete penetration testing environment for Android applications using Android Studio emulators with Magisk root, Frida instrumentation, SSL/TLS bypass, and security testing tools.
## What This Project Provides
A comprehensive guide and toolchain for setting up a mobile application security testing environment including:
- **Rooted Android Emulator**: Using Magisk (面具) for root access
- **Frida Framework**: Dynamic instrumentation for runtime analysis
- **SSL/TLS Bypass**: Certificate pinning bypass modules
- **Traffic Interception**: Proxy configuration for HTTPS inspection
- **Anti-Detection**: Modules to hide root, Magisk, and emulator detection
## Prerequisites
- **Android Studio**: Latest version from [developer.android.com](https://developer.android.google.cn/studio)
- **SDK Platform-Tools**: ADB and fastboot (installed with Android Studio)
- **Proxy Tool**: Burp Suite, Charles, or mitmproxy
- **Git**: For cloning tooling repositories
## Environment Setup
### 1. Install Android Studio and SDK
```bash
# Download Android Studio from official site
# https://developer.android.google.cn/studio
# After installation, verify SDK location (macOS)
ls ~/Library/Android/sdk
# Configure environment variables (bash)
echo 'export ANDROID_HOME=~/Library/Android/sdk' >> ~/.bash_profile
echo 'export PATH=$PATH:$ANDROID_HOME/platform-tools' >> ~/.bash_profile
echo 'export PATH=$PATH:$ANDROID_HOME/tools' >> ~/.bash_profile
echo 'export PATH=$PATH:$ANDROID_HOME/tools/bin' >> ~/.bash_profile
echo 'export PATH=$PATH:$ANDROID_HOME/emulator' >> ~/.bash_profile
source ~/.bash_profile
# For zsh users
echo 'export ANDROID_HOME=~/Library/Android/sdk' >> ~/.zshrc
echo 'export PATH=$PATH:$ANDROID_HOME/platform-tools' >> ~/.zshrc
source ~/.zshrc
# Verify ADB installation
adb version
```
### 2. Create Android Virtual Device (AVD)
```bash
# Create AVD via Android Studio GUI:
# More Actions → Virtual Device Manager → Create Device
# Recommended configuration:
# Device: Pixel 9 Pro
# System Image: API 36 (Android 16), Google APIs, arm64-v8a
# RAM: 4096 MB
# Internal Storage: 16 GB
# VM Heap: 512 MB
# Boot option: Cold Boot
# List available AVDs
emulator -list-avds
# Launch emulator from command line
emulator -avd Pixel_9_Pro_API_36 -writable-system
```
### 3. Root with Magisk (Method A: rootAVD - Recommended)
```bash
# Clone rootAVD (migrated to GitLab)
git clone https://gitlab.com/newbit/rootAVD.git
cd rootAVD
# Download latest Magisk APK
# https://github.com/topjohnwu/Magisk/releases
# Rename Magisk-v28.1.apk to Magisk.zip and place in rootAVD directory
# List available AVD images
./rootAVD.sh ListAllAVDs
# Root the specific system image
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img
# Restart emulator (cold boot)
# Verify Magisk installation in app drawer
```
### 4. Root with Magisk (Method B: Manual Patch)
```bash
# Start emulator with writable system
emulator -avd Pixel_9_Pro_API_36 -writable-system
# Get root access via ADB
adb root
adb remount
# Install Magisk APK
adb install Magisk-v28.1.apk
# Push ramdisk to device
adb push $ANDROID_HOME/system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img /sdcard/Download/
# In Magisk app:
# Install → Select and Patch a File → Choose ramdisk.img
# Download patched file from /sdcard/Download/magisk_patched_*.img
# Pull patched image
adb pull /sdcard/Download/magisk_patched_xxxxx.img
# Replace original ramdisk
cp magisk_patched_xxxxx.img $ANDROID_HOME/system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img
# Restart emulator
```
## Magisk Configuration
```bash
# Enable Zygisk (required for many modules)
# Magisk app → Settings → Enable Zygisk → Reboot
# Hide Magisk app (randomize package name)
# Magisk app → Settings → Hide the Magisk App → Enter custom name
# Configure DenyList (hide root from apps)
# Magisk app → Settings → Configure DenyList
# Add target apps (banking apps, games, etc.)
```
## Install ZygiskNext (Improved Zygisk)
```bash
# Download ZygiskNext
# https://github.com/Dr-TSNG/ZygiskNext/releases
# Install via Magisk
# Magisk → Modules → Install from storage → Select ZygiskNext-*.zip
# Reboot
# Disable built-in Zygisk after installing ZygiskNext
# Magisk → Settings → Disable Zygisk → Reboot
```
## Install Shamiko (Hide Magisk from Detection)
```bash
# Download Shamiko
# https://github.com/LSPosed/LSPosed.github.io/releases
# Install via Magisk
# Magisk → Modules → Install from storage → Select Shamiko-*.zip
# Reboot
# Enable Shamiko whitelist mode
adb shell su -c 'touch /data/adb/shamiko/whitelist'
# Verify Shamiko status
adb shell su -c 'ls -la /data/adb/shamiko/'
```
## Install LSPosed Framework
```bash
# Download LSPosed Zygisk version
# https://github.com/LSPosed/LSPosed/releases
# Install via Magisk
# Magisk → Modules → Install from storage → Select LSPosed-*.zip
# Reboot
# Access LSPosed manager
# Notification → LSPosed → Enable modules
```
## Install Frida
```bash
# Download Frida server for Android
# https://github.com/frida/frida/releases
# Select frida-server-*-android-arm64.xz
# Extract and push to device
xz -d frida-server-*-android-arm64.xz
adb push frida-server-*-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"
# Run Frida server
adb shell "su -c /data/local/tmp/frida-server &"
# Install Frida tools on host
pip install frida-tools
# Verify Frida connection
frida-ps -U
```
## SSL/TLS Certificate Pinning Bypass
### Method 1: HTTP Toolkit Module
```bash
# Download HTTP Toolkit certificate injection module
# https://github.com/httptoolkit/frida-android-unpinning
# Install as Magisk module
# Magisk → Modules → Install from storage → Select module zip
# Configure proxy in emulator
# Settings → Network & Internet → Internet → Wi-Fi → Modify
# Proxy: Manual
# Hostname: <host_machine_ip>
# Port: 8080 (Burp/Charles default)
```
### Method 2: Frida Script (Universal SSL Pinning Bypass)
```javascript
// ssl-bypass.js
Java.perform(function() {
console.log("[*] Universal SSL Pinning Bypass loaded");
// OkHttp3 Certificate Pinner
try {
var CertificatePinner = Java.use('okhttp3.CertificatePinner');
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
console.log('[+] OkHttp3 Certificate Pinner bypassed');
return;
};
} catch(err) {
console.log('[-] OkHttp3 not found');
}
// TrustManager
try {
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
var SSLContext = Java.use('javax.net.ssl.SSLContext');
var TrustManager = Java.registerClass({
name: 'com.sensepost.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('[+] SSLContext TrustManager bypassed');
SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
};
} catch(err) {
console.log('[-] TrustManager bypass failed: ' + err);
}
// Conscrypt (Android N+)
try {
var ConscryptFileDescriptorSocket = Java.use('com.android.org.conscrypt.ConscryptFileDescriptorSocket');
ConscryptFileDescriptorSocket.verifyCertificateChain.implementation = function() {
console.log('[+] Conscrypt certificate verification bypassed');
};
} catch(err) {
console.log('[-] Conscrypt not found');
}
});
```
```bash
# Run Frida script
frida -U -f com.example.app -l ssl-bypass.js --no-pause
```
### Method 3: JustTrustMe (LSPosed Module)
```bash
# Download JustTrustMe
# https://github.com/Fuzion24/JustTrustMe/releases
# Install APK
adb install JustTrustMe.apk
# Enable in LSPosed
# LSPosed → Modules → JustTrustMe → Enable
# Select target app → Reboot app
```
## Install System CA Certificate
```bash
# Convert certificate to PEM format
openssl x509 -inform DER -in burp-cert.der -out burp-cert.pem
# Get certificate hash
CERT_HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp-cert.pem | head -1)
# Rename certificate
cp burp-cert.pem ${CERT_HASH}.0
# Push to system
adb root
adb remount
adb push ${CERT_HASH}.0 /system/etc/security/cacerts/
adb shell "chmod 644 /system/etc/security/cacerts/${CERT_HASH}.0"
adb reboot
```
## Common Frida Scripts
### List Installed Packages
```bash
frida-ps -Uai
```
### Hook Method to Bypass Root Detection
```javascript
// root-bypass.js
Java.perform(function() {
var RootDetection = Java.use('com.example.app.RootDetection');
RootDetection.isRooted.implementation = function() {
console.log('[+] Root check bypassed');
return false;
};
});
```
```bash
frida -U -f com.example.app -l root-bypass.js --no-pause
```
### Dump App Memory
```javascript
// memory-dump.js
Java.perform(function() {
var ActivityThread = Java.use('android.app.ActivityThread');
var app = ActivityThread.currentApplication();
var context = app.getApplicationContext();
console.log('[*] Package Name: ' + context.getPackageName());
console.log('[*] Files Dir: ' + context.getFilesDir().getAbsolutePath());
});
```
### Intercept Crypto Operations
```javascript
// crypto-hook.js
Java.perform(function() {
var Cipher = Java.use('javax.crypto.Cipher');
Cipher.doFinal.overload('[B').implementation = function(input) {
console.log('[*] Cipher.doFinal called');
console.log('[*] Input: ' + Java.use('java.util.Arrays').toString(input));
var result = this.doFinal(input);
console.log('[*] Output: ' + Java.use('java.util.Arrays').toString(result));
return result;
};
});
```
## ADB Commands Reference
```bash
# Device connection
adb devices
adb connect <ip>:5555
# Root shell
adb root
adb shell
# Package management
adb install app.apk
adb install -r app.apk # Reinstall
adb uninstall com.example.app
adb shell pm list packages
adb shell pm path com.example.app
# File operations
adb push local/file /sdcard/
adb pull /sdcard/file local/
# Logcat
adb logcat
adb logcat | grep -i "keyword"
adb logcat -c # Clear logs
# Screen capture
adb shell screencap /sdcard/screen.png
adb pull /sdcard/screen.png
# Activity management
adb shell am start -n com.example.app/.MainActivity
adb shell am force-stop com.example.app
# Network
adb shell settings put global http_proxy <ip>:8080
adb shell settings delete global http_proxy
adb shell settings delete global https_proxy
```
## Troubleshooting
### Emulator Won't Start
```bash
# Check available system images
sdkmanager --list | grep system-images
# Cold boot emulator
emulator -avd <name> -no-snapshot-load
# Wipe data
emulator -avd <name> -wipe-data
```
### ADB Not Detecting Device
```bash
# Restart ADB server
adb kill-server
adb start-server
# Check emulator console port
adb connect localhost:5554
```
### Magisk Not Working After Reboot
```bash
# Re-run rootAVD script
cd rootAVD
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img
# Verify ramdisk wasn't overwritten
ls -lh $ANDROID_HOME/system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img
```
### Frida Server Connection Failed
```bash
# Kill existing Frida server
adb shell "su -c killall frida-server"
# Restart with verbose logging
adb shell "su -c '/data/local/tmp/frida-server -l 0.0.0.0:27042' &"
# Forward port
adb forward tcp:27042 tcp:27042
# Test connection
frida-ps -H localhost:27042
```
### SSL Pinning Still Active
```bash
# Stack multiple bypass methods
# 1. Install HTTP Toolkit module
# 2. Enable JustTrustMe in LSPosed
# 3. Run Frida universal bypass script
# 4. Install system CA certificate
# Verify certificate installation
adb shell "ls /system/etc/security/cacerts/ | grep -i <hash>"
```
### App Crashes on Launch
```bash
# Check if DenyList is configured
# Magisk → Settings → Configure DenyList → Remove app
# Disable Shamiko temporarily
adb shell "su -c rm /data/adb/shamiko/whitelist"
adb reboot
# Check logcat for crashes
adb logcat | grep -i "fatal\|exception"
```
## Best Practices
1. **Always create snapshots** before making major changes to AVD
2. **Use Cold Boot** for Magisk to load properly
3. **Keep Magisk and modules updated** for latest bypass techniques
4. **Test bypasses incrementally** - enable one at a time
5. **Use ZygiskNext + Shamiko** for better detection evasion
6. **Avoid Google Play system images** - use Google APIs instead
7. **Clear app data** after installing bypass modules
8. **Monitor logcat** during testing to identify security checks
## References
- Magisk: https://github.com/topjohnwu/Magisk
- rootAVD: https://gitlab.com/newbit/rootAVD
- Frida: https://frida.re/docs/android/
- LSPosed: https://github.com/LSPosed/LSPosed
- ZygiskNext: https://github.com/Dr-TSNG/ZygiskNext
- Shamiko: https://github.com/LSPosed/LSPosed.github.io
Creator's repository · aradotso/security-skills