最近碰到一个异地远程 ADB 调试的需求,Android 设备在我手头,但是调试人员远在另一个城市,而且设备本身很重,邮寄又麻烦也根本来不及。所以怎么才能让对方在异地调试,而无需跑过来插一下 USB 呢?

0x00 分析

我一直错误地以为 ADB 即使远程调试也是需要插一下 USB 的,上网搜索一下“ADB 远程调试”,结果也大都是让你先插下 USB,再去点那个允许调试的对话框。但是我小小地调查一下后发现其实不然……

瞄了眼 ADB 的 Google 官方文档(简单翻译):

Security commands Description(描述)
keygen file 生成 RSA 公私密钥对。私钥保存成名为 file 的文件。公钥保存成名为 file.pub 的文件。当你首次通过 USB 连接 ADB 时,RSA 公私密钥对是必需的。你必须接受调试电脑的 RSA 公钥来明确授权这台电脑 ADB 连接这个设备(注:就是插 USB 时弹出来那个允许调试的对话框)。……

文档的详细说明中还给了个环境变量名 ANDROID_VENDOR_KEYS,可以用来手动指定电脑 ADB 要用的密钥对的路径,或者默认 $HOME/.android 目录( windows 默认 %userprofile%\.android

0x01 解决方法

这下好办了,这不跟 SSH 一个道理嘛!给远程调试的人发个私钥就行了。看好咯,下面照我说的做!

  1. 前往官网下载 platform tools,如果你有 Android Studio 安装过 platform tools 的话就不用另下载了。下完了解压到任意合适的目录;
  2. 把上面解压的目录添加到系统环境变量 PATH 里;
  3. 终端运行 adb keygen keypair
  4. 在终端当前工作目录,或者默认的 $HOME/.android 目录里找到 keypairkeypair.pub 这两个文件;
  5. 设置 ANDROID_VENDOR_KEYS 变量为你存放密钥对的路径(非必须,可以用默认的 $HOME/.android
  6. 复制下公钥 keypair.pub,进 Android 设备终端,echo [公钥粘贴过来] >> /data/misc/adb/adb_keys
  7. 重启 Android 设备的 adbd(或者干脆重启整个 Android 系统吧,不要忘了开 adb);
  8. 把私钥 keypair 发给要调试的人,注意要保护密钥不泄露哦~

远端如何调试呢:

  1. 下载并解压上文说的 platform tools,并把目录添加到 PATH
  2. 把收到的私钥文件 keypair 放到 ANDROID_VENDOR_KEYS 指定的目录(或者默认的 $HOME/.android 目录)
  3. 命令行 adb tcpip 5555
  4. 接着 adb connect [Android 设备的 IP],等待提示连接成功;
  5. 现在就可以 adb shell 进入设备终端调试了!push/pull 传送文件等同 USB 别无二致。

0x02 结论和其他

ADB 调试只需要对应的 RSA 私钥就能连接上了,和 SSH 很类似的,并不一定要先插 USB 点对话框进行验证。

有一点你可能会有疑问,把公钥放到 Android 设备里这一步要进设备终端,不还是要插 USB 的么?其实我这里是用串口连上去调试的,但是这个疑问不无道理,要把公钥放到 /data/misc/adb/adb_keys 里,就首先需要有 root 权限(串口连接还需要物理接触设备),但这就绕进先有鸡先有蛋里去了。

而这里讨论的主题是: 如何让远在另一个城市的人连接到我这里的 Android 设备上进行调试,按照通常的错误认识,那个人一定要先跑过来插一下 USB,所以本文澄清下,把公钥导入设备,私钥发给对方就可以了,不需要他跑过来插 USB。