百趣云 百趣云的博客

Appium 自动化的特征检测与绕过

Appium 为什么会被检测

用 Appium 做 App 自动化(抢票、薅羊毛、批量操作)时,经常遇到"脚本一跑就触发验证,手动操作就没事"——App 检测到了自动化框架。检测点分几层:

1. 系统属性层

Appium 驱动基于 UIAutomator2/Espresso,会在系统里留特征:

// 检测代码的典型实现
// UIAutomator2 的服务端口和包名特征
getSystemService("uiautomator") != null
// 或检测已安装包
pm.getInstalledPackages() 包含 "io.appium.uiautomator2.server"

2. 输入事件层

Appium 的点击/滑动通过系统 API 注入,事件特征和真实触摸不同:

  • MotionEvent.getToolType():真实触摸是 TOOL_TYPE_FINGER,注入的可能是其他值
  • 事件的 downTime/eventTime 间隔模式:真实操作有自然抖动,脚本的事件时间戳过于规整
  • 压力值(pressure)和接触面积(size):真实手指按压有值且变化,注入事件常为固定值

3. 行为层

脚本的操作路径、速度、坐标精度(每次都点正中心)都是统计特征。

绕过方案

系统属性层:root 后卸载/冻结 Appium 的服务包(用的时候装,用完冻结),或 Xposed hook 包管理器的查询接口,对 Appium 相关包名返回"未安装"。

输入事件层:放弃 Appium 的事件注入,改用更底层的输入方式:

# 方案1:adb shell input(事件来自 shell 用户,特征比 Appium 少)
adb shell input tap 500 800
adb shell input swipe 300 1000 300 500 800   # 800ms 的滑动

# 方案2:root 后直接写 /dev/input/eventX(最底层,和真实触摸同通道)
# 用 sendevent 命令或自己写程序注入

/dev/input 层注入的事件和真实触摸走完全相同的内核通道,应用层无法区分——这是自动化点击的终极方案。

行为层:操作路径拟人化(参考"行为风控"篇):随机坐标偏移、拟人滑动轨迹、随机间隔。

精髓一:检测点逆向先行

别盲目绕过——先逆向 App 的自动化检测代码:

jadx 搜关键词:
"uiautomator" "appium" "isAutomation" "checkAutomation"
MotionEvent.getToolType / getPressure 的调用点

把检测清单列出来,逐条对抗。很多 App 的自动化检测其实只做了系统属性层(查 Appium 包名),冻结服务包就过了。

精髓二:Appium 的替代方案对比

方案检测难度开发效率适用
Appium易被检测高(API 完善)弱检测 App、测试场景
adb input 命令中等低(坐标硬编码)简单操作
/dev/input 注入极难检测强检测 App
无障碍服务(AccessibilityService)中等需要读界面内容的场景
协议模拟(无 UI)不触发 UI 检测终极方案

能协议模拟就别 UI 自动化——UI 自动化天然慢、脆、易被检测,协议层方案在所有维度碾压。UI 自动化只用于协议无法覆盖的场景(如必须真人交互的验证环节)。

精髓三:无障碍服务的双刃剑

很多"脚本 App"(按键精灵、自动点击器)基于无障碍服务实现。检测无障碍的方法:

// App 检测无障碍服务列表
AccessibilityManager am = ...;
am.getEnabledAccessibilityServiceList(...)  // 有可疑服务即判定

绕过:Xposed hook 该方法返回空列表。但注意无障碍服务本身也是业务能力(能读屏幕内容做智能决策),对抗检测的同时可以合法使用它的能力——这是"按键精灵类"工具的技术底座。

总结

  1. Appium 检测三层:系统属性、输入事件特征、行为统计
  2. 终极输入方案是 /dev/input 层注入,与真实触摸同通道
  3. 先逆向检测代码列清单,很多 App 只查了包名
  4. 能协议模拟就别 UI 自动化,维度碾压

交流微信:run1255

By 百趣云 阅读量:16 On