ADB高频命令实战指南:从设备调试到应用逆向分析
第二天了。如果你的第一天是在安装 JDK、下载 Android Studio、解压各种逆向工具的折腾中度过的那从今天起我们终于进入真正“动手”的阶段。今天的主线任务非常明确把 ADB 高频命令练到滚瓜烂熟并且用一台真实的 Android 设备把整个交互链路跑通。ADB 这个名字你可能早就听过甚至可能已经会两三条命令比如 adb devices、adb install但大概率是“复制粘贴侠”式用法——能用却不懂背后的工作原理。这其实很危险因为后续你做包名定位、日志过滤、Activity 拉起、文件提取时只要环境或状态稍微出点问题看不懂报错就只会卡死。今天这篇我不打算给你列一张几十条命令的“字典”而是按逆向实际工作流的顺序把每条高频命令的用途、参数、坑位一次讲透。适合刚起步的逆向新人也适合那些想把自己的 ADB 操作从“半懂不懂”提升到“肌肉记忆”的进阶开发者。1. ADB 的本质先搞懂通话链路再看命令ADB 全称 Android Debug Bridge中文常译作“安卓调试桥”。这个“桥”字很有意思——它连接的对象是你的电脑宿主机和 Android 设备提供的是一条稳定、可复用的双向通信通道。别看现在手机厂商各搞各的定制系统但在调试底层这件事上大家无一例外都保留了 ADB 这个标准入口。理解了这一点你就能明白为什么逆向学习的第二天就必须碰它因为不管是静态分析前的 APK 提取还是动态分析时的进程操控ADB 都是最底层的那把钥匙。1.1 ADB 工作过程的三个角色很多人以为 adb 是一个“程序”其实严格来说它是一套客户端-服务端-守护进程的体系由三部分协作客户端client运行在你的电脑上。每当你敲一条 adb xxx 命令系统就会启动一个客户端进程把你的指令打包成协议消息。服务端server同样运行在你的电脑上但它常驻后台负责监听 5037 端口维护当前电脑连接的所有设备列表并把客户端的请求转发给正确的设备。adbd 和手机之间的连接管理、消息路由都由它承担。守护进程adbd运行在 Android 设备内部。它只有在设备开启“USB 调试”后才会启动负责真正执行命令比如安装应用、读取文件、执行 shell 指令。可以这样类比客户端是去柜台办事的“客户”服务端是公司前台adbd 则是后面工位上真正干活的员工。客户只负责提需求前台负责找到人员工负责落地执行。这个前台接单、分发的机制使得电脑可以同时连着多台设备也可以随时切换目标而不用每次重新建立物理连接。值得提前记住的是服务端与设备之间并非只能走 USB。ADB 协议本身支持 TCP/IP 传输所以只要手机和电脑在同一网络内执行 adb connect IP:端口 就能进入“无线调试”模式。后面实操部分我会专门演示这一招。1.2 为什么逆向学习必须把 ADB 练熟在逆向这个领域ADB 几乎贯穿所有阶段的全部关键动作。你可以把它理解成一个“多面手”当你需要快速识别目标 App 的包名、版本、安装路径ADB 是效率最高的方式当你需要把设备里的 APK 原封不动搬回电脑进行分析ADB 的 pm path pull 组合一分钟内完成当你需要观察 App 启动时的日志、崩溃现场、组件调用顺序ADB 的 logcat 就是设备黑匣子当你需要模拟用户点击、滑动、输入、旋转屏幕ADB 的 input、wm 命令可以精准操控当你后面引入 Frida、Xposed 这些动态插桩工具时启动目标应用、检查进程状态依然离不开 ADB 兜底。所以今天的每一分钟都不是白费的。把 ADB 练好等于一口气学完了后面十几天课程里都会用到的公共同基础设施。2. 开工前的 15 分钟把 ADB 环境打磨顺滑工欲善其事必先利其器。这一节我会把环境准备拆成四个步骤下载工具、修复 PATH、开启设备调试、解决多版本冲突。每一步都踩过无数人的坑我按顺序走一遍。2.1 获取 ADB 的两种常见方式方式一下载完整版 Android Studio通过 SDK Manager 勾选“SDK Platform-Tools”。适合你未来要深度开发 App、用模拟器调试、打包签名需要图形化工程管理工具的情况。缺点是安装包大、首次初始化时间长而且 Studio 内置的 SDK 路径在不同版本上变化较多对只想玩逆向的朋友来说有点“杀鸡用牛刀”。方式二单独下载 platform-tools 压缩包。这是官方提供的命令行工具集体积小解压即用内部包含 adb.exe、fastboot.exe 等核心工具。这也是我更推荐逆向学习者采用的方式。下载完成解压到固定目录比如 Windows 下放到 D:\platform-tools后面所有操作都围绕这个目录展开。提示注意不要从第三方下载站拿压缩包那里面的 adb 可能被修改过也可能捆绑额外软件。认准官方渠道这是环境安全的第一道防线。2.2 解决“adb 不是内部或外部命令”这是几乎每个新手的第一次碰壁。原因不复杂你在命令行里敲 adb操作系统会在当前目录和 PATH 环境变量列出的目录中寻找 adb 可执行文件都找不到就会报这个错。解决办法有两种我建议直接做第二种。第一种每次运行时手动切换目录cd /d D:\platform-tools adb version第二种把 platform-tools 加入 PATH。在 Windows 里右键“此电脑”→“属性”→“高级系统设置”→“环境变量”在系统变量里找到 Path点击编辑新建一行填入 D:\platform-tools保存后重新打开命令行窗口。macOS 和 Linux 则在 ~/.bashrc 或 ~/.zshrc 里导出 PATH。配置完成后输入 adb version能显示类似 Android Debug Bridge version 1.0.41 的结果就算安装成功。这里补充一个排查细节如果你已经配了 PATH 却仍然报错用 where adbWindows或 which adbmacOS/Linux查看系统实际解析到的 adb 路径。许多人在电脑上装过多个 SDK旧版本的 adb 路径排在前面导致执行的根本不是你配置的那个。这种情况光追加 PATH 是没有用的需要把旧路径从环境变量里删掉。2.3 设备端开启开发者模式与 USB 调试命令环境准备好之后还要让手机愿意“接电话”打开“设置”→“关于手机”找到“版本号”那一项连续点击版本号 7 次系统会提示“已进入开发者模式”返回设置找到“开发者选项”打开“USB 调试”开关用数据线连电脑手机上弹出“是否允许 USB 调试”对话框勾选“始终允许”点允许。如果你找不到“开发者选项”大概率是刚才点击的位置不对。注意是“版本号”不是“操作系统版本”或“内核版本”。另外部分新机型默认隐藏开发者选项需要在设置搜索框里输入“开发者”直接跳转。提示连上电脑后手机端会要求选择 USB 连接模式。尽量选择“文件传输MTP”而不是“仅充电”。有些系统在“仅充电”模式下会限制调试通道导致 adb 怎么都连不上的奇怪问题。2.4 无线调试与多版本 ADB 冲突USB 调试不是唯一选择。当你在工位之间走动或者没有合适数据线时无线调试非常有用。先通过 USB 连一次执行adb tcpip 5555这条命令告诉设备在 5555 端口开放 ADB 调试服务。然后拔掉数据线执行adb connect 192.168.1.100:5555把 IP 换成你手机的局域网地址。看到 connected 字样后后续操作与 USB 模式完全一致。无线调试最大的坑是电脑上同时跑着多个版本的 ADB 服务。比如你安装过 Android Studio又用过第三方工具箱它们各自带了不同版本的 adb.exe。你在新终端敲 adb 命令时系统可能直接提示“检测到电脑上同时运行了多个版本的 adb 服务版本不一致”。这个警告的本质是不同版本的 server 使用了不同的通信协议把旧的/冲突的 adb 进程留着会导致新 server 与设备握手失败甚至出现设备列表错乱。解决办法一句话彻底清理旧的 ADB 服务重建干净的单一实例。adb kill-server然后在任务管理器中结束所有名字含 adb.exe 的进程再执行adb start-server adb devices这一步之后绝大多数“命令没反应”“设备连不上”“经常 offline”的诡异问题都会消失。3. 高频命令速查把常用姿势固化到肌肉里环境理顺之后我开始按逆向日常使用的频率把这组命令过一遍。先看设备状态再看应用管理然后是文件传输、shell 交互和日志采集。每一条我都会解释“为什么这样写”而不只是让你抄答案。3.1 设备状态管理三板斧先来最基础的三条。adb devices列出当前连接的所有设备。输出有两列序列号和状态。状态只有三种必须学会分辨device 表示正常offline 表示设备掉线unauthorized 表示设备未授权。adb kill-server adb start-server这两条是 ADB 的“重启大法”。当你看到命令卡在 waiting for device或者设备的在线状态反复横跳时先执行这两条再插拔一次数据线大部分问题都能自愈。adb reboot远程重启设备。做自动化测试前用它把设备恢复到干净状态比手动重启方便得多。除了这三条我每次拿到一台新设备还会顺手确认四个参数adb shell getprop ro.product.model adb shell getprop ro.build.version.release adb shell wm size adb shell wm density它们依次返回设备型号、Android 系统版本、屏幕分辨率和像素密度。做屏幕适配分析、确定目标 App 运行环境时这些参数就是你的“环境身份证”。3.2 应用管理安装、卸载、查包、捞包这一组命令是整个逆向流程中使用频率最高的部分没有之一。先说安装adb install C:\apps\demo.apk如果需要覆盖安装并保留应用数据加 -r 参数adb install -r C:\apps\demo.apk如果希望允许降级安装比如从版本 2.0 退回 1.9加 -dadb install -r -d C:\apps\demo.apk如果想要安装完成后直接授予所有运行时权限加 -gadb install -g C:\apps\demo.apk卸载应用要注意参数是包名不是应用名adb uninstall com.example.demo查看设备装了什么包adb shell pm list packages按关键词过滤Windows 命令行用 findstrmacOS/Linux 用 grepadb shell pm list packages | findstr demo找目标 App 的 APK 路径adb shell pm path com.example.demo输出通常是 package:/data/app/com.example.demo-xxxx/base.apk 这样的格式。拿到路径后用 pull 拉回本地adb pull /data/app/com.example.demo-xxxx/base.apk C:\apps\base.apk这一套连招下来你从只知道一个包名到本机多了一个完整的 APK 文件总耗时不会超过一分钟。这就是逆向工作流里最高频的入口动作建议多练几遍。3.3 文件传输只记住两条对称命令文件传输就两条命令方向相反adb push 本地路径 设备路径 adb pull 设备路径 本地路径实际例子adb push C:\test.txt /sdcard/test.txt adb pull /sdcard/log.txt C:\data\这里要提一个低级但常见的坑路径包含空格时必须用双引号把整个路径包起来。比如 C:\Program Files\demo.apk就要写成adb push C:\Program Files\demo.apk /sdcard/demo.apk另外设备路径推荐统一走 /sdcard/ 目录作为中转。直接向 /data/ 目录推送文件几乎都会因为权限不足而失败没必要和系统权限较劲。3.4 Shell 命令进入设备内部世界执行adb shell你会进入设备内部的 Linux shell 环境这时你可以像在 Linux 终端一样操作。如果只是想临时执行一条命令而不进入交互模式直接在 adb shell 后面跟命令adb shell ls /sdcard adb shell cat /proc/cpuinfo逆向分析时我常用这些 shell 命令ps -A查看所有进程列表top查看实时 CPU 占用netstat -tunap查看网络连接ls -al查看目录及详细文件信息su切换 root 用户前提是你的设备已经 rootshell 模式下还能模拟用户输入这在自动化埋点、自动遍历页面时极其好用adb shell input keyevent KEYCODE_HOME adb shell input keyevent KEYCODE_BACK adb shell input tap 540 1280 adb shell input swipe 540 1280 540 400 200tap 后面的两个数字是屏幕上的像素坐标swipe 的最后一位是滑动耗时单位毫秒。坐标可以通过开发者选项里的“指针位置”功能获取打开后点击屏幕屏幕顶部会实时显示触摸坐标非常方便。3.5 日志采集logcat 是设备黑匣子Android 运行时的系统日志、应用日志、崩溃堆栈全部通过 logcat 输出。最基础的用法adb logcat实时打印日志刷屏速度惊人所以更常用的其实是这几个带参数的姿势adb logcat -c adb logcat -d adb logcat -d -t 50 adb logcat -s TagName-c 清空历史日志-d 输出已有缓存日志后自动退出-t 50 表示只输出最近 50 行-s 后面跟标签名可以只看某个 Tag 的日志。抓崩溃日志的典型姿势adb logcat -d | findstr FATALmacOS/Linux 把 findstr 换成 grep。日志量太大的时候建议重定向到文件adb logcat -d app_log.txt然后慢慢在文本编辑器里搜索关键词。直接盯着滚动终端看日志眼睛迟早会花。4. 强制屏幕方向与 App 交互你早晚用得上的组合技平时手工转手机测横屏很容易但自动化或者远程操作时你就需要让设备瞬间改变屏幕方向。这一节把方向控制和 Activity 启动放在一起讲因为它们组合起来可以解决很多模拟器、深度页面、横竖屏适配的验证问题。4.1 用 wm 和 settings 两条路线控制方向先看当前屏幕基本参数adb shell wm size adb shell wm density方向控制的命令有两套建议都记住因为它们在不同系统版本和厂商 ROM 上的表现不一样。第一套走 settings 配置adb shell settings put system accelerometer_rotation 0 adb shell settings put system user_rotation 0第一行关闭自动旋转第二行把手动方向设为 0。第二行的参数 0 到 3分别代表 0 度、90 度、180 度、270 度旋转状态。第二套走 wm 命令adb shell wm user-rotation lock 1这条把屏幕锁定在 90 度方向。在部分原生 Android 系统上很有效但在一些厂商深度定制的 ROM 上可能不生效。如果你发现命令执行没有反应就改用第一套 settings 方式。恢复自动旋转adb shell settings put system accelerometer_rotation 1 adb shell wm user-rotation unlock一个实用小技巧改变方向后如果界面卡片没有立刻刷新可以执行一次adb shell input keyevent KEYCODE_POWER关屏再点亮大部分设备在亮屏后都会重新应用方向参数省得你去手动折腾屏幕开关。4.2 启动指定 Activity直达深链页面做逆向分析时你经常遇到“主界面能进某个深层页面怎么都点不进去”的困境。这时候有两种路径要么靠人肉点击找入口要么直接用 am 命令拉起目标页面。显然是后者更香。基本格式adb shell am start -n 包名/Activity全称实例adb shell am start -n com.example.demo/.MainActivity如果 Activity 全称是 com.example.demo.MainActivity而包名也是 com.example.demo可以简写为上面的形式。如果 Activity 位于子包名路径下则要写全adb shell am start -n com.example.demo/com.example.demo.ui.SplashActivity还可以在启动时附带参数adb shell am start -n com.example.demo/.MainActivity --es key value --el start_time 123456--es 传字符串--el 传长整数。这在测试带参数跳转的页面时非常关键。另一个实用变体是 -W 参数adb shell am start -W com.example.demo/.MainActivity-W 表示等待启动完成并输出启动耗时信息。后面你如果用 Frida 做启动阶段 Hook这个命令就能帮你准确判断启动时序。4.3 实时查看当前前台应用怀疑某个弹窗、悬浮球是哪个应用拉起来的用一条命令直接看当前焦点窗口adb shell dumpsys window | grep mCurrentFocus输出里通常包含类似 com.example.demo/com.example.demo.MainActivity 这样的信息一看就知道谁在前台。如果想看更详细的 Activity 调用栈adb shell dumpsys activity top这条命令会输出当前顶部的 Activity 及其关联信息。在逆向分析弹窗广告、强制跳转问题的时候它是定位“幕后黑手”的好帮手。5. 逆向实战中 ADB 的正确打开方式单独的命令你已经见过了但这还不够。真正的工作流是把命令串成一条流水线从目标定位到样本采集从崩溃复现到日志分析一气呵成。我挑三个最常见场景带你过一遍完整流程。5.1 场景一5 分钟内弄到目标 App 的安装包假设你看到一款 App 的新功能很值得研究但你手里没有渠道包最好的来源其实是已经安装该 App 的设备本身。操作步骤手机连电脑执行 adb devices 确认设备在线执行 adb shell pm list packages | findstr 关键词找到精确包名执行 adb shell pm path 包名拿到 base.apk 路径执行 adb pull 路径 本地目录把文件拉到电脑对本地文件执行一次校验避免传输损坏。相比去各种非官方下载站点碰运气这种自己从设备导出的方式来源可信、版本精确做样本比对分析时更有说服力。5.2 场景二捕捉应用启动瞬间的关键日志典型场景是这样目标页面点击后闪退崩溃堆栈可能一闪而过但你不知道它到底在什么阶段崩的。这时可以按四步走清空旧日志adb logcat -c启动目标应用adb shell am start -n 包名/主Activity等待 2 到 3 秒让初始化链路完整跑完导出日志adb logcat -d startup.log然后在日志文件里搜索 FATAL、Exception、ClassNotFoundException、Process 等关键词。如果没搜到明显的崩溃信息就切到另一个视角执行 adb shell dumpsys activity top 查看 Activity 是否真的成功启动。有些崩溃发生在 Activity 实例化之前日志中只会留下“Process ... has died”之类的片段这时候结合 am start -W 的启动时长一起分析能更快定位问题阶段。5.3 场景三用 monkey 做轻量自动化遍历写复杂自动化脚本太费时间的时候monkey 就是现成的“乱拳打死老师傅”工具。它会向目标应用随机发送事件流包括点击、滑动、按键、系统事件adb shell monkey -p com.example.demo -v 500-p 指定目标包名-v 意为 verbose500 是打算发送的事件数量。如果应用不稳定大概率会在随机事件中崩溃。崩溃发生时monkey 会在输出末尾打印 error 信息再配合 logcat 就能抓个正着。增加 -s 参数可以固定随机种子adb shell monkey -p com.example.demo -s 12345 -v 500同一个种子会生成完全相同的事件序列。这样在修复某个崩溃之后你还能用同一套事件流验证问题是否真的被解决而不需要靠运气复现。6. 常见问题排查与我的踩坑经验最后这部分是实战中最常遇到的五类坑。很多问题都不是命令记不住而是环境或状态不干净我按优先级给你列好排查路径。6.1 unauthorized 状态怎么解决unauthorized 说的是设备连上了但用户没有授权 USB 调试。常见原因有两个第一次连接时手机弹窗被手滑点掉了或者手机屏幕锁着弹窗根本没弹出来。处理顺序拔掉数据线手机上进入开发者选项点“撤销 USB 调试授权”重新插线在弹窗上勾选“始终允许”点击允许执行 adb devices状态应当变为 device。如果还是 unauthorized执行 adb kill-server 和 adb start-server 重置服务然后再查一次设备列表。6.2 多版本 ADB 服务冲突我在 2.4 节提过这里再给一个更完整的处理办法。当系统提示“检测到电脑上同时运行了多个版本的 adb 服务版本不一致”时核心思路是把旧的/冲突的 adb 进程全部清理掉。可以在任务管理器里搜 adb把所有相关进程结束同时在服务列表里查看有没有名为 adb 的服务残留。清理完毕后执行 adb start-server 重建服务问题就会消失。如果你同时装了 Android Studio、第三方模拟器和独立的 platform-tools建议只保留一个版本的 adb并把它在所有终端工具里的路径统一。6.3 设备显示 offline 的排查顺序offline 状态的问题比 unauthorized 更杂常见诱因包括数据线不支持数据传输、USB 接口供电不足、ADB 服务与 adbd 版本不匹配等。我的排查顺序换数据线优先换原装线换电脑 USB 口优先笔记本后置口或台式机机箱背面接口执行 adb kill-server 和 adb start-server拔插设备重启一次调试通道换一台电脑交叉验证定位到底是设备问题还是电脑问题。按这个顺序能解决 90% 以上的 offline少走很多弯路。6.4 模拟器连接不上用 Android Studio 自带模拟器时设备列表里一般会自动出现 emulator-5554 这样命名的设备。如果没有可以手动连接adb connect 127.0.0.1:5555模拟器的调试端口通常在 5555 到 5585 区间多个模拟器同时运行时端口会递增。使用第三方模拟器时先检查它的设置里有没有单独提供 ADB 调试开关很多模拟器默认关闭并不是你没连对端口。写到这里今天的 ADB 工具基石就算打完了。我个人实际摸索下来的体会是ADB 这个工具真不用死记命令关键在于建立“遇到问题先反应出对应命令”的条件反射。能一次拉包、一次定位、一次复现效率就上来了。明天开始进入 APK 结构拆解和 Jadx 静态分析到时候 pm 和 pull 这两个动作会成为你每天都要重复的基本功。现在就把设备连一次把上面的流程完整走一遍别偷懒明天你会感谢今天的自己。