Android应用能否检测自身是否通过ADB侧载?
检测Android应用是否通过ADB侧载的方法
嘿,这个问题问得很精准!确实ADB侧载可以通过--installer-name参数伪装安装来源,但咱们的应用还是能通过几种方式来识别自身是否是通过ADB侧载安装的,下面是几个实用的方案:
1. 检查安装器包名(基础方案,可能被绕过)
通过PackageManager.getInstallerPackageName()获取应用的安装器包名,默认情况下:
- 从Google Play、系统自带安装器安装的应用,会返回对应的安装器包名(比如
com.android.vending、com.android.packageinstaller) - 直接用
adb install安装且未指定--installer-name时,返回值为null或者com.android.shell
不过要注意,用户可以通过adb install --installer-name com.android.packageinstaller your.apk来伪装安装来源,所以这个方法不是绝对可靠,但可以作为初步筛查。
代码示例:
PackageManager pm = getPackageManager(); String installerPackageName = pm.getInstallerPackageName(getPackageName()); if (installerPackageName == null || installerPackageName.equals("com.android.shell")) { // 可能是ADB侧载安装 }
2. 检查安装标志(更可靠,API 24+)
从Android 7.0(API 24)开始,PackageInfo中新增了installFlags字段,其中包含PackageManager.INSTALL_FLAG_ADB_INSTALL标志——只要是通过ADB安装的应用,系统都会设置这个标志,即使指定了--installer-name也无法移除。
代码示例:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { try { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); if ((packageInfo.installFlags & PackageManager.INSTALL_FLAG_ADB_INSTALL) != 0) { // 确定是通过ADB侧载安装的 } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } }
3. 结合签名与安装来源的交叉验证(进阶方案)
如果你的应用是通过正规渠道发布的,可以预先保存正规安装器的包名和对应的签名信息,在应用启动时:
- 获取当前安装器的包名
- 验证该安装器的签名是否与预存的正规签名一致
- 如果不一致,且安装标志显示是ADB安装,就可以判定为非正规侧载
这个方案可以进一步降低被绕过的概率,尤其是针对恶意篡改安装来源的情况。
注意事项
- 对于Root过的设备,恶意用户可以通过修改系统文件或使用Xposed模块篡改这些检测结果,所以没有100%无懈可击的方法
- 这些检测逻辑建议放在应用启动的早期阶段执行,比如
Application.onCreate()中
内容的提问来源于stack exchange,提问作者Sad.coder




