NOIR is a free, open source threat detection & response project written in Kotlin and released under MIT. It has 1,445 GitHub stars, 101 forks and 0 open issues, and was last pushed 15 hours ago. On this registry it ranks #59 of 76 tracked projects in Threat Detection & Response, with 5 head-to-head comparisons available.

What is NOIR?

NOIR is a cross-platform desktop audit tool that uses adb to inventory a connected Android phone's apps, permissions, and the network endpoints embedded in their APKs, then reports what data could leak and which reversible fixes to apply — built for people auditing their own devices, their own applications, or authorized security research.

What it is

NOIR is a Kotlin application, distributed as a Kotlin Multiplatform project under the MIT licence, that runs on a computer rather than on the phone. It talks to a connected Android device over adb, reads the installed application inventory and the permissions each app holds, extracts network endpoints from the APKs, classifies apps by vendor and category, computes a risk score, and produces remediation advice with a rollback command for every action. It ships as a command-line tool with a terminal UI and runs on macOS (Intel and Apple Silicon), Windows 10 and 11, and Debian or Ubuntu.

The concrete problem it solves is the manual chain that a privacy audit otherwise requires: shelling into a device with adb, pulling APKs, running unzip and strings across dex files to find reporting URLs, and reaching for jadx when something looks suspicious. NOIR performs the endpoint extraction on the device itself and returns only a few kilobytes rather than whole packages, then parses the binary AndroidManifest.xml (AXML) to surface exported components with no permission protection, cleartext traffic, backup, debuggable flags, and targetSdk. It replaces that ad-hoc assembly of Android platform tools with a single guided workflow.

Key capabilities

  • Inventories every app that holds both network permission and sensitive permissions, and lists exactly what each one has been granted.
  • Extracts URLs from each APK's dex files on the device using unzip + strings, returning only a few kilobytes instead of the full package.
  • Classifies apps by vendor (Xiaomi, Google, Tencent, Amap and others) and by category such as telemetry, advertising, location, or input method, then scores risk from permissions combined with reporting endpoints.
  • Correlates permissions with the data they expose — location, contacts, SMS, call log, microphone, camera, screen, app list, device identifiers, files, calendar, accounts — and pairs each with the domains it may flow to.
  • Detects shared UIDs such as android.uid.system and lists which packages effectively share one permission union.
  • Grades each remediation as safe to automate, requiring confirmation, or not advised, and writes a rollback file alongside the executed actions; uninstalls only happen with an explicit --aggressive flag.
  • Runs a deep command that pulls a single APK and uses jadx to search for high-risk calls including Runtime.exec, setApplicationEnabledSetting, DexClassLoader, and MediaProjection.

Who uses it and how

  • Individuals auditing their own handset, who run noir with no arguments and follow a wizard that checks for adb, waits up to 180 seconds for a device to be plugged in, scans, and then offers to execute 19 safe remediation actions.
  • Debloating work: the project's topics include bloatware and debloat, and the remediation tiers are designed so that vendor and preinstalled packages can be disabled with a recorded path back.
  • Security researchers performing authorized static analysis of a single application, using deep when endpoint extraction alone is not enough.
  • Analysts on mixed desktop environments, since portable builds for macOS, Windows, and Linux bundle their own runtime and need no separate Java installation.
  • Scripted or unattended setup, using noir setup --yes for non-interactive provisioning and --adb or --jadx to point at specific binaries when auto-discovery fails.

Getting started

Download the portable package for your platform from Releases — noir-v0.1.1-macOS-portable.zip, noir-v0.1.1-Windows-portable.zip, or noir-v0.1.1-Linux-portable.zip — and double-click the bundled launcher (Start NOIR.command, Start NOIR.bat, or Start-NOIR.sh). Building from source instead takes ./gradlew :cli:installDist, and noir doctor verifies the platform, Java, adb, connected devices, and jadx before a scan.

How it compares

No paid products or directly comparable tools are named in the facts supplied for this entry; jadx appears only as an optional dependency that NOIR invokes for deep analysis. On the evidence available, it stands alone in this registry.

When to use it — and when not to

Choose NOIR when you have physical access to the device, can enable USB debugging, and want a repeatable static report with reversible actions; you will still need adb on the machine, jadx for the deep command, and JDK 17 or later if you build from source rather than using a portable package. It is not a fit if you need runtime instrumentation or continuous monitoring, since the workflow described is adb-driven static inspection, and it deliberately does not root the device or modify system partitions. The current release is v0.1.1, so expect early-stage tooling rather than a settled, long-maintained platform.

project readme (upstream, from github) — read inline
  ███╗   ██╗ ██████╗ ██╗██████╗
  ████╗  ██║██╔═══██╗██║██╔══██╗
  ██╔██╗ ██║██║   ██║██║██████╔╝
  ██║╚██╗██║██║   ██║██║██╔══██╗
  ██║ ╚████║╚██████╔╝██║██║  ██║
  ╚═╝  ╚═══╝ ╚═════╝ ╚═╝╚═╝  ╚═╝

NOIR

build release license platforms

把「这台手机到底能泄露什么」变成一份可复现的报告。

NOIR 是一个跑在电脑上的审计工具,通过 adb 读取已连接 Android 设备的应用清单、权限和 APK 里的网络端点,给出分类、风险评分和可执行的处置建议。它也可以在需要时调用 jadx 对单个应用做反编译和关键字检索。

定位:审计与自我防护。面向自己的设备、自己的应用、已授权的安全研究。

官网 / Website: https://verlintas.dev/noir/ · 中文


它做什么

  1. 盘点:列出所有「有网络权限 + 敏感权限」的应用,以及它们各自拿到了什么。
  2. 抽取端点:在设备端用 unzip + strings 从每个 APK 的 dex 里提取 URL,只回传几 KB,不把整包拉回电脑。
  3. 分类与打分:按包名和域名识别厂商(Xiaomi / Google / 腾讯 / 高德 …)与类别(遥测、广告、定位、输入法 …),结合权限和上报端点计算风险分。
  4. 数据关联:把权限翻译成"能拿到什么数据"(位置/通讯录/短信/通话/麦克风/相机/屏幕/应用列表/设备标识/文件/日历/账号),再和上报域名配对,得出"哪类数据可能流向哪里"。
  5. 共享 UID:识别 android.uid.system 这类共享用户,列出哪些包实际上共享同一套权限并集。
  6. 清单层:解析 AndroidManifest.xml 二进制 AXML,找出没有权限保护的导出组件、明文流量、备份、debuggable、targetSdk。
  7. 给建议:区分「可安全自动执行」「需人工确认」「不建议动」,并为每条动作生成回滚命令。
  8. 必要时深挖:deep 会把单个 APK 拉到本地,用 jadx 反编译后检索 Runtime.exec、setApplicationEnabledSetting、DexClassLoader、MediaProjection 等高风险调用。

它不做什么

  • 不联网、不上传任何数据、不需要账号。
  • 不修改系统分区,不需要 root。
  • 不会自动卸载任何东西,除非你显式加 --aggressive。

第一次运行

noir

不带参数会进入向导:

  1. 检查 adb,没有就问你要不要自动下载(~/.noir/tools)
  2. 检查设备,没有就打印开发者模式 / USB 调试的开通步骤,然后等你插线(最多 180 秒)
  3. 问一句「开始扫描?」,扫完直接出仪表盘
  4. 问一句「执行这 19 条安全处置?」,y 就执行,并写好回滚文件

全程只会问两三个 y/n,其余都是自动的。

环境自检

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          # 缺什么下什么
noir setup --yes    # 不询问,适合脚本

出现问题时

所有错误都会带「怎么办」,而不是抛异常栈:

╭─ ERROR ──────────────────────────────────────────────────────────╮
│ 指定的 adb 不存在:/nonexistent/adb                              │
├──────────────────────────────────────────────────────────────────┤
│ 检查路径,或运行 noir setup 自动安装。                           │
╰──────────────────────────────────────────────────────────────────╯

没有设备时给出的是可执行步骤:

╭─ 没有检测到设备 ──────────────────────────────────────────────╮
│  1. 打开开发者模式                                           │
│     小米 / HyperOS:设置 → 我的设备 → 全部参数 → 连点「MIUI 版本」7 次
│  2. 开启 USB 调试:设置 → 系统 → 开发者选项 → USB 调试        │
│  3. 插线后手机弹「允许 USB 调试吗?」→ 勾选「一律允许」        │
│  4. 还不行就换一根数据线(很多线只能充电)                    │
╰──────────────────────────────────────────────────────────────╯

已连接但没授权时,会单独提示「撤销 USB 调试授权后重插」。

支持平台

系统 状态
macOS (Intel / Apple Silicon) ✅
Windows 10 / 11 ✅
Debian / Ubuntu ✅

依赖:

  • JDK 17+
  • Android platform-tools(adb)
  • jadx(仅 deep 命令需要)

程序会自动在常见安装位置查找 adb 和 jadx;找不到时可以用 --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

安装

方式一:下载即用(推荐)

到 Releases 下载对应平台的 portable 包:

noir-v0.1.1-macOS-portable.zip
noir-v0.1.1-Windows-portable.zip
noir-v0.1.1-Linux-portable.zip
SHA256SUMS.txt

解压后双击启动器即可,包内自带运行时,不需要安装 Java:

系统 双击这个 如果被拦
macOS Start NOIR.command 右键 → 打开;或 xattr -dr com.apple.quarantine "Start NOIR.command" NOIR.app
Windows Start NOIR.bat SmartScreen → 更多信息 → 仍要运行(批处理会切到 UTF-8 并调用包内 JRE)
Linux Start-NOIR.sh 先 chmod +x Start-NOIR.sh,或在终端执行

启动器会打开一个终端窗口跑完向导,并在结束时停住(不会一闪而过)。

adb 和 jadx 不在包里——首次运行会询问是否自动下载到 ~/.noir/tools。

方式二:从源码构建

git clone https://github.com/Verlintas/NOIR
cd NOIR
./gradlew :cli:installDist
./cli/build/install/noir/bin/noir --about

构建

git clone <repo> && cd NOIR
./gradlew :cli:installDist

产物:

cli/build/install/noir/bin/noir        # macOS / Linux
cli/build/install/noir/bin/noir.bat    # Windows

也可以直接:

./gradlew :cli:run --args="devices"

界面

NOIR dashboard on a Xiaomi 17 Pro Max

真机输出(macOS Terminal):渐变 logo、CJK 对齐的表格、按风险着色的分数、 每处理完一个 APK 就刷新一次的进度条。

noir ui 会把结果渲染成一块等宽仪表盘;颜色和边框都会按终端能力自动降级:

  • --ascii:纯 ASCII 边框,给旧版 Windows 控制台
  • --no-color / --color:关闭或强制 ANSI 颜色(默认按是否为 TTY 自动判断)
  • --quiet:只留仪表盘,不打印扫描过程
  • --no-clear:不清屏(方便把输出重定向到文件)

用法

noir --about              # 它是什么、会写什么、许可
noir --version
noir devices
noir scan                 # 全量扫描,输出 JSON / Markdown / 域名清单
noir ui                   # 扫描并渲染仪表盘
noir auto                 # 扫描 + 分类 + 生成处置计划(dry-run)
noir auto --apply         # 执行安全的 appops 动作(可回滚)
noir auto --apply --aggressive   # 额外卸载被标记的用户应用
noir deep com.example.app # 拉包 + jadx + 关键字检索
noir block com.example.app        # 打印处置命令
noir block com.example.app --apply

常用参数:

参数 说明
--serial 指定设备
--out 输出目录(默认 noir-out)
--min 只保留分数 ≥ N 的应用
--limit 最多输出 N 条
--only 只扫描匹配的包名,例如 --only 'com\.miui\.'
--adb / --jadx 手动指定工具路径
--yes 自动化场景下跳过确认

DeepScan:一条命令反编译 + 处置

noir deepscan                  # 反编译风险最高的 15 个应用
noir deepscan --top 30         # 更多
noir deepscan --all            # 全部被标记应用(慢,占磁盘)
noir deepscan --jobs 4         # 并行 jadx 数量

流程是:扫描 → 按风险排序 → 逐个 adb pull + jadx → 统计代码级信号 (Runtime.exec、DexClassLoader、setApplicationEnabledSetting、 enabled_accessibility_services、MediaProjection、SystemProperties.set、 短信/设备标识、WebView 桥、无障碍/通知监听/设备管理员 …)→ 解析清单 (导出组件、明文流量、备份、debuggable)→ 识别 SDK(Umeng/Firebase/AppsFlyer…) → 输出 deepscan.md / deepscan.tsv → 询问是否清理。

noir deepscan --apply          # 分析后执行安全 appops
noir deepscan --apply --purge  # 再逐个确认卸载高风险用户应用

反编译结果按 包名 + APK 路径 缓存,第二次跑同一个应用会直接复用。

输出

noir-out/
├── report.json               # 结构化结果(应用、权限、端点、建议)
├── report.md                 # 人类可读报告
├── domains-trackers.txt      # 统计/广告/崩溃上报,可整份导入
├── domains-other.txt         # 用途不明,导入前逐条判断
├── domains-functional.txt    # 推送/登录/更新/支付/商店/云同步,禁止拦截
├── domains.txt               # 等于 trackers(兼容旧脚本)
├── plan.txt                  # 本次可执行的 appops
└── rollback.txt              # 回滚命令

隐私

  • 工具本身不联网:没有遥测、没有版本检查、没有崩溃上报
  • 扫描结果只写在你指定的 --out 目录
  • 唯一的外部请求发生在 noir setup(下载 adb/jadx)和 noir deep(jadx 是本地进程)
  • 报告里可能包含你设备上的包名和端点,分享前自行检查

缓存

扫描结果按 包名 + APK 路径 缓存在 ~/.noir/endpoints.tsv。应用更新后路径变化会自动重新分析,重复扫描通常只需几秒。


架构

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 走另一条支线:adb pull → jadx → 源码 grep。

设计取舍

  • 端点抽取在设备端完成:adb shell 内跑 unzip | strings | grep,避免把几百个 APK 拉回电脑。设备缺少 unzip/strings 时自动退化为本地解析。
  • 共享 UID 特殊处理:Android 上 android.uid.system 下的应用(常见 50+ 个)权限记录在 dumpsys package 尾部的 Shared users 段。解析器会把这些权限合并回每个包,否则最该被看见的应用反而会消失。
  • 建议分级:只有 appops 级别的动作标记为可自动执行;卸载必须显式开启。
  • 无遥测:程序不包含任何上报逻辑。

常见问题

需要 root 吗? 不需要。全部通过 adb 的 shell 权限完成;卸载只是 --user 0 级别,APK 仍在系统分区。

会改坏手机吗? 默认完全只读。--apply 只改 app-ops,每条都能用 default 还原,rollback.txt 会写出来。 noir block 的卸载也会先打印 pm install-existing 的恢复命令。

为什么有些应用只给"人工复核"? 系统应用不能真正卸载(--user 0 卸载也会被 OTA 或恢复出厂装回来),所以只建议 app-ops 或 DNS 层拦截。

DNS 拦截为什么只导出不执行? 跨平台改 DNS 很容易把设备网断掉(我们在开发中踩过),所以只导出清单:

  • domains-trackers.txt —— 统计/广告/崩溃上报,可以整份导入
  • domains-other.txt —— 用途不明,导入前逐条判断
  • domains-functional.txt —— 推送、登录、更新、支付、应用商店、云同步,拦了会掉功能
  • domains.txt —— 现在只包含 trackers,兼容旧脚本

IP、localhost 和带 test/staging 的域名会被自动剔除。

支持 iOS 吗? 不支持。core 是按 Kotlin Multiplatform 组织的,但审计逻辑依赖 Android 的 dumpsys 和 APK 格式。

参与

  • CONTRIBUTING.md — 构建、测试、规则放在哪
  • SECURITY.md — 漏洞报告方式(请不要开公开 issue)
  • Issues — bug 请附上 noir doctor 输出

路线图

  • 等宽仪表盘(noir ui)
  • DeepScan(批量反编译 + 代码级信号)
  • 自带运行时的双击即用包(jpackage)
  • 图形界面(Compose Multiplatform)
  • 规则文件可配置(YAML),支持社区规则包
  • 与 apktool / jadx 的批量流水线
  • 设备端 DNS/VPN 拦截方案导出
  • 扫描结果签名与版本对比

免责声明

NOIR 只应用于你自己的设备,或你获得明确授权的设备。它给出的是静态证据 ("这个应用具备这个能力,并且代码里有这个端点"),不能证明某次具体传输发生过。 请结合网络层证据自行判断。

许可

MIT © 2026 Verlintas

Frequently asked questions

Is NOIR free to use?

NOIR is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does NOIR do?

手机隐私审计:用 adb 扫出 Android 应用的权限、上报端点与数据流向,并给出可回滚的处置。Desktop Android leak audit: permissions, endpoints, data flows, reversible fixes.

What is NOIR written in?

NOIR is primarily written in Kotlin. Its source is publicly available at https://github.com/Verlintas/NOIR, and it has 1,445 GitHub stars.