Dynamic Analysis of an Android Application: A Complete Runtime Guide
Dynamic analysis of an Android application involves installing the APK on a device or emulator, instrumenting the runtime with tools like Frida, capturing network traffic via proxies, and correlating logs with static decompilation artifacts to observe actual behavior.
Dynamic analysis allows security researchers to observe an Android application's true runtime behavior, exposing hidden API endpoints, encryption keys, and malicious operations that static analysis might miss. This guide leverages the android-reverse-engineering-skill repository to demonstrate a systematic approach to runtime inspection using adb, Frida, and network interception tools.
Prerequisites and Environment Setup
Installing Core Dependencies
Before analyzing any application, ensure your workstation has the required toolchain. The repository provides install-dep.sh to automate this process.
Run the helper script located at plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh for each component:
# Install Java, adb and decompilers
bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh java
bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh adb
bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh jadx
Verifying ADB Availability
Confirm that adb is properly installed using the check-deps.sh script. This validates both required and optional dependencies.
bash plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/check-deps.sh
# Look for “[OK] adb detected (optional)” in the output
Preparing the Target Device and Application
Connecting a Device or Emulator
Dynamic analysis requires a running Android environment. Connect a physical device via USB or launch an Android Virtual Device (AVD).
# List attached devices
adb devices
# If none, start an emulator
emulator -avd Pixel_5_API_33
Identifying and Extracting the APK
Locate the target package on the device and extract the APK file to your workstation. The Setup Guide in plugins/android-reverse-engineering/skills/android-reverse-engineering/references/setup-guide.md documents these commands.
# Identify package
adb shell pm list packages | grep <keyword> # e.g., myapp
# Export the installed APK
PKG=com.example.myapp
APK_PATH=$(adb shell pm path $PKG | cut -d':' -f2)
adb pull $APK_PATH ./myapp.apk
Runtime Instrumentation and Observation
Installing the Target APK
Install the extracted (or re-signed) APK onto the test device. The -r flag allows overwriting existing versions.
adb install -r myapp.apk
Instrumenting with Frida
Runtime instrumentation reveals method calls and data flows that static analysis cannot predict. While the repository focuses on static tooling, the call-flow-analysis reference in plugins/android-reverse-engineering/skills/android-reverse-engineering/references/call-flow-analysis.md helps locate entry points for hooking.
Create a Frida script to intercept Retrofit calls:
// log_retrofit.js – Frida script
Java.perform(function () {
var Retrofit = Java.use('retrofit2.Retrofit');
Retrofit.create.implementation = function (cls) {
console.log('[Frida] Retrofit.create called for', cls.getName());
return this.create(cls);
};
});
Attach the script to the running application:
# Example: start a Frida server on the device (requires root or a Frida-compatible app)
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
# Attach a script that logs Retrofit calls
frida -U -f com.example.myapp -l log_retrofit.js --no-pause
Capturing Network Traffic
Intercept HTTPS and HTTP requests using a proxy. Forward device traffic to a local proxy using adb reverse (preferred for Android 10+) or adb forward.
# Forward device traffic to local proxy port 8080
adb reverse tcp:8080 tcp:8080 # device → host (recommended for newer Android)
# Or forward if reverse isn’t available
adb forward tcp:8080 tcp:8080
# Start mitmproxy
mitmproxy -p 8080
Collecting System Logs
Capture real-time system logs to observe crashes, exceptions, and custom debug output.
adb logcat > logcat.txt & # background capture
# ... interact with the app on the device ...
# When finished, stop capture
kill %1
Correlating Runtime Data with Static Analysis
After observing runtime behavior, map your findings back to the decompiled source code. The repository provides decompile.sh and find-api-calls.sh to generate the sources/ directory, while call-flow-analysis.md documents grep patterns for locating specific constructs.
Search for URLs or method names discovered during dynamic analysis:
# Find where a captured URL originates
grep -rn "auth/login" sources/
The sources/ directory is produced by plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/decompile.sh, and API patterns are extracted using plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/find-api-calls.sh.
Summary
Dynamic analysis of an Android application requires a systematic workflow that bridges runtime observation with static code review. Key takeaways include:
- Prepare the environment using
install-dep.shandcheck-deps.shto ensureadband decompilers are available. - Extract the target APK from a device using
adb shell pm pathandadb pull, as documented in the Setup Guide. - Instrument the runtime with Frida or Xposed to intercept method calls, using entry points identified via
call-flow-analysis.md. - Capture network traffic by forwarding device connections through
adb reverseto a proxy like mitmproxy. - Correlate findings by grepping runtime artifacts (URLs, class names) against the
sources/directory generated bydecompile.sh.
Frequently Asked Questions
What is the difference between static and dynamic analysis of Android apps?
Static analysis examines the APK file without executing it, using tools like jadx or vineflower to decompile bytecode into readable Java sources. Dynamic analysis observes the application during execution, capturing network traffic, method invocations, and system logs to reveal runtime-only behaviors such as API key generation, encrypted communication, and anti-tampering checks.
Do I need a rooted device for dynamic analysis?
Root access is required for deep instrumentation using Frida in server mode or Xposed frameworks, as these need to inject code into the Android runtime (ART). However, basic dynamic analysis—such as capturing network traffic with a proxy or viewing logcat output—can often be performed on non-rooted devices or emulators, provided the app allows debugging or you can re-sign the APK with a debuggable flag.
How do I bypass SSL pinning during dynamic analysis?
SSL pinning bypasses typically require runtime instrumentation. Using Frida, you can inject scripts that hook the X509TrustManager or OkHttp certificate validation methods to accept all certificates. Alternatively, re-signing the APK after patching the /smali code to disable pinning checks (using apktool and apksigner) is effective when source modification is preferred over runtime hooks.
What tools does the android-reverse-engineering-skill provide for dynamic analysis?
The repository provides adb integration helpers such as install-dep.sh and check-deps.sh for environment setup, plus documentation in setup-guide.md for APK extraction. While the primary focus is static decompilation via decompile.sh and find-api-calls.sh, the call-flow-analysis.md reference is critical for dynamic work—it provides grep patterns to locate entry points, lifecycle methods, and DI bindings that serve as hook targets for Frida or Xposed during runtime instrumentation.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →