
简介面向 Android 开发、测试与安全调试场景的 adb 1.0.39 Windows 版工具包适合需要在本机完成设备连接、应用部署与日志排查的初中级开发者使用。压缩包共收录 1716 个文件整体约 9.53MB除 adb、fastboot 等可执行文件与 dll 依赖库外还包含大量 html 文档、py 辅助脚本、md 说明、js 与 css 前端资源以及 json 配置和 license 声明并带有 atrace、systrace 等性能采集相关文件目录层次接近官方 platform-tools 的原始组织方式。已有 416 人学习下载。读者可获得设备管理、文件双向传输、shell 命令执行、logcat 日志抓取、应用安装卸载与备份恢复等常用能力的完整命令行环境也能借助包内脚本与说明理解 atrace 性能数据的采集流程为自动化测试、脚本编写和问题定位提供可直接复用的工具链。1. adb 1.0.39 windows版三个文件撑起的设备侧入口上周帮一个做移动端合规检测的朋友搭环境机器是一台没 root 的样机电脑是台干净的 Windows 笔记本不许装 IDE也不许装整套 SDK只允许放一个绿色目录。要干的活很具体——把设备上装了哪些第三方包、每个包要了哪些高危权限、最近有没有异常日志刷屏全部拉出来做成清单。这种场景下绕不开 adb 1.0.39 windows版这类裸二进制包解压出来就是adb.exe加两个 DLL丢进固定目录配好 PATHadb devices认到设备后面做 android 安全 方向的包枚举、权限比对、日志切片、文件取证就都有了落脚点。它适合谁适合手上只有数据线和 Windows、想把调试链路压到最薄的人不适合指望它替代 Android Studio 的人。这一版最需要先记住的边界是它没有adb pairAndroid 11 之后那套无线调试配对用不了只能走老的adb tcpip路子。下面按“怎么装、怎么摸设备、怎么动数据、哪里翻车”四段拆。2. 落地部署把 adb.exe 从压缩包塞进 PATH 的三步与两个依赖先把“能不能跑起来”这件事做干净。很多人拿到 adb 压缩包第一反应是双击adb.exe然后看窗口一闪而过以为文件坏了——它本来就是个命令行工具双击必然闪退这不是文件问题。2.1 压缩包里真正必需的是哪几个文件Windows 版的 adb 不是单文件程序它至少依赖两个同目录的 DLL。常见做法是把整个目录一起解压只把adb.exe单独拷出来是最典型的翻车起点。文件作用少了会怎样adb.exe客户端 服务端主程序命令不存在AdbWinApi.dllWindows USB 通道封装报“找不到 AdbWinApi.dll”进程直接退出AdbWinUsbApi.dllUSB 设备枚举与读写能启动但adb devices永远空列表fastboot.exe刷机模式工具调试场景可选不影响日常 adb 使用我一般把整个目录解压到D:\tools\platform-tools不放在桌面、不放在“下载”里也不放在含中文或空格的路径下。原因在后面的避坑章节会展开简单说含空格的路径在某些批处理拼接里会被当成两个参数报出来的错还特别误导。提示解压后的目录里如果还有source.properties那是版本描述文件别删出问题时靠它确认你手上到底是哪一版。2.2 PATH 怎么加才不留后患加环境变量的目的是省掉每次cd。图形界面走“系统属性 → 环境变量 → 用户变量 Path → 新建一行”这是最稳的。命令行也能做但有一个必须知道的风险。echo off REM 只改当前用户的 PATH不要加 /M改系统级需要管理员且会覆盖式写入 set ADB_DIRD:\tools\platform-tools REM 先看看当前 PATH 有多长超过 1000 字符就别用 setx echo %PATH% REM setx 有 1024 字符截断的老毛病稳妥做法是手工在图形界面追加 REM setx PATH %PATH%;%ADB_DIR%这段脚本的关键在注释里那两条setx写入的是“用户变量”时生效范围有限而它对超过 1024 字符的 PATH 会做截断——一旦截断你机器上其他工具的路径一起失效症状是“装了个 adb结果 Python、Node 全找不到了”排查起来非常费时间。所以我一般不用setx改 PATH只在临时窗口里用set PATH%PATH%;D:\tools\platform-tools做一次性验证确认没问题再进图形界面固化。验证只需要两条命令注意第二条的-l参数它会多打印设备型号、传输协议和连接方式比裸adb devices信息量大得多。# 确认客户端版本输出里会有 Android Debug Bridge version 1.0.39 adb version # 确认设备是否被识别-l 输出型号与 transport_id adb devices -ladb version的输出一般有三行版本号、Revision、Install path。如果 Revision 那行显示的不是你刚解压的目录说明机器上还有另一份 adb 在抢戏——这是后面“版本不匹配”类故障的根。2.3 第一次握手5037 端口与 adb serveradb devices的执行过程其实是三步客户端检查本机有没有 adb server 在跑没有就拉起一个然后 server 通过 5037 端口接收客户端指令并枚举 USB 设备。理解这条链路后面一大半的连接问题都能自己定位。# 看 5037 被谁占了Windows 下 netstat -ano | findstr :5037 # 拿到 PID 后查进程名 tasklist | findstr 上面的PID # 确认是自己这边状态脏了重启 server 最省事 adb kill-server adb start-servernetstat -ano里的-a列全部连接、-n用数字端口不解析服务名、-o带上 PID三个参数缺一不可少了-o你只看到一个端口被占却不知道找谁。找到 PID 后tasklist查名字如果发现是另一个版本的adb.exe比如某 IDE 自带的先把它退掉否则你 kill 一次它自动拉回来一次看起来就像“命令没用”。设备端那一半也要配合开发者选项打开、USB 调试打开、插线后设备弹出“允许 USB 调试吗”的授权框并勾选“一律允许”。这一步没做的话adb devices会显示unauthorized不是没连上是连上了但没被信任。3. 安全视角的设备画像用 pm 和 dumpsys 把一台机器摸清环境通了之后第一件有价值的事不是装 APK而是把设备“画像”出来。做 android 安全 评估时最先要回答的三个问题是这台机器上有哪些应用、这些应用各自要了什么权限、系统层面有没有异常配置。这三问用 adb 原生命令就能答完不需要装任何东西到设备上。3.1 包枚举-3、-s、-d 三个开关的区别pm list packages是最常被低估的一条命令。默认全量输出几百行直接看没有意义关键在过滤参数。# 只列第三方包用户自己装的做资产盘点时最常用 adb shell pm list packages -3 # 只列系统包排查预装软件、比对基线用 adb shell pm list packages -s # 只列已禁用的包找被“藏起来”的应用 adb shell pm list packages -d # 加上 -f 会同时输出 APK 的绝对路径做样本提取时必带 adb shell pm list packages -3 -f-3和-s的划分依据是包的安装位置与签名身份不是“能不能卸载”所以有些厂商预装但可卸载的应用仍然算系统包这一点在做资产清单时容易算错。-f输出的路径形如package:/data/app/~~xxx/com.example.demo-yyy/base.apk那串带~~的随机目录是 Android 11 之后引入的别试图去猜规律直接拿路径用。拿到包名之后取 APK 本体就一步# 查这个包由几个 APK 组成分包应用会返回多行 adb shell pm path com.example.demo # 按返回的路径逐个 pull不要只拉 base.apk adb pull /data/app/~~xxx/com.example.demo-yyy/base.apk .\samples\pm path返回多行是常态split APK 的包里base.apk只含主逻辑配置和资源在split_config.*.apk里。只拉 base 会导致后续静态分析时资源缺失、so 库找不到这个坑我在第一次做样本归档时踩得很实在。3.2 权限面dumpsys package 该看哪几行dumpsys package的输出非常长直接甩到终端里翻页找等于没看。有效的做法是在设备侧先过滤只把关键段落带回来。# 在设备侧过滤避免几百 KB 文本走一遍 USB adb shell dumpsys package com.example.demo | grep -E requested permissions|install permissions|runtime permissions # 只看已经实际授予的运行时权限 adb shell dumpsys package com.example.demo | grep -A 40 runtime permissionsrequested permissions是清单里声明的runtime permissions是用户实际点过同意的两者经常对不上——一个应用声明了通讯录权限但用户拒绝了它在runtime permissions段里会显示grantedfalse。做合规比对时看的是后者看前者只能说明“它想要什么”不能说明“它拿到了什么”。-A 40这个参数的意思是匹配行之后再多带 40 行因为权限段是缩进列表光匹配标题行拿不到内容。40 不是定值包权限多的时候可以加到 80加多了无非是输出长一点不影响正确性。3.3 属性、配置与日志三处最容易出线索的地方系统属性里藏着设备身份和调试开关状态getprop一次性全打印太多按键名过滤更实用。# 设备型号、系统版本、编译指纹 adb shell getprop | grep -E ro.product.model|ro.build.version.release|ro.build.fingerprint # 调试相关开关确认 USB 调试与 ADB 授权状态 adb shell settings get global adb_enabled adb shell settings get secure adb_keyssettings get global adb_enabled返回1表示调试开关是开的。这条在排查“为什么别人的机器能连我的不能连”时特别有用——很多时候不是驱动问题是那台机器的调试开关被策略关掉了。日志切片是另一条主线。全量logcat是灾难正确姿势是先清空缓冲、复现动作、再按 tag 抓。# 清空历史缓冲避免旧日志干扰 adb logcat -c # 抓最近 200 行并落盘-d 表示抓完就退出不阻塞 adb logcat -d -t 200 logcat_snapshot.txt # 按关键字过滤多个关键字用 | 分隔设备侧 grep adb shell logcat -d -t 500 | grep -iE crash|exception|denied-d是“dump 完立刻返回”不加它终端会被日志流占住很多人第一次用 logcat 以为命令卡死了其实是它在持续输出。-t 200限制行数配合-d使用才不会把几万行历史日志一次性灌进文件。4. 数据面操作pull、backup、run-as 三条路的边界在哪画像做完下一步通常是动数据把设备上的文件取下来、把测试文件推上去、看看应用私有目录里有什么。这三件事分别对应pull/push、adb backup、run-as它们的权限门槛完全不同混着用就会撞墙。4.1 pull 与 push/data/local/tmp 是最靠谱的中转站adb pull能取什么取决于 adb shell 这个身份能读什么。它默认是shell用户UID 2000不属于任何应用也不在 root 组。# 取外部存储的公开目录这是 shell 用户能读的范围 adb pull /sdcard/DCIM/Camera/ .\evidence\camera\ # 取应用的外部私有目录Android 10 之后 shell 通常读不到 adb pull /sdcard/Android/data/com.example.demo/ .\evidence\demo\ # 推文件到临时目录这是 shell 用户可写且不受 SELinux 限制的位置 adb push .\probe.txt /data/local/tmp/probe.txt # 推完改权限并确认落地 adb shell chmod 644 /data/local/tmp/probe.txt ls -lZ /data/local/tmp/probe.txt/data/local/tmp这个路径值得单独记它是 shell 用户可读可写、SELinux 上下文为shell_data_file的少数位置之一几乎所有“我需要把一个二进制推上去跑一下”的场景都从这里起步。推到/sdcard会带上media_rw_data_file上下文某些场景下反而不方便执行。ls -lZ里的-Z是显示 SELinux 上下文这个参数在排查“文件明明在、就是读不了”时几乎是唯一有效的手段。看不到上下文你只能猜看得到你一眼就知道是权限位问题还是标签问题。4.2 adb backup能跑但别把它当成取数主路adb backup曾经是拿应用私有数据的标准手段现在它的适用面窄了很多理解它为什么窄比记住命令本身重要。# 备份指定应用-apk 带上安装包本体-shared 带上外部存储 adb backup -f demo.ab -apk -shared com.example.demo # 全量备份注意这会提示用户在设备上点“备份我的数据” adb backup -f full.ab -apk -shared -all命令本身没变变化在设备侧应用需要在清单里显式开启android:allowBackuptrue且从 Android 12 起系统对备份范围做了更严的限制很多应用即使开了开关备份出来的.ab文件里也只有壳没有数据。判断方法很直接——看文件大小几十 KB 的.ab基本是空的正常带数据的至少几百 KB 到几 MB。.ab文件不是标准 tar头部的魔法字符串之后是压缩过的数据块。要拆它需要额外的解包工具常见的做法是用支持 ab 格式的解包脚本先转成 tar 再展开。这一步属于“能拆但成本不低”所以我的实际选择是能做run-as的场景绝不用 backupbackup 只作为退路。4.3 run-as 与 SELinux为什么你的 cat 明明路径对却被拒run-as的设计初衷是给可调试应用提供一个切身份的入口它只对android:debuggabletrue的包有效。这一条把绝大多数线上应用直接排除了。# 先确认这个包是否可调试输出里有 DEBUGGABLE 才行 adb shell dumpsys package com.example.debug | grep -i pkgFlags # 切到应用身份后读私有目录 adb shell run-as com.example.debug ls -l /data/data/com.example.debug/ # 直接读 shared_prefs注意这一步不需要 root adb shell run-as com.example.debug cat /data/data/com.example.debug/shared_prefs/config.xml如果pkgFlags里没有DEBUGGABLErun-as会直接返回 “Package ... is not debuggable”这不是权限不足是设计如此。很多人在这里反复chmod 777纯属白费功夫——文件权限是第二道门第一道门是 SELinux 标签和进程域shell进程无论怎么改文件权限位都进不了untrusted_app域可访问的目录。注意run-as成功后拿到的身份是应用 UID此时对/data/data/包名的读写等价于应用自身但对其他应用的目录依然无权限。不要指望用它横穿。想在非调试包上取私有数据只剩两条路设备已 root或者应用自己把数据导出到外部存储。前者取决于设备后者取决于应用都不是 adb 能单方面解决的。认清这条边界能省掉大量无效尝试。5. 避坑清单5037 被占、unauthorized 和 backup 空包怎么破下面这几条是在实际交付里反复出现的按现象、原因、解决三段记遇到时能少走几圈。5.1 连接侧的四类故障现象一adb devices列表为空但设备管理器里能看到设备。原因通常是驱动问题。Windows 自带的是通用 USB 驱动adb 需要的是设备厂商提供的 ADB 接口驱动未安装时设备会以“未知设备”或“MTP 设备”出现adb server 枚举不到 ADB 接口。解决打开设备管理器找带黄色感叹号的条目手动更新驱动并指向解压目录部分机型需要用厂商提供的驱动安装包。装完后adb kill-server adb devices重试不要只拔插数据线。现象二设备显示unauthorized。原因是这台电脑的 adb 公钥没有被设备记住。首次连接时设备会弹授权框如果当时点了“拒绝”或没勾“一律允许”就会一直是这个状态。解决先adb kill-server然后进设备“开发者选项”找到“撤销 USB 调试授权”点一下重新插线等授权框弹出后勾选“一律允许”。如果授权框根本不弹检查是不是把~/.android/adbkey删了又没重启 server——密钥文件缺失时 server 不会主动重建adb kill-server会触发重新生成。现象三设备显示offline或反复在device/offline之间跳。原因是 adb server 版本与设备端 adbd 协议协商不一致最常见于机器上同时存在多个版本的 adb.exeIDE 自带一个、你自己放了一个两个 server 抢占 5037 端口。解决netstat -ano | findstr :5037找出占用进程退掉多余的那份只保留一个 adb 在 PATH 里。如果两版确实都要用给其中一个指定独立端口set ANDROID_ADB_SERVER_PORT5038让它走不同端口互不干扰。现象四报 “adb server version (xx) doesnt match this client (xx)”。原因和上一条同源但表现更明确客户端连上了一个旧版 server。旧 server 是别的工具先启动的一直驻留。解决adb kill-server后再执行任意 adb 命令会拉起与你客户端版本匹配的 server。如果 kill 之后马上又被别人拉起来说明有后台进程在监听得先找到并停掉它。5.2 版本与数据侧的三类故障现象五adb pair命令不存在。这是这一版 adb 的硬边界。adb pair和adb mdns是后续版本才引入的1.0.39 上执行会直接报未知命令。解决Android 11 之后的无线调试配对必须用新版 adb这一条没有绕法。如果受限于环境只能用这个版本就退回adb tcpip 5555的老路子先用 USB 连上执行adb tcpip 5555拔线后用adb connect 设备IP:5555连接。前提是设备和电脑在同一网段且设备端允许该端口访问。现象六adb backup跑完了.ab文件只有几十 KB。原因有两层应用没开allowBackup或者系统的备份范围限制把应用数据排除了。命令返回码仍然是 0所以看起来“成功”了。解决先dumpsys package 包名 | grep -i allowBackup确认开关状态确认开了还是空包就说明走不通换run-as仅调试包或放弃这条路。不要在这个命令上反复试参数参数不是变量。现象七adb shell screencap -p screen.png出来的图打不开。原因是adb shell会对输出做换行符转换把\n变成\r\n二进制数据被污染。这是 Windows 上最经典的坑之一。解决改用adb exec-out它不经过 shell 的换行转换# 正确姿势exec-out 直通二进制 adb exec-out screencap -p screen.png # 老设备不支持 exec-out 时的替代方案先落盘再 pull adb shell screencap -p /data/local/tmp/s.png adb pull /data/local/tmp/s.png .\screen.png adb shell rm /data/local/tmp/s.png顺带一个同源问题路径里有空格或中文时adb pull的源路径和目标路径都要加引号否则会被拆成多个参数报出来的错是“remote object doesnt exist”非常容易被误导成设备上文件不存在。6. 进阶玩法把体检命令串成一份可复现的 bat 报告单条命令敲多了必然漏项。我现在的习惯是把设备画像的固定几条串成一个批处理跑一次出一份带时间戳的文本报告归档和横向比对都省事。echo off setlocal enabledelayedexpansion REM 所有产物落在当前目录的 report 子目录避免污染工作区 set OUT.\report if not exist %OUT% mkdir %OUT% REM 先确认设备在线离线就直接退出别继续跑一堆空命令 adb devices | findstr /r /c:device$ nul if errorlevel 1 ( echo [FAIL] no device in device state exit /b 1 ) REM 设备基础信息 adb shell getprop %OUT%\props.txt adb shell getprop ro.build.fingerprint %OUT%\fingerprint.txt REM 第三方包清单与安装路径-f 带上 APK 路径 adb shell pm list packages -3 -f %OUT%\packages_third.txt adb shell pm list packages -s %OUT%\packages_system.txt adb shell pm list packages -d %OUT%\packages_disabled.txt REM 全局配置快照调试开关与安装来源策略都在这 adb shell settings list global %OUT%\settings_global.txt adb shell settings list secure %OUT%\settings_secure.txt REM 日志切片-d 抓完即退-t 限制行数 adb logcat -d -t 1000 %OUT%\logcat_tail.txt echo [OK] report written to %OUT% endlocal脚本里几个值得注意的点findstr /r /c:device$用行尾锚定是为了避免把unauthorized、offline里的device子串误判成在线/c:保证整串匹配/r启用正则。settings list global比逐条settings get高效得多一次拿全后续在本地用文本工具筛。logcat -d -t 1000限制在 1000 行是有意的——行数拉太大USB 传输时间会明显变长而且日志滚得快越早的越没价值。跑完之后我会先看packages_third.txt的行数。同一台设备两次体检第三方包数量突然多出十几个基本可以确定中间装过东西settings_secure.txt里的install_non_market_apps和adb_enabled两项是判断设备是否被人动过调试配置的第一手依据。这些判断不需要任何额外工具文本比对就够了。再补一个实用技巧把两次报告放同一目录用fc做差异比对只关注变化行。REM /n 显示行号便于回查原文定位 fc /n .\report_old\packages_third.txt .\report\packages_third.txt这条命令的输出比任何图形化对比工具都直接尤其在只有一台 Windows 干净机器可用的时候。我一般把它写进固定流程每次体检前后各跑一次变化项单独记录。最后说一条教训。早些年我做设备侧排查习惯现场敲命令敲完就过报告靠回忆补——结果有一次两台设备的包清单记混了结论整个反过来返工了大半天。从那以后我每次连上设备第一条命令永远是那个 bat不管多急都强制走一遍产物落盘再动手分析。这个习惯看着笨但它把“我以为是”变成了“文件里写着”。希望帮到你。本文还有配套的精品资源点击获取