← All guides AI Release
RU Subscribe to @ai_release1

How to Audit Android App Privacy via ADB: Permissions, Trackers and Network Endpoints

Updated: 07.11.2026 · AI Release · @ai_release1
How to Audit Android App Privacy via ADB: Permissions, Trackers and Network Endpoints

TL;DR

Requirements and setup

Illustration: Requirements and setup
Illustration: Requirements and setup

- [ ] adb version prints a version string

- [ ] adb devices lists exactly one device with state device

- [ ] apkanalyzer --help prints usage

- [ ] mitmproxy --version prints a version string

Example: a correctly prepared workstation shows:

$ adb devices
List of devices attached
R58M12ABCDE	device

The word device (not unauthorized, not offline) means the RSA key was accepted on the phone screen.

Step 1. Inventory the app and dump its declared permissions

What to do: list installed third-party packages, copy the target APK to your laptop, and export the manifest permissions.

# 1. Third-party packages only (-3 skips system apps)
adb shell pm list packages -3

# 2. Where the APK lives on the device
adb shell pm path <your.package>

# 3. Pull it (use the path printed by the previous command)
adb pull /data/app/~~<hash>/<your.package>-<hash>/base.apk ./<your.package>.apk

# 4. Declared permissions, straight from the manifest
apkanalyzer manifest print ./<your.package>.apk | grep -i "uses-permission"

Why: the manifest lists what the app *asks for*. That is the input for everything else — a notes app requesting READ_SMS is a finding even before you look at traffic. Pulling the APK also lets you analyse it offline without touching the device again.

How to check: apkanalyzer prints one line per permission. Example:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

Write each line into your report file as permission | declared | granted?. The granted? column is filled in Step 2 — declaration alone is not proof that the permission is active.

If you pulled the app from a third-party store rather than Google Play, verify the store itself first: How to Install Verified Third-Party App Stores on Android 17 (QPR2): Step-by-Step Guide.

Step 2. Read runtime state, app-ops, and embedded tracker SDKs

Illustration: Step 2. Read runtime state, app-ops, and embedded tracker SDKs
Illustration: Step 2. Read runtime state, app-ops, and embedded tracker SDKs

What to do: separate *requested* from *actually granted*, then scan the DEX code for third-party SDK packages.

# Runtime (dangerous) permissions and their actual grant state
adb shell dumpsys package <your.package> | grep -A 40 "runtime permissions:"

# AppOps: per-operation allow/ignore, includes ops with no manifest permission
adb shell cmd appops get <your.package>

# Tracker SDKs compiled into the APK (vendor prefixes are examples — confirm
# each one against that vendor's own documentation)
apkanalyzer dex packages ./<your.package>.apk \
  | grep -Ei 'com\.(google\.android\.gms\.ads|facebook\.appevents|adjust\.sdk|appsflyer)'

Why: dumpsys package shows the real switch position for each dangerous permission, and AppOps catches operations the manifest never mentions (clipboard reads, background starts). The DEX scan answers "which third-party code ships inside" — an advertising or attribution SDK is a data-sharing endpoint by design.

How to check: you should see a permission block with explicit granted= values and at least one AppOps line per operation.

Example:

runtime permissions:
  android.permission.POST_NOTIFICATIONS: granted=true, flags=[ USER_SENSITIVE_WHILE_INVISIBLE ]
  android.permission.ACCESS_FINE_LOCATION: granted=false
POST_NOTIFICATION: allow
READ_CLIPBOARD: allow
RUN_IN_BACKGROUND: allow

For the SDK scan, the last field of each output line is the package name; leading columns are size counters whose meaning depends on the tool version — check the documentation.

P d   142   142  com.adjust.sdk
P d    88    88  com.facebook.appevents

Record it as: SDK | package prefix | evidence (apkanalyzer line). If the grep returns nothing, the app may still load SDKs dynamically — note that as "not detected statically" rather than "absent".

Step 3. Capture network endpoints and compile the report

Illustration: Step 3. Capture network endpoints and compile the report
Illustration: Step 3. Capture network endpoints and compile the report

What to do: route device traffic through mitmproxy on your laptop, run a scripted 5-minute session in the app (launch → browse one screen → background it → kill it), then reset the proxy.

# 1. Start the interceptor on the laptop
mitmproxy --listen-port 8080

# 2. Point the device at it (same Wi-Fi network as <proxy-host>)
adb shell settings put global http_proxy <proxy-host>:8080

# 3. Drive the app, then watch hostnames appear in the mitmproxy flow list

# 4. Clear the proxy when finished
adb shell settings put global http_proxy :0

Why: http_proxy is a global Android setting, so every app on the device obeys it without a VPN profile. The flow list gives you the real endpoints — the ones the app contacts at runtime, not the ones in the manifest.

How to check: the mitmproxy window lists flows with hostnames and status codes. Example:

GET   https://app.example.com/v1/sync        200
POST  https://analytics.example.net/collect  204
GET   https://cdn.example.com/assets/1.json  200

If HTTPS flows appear as << SSL handshake failed >> or the app logs Trust anchor for certification path not found, that is certificate pinning or the Android 7+ rule that ignores user-installed CAs — see Troubleshooting.

For apps that hide traffic this way, a complementary signal is the log stream:

adb logcat -c && adb logcat | grep -Ei 'adjust|appsflyer|firebase|okhttp|retrofit'

Example: an SDK initialisation line such as D/Adjust ( 4211): Adjust SDK initialised tells you the SDK is active even if its traffic was blocked.

Final deliverable — one table, three columns:

FindingEvidenceAction
`READ_CLIPBOARD` allowed`cmd appops get` line `READ_CLIPBOARD: allow`report to vendor / restrict
Attribution SDK bundled`apkanalyzer dex packages` line `com.adjust.sdk`add to data-sharing list
Contact to `analytics.example.net`mitmproxy flow `POST /collect 204`document endpoint + purpose

Success looks like a table where every row has a command output behind it. No row without evidence.

Troubleshooting

Problem. Device is listed but every command fails with an authorisation error.

Problem. grep fails on Windows.

adb shell dumpsys package <your.package> | Select-String -Pattern "runtime permissions" -Context 0,40

Problem. HTTPS traffic is unreadable after the proxy is set.

Summary and next steps

You now have a permission table backed by dumpsys output, a list of tracker SDK packages extracted from the APK, and a set of endpoints observed in mitmproxy during a scripted session. Repeat the same three steps for each app on your list and keep one report file per package, so results stay comparable across releases.

FAQ

Do I need root to audit an app's network traffic?

No for the proxy method — adb shell settings put global http_proxy works on a stock device. Root is only required for on-device packet capture with tcpdump, and for inspecting traffic from apps that pin certificates.

Why does adb devices show unauthorized instead of device?

The phone has not accepted your workstation's RSA key yet. Accept the on-screen prompt, or run Developer options > Revoke USB debugging authorizations and replug the cable.

How do I find which tracker SDKs an app ships?

Pull the APK with adb pull, then run apkanalyzer dex packages and filter the output for known vendor prefixes. Static detection only proves the code is bundled; confirm activity in adb logcat or in the captured flows.

Can I run this audit on an app installed from a third-party store?

Yes, but verify the store and the APK signature first — the procedure is identical once the package is installed. The store-side checks are described in the third-party app stores guide.

🤖 AI summary