一.外挂与功能分析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.小结
需要android的API支持控件监控与事件模拟两个功能,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)
|
|