AccessibilityService分析与防御

编程入门 行业动态 更新时间:2024-10-20 01:20:50

<a href=https://www.elefans.com/category/jswz/34/1750490.html style=AccessibilityService分析与防御"/>

AccessibilityService分析与防御

转载请注明出处:

前言

提起AccessibilityService,你最容易联想到的肯定是微信抢红包插件!但这个服务的设计初衷,是为了帮助残障人士可以更好的使用App。

一些“调皮”的开发者利用AccessibilityService可以监控与操作其他App的特性加上系统远超人类的反应速度,在某些竞争类场景开发出了作弊外挂,最常见的就是你所嫉愤的微信抢红包插件了。

微信抢红包插件对原本平等的竞争环境产生了不公,不过这是微信团队要操心解决的事。可万万没想到,有一天,我正在写的App也遭此毒手!!!这都欺负到头上了能忍吗?不能啊!

OK,所以我们今天先来分析一下AccessibilityService运行原理,然后分享一些我在应对此类竞争场景下基于AccessibilityService等自动化作弊工具的防御措施。

外挂简史

先说下背景:

场景是和抢红包类似的另一种:抢单。用户下单后订单会经过系统,在配送端App发布,配送人员在配送端App通过距离、价钱、时间等维度进行筛选并抢单然后配送。显而易见,价高距离短的订单非常抢手,这样就形成一种竞争环境,于是,自动抢单外挂也就有了存在的理由。

然后我们来看下外挂进化史:

  • 第一代外挂

    第一代外挂还比较粗糙,需要依赖按键精灵来实现,且需要Root权限。

    【防御】简单反编译拆包了解后,考虑暂时没有更好的办法禁止按键精灵对App的模拟点击,直接封禁Root可能会有大量误杀,第一代防御仅简单的检查是否安装了按键精灵,然后限制用户抢单。

  • 第二代外挂

    可能因为第一代的防御过于粗糙,第二代外挂很快有了新的改进,不再需要单独安装按键精灵这个App,他们把按键精灵集成到了自己的app里……

    【防御】此时团队内部简单商量后决定,快刀斩乱麻,直接封禁Root权限,检测到Root后将限制抢单。

  • 第三代外挂

    禁止Root后终于消停了一段时间,但显然人民群众的智慧是无限的,很快新的免Root外挂出世了……经过反编译外挂后,第三代外挂采用了AccessibilityService来实现。

    【防御】此时已知的外挂并不多,所以除了继续封禁Root以外,还建立了可远程配置的外挂package name黑名单列表,若检测到已安装app列表里存在特定外挂包名后,将会进行抢单限制。
    package name需要先获取到安装包来查看包名,随着外挂数量逐步上涨,外挂安装包获取难度大的缺点开始暴露了。

  • 【第三代防御】

    此时针对上一个版本的防御措施做了一次优化:
    1.优先检查外挂package name
    2.次级检测外挂app name,加package name白名单防误判。这样就不需要再获取app的安装包了
    3.增加骑手举报反馈入口
    4.收集了已启动的辅助模式列表备用(本想再快到斩乱麻的禁止辅助模式的开启,但这个误杀范围实在是太大了,最终还是停留在了想一想的阶段)

  • 第四代外挂

    在通过app name封禁后,外挂们挣扎了几次都被即时遏制了。但很快,我们收到了最新的外挂信息:新出来的外挂没有图标,看不到名字…… (你们厉害你们厉害!!!)

哎呀~真是活久见,两波从来没见过的人在互相进步啊这是!!!禁止外挂安装这种简单的防御措施已经挡不住这帮疯狂的人类了,我只能一头扎进了AccessibilityService的源码中,看这到底是个啥东西,然后去思考相应的防御方案。

AccessibilityService运行原理

AccessibilityService内部运行

这不是一篇AccessibilityService教程文章,没有AccessibilityService完整的使用示例代码和源码,但为了上下文不至于断档太大,我们这里还是会简单贴一些小段代码。同时需要说明的是,严谨的来说AccessibilityService只是一个Service,文本查找点击事件等操作对于一个Service来说是完全没法做到的。但为了行文方便,所以后面某些AccessibilityService代指辅助模式服务。

public class MyAccessibilityService extends AccessibilityService {...@Overridepublic void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {//获取eventTypeint eventType = accessibilityEvent.getEventType();if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();if (nodeInfo != null) {//查询文案为BUTTON3的ViewList<AccessibilityNodeInfo> button3 = nodeInfo.findAccessibilityNodeInfosByText("BUTTON3");nodeInfo.recycle();for (AccessibilityNodeInfo item : button3) {//对这个View执行点击操作item.performAction(AccessibilityNodeInfo.ACTION_CLICK);}}}}...
}

AccessibilityService真的很简单,只要写一个Service继承AccessibilityService,然后还有其他一些配置,之后每当你监控的应用界面有变动时就会回调到这个onAccessibilityEvent这个方法,你可以在里面取得此时变动的event类型是什么,还能拿到当前这个应用可视化的View树,然后取得其中的某个View来执行某些操作。

那至于其原理,用屁股想想也知道是肯定是被监控的App发生界面改变时通知了系统,然后系统又通知给了我们注册的Service。嗯……屁股想的没错……那App怎么通知系统的?系统又怎么通知我们的呢?

哎呀,屁股想不出来了,没关系,屁股决定脑袋,脑袋知道怎么办。这个时候我们就该钻到源码里来一探

更多推荐

AccessibilityService分析与防御

本文发布于:2024-02-06 16:39:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1750615.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:AccessibilityService

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!