黑马程序员技术交流社区

标题: 使用AccessibilityService开发外挂:应用宝非root安装与微信抢红... [打印本页]

作者: 翁志雄Gson    时间: 2015-12-26 18:24
标题: 使用AccessibilityService开发外挂:应用宝非root安装与微信抢红...
一.外挂与功能分析1.概念:外挂
游戏外挂其实是一种游戏外辅程序或者游戏修改器(作弊),它可以协助玩家用最少的时间和金钱去完成功力升级和过关斩将。
2.外挂类型
外挂的类型主要包含以下两种
第一种 是修改账号核心数据。包含以下数据:
1(血条):比如将残血100改成10000
2(魔法值):比如将10点魔法值改成100000
3(钱是购买武器与升级的利器):比如改成游戏上限的数值
4属性(攻击 敏捷 力量)
其原理是 外挂程序产生欺骗性的网络游戏封包,并将这些封包发送到网络游戏服务器,利用这些虚假信息欺骗服务器进行游戏数值的修改。
第二种 是模拟用户在线操作
是将游戏中大量繁琐和无聊的攻击动作使用外挂自动完成、做任务砍树10000 换钱,鼠标一次点击砍掉一棵树。
咱们要讲的应用宝非root安装与微信抢红包是属于第二类型

3.外挂开发流程有以下两部分

1.前期部分工作是对外挂的主体游戏进行分析,分析的内容包含游戏包数据的结构、内容以及加密算法
2.后期部分工作主要是根据前期对游戏的分析结果,使用大量的程序开发技术编写外挂程序以实现对游戏的控制或修改 比较好理解的是动作模拟技术如:鼠标模拟技术,键盘模拟技术

4.应用宝的非root安装




1.下载应用宝安装
2.到辅助功能打开 应用宝
3.在应用宝中任意下载一个apk
4.注意观察出现界面上是否有"安装"字样的控件,有的话会被自动点击。
分析结果:需要监控界面的控件是否有"安装"字样 。有的话 编写的外挂需要模拟用户的点击操作完成安装。

5.微信抢红包

1.下载微信 使用账号登录
2.在聊天界面让好友发送一个红包
3.出现"微信红包"字段 需要用户点击抢到红包
分析结果:需要监控界面的控件是否有"微信红包"字样 。有的话,编写的外挂需要模拟用户的点击操作,完成"微信红包"的抢红包操作。
6.小结
需要androidAPI支持控件监控与事件模拟两个功能,AccessibilityService就是我们学习的重点。
二.AccessibilityService快速入门
1.介绍

Accessibility就是可获取的意思。加上Service 就是AccessibilityService:即可以获取系统事件数据的一个后台服务。 接下来可以点以下链接看到文档的介绍:

http://android.xsoftlab.net/reference/android/accessibilityservice/AccessibilityService.html

AccessibilityService能实时地获取当前操作应用的窗口元素信息,并能够双向交互,既能获取用户的输入,也能对窗口元素进行操作,比如点击按钮。
2.开发步骤

调用Android Accessibility API需要四个步骤:申请权限、编写AccessibilityService实现、注册 Service、配置 Accessibility Service Info

1.在功能清单注册权限

<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>

2.继承AccessibilityService重写

/*** 将来处理界面查询识别与事件创建 **/
public class MyAccessibilityService extends AccessibilityService {
    /** 接收到事件 **/
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.i("itheima", event.toString());
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            // 判断事件类型并进行业务逻辑处理
        }
    }


3.在功能清单里注册

    <!-- 1.要求有权限 2.辅助功能 能调用的隐式意图 -->
    <service
        android:name="com.itheima.extra.sevice.MyAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>

        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice" />
    </service>
    <!-- meta-data配置将来需要接收哪个应用的 事件 与事件类型 -->
[size=12.0000pt]
[size=12.0000pt]
4.res/xml新建一个xml文件 加上以下配置

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:canRetrieveWindowContent="true"
    android:description="@string/xml_desc"
    android:notificationTimeout="100"
    android:packageNames="com.itheima.tt" />

注意事项
在配置 Accessibility Service Info时,如果明确的知道目标APP的包名,那一定要使用packageNames属性进 行设置。不然每个应用的每个页面都监控容易造成app压力大而崩溃。
案例一.应用宝的非root安装 外挂实现




file:///C:\Users\itheima\AppData\Local\Temp\ksohtml\wps5CA3.tmp.png
1.在功能清单注册权限
参考下面第3

2.继承AccessibilityService重写

/*** 将来处理界面查询识别与事件创建 **/
public class MyAccessibilityService extends AccessibilityService {
    /** 接收到事件 **/
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.i("itheima", event.toString());
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            // 判断事件类型并进行业务逻辑处理
            // 查询按键并点击
            queryBtnAndClick(event);
        }
    }


@Override
protected void onServiceConnected() {
   
    super.onServiceConnected();
    Log.i("itheima", "onServiceConnected---");
    // ----------与xml配置具有相同的功能
    AccessibilityServiceInfo info = getServiceInfo();
    //配置监控应用包名
    info.packageNames = new String[] { "com.itheima.tt", "com.android.packageinstaller" };
    //配置获取事情件类型
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
    info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;//配置窗口切换
    info.notificationTimeout = 100;
    setServiceInfo(info);

}
/** 响应点击 **/
private void queryBtnAndClick(AccessibilityEvent event) {

    AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
    if (nodeInfo == null) {
    Log.i("itheima", "rootWindow为空");
    return;
    }
List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("安装");
System.out.println(list.size());
for (AccessibilityNodeInfo n : list) {
    n.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}}}
[size=12.0000pt]

3.在功能清单里注册
    <!-- 1.要求有权限 2.辅助功能 能调用的隐式意图 -->
    <service
        android:name="com.itheima.extra.sevice.MyAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>

        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice" />
    </service>
    <!-- meta-data配置将来需要接收哪个应用的 事件 与事件类型 -->

4.res/xml新建一个xml文件 加上以下配置

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:canRetrieveWindowContent="true"
    android:description="@string/xml_desc"
    android:notificationTimeout="100"
    android:packageNames="com.itheima.tt" />

注意事项
1.xml里面配置的话由于ecllipse不能自动提示,开发者可以复制第4步的配置。
2.root安装 比Intent安装便利许多,比root安装更不受手机是否已经root限制。是自动安装方案里比较优先的实现。
3.一定要在设置应用的辅助功能里面打开该服务

案例二.微信抢红包




file:///C:\Users\itheima\AppData\Local\Temp\ksohtml\wps5CA4.tmp.png
1.在功能清单注册权限
参考下面第3

2.继承AccessibilityService重写

    /** 可获取事件服务 ***/
@SuppressLint("NewApi")
public class MyAccessibilityService extends AccessibilityService {
    /** 服务被连接 **/
    @Override
    protected void onServiceConnected() {
        
        super.onServiceConnected();
        Log.i("itheima", "------事件服务连接成功------");
        configServiceInfo();
    }
    private void configServiceInfo() {
        // 获取 xml/配置文件中的<accessibility-service
        AccessibilityServiceInfo info = getServiceInfo();
        info.packageNames=new String[]{"com.itheima.wx"};
        info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
        super.setServiceInfo(info);
    }
    /** 以下为模拟微信抢红包涉及的相关界面**/
    private String chatUi = "com.itheima.wx.MainActivity";
    private String startGetUi = "com.itheima.wx.StartGetActivity";
    private String gotUi = "com.itheima.wx.GotPacketActivity";
    private String showDetail = "com.itheima.wx.DetailActivity";
    /** 接收满足条件设置的事件AccessibilityEvent **/
    @SuppressLint("NewApi")
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.i("itheima", "----onAccessibilityEvent 接收到事件------" + event);
        // if (event.getAction() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {//可以加强一个事件判断
        // 判断界面
        String className = event.getClassName().toString();
        Log.i("itheima", "----onAccessibilityEvent 接收到事件------" + className + "|");
        if (className.equals(chatUi)) {
            // 找到微信红包点击 [微信红包]
            String tag = "微信红包";
            findTagAndClick(tag);
            Log.i("itheima", "-找到微信红包点击 [微信红包]--");
        } else if (className.equals(startGetUi)) {
            // 找到小人 点击
            String tag = "抢红包";
            findTagAndClick(tag);
            Log.i("itheima", "- 找到小人 点击--");
        } else if (className.equals(gotUi)) {
            // 拿到红包访问拆开
            String tag = "拆开?";
            findTagAndClick(tag);
            Log.i("itheima", "-  拿到红包访问拆开-");
        } else if (className.equals(showDetail)) {
            // 详情界面返回
            String tag = "返回";
            findTagAndClick(tag);
            Log.i("itheima", "-  详情界面返回-");
        }
    }

    // }

    @SuppressLint("NewApi")
    public void findTagAndClick(String tag) {
        AccessibilityNodeInfo root = getRootInActiveWindow();
        List<AccessibilityNodeInfo> nodes = root.findAccessibilityNodeInfosByText(tag);
        if (!nodes.isEmpty()) {
            for (AccessibilityNodeInfo node : nodes) {
                node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    }

    @Override
    public void onInterrupt() {

    }

}

3.在功能清单里注册

创建一个由辅助功能开启/关闭的服务 该服务主要完成界面事件的获取
    <service android:name="com.itehima.wx.modify.service.MyAccessibilityService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice" />
    </service>

4.res/xml目录下创建一个xml文件配置如下

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
     android:notificationTimeout="100"
    android:packageNames="com.itheima.wx"
    android:description="@string/description"
     android:canRetrieveWindowContent="true"
  />

页面节点查找技巧
假如界面上有一个控件带有字符串"微信红包",那咱们怎么把该控件的信息查找出来?提供以下两种查询方法
findAccessibilityNodeInfosByText该方法按字符串查找控件。只有符合查找字符串的就可以获取节点信息
findAccessibilityNodeInfosByViewId 该方法按控件的id 查找控件。只要拿到布局界面上的@+id/id值即可获取节点信息


那应用不是咱们开发的怎么知道id值为多少?



1.可以反编译 apktool 工具获取layout布局文件
2.使用sdk/tools/hierarchyviewer.bat 分析工具
3.使用以下代码在运行时遍历视图节点

/** 遍历界面元素 **/
public void printNodes() {
    Log.i("itheima", "==============================================");
    AccessibilityNodeInfo rowNode = getRootInActiveWindow();
    if (rowNode == null) {
        Log.i("itheima", "noteInfo is null");
        return;
    } else {
        recycle(rowNode);
    }
}

/** 递归遍历 **/
public void recycle(AccessibilityNodeInfo info) {
    if (info.getChildCount() == 0) {
        Log.i("itheima", "child widget--" + info.getClassName());
        Log.i("itheima", "Text:" + info.getText());
        Log.i("itheima", "windowId:" + info.getWindowId());
    } else {
        for (int i = 0; i < info.getChildCount(); i++) {
            if (info.getChild(i) != null) {
                recycle(info.getChild(i));
            }
        }
    }
}

源代码分享
源代码-外挂.zip (4.98 MB, 下载次数: 490)




作者: 夕阳游子    时间: 2015-12-26 18:40
谢烟客出品,必属精品
作者: lalala1a    时间: 2016-5-6 21:55
关注关注~~以后学到了再来看看~
作者: 天真不穿鞋    时间: 2016-5-6 22:38
啦啦啦啦啦啦啦啦啦啦啦啦啦啦
作者: 天真不穿鞋    时间: 2016-5-6 22:42
啦啦啦啦啦啦啦啦啦啦啦啦啦啦
作者: 天真不穿鞋    时间: 2016-5-6 22:47
啦啦啦啦啦啦啦啦啦啦啦啦啦啦
作者: zhoujiegun    时间: 2016-5-6 22:58
谢谢大神分享
作者: helifu00    时间: 2016-5-7 23:29
哇塞,太爽了吧!棒棒哒
作者: 张金金金    时间: 2016-5-7 23:38
都看不懂,感觉很厉害的样子,先保存一下.
作者: 艺高人胆大    时间: 2016-5-7 23:45
能弄外挂的很牛啊   
作者: Unknown_Explore    时间: 2016-5-8 09:56
我也要做个出来





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2