Goal and boundaries
Mobile reverse engineering means starting from a compiled artifact, such as an Android .apk or iOS .ipa, and understanding how it works. The goal can be learning, auditing your own app, checking security practices or documenting behavior.
This guide is not about bypassing authentication, accessing private data, abusing undocumented APIs or tracking users without permission. Use these techniques only on apps you own, test environments, intentionally vulnerable labs or explicitly authorized audits.
Define the legal scope
Before any analysis, write down the scope:
Application:
Version:
Platform: Android / iOS
Goal: learning / internal audit / bug bounty / pentest
Authorization: yes / no
Test dates:
Allowed actions:
Forbidden actions:
Security contact:
A publicly downloadable app does not automatically authorize secret extraction, private API automation, protection bypasses or access to data that is not yours. Prefer your own apps, open-source apps, OWASP Mobile labs, staging environments or bug bounty programs with explicit rules.
Static and dynamic analysis
Static analysis inspects the app without running it: manifest, permissions, configuration files, resources, strings, decompiled code, certificates and embedded libraries.
Dynamic analysis observes the app while it runs: logs, local files, saved preferences, local databases, user scenarios and, in an authorized setting, network exchanges.
Static analysis gives you the map; dynamic analysis shows the real behavior.
Prepare the environment
Keep your analysis environment separate from your personal phone. Ideally use:
- a Linux, macOS or Windows computer;
- a test Android phone or emulator;
- a dedicated test account;
- no sensitive personal data on the device;
- fake data for scenarios.
Useful tools
On Android, common tools include:
adbto communicate with a device;jadxto decompile an APK into approximate Java/Kotlin;apktoolto decode resources and the manifest;- Android Studio for emulation, logs and inspection;
- MobSF for an automated first pass;
- mitmproxy, Burp Suite, Proxyman or Charles Proxy for authorized traffic observation;
- Frida for dynamic instrumentation in a strict testing scope.
On iOS, analysis is often more constrained. You may use Xcode, Console.app, MobSF, Frida, Mach-O tools and sometimes class-dump or modern alternatives. Android is usually easier for beginners.
Retrieve and document the APK
From a test Android device, locate an app:
adb shell pm list packages | grep app.name
adb shell pm path com.example.application
Then pull the file:
adb pull /data/app/path/base.apk ./application.apk
Depending on the Android version, an app may be split into several APKs: base.apk, language split, architecture split or density split. Document the version:
aapt dump badging application.apk
sha256sum application.apk
The hash removes ambiguity from the report.
First pass with apktool
apktool decodes resources and the manifest:
apktool d application.apk -o application_decoded
You get a tree such as:
application_decoded/
├── AndroidManifest.xml
├── apktool.yml
├── res/
├── smali/
└── assets/
The manifest describes package name, activities, services, receivers, providers, deep links, permissions and network configuration. The useful question is not only "which permissions are requested?", but "are they consistent with the advertised features?".
Exported components and permissions
An exported component can be called by other apps:
<activity
android:name=".SomeActivity"
android:exported="true" />
This is not automatically a vulnerability, but it deserves review. Also check sensitive permissions such as location, camera, contacts, storage, microphone or notifications. Every permission should have a clear product reason.
Decompile with JADX
JADX gives an approximate Java/Kotlin representation:
jadx-gui application.apk
jadx -d jadx_output application.apk
The output may be incomplete, obfuscated or different from the original source. It is still useful to understand architecture, models, libraries and sensitive areas.
Useful searches:
http, https, api, baseUrl, retrofit, okhttp, graphql,
firebase, sentry, amplitude, mixpanel,
token, auth, jwt, bearer, secret, client_id
These searches are for mapping risk during defensive audits, not for reusing secrets.
Resources and configuration
Inspect assets/, res/raw/ and res/xml/. You may find environment URLs, flags, JSON files, Firebase configuration, public certificates or network security rules.
Android network configuration can look like:
<application
android:networkSecurityConfig="@xml/network_security_config">
</application>
Check whether cleartext HTTP is allowed, whether specific domains are configured, whether debug and release differ, which certificates are trusted and whether certificate pinning is used.
Local storage
In an authorized environment, you often inspect:
/data/data/com.example.application/
├── shared_prefs/
├── databases/
├── files/
├── cache/
└── no_backup/
Look for tokens, personal data, histories, sensitive preferences, temporary files or session data. Good practices include minimal storage, encryption for sensitive data, session expiry, no static secrets and no sensitive data in logs.
Logs and network traffic
Android logs can be read with:
adb logcat
adb logcat | grep com.example.application
A production app should never log tokens, passwords, emails, locations, payment details or confidential business data.
Network observation must remain authorized: test account, fake data, test environment and explicitly covered endpoints. You can document contacted domains, JSON formats, response codes, errors, TLS usage and server-side control consistency. Without explicit authorization, avoid TLS bypasses, pinning bypasses, request replay or automation.
Obfuscation
With R8 or ProGuard, code may look like this:
public final class a {
public final String b;
public final int c;
}
To navigate it, start from strings, follow network calls, identify data models, find Retrofit or serialization annotations and progressively rebuild the call graph.
MobSF for an initial pass
MobSF automates an initial report:
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
Then open:
http://localhost:8000
MobSF can identify permissions, trackers, URLs, sensitive files, certificates, libraries, manifest details and weak configurations. An automated report is not the final truth; it is a starting point.
Audit methodology
A clean analysis follows a reproducible method:
- Identify the app: name, package, version, hash, source, date.
- Inspect the manifest: permissions, exported components, deep links, providers, services, network config.
- Map dependencies: analytics, crash reporting, networking, payment, authentication, advertising, encryption.
- Find sensitive areas: auth, sessions, local storage, logs, WebView, deep links, temporary files.
- Test dynamically with a test account.
- Write a clear report: summary, impact, conditions, evidence, risk and recommendation.
Fictional mini-analysis
For a fictional DemoBike app, the manifest may request:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
That is coherent for showing nearby bike stations. In network_security_config.xml, a good sign would be:
<base-config cleartextTrafficPermitted="false" />
In decompiled code, you may spot Retrofit:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.build();
In a public report, avoid exposing sensitive details if the real URL is private. Document the communication pattern and risk instead.
Frequent warning signs
Common issues include:
- secrets embedded in the APK;
- security controls only on the client side;
- verbose logs;
- misconfigured WebView;
- overly permissive deep links;
- local storage of tokens or personal data in cleartext;
- permissive network configuration;
- sessions without clear expiry.
Anything inside an APK can eventually be extracted. Critical secrets belong on the server.
What to avoid
Avoid using private endpoints found during reverse engineering, bypassing protections, accessing data that is not yours, publishing secrets, automating calls without permission, testing production without agreement or generating excessive load.
A simple rule: if you could not calmly explain the action in an audit report sent to the app owner, do not do it.
Learn safely
Use targets designed for learning: intentionally vulnerable apps, OWASP Mobile labs, open-source apps, personal projects, mobile CTF challenges or scoped bug bounties.
Skills to develop: Android internals, Kotlin/Java, HTTP/TLS, OAuth/OIDC, secure storage, applied cryptography, backend architecture and report writing.
Quick checklist
[ ] APK obtained legally
[ ] Version and hash documented
[ ] Manifest analyzed
[ ] Permissions reviewed
[ ] Exported components identified
[ ] Deep links inspected
[ ] Network security config checked
[ ] Decompiled code reviewed
[ ] Main dependencies listed
[ ] Local storage analyzed
[ ] Logs checked
[ ] Network traffic observed only within the authorized scope
[ ] Sensitive data searched
[ ] Report written
[ ] Vulnerabilities reported responsibly
Conclusion
Mobile reverse engineering sits between development, security, architecture and technical investigation. Used well, it improves app security and helps you become a better developer.
Used poorly, it can become intrusive or illegal. The difference often comes down to one thing: authorization.
