news 2026/10/24 3:57:12

谁在偷偷连你的手机?拆解安卓 USB 调试入侵“自动拍照取证“的完整实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
谁在偷偷连你的手机?拆解安卓 USB 调试入侵“自动拍照取证“的完整实现

谁在偷偷连你的手机?拆解安卓 USB 调试入侵"自动拍照取证"的完整实现

上一篇文章发了我的开源手机安全六件套(GitHub 传送门),评论区有朋友对「ADB 入侵自动拍照」最感兴趣,这篇就把它的实现掰开揉碎讲清楚。

先说风险:USB 调试就是一个常开的门

很多开发者(包括曾经的我)手机的开发者选项常年开着、USB 调试永远不关。这意味着:

任何一台装了 adb 的电脑,只要拿到数据线接触你手机的机会,就能静默安装应用、拉取文件、截取屏幕,甚至执行 shell 命令

部分恶意公共充电桩也走 USB 通道做数据嗅探

更麻烦的是:这个过程在手机上几乎无感知,被连了你都不知道

传统安全软件只做「提醒」,但提醒的问题在于——事发时你可能根本不在手机旁。所以 AdbGuard 的思路是:不仅告警,还要取证。谁连的、什么时候连的、人在哪,全部留下证据。

整体设计:双通道监听 + 防抖

要抓住"USB 设备接入"这个瞬间,安卓给了两条路:

Manifest 静态注册 UsbDeviceAttachedReceiver:App 被杀也能收到系统广播,做兜底

前台服务内运行时注册:服务存活时实时响应,做主通道

同一个 U 盘插入,两个通道可能同时收到广播。所以需要一个统一的处理入口 + 防抖去重:

kotlin

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// UsbAlertHelper.kt(节选)

object UsbAlertHelper {

private var lastAction = ""

private var lastEventAt = 0L

fun handleUsbEvent(context: Context, action: String?, deviceName: String): Boolean {

if (action != UsbManager.ACTION_USB_DEVICE_ATTACHED &&

action != UsbManager.ACTION_USB_DEVICE_DETACHED

) return false

// 防抖:双通道可能同时收到同一广播

val now = System.currentTimeMillis()

if (action == lastAction && now - lastEventAt < 2000) return false

lastAction = action

lastEventAt = now

// ... 告警 + 取证

}

}

静态注册的接收器只负责转发:

kotlin

1

2

3

4

5

6

7

8

9

10

11

12

13

// UsbPlugReceiver.kt —— Manifest 静态注册兜底通道

class UsbPlugReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {

try {

UsbAlertHelper.handleUsbEvent(

context.applicationContext,

intent.action,

UsbAlertHelper.deviceNameOf(intent)

)

} catch (_: Exception) { }

}

}

一个容易被忽略的细节:ACTION_USB_DEVICE_ATTACHED 是系统受保护广播,只有系统才能发送,所以 exported=true 也不用担心伪造——第三方 App 伪造不了这个 action。

设备名提取:一个小坑

告警里要告诉用户"什么东西插进来了",从 Intent 里取 UsbDevice。安卓 13 前后取法不同,要兼容:

kotlin

1

2

3

4

5

6

7

8

9

10

11

@Suppress("DEPRECATION")

fun deviceNameOf(intent: Intent): String {

val device: UsbDevice? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {

intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, UsbDevice::class.java)

} else {

@Suppress("DEPRECATION")

intent.getParcelableExtra(UsbManager.EXTRA_DEVICE)

}

return device?.productName?.takeIf { it.isNotBlank() } ?: "未知设备"

}

这个函数能直接把"某人的电脑""充电宝""钓鱼线"区分出来——至少在告警里你能看到设备的 productName。

关键一步:拉起前置拍照取证

确认是"接入"事件后,通过自定义 action 拉起前台服务执行拍照:

kotlin

1

2

3

4

5

6

7

8

9

10

const val ACTION_USB_PHOTO = "com.phonGuard.adbguard.action.USB_PHOTO"

// 事件处理中:立即告警(不等轮询)+ 写时间线 + 触发取证

if (config.usbPlugAlertEnabled) {

NotificationHelper.sendAlertNotification(

context, AdbGuardApp.CHANNEL_ADB_GUARD,

title, message, USB_ALERT_ID

)

}

拍照环节有几个实打实的坑,都踩过:

后台启动相机受限:Android 9+ 对后台进程打开相机有严格限制,必须走前台服务(startForegroundService)并在通知栏可见,这正是把监听逻辑放进常驻服务的原因

相机权限与隐私声明:取证拍照必须在隐私政策里明确声明"安全取证用途",上架应用商店时这是审核点

连拍而非单拍:单张照片可能拍糊/闭眼,连拍 3-5 张间隔抓拍,取证成功率直线上升

写入要快:拍照后立即落盘到应用私有目录(MODE_PRIVATE),再更新 UI 列表——取证数据第一时间固化,防止进程被杀丢证据

再补两道保险:TTS 语音 + 事件时间线

TTS 语音播报:连接事件确认后,直接语音喊出来——"检测到 USB 设备接入"。人在旁边时这是最即时的威慑;不在旁边,语音也会吓退操作者

事件时间线:每次事件(接入/断开/拍照)写入 SecurityLogger,带时间戳和严重等级,事后在 App 里可以完整回溯"那天下午到底发生了什么"

kotlin

1

2

3

4

5

6

7

8

9

10

// 事件入时间线(节选)

app.securityLogger.logEvent(

SecurityLogger.SecurityEvent(

type = "usb",

subType = if (attached) "attached" else "detached",

message = message,

severity = if (attached) 2 else 0

)

)

小结

整套方案的核心思路一句话:感知(双通道监听)→ 确认(防抖去重)→ 告警(通知+TTS)→ 取证(连拍落盘)→ 留痕(事件时间线) 。

安全工具最难的不是某个 API 怎么调,而是把"事发瞬间"的完整链条都接住——任何一个环节断了,证据就没了。

开源仓库(觉得思路有用就点个 Star ⭐):

https://github.com/hnpdsyn/PhoneGuard1

Releases 里可以直接下载 6 个 APK,AdbGuard 对应 adbguard-release.apk。

下篇预告:应用锁「假崩溃 + 图标伪装」是怎么骗过窥屏者的——假弹窗的绘制时机、伪装图标的 activity-alias 配置,都会拆开讲。关注不迷路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/24 3:57:11

用 A2A 协议打通远程智能体:ADK 多智能体协作实战指南

用 A2A 协议打通远程智能体:ADK 多智能体协作实战指南 【免费下载链接】adk-docs An open-source, code-first toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control. 项目地址: https://gitcode.com/GitHub_Trending/ad/…

作者头像 李华
网站建设 2026/10/24 3:55:38

直流电与交流电及电能和电功率

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/24 3:54:09

ai-md - SKILL

name: ai-md description: “Convert human-written CLAUDE.md into AI-native structured-label format. Battle-tested across 4 models. Same rules, fewer tokens, higher compliance.” risk: safe source: community date_added: “2026-03-11” AI.MD v4 — 完整的原生 …

作者头像 李华
网站建设 2026/10/24 3:52:16

Path of Building PoE2 免费Build规划器指南:离线规划天赋树与装备

Path of Building PoE2 免费Build规划器指南&#xff1a;离线规划天赋树与装备 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 Path of Building PoE2 是一款免费的《流放之路2》离线Build规划器&#x…

作者头像 李华
网站建设 2026/10/24 3:44:58

从预览版到开源权重:M3.1 Flash 一个月内走完了两段路

从预览版到开源权重&#xff1a;M3.1 Flash 一个月内走完了两段路 【免费下载链接】MiniMax-M3.1-Flash MiniMax-M3.1-Flash 是一款原生多模态混合专家&#xff08;MoE&#xff09;模型&#xff0c;面向编程、智能体工作流、计算机使用和网络安全等场景。它支持文本、图像和视频…

作者头像 李华
网站建设 2026/10/24 3:42:13

YimMenu 完整配置教程:5分钟修复菜单不显示,切换中文界面

YimMenu 完整配置教程&#xff1a;5分钟修复菜单不显示&#xff0c;切换中文界面 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Tr…

作者头像 李华