@Lee_points: Please listen to some advice — I told you long ago not to use a Chinese Android phone for circumventing the firewall. Scan your phone with adb and see how it's leaking your privacy. https://github.com/Verlintas/NOIR
Summary
An introduction to the open-source tool NOIR: an Android privacy auditing tool that runs on your computer, scanning connected devices via adb for app permissions, APK network endpoints, and manifest information, then generating risk scores, data-flow correlations, and reversible remediation suggestions.
View Cached Full Text
Cached at: 11/03/26, 02:21 AM
Verlintas/NOIR
Source: https://github.com/Verlintas/NOIR
███╗ ██╗ ██████╗ ██╗██████╗ ████╗
██║██╔═══██╗██║██╔══██╗ ██║██╗ ██║██║ ██║██║██████╔╝ ██║╚██╗██║██║ ██║██║██╔══██╗ ██║
╚████║╚██████╔╝██║██║ ██║ ╚═╝
╚═══╝ ╚═════╝ ╚═╝╚═╝ ╚═╝
NOIR
build release license platforms
Turn “what can this phone leak?” into a reproducible report.
NOIR is an audit tool that runs on your computer. Through adb it reads the app list, permissions, and network endpoints found in the APKs of a connected Android device, then produces classifications, risk scores, and actionable remediation advice. When needed, it can also invoke jadx to decompile individual apps and search for keywords.
Positioning: audit and self-protection. For your own device, your own apps, and authorized security research.
Website: https://verlintas.dev/noir/ · 中文
What it does
- Inventory: list every app that has both network access and sensitive permissions, along with exactly what each one was granted.
- Endpoint extraction: on the device, use
unzip + stringsto extract URLs from each APK’s dex, transferring only a few KB back instead of pulling the full package to your computer. - Classification and scoring: identify vendors by package name and domain (Xiaomi / Google / Tencent / Amap / …) and categories (telemetry, ads, location, IME, …), then compute a risk score from permissions combined with the reporting endpoints.
- Data correlation: translate permissions into “what data can be accessed” (location / contacts / SMS / calls / microphone / camera / screen / app list / device identifiers / files / calendar / accounts), pair them with the reporting domains, and derive “which categories of data may flow where.”
- Shared UIDs: detect shared users such as
android.uid.systemand list which packages actually share the union of the same permissions. - Manifest layer: parse the binary AXML of
AndroidManifest.xmlto find exported components without permission protection, cleartext traffic, backup settings, debuggable flags, and targetSdk. - Recommendations: distinguish between “safe to automate,” “needs manual confirmation,” and “leave alone,” and generate a rollback command for every action.
- Deep dives when needed:
deeppulls a single APK locally, decompiles it withjadx, and searches for high-risk calls such asRuntime.exec,setApplicationEnabledSetting,DexClassLoader,MediaProjection, and more.
What it does not do
- No network access, no data uploads, no account required.
- Never modifies the system partition; no root needed.
- Never uninstalls anything automatically unless you explicitly pass
--aggressive.
First run
noir
Running without arguments launches a wizard:
- Checks for
adb— if missing, it asks whether to auto-download it (~/.noir/tools) - Checks for a device — if none is found, it prints the steps to enable Developer Mode / USB debugging, then waits for you to plug in (up to 180 seconds)
- Asks “Start scanning?” — when done, it goes straight to the dashboard
- Asks “Execute these 19 remediation actions?” — answer
yto run them, and rollback files are written
Throughout, you’ll only be asked two or three y/n questions; everything else is automatic.
Environment check
noir doctor
NOIR doctor
platform Mac OS X aarch64
java 17.0.19
adb /opt/homebrew/.../platform-tools/adb Version 37.0.1-15733141
device 178b0d2f device 2509FPN0BC
jadx /opt/homebrew/bin/jadx
noir setup # downloads whatever is missing
noir setup --yes # no prompts; suitable for scripts
When something goes wrong
Every error comes with “what to do” instead of a stack trace:
╭─ ERROR ──────────────────────────────────────────────────────────╮
│ Specified adb does not exist: /nonexistent/adb │
├──────────────────────────────────────────────────────────────────┤
│ Check the path, or run noir setup to install automatically. │
╰──────────────────────────────────────────────────────────────────╯
When no device is detected, you get actionable steps:
╭─ No device detected ─────────────────────────────────────────────╮
│ 1. Enable Developer Mode │
│ Xiaomi / HyperOS: Settings → My device → All specs → tap │
│ "MIUI version" 7 times │
│ 2. Enable USB debugging: Settings → System → Developer options │
│ → USB debugging │
│ 3. After plugging in, tap "Allow USB debugging?" on the phone │
│ → check "Always allow" │
│ 4. Still not working? Try a different cable (many are │
│ charge-only) │
╰──────────────────────────────────────────────────────────────────╯
If a device is connected but not authorized, you get a separate prompt to “revoke USB debugging authorization and replug.”
Supported platforms
| OS | Status |
|---|---|
| macOS (Intel / Apple Silicon) | ✅ |
| Windows 10 / 11 | ✅ |
| Debian / Ubuntu | ✅ |
Dependencies:
- JDK 17+
- Android platform-tools (
adb) - jadx (only needed for the
deepcommand)
The tool automatically looks for adb and jadx in common install locations; if not found, you can specify them with --adb / --jadx.
# macOS
brew install --cask android-platform-tools jadx
# Debian / Ubuntu
sudo apt install adb
# jadx: https://github.com/skylot/jadx/releases
# Windows (scoop)
scoop install adb jadx
Installation
Option 1: Download and run (recommended)
Grab the portable package for your platform from Releases:
noir-v0.1.1-macOS-portable.zip
noir-v0.1.1-Windows-portable.zip
noir-v0.1.1-Linux-portable.zip
SHA256SUMS.txt
Unzip and double-click the launcher — the package includes its own runtime, so no Java installation is needed:
| OS | Double-click this | If it gets blocked |
|---|---|---|
| macOS | Start NOIR.command | Right-click → Open; or xattr -dr com.apple.quarantine "Start NOIR.command" NOIR.app |
| Windows | Start NOIR.bat | SmartScreen → More info → Run anyway (the batch file switches to UTF-8 and invokes the bundled JRE) |
| Linux | Start-NOIR.sh | First run chmod +x Start-NOIR.sh, or run it from the terminal |
The launcher opens a terminal window, runs through the wizard, and pauses at the end (it won’t flash by).
adb and jadx are not bundled — on first run you’ll be asked whether to auto-download them to ~/.noir/tools.
Option 2: Build from source
git clone https://github.com/Verlintas/NOIR
cd NOIR
./gradlew :cli:installDist
./cli/build/install/noir/bin/noir --about
Building
git clone && cd NOIR
./gradlew :cli:installDist
Artifacts:
cli/build/install/noir/bin/noir # macOS / Linux
cli/build/install/noir/bin/noir.bat # Windows
You can also run directly:
./gradlew :cli:run --args="devices"
Interface
NOIR dashboard on a Xiaomi 17 Pro Max
Real output on device (macOS Terminal): gradient logo, CJK-aligned tables, risk-colored scores, and a progress bar that refreshes after each APK is processed.
noir ui renders the results as a monospaced dashboard; colors and borders degrade gracefully based on terminal capabilities:
--ascii: pure ASCII borders, for legacy Windows consoles--no-color/--color: disable or force ANSI colors (auto-detected via TTY by default)--quiet: dashboard only, no scan progress output--no-clear: don’t clear the screen (handy for redirecting output to a file)
Usage
noir --about # what it is, what it writes, license
noir --version
noir devices
noir scan # full scan; outputs JSON / Markdown / domain lists
noir ui # scan and render the dashboard
noir auto # scan + classify + generate remediation plan (dry-run)
noir auto --apply # execute safe appops actions (reversible)
noir auto --apply --aggressive # also uninstall flagged user apps
noir deep com.example.app # pull APK + jadx + keyword search
noir block com.example.app # print remediation commands
noir block com.example.app --apply
Common options:
| Option | Description |
|---|---|
--serial <sn> | Target a specific device |
--out <dir> | Output directory (default noir-out) |
--min <n> | Only keep apps with score ≥ N |
--limit <n> | Output at most N entries |
--only <regex> | Only scan matching package names, e.g. --only 'com\.miui\.' |
--adb <path> / --jadx <path> | Manually specify tool paths |
--yes | Skip confirmations in automated scenarios |
DeepScan: decompile + remediate in one command
noir deepscan # decompile the 15 highest-risk apps
noir deepscan --top 30 # more of them
noir deepscan --all # all flagged apps (slow, disk-heavy)
noir deepscan --jobs 4 # parallel jadx instances
The flow is: scan → sort by risk → adb pull + jadx one by one → gather code-level signals (Runtime.exec, DexClassLoader, setApplicationEnabledSetting, enabled_accessibility_services, MediaProjection, SystemProperties.set, SMS/device identifiers, WebView bridges, accessibility / notification listener / device admin, …) → parse the manifest (exported components, cleartext traffic, backup, debuggable) → identify SDKs (Umeng / Firebase / AppsFlyer / …) → output deepscan.md / deepscan.tsv → ask whether to clean up.
noir deepscan --apply # run safe appops after analysis
noir deepscan --apply --purge # then confirm uninstalling high-risk user apps one by one
Decompilation results are cached by package name + APK path, so re-running against the same app reuses them directly.
Output
noir-out/
├── report.json # structured results (apps, permissions, endpoints, advice)
├── report.md # human-readable report
├── domains-trackers.txt # analytics / ads / crash reporting — safe to import wholesale
├── domains-other.txt # unknown purpose — evaluate each entry before importing
├── domains-functional.txt # push / login / updates / payments / store / cloud sync — never block these
├── domains.txt # same as trackers (back-compat with older scripts)
├── plan.txt # appops actions executable this run
└── rollback.txt # rollback commands
Privacy
- The tool itself makes no network calls: no telemetry, no version checks, no crash reporting
- Scan results are written only to the
--outdirectory you specify - The only external requests occur during
noir setup(downloading adb/jadx) andnoir deep(jadx is a local process) - Reports may contain package names and endpoints from your device — review before sharing
Caching
Scan results are cached by package name + APK path in ~/.noir/endpoints.tsv. When an app updates and its path changes, it is automatically re-analyzed; repeat scans typically take only a few seconds.
Architecture
adb ──▶ pm / dumpsys ──▶ Dumpsys parser ──┐
├─▶ cache (pkg + apk path)
adb ──▶ unzip/strings ──▶ endpoints ──────┘
│
▼
Classifier ─▶ score ─▶ Advisor
│
▼ ▼
report.json plan.txt
report.md rollback.txt
│
▼
Tui / CLI
deep takes a different branch: adb pull → jadx → grep over the source.
Design trade-offs
- Endpoint extraction happens on-device:
unzip | strings | grepruns insideadb shell, avoiding pulling hundreds of APKs back to your computer. If the device lacksunzip/strings, it automatically falls back to local parsing. - Special handling for shared UIDs: apps under
android.uid.systemon Android (often 50+) have their permissions recorded in theShared userssection at the end ofdumpsys package. The parser merges these permissions back into each package — otherwise the apps most worth seeing would disappear. - Tiered recommendations: only appops-level actions are marked as safe to automate; uninstalling must be explicitly enabled.
- No telemetry: the program contains no reporting logic whatsoever.
FAQ
Do I need root?
No. Everything runs through adb shell permissions; uninstalling is only at the --user 0 level, and the APK remains in the system partition.
Will it break my phone?
By default it is completely read-only. --apply only changes app-ops, every one of which can be restored with default, and rollback.txt records them all. Uninstalls via noir block also print the pm install-existing recovery command first.
Why do some apps only get “manual review”?
System apps cannot be truly uninstalled (--user 0 uninstall will be restored by OTA or factory reset), so only app-ops or DNS-level blocking is recommended.
Why does DNS blocking only export lists instead of applying them? Changing DNS across platforms can easily cut the device off the network (we hit this during development), so we only export the lists:
domains-trackers.txt— analytics / ads / crash reporting; safe to import wholesaledomains-other.txt— unknown purpose; evaluate each entry before importingdomains-functional.txt— push, login, updates, payments, app store, cloud sync; blocking these breaks functionalitydomains.txt— now contains only trackers, kept for compatibility with older scripts
IPs, localhost, and domains containing test/staging are automatically filtered out.
Does it support iOS?
No. core is organized as Kotlin Multiplatform, but the audit logic depends on Android’s dumpsys and the APK format.
Contributing
- CONTRIBUTING.md — where builds, tests, and rules live
- SECURITY.md — how to report vulnerabilities (please don’t open public issues)
- Issues — for bugs, include
noir doctoroutput
Roadmap
-
Monospaced dashboard (
noir ui) - DeepScan (batch decompilation + code-level signals)
- Double-click-to-run portable packages with bundled runtime (jpackage)
- Graphical interface (Compose Multiplatform)
- Configurable rule files (YAML) with community rule packs
-
Batch pipeline with
apktool/jadx - On-device DNS/VPN blocking list export
- Signed scan results with version comparison
Disclaimer
NOIR should only be used on your own device, or a device you have explicit authorization to audit. It provides static evidence (“this app has this capability, and this endpoint exists in its code”), which cannot prove that any specific transmission actually took place. Please make your own judgment in combination with network-level evidence.
License
MIT © 2026 Verlintas
Similar Articles
@geekbb: I always tell you not to use domestic phones, but you don't take it seriously. Now let's find out who's actually sending your location and contacts outbound. Plug in via USB, run an adb scan, and you'll get a list of domains along with rollback commands. https://github.com/Verlintas/NOIR
The NOIR tool on GitHub can scan domestic phones via adb over USB, generating a list of domains that exfiltrate data such as location and contacts, along with rollback commands, for checking a phone's privacy leaks.
@Verlintas: I just had Big Fat Fish scan my Xiaomi 17 Pro Max, and you won't believe what it found...
A user ran the Big Fat Fish tool on their Xiaomi 17 Pro Max and cited warnings that domestic Android phones may report their app lists, advising against using Chinese phones for circumventing the firewall or installing foreign apps.
@wquguru: Reverse-analyzed Claude Code with REA (Mac CLI, Mac App, Android App) — this should be the most complete proxy ruleset out there. A few key points: 1. Android: strongest detection. Anti-fraud checks via Sift, SIM card country detection, and hardware device IDs are collected…
The author reverse-engineered Claude Code's Mac CLI, Mac App, and Android App using REA, noting that the Android client has the strongest anti-fraud detection via Sift — collecting SIM card country and hardware device IDs — while the Mac client only gathers random telemetry through Sentry/Datadog. The full proxy ruleset has been made public.
@wquguru: After statically reverse-engineering Claude, I found eight major pitfalls that even 100 Mac Minis can’t save you from: 1. Putting a mainland Chinese SIM card in your phone: Sift records it, and if it doesn’t match the country of your exit IP, you’re toast 2. Clearing app data and switching to a new account: Basically useless, Sift’s installat…
Through static reverse engineering of Claude’s Android client, Mac app, and CLI, the author identifies eight major risk-control pitfalls, explaining how services such as Sift and Sentry use hardware-level device fingerprints, SIM card country information, and IP address histories to identify and restrict accounts.
@math_fournity: https://x.com/math_fournity/status/2107493047319802364
The author shares a dual-phone, dual-VPN architecture (a Pixel flashed with LineageOS + ProtonVPN + a commercial VPN relay + Cloudflare WARP) for reliably accessing AI services like Claude from within China while avoiding account bans, along with suggestions for fixing DNS pollution.