android-studio-pentest-environment

v2026.09.24

Set up a complete Android app penetration testing environment using Android Studio emulators with Magisk root, Frida, HTTP Toolkit, and LSPosed modules

GitHub
安装命令
npx skhub add reason-machines/android-studio-pentest-environment
Markdown
SKILL.md

Android Studio Pentest Environment Setup

Skill by ara.so — Security Skills collection.

This skill provides expertise in setting up a complete Android application penetration testing environment using Android Studio Virtual Device Manager (AVD) with root access via Magisk, Frida dynamic instrumentation, HTTP Toolkit for traffic interception, and LSPosed modules for runtime manipulation.

What This Project Does

This project guides you through building a 2026-ready Android app penetration testing lab that includes:

  • Android Studio AVD with Google APIs (API 36/Android 16)
  • Magisk (root) via rootAVD automation
  • Frida for dynamic instrumentation
  • HTTP Toolkit for HTTPS traffic interception
  • LSPosed with TrustMeAlready and JustTrustMe modules for SSL pinning bypass
  • Shamiko for root hiding
  • ZygiskNext as modern Zygisk replacement

Prerequisites

Install Android Studio and SDK

# macOS - Add to ~/.bash_profile or ~/.zshrc
export ANDROID_HOME="$HOME/Library/Android/sdk"
export PATH="$PATH:$ANDROID_HOME/platform-tools"
export PATH="$PATH:$ANDROID_HOME/tools"
export PATH="$PATH:$ANDROID_HOME/tools/bin"
export PATH="$PATH:$ANDROID_HOME/emulator"

# Linux
export ANDROID_HOME="$HOME/Android/Sdk"
export PATH="$PATH:$ANDROID_HOME/platform-tools"

# Windows (PowerShell $PROFILE)
$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
$env:Path += ";$env:ANDROID_HOME\platform-tools"

Apply the configuration:

source ~/.bash_profile  # or ~/.zshrc
adb version  # Verify installation

Create Android Virtual Device

# List available system images
sdkmanager --list | grep system-images

# Download recommended image (Google APIs, not Google Play)
sdkmanager "system-images;android-36;google_apis;arm64-v8a"

# Create AVD via Android Studio GUI:
# 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

Root the Emulator with Magisk

Method A: rootAVD (Recommended)

# Clone rootAVD (GitLab is now primary, GitHub is read-only)
git clone https://gitlab.com/newbit/rootAVD.git
cd rootAVD

# Download latest Magisk APK and rename to Magisk.zip
curl -L -o Magisk.zip https://github.com/topjohnwu/Magisk/releases/download/v28.1/Magisk-v28.1.apk

# List available AVDs
./rootAVD.sh ListAllAVDs

# Root the specific system image
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img

# Cold boot the emulator (automatic if configured)

Method B: Manual Magisk Patch (Fallback)

# Start emulator with writable system
emulator -avd Pixel_9_Pro_API_36 -writable-system &
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/google_apis/arm64-v8a/ramdisk.img" /sdcard/Download/

# In Magisk app: Install → Select and Patch a File → choose ramdisk.img
# Download patched file back to host
adb pull /sdcard/Download/magisk_patched_*.img ./

# Replace ramdisk and restart
cp magisk_patched_*.img "$ANDROID_HOME/system-images/android-36/google_apis/arm64-v8a/ramdisk.img"
adb reboot

Configure Magisk

# Open Magisk app and enable:
# - Zygisk (Settings → Zygisk)
# - Hide Magisk app (Settings → Hide Magisk → Random package name)

# Verify root
adb shell su -c "id"
# Expected: uid=0(root) gid=0(root)

Install Frida

Frida Server on Device

# Download Frida server matching your Frida tools version
FRIDA_VERSION="16.5.9"
curl -L -o frida-server.xz "https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/frida-server-${FRIDA_VERSION}-android-arm64.xz"
unxz frida-server.xz

# Push to device
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server"

# Start Frida server
adb shell "su -c '/data/local/tmp/frida-server &'"

# Verify
frida-ps -U

Frida Tools on Host

# Install Frida CLI
pip install frida-tools==16.5.9

# Verify connection
frida-ps -U
# Should list running processes on emulator

Frida Usage Examples

# attach_script.py - Hook a function
import frida
import sys

def on_message(message, data):
    print(f"[*] {message}")

package = "com.example.app"
device = frida.get_usb_device()
session = device.attach(package)

script_code = """
Java.perform(function() {
    var MainActivity = Java.use('com.example.app.MainActivity');
    MainActivity.checkRoot.implementation = function() {
        console.log('[*] checkRoot() bypassed');
        return false;
    };
});
"""

script = session.create_script(script_code)
script.on('message', on_message)
script.load()
sys.stdin.read()
# Hook SSL pinning check
frida -U -f com.example.app -l ssl-pinning-bypass.js --no-pause

Install LSPosed and Modules

Install LSPosed (Zygisk version)

# Download LSPosed Zygisk release
curl -L -o LSPosed.zip https://github.com/LSPosed/LSPosed/releases/download/v1.9.2/LSPosed-v1.9.2-7024-zygisk-release.zip

# Flash via Magisk
adb push LSPosed.zip /sdcard/Download/
# In Magisk: Modules → Install from storage → select LSPosed.zip
adb reboot

Upgrade to ZygiskNext

# Download ZygiskNext (modern Zygisk replacement)
curl -L -o ZygiskNext.zip https://github.com/Dr-TSNG/ZygiskNext/releases/download/v4.0.2/Zygisk-Next-4.0.2-291-release.zip

# Flash via Magisk
adb push ZygiskNext.zip /sdcard/Download/
# Magisk: Modules → Install → ZygiskNext.zip
# Disable built-in Zygisk in Magisk settings
adb reboot

Install TrustMeAlready (SSL Pinning Bypass)

# Download TrustMeAlready module
curl -L -o TrustMeAlready.apk https://github.com/ViRb3/TrustMeAlready/releases/download/v1.11/TrustMeAlready-v1.11.apk

# Install APK
adb install TrustMeAlready.apk

# Activate in LSPosed:
# 1. Open LSPosed Manager
# 2. Modules → Enable TrustMeAlready
# 3. Select target apps or enable globally
# 4. Reboot

Install JustTrustMe (Alternative)

# Download JustTrustMe
curl -L -o JustTrustMe.apk https://github.com/Fuzion24/JustTrustMe/releases/download/v.2/JustTrustMe.apk

adb install JustTrustMe.apk
# Activate in LSPosed similar to TrustMeAlready

HTTP Traffic Interception

Method A: HTTP Toolkit

# Install HTTP Toolkit
brew install --cask http-toolkit  # macOS
# Or download from https://httptoolkit.com/

# Start HTTP Toolkit and select "Android Device via ADB"
# It will automatically:
# 1. Install HTTP Toolkit app on emulator
# 2. Configure system proxy
# 3. Install CA certificate

# Verify proxy is set
adb shell settings get global http_proxy

Method B: Manual Proxy Setup

# Set up proxy (e.g., Burp Suite on 127.0.0.1:8080)
adb shell settings put global http_proxy 127.0.0.1:8080

# Install CA certificate
# 1. Export cert from Burp (DER format)
# 2. Convert to PEM and get hash
openssl x509 -inform DER -in burp.cer -out burp.pem
HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp.pem | head -1)

# Push to system store
adb root
adb remount
adb push burp.pem "/system/etc/security/cacerts/${HASH}.0"
adb shell chmod 644 "/system/etc/security/cacerts/${HASH}.0"
adb reboot

Install Shamiko (Root Hiding)

# Download Shamiko
curl -L -o Shamiko.zip https://github.com/LSPosed/LSPosed.github.io/releases/download/shamiko-281/Shamiko-v0.7.4-281-release.zip

# Flash via Magisk
adb push Shamiko.zip /sdcard/Download/
# Magisk: Modules → Install → Shamiko.zip
adb reboot

# Configure Shamiko whitelist mode
# Magisk: Shamiko → Whitelist mode → Add apps to hide root from

Testing and Verification

Verify Root Status

# Check root access
adb shell su -c "whoami"
# Expected: root

# Test with Magisk app
adb shell pm list packages | grep -i magisk
# Should show random package name if hidden

Verify Frida

# List processes
frida-ps -U

# Test hook
frida -U -f com.android.settings -l test.js

# test.js content:
# Java.perform(() => {
#     console.log('[*] Frida is working!');
# });

Verify SSL Pinning Bypass

# Start HTTP Toolkit or Burp
# Launch target app
# Attempt HTTPS request
# Traffic should appear in proxy without certificate errors

Common Patterns

Install APK and Analyze

# Install APK
adb install target.apk

# List app info
adb shell pm list packages -f | grep target
adb shell dumpsys package com.example.target | grep version

# Pull APK for static analysis
adb shell pm path com.example.target
adb pull /data/app/com.example.target-xxx/base.apk

Hook Function with Frida

// hook_login.js
Java.perform(() => {
    const LoginActivity = Java.use('com.example.app.LoginActivity');
    
    LoginActivity.validateCredentials.implementation = function(username, password) {
        console.log(`[*] Username: ${username}`);
        console.log(`[*] Password: ${password}`);
        return this.validateCredentials(username, password);
    };
});
frida -U -f com.example.app -l hook_login.js --no-pause

Bypass Root Detection

// bypass_root.js
Java.perform(() => {
    // Hook common root detection methods
    const RootBeer = Java.use('com.scottyab.rootbeer.RootBeer');
    RootBeer.isRooted.implementation = () => false;
    
    const File = Java.use('java.io.File');
    File.exists.implementation = function() {
        const path = this.getAbsolutePath();
        if (path.includes('su') || path.includes('magisk')) {
            return false;
        }
        return this.exists();
    };
});

Extract Secrets from Memory

# dump_strings.py
import frida
import sys

package = "com.example.app"
device = frida.get_usb_device()
pid = device.spawn([package])
session = device.attach(pid)

script = session.create_script("""
Java.perform(() => {
    const String = Java.use('java.lang.String');
    String.$init.overload('java.lang.String').implementation = function(str) {
        if (str.includes('api_key') || str.includes('secret')) {
            console.log('[*] Found secret: ' + str);
        }
        return this.$init(str);
    };
});
""")

script.load()
device.resume(pid)
sys.stdin.read()

Troubleshooting

Magisk Not Showing Root

# Verify Magisk installation
adb shell ls -la /data/adb/magisk/

# Check Magisk daemon
adb shell su -c "magisk --version"

# Reinstall via rootAVD
cd rootAVD
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img restore
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img

Frida Server Crashes

# Check architecture match
adb shell getprop ro.product.cpu.abi
# Should be arm64-v8a

# Kill existing server
adb shell "su -c 'killall frida-server'"

# Restart with debug output
adb shell "su -c '/data/local/tmp/frida-server -D'"

LSPosed Not Working

# Verify Zygisk is enabled
adb shell su -c "magisk --sqlite 'SELECT * FROM settings WHERE key=\"zygisk\"'"

# Check LSPosed installation
adb shell ls -la /data/adb/lspd/

# Clear LSPosed cache
adb shell su -c "rm -rf /data/adb/lspd/cache"
adb reboot

SSL Pinning Bypass Not Working

# Ensure modules are activated for target app
# LSPosed Manager → Modules → TrustMeAlready → Check target app

# Try alternative: disable pinning via Frida
frida -U -f com.example.app --codeshare akabe1/frida-multiple-unpinning

# Verify certificate installation
adb shell "su -c 'ls -la /system/etc/security/cacerts/'"

Emulator Boot Loop After Root

# Restore from snapshot if created
# Android Studio → Device Manager → Snapshots → Restore

# Or restore original ramdisk
cd rootAVD
./rootAVD.sh system-images/android-36.1/google_apis/arm64-v8a/ramdisk.img restore

# Cold boot
emulator -avd Pixel_9_Pro_API_36 -no-snapshot-load

ADB Not Finding Device

# Restart ADB server
adb kill-server
adb start-server

# Check emulator is running
emulator -list-avds
adb devices

# Connect manually if needed
adb connect 127.0.0.1:5555

Environment Variables

Always use environment variables for sensitive configuration:

# Example: Frida script with API key
# frida_config.js
const API_KEY = Java.use('java.lang.System').getenv('TARGET_API_KEY');
# Set before running
export TARGET_API_KEY="your-key-here"
frida -U -f com.example.app -l frida_config.js

References

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

NOASSERTION

源路径

skills/android-studio-pentest-environment

默认分支

main

最新提交

304c245

Tree SHA

010f47d