您的位置:首页 > 移动开发 > Android开发

Android 中利用XPosed拦截系统消息

2017-04-24 14:06 309 查看
一、前言 

关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xposed框架是免费的而且还是开源的,网上也有很多文章介绍了Xposed框架的原理实现,不了解的同学可以自行查阅即可,本文主要介绍如何通过这个框架来进行系统方法的拦截功能,比如我们开发过程中,对于一些测试环境很难模拟,特别是测试同学有时候像随机改变设备的imei,mcc等信息用来模拟不同测试场景,这时候如果可以去修改系统的这个值的话对于测试来说就非常方便了,其实这些在网上已经有很多类似的小工具了,下面就来详细的讲解如何使用这个框架。

第二步:编写模块代码 

模块代码编写还是比较简单的,我们只要新建一个实现IXposedHookLoadPackage接口的类,然后在handleLoadPackage回调方法中进行拦截操作即可,而具体的拦截操作是借助XposedHelpers.findAndHookMethod方法和XposedBridge.hookMethod方法实现的,这两个方法也是比较简单的,从参数含义可以看到,主要是Hook的类名和方法名,然后还有一个就是拦截的回调方法,一般是拦截之前做什么的一个beforeHookedMethod方法和拦截之后做什么的一个afterHookedMethod方法。

如果你想Hook一个类的具体方法,那么就必须要清楚的了解到这个方法的相信信息,比如参数类型和个数,返回类型等。因为在拦截的过程中必须要对这个方法进行分析,比如得到方法参数来进行具体参数修改,返回值信息来进行返回值修改,这里看到了获取imei值的方法是一个无参数的返回字符串类型的方法,那么如果要拦截他的返回值,就需要修改他的返回值使用setResult方法即可。所以从这里可以看到不管是你hook系统的方法,还是日后去hook第三方应用的具体类方法,第一步都得了解到你hook对象的具体信息,关于系统方法咋们可以通过查看源码来得到信息,而对于第三方应用的话那么只能借助反编译技术了,比如修改游戏金币功能,你必须先反编译游戏知道修改金币的类和具体方法才可行。

importandroid.app.ActivityManager;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;

import java.util.ArrayList;
import java.util.List;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

import static de.robv.android.xposed.XposedBridge.log;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

public class HideModule {

static void hideModule(XC_LoadPackage.LoadPackageParam loadPackageParam) {

//利用PackageManager拦截当前包名,并hook其中的方法
findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledApplications", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
List<ApplicationInfo> applicationList = (List) param.getResult();
List<ApplicationInfo> resultapplicationList = new ArrayList<>();
for (ApplicationInfo applicationInfo : applicationList) {
String packageName = applicationInfo.packageName;
if (isTarget(packageName)) {
log("Hid package: " + packageName);
} else {
resultapplicationList.add(applicationInfo);
}
}

4000
param.setResult(resultapplicationList);
}
});
findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledPackages", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
List<PackageInfo> packageInfoList = (List) param.getResult();
List<PackageInfo> resultpackageInfoList = new ArrayList<>();

for (PackageInfo packageInfo : packageInfoList) {
String packageName = packageInfo.packageName;
if (isTarget(packageName)) {
log("Hid package: " + packageName);
} else {
resultpackageInfoList.add(packageInfo);
}
}
param.setResult(resultpackageInfoList);
}
});
findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getPackageInfo", String.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String packageName = (String) param.args[0];

log("packageName: " + packageName);

}
});
findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getApplicationInfo", String.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
String packageName = (String) param.args[0];
if (isTarget(packageName)) {

log("packageName: " + packageName );
}
}
});
findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningServices", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
List<ActivityManager.RunningServiceInfo> serviceInfoList = (List) param.getResult();
List<ActivityManager.RunningServiceInfo> resultList = new ArrayList<>();

for (ActivityManager.RunningServiceInfo runningServiceInfo : serviceInfoList) {
String serviceName = runningServiceInfo.process;
if (isTarget(serviceName)) {
log("Hid service: " + serviceName);
} else {
resultList.add(runningServiceInfo);
}
}
param.setResult(resultList);
}
});
findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningTasks", int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
List<ActivityManager.RunningTaskInfo> serviceInfoList = (List) param.getResult();
List<ActivityManager.RunningTaskInfo> resultList = new ArrayList<>();

for (ActivityManager.RunningTaskInfo runningTaskInfo : serviceInfoList) {
String taskName = runningTaskInfo.baseActivity.flattenToString();
if (isTarget(taskName)) {
log("Hid task: " + taskName);
} else {
resultList.add(runningTaskInfo);
}
}
param.setResult(resultList);
}
});
findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningAppProcesses", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfos = (List) param.getResult();
List<ActivityManager.RunningAppProcessInfo> resultList = new ArrayList<>();

for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfos) {
String processName = runningAppProcessInfo.processName;
if (isTarget(processName)) {
log("Hid process: " + processName);
} else {
resultList.add(runningAppProcessInfo);
}
}
param.setResult(resultList);
}
});
}

private static boolean isTarget(String name) {
return name.contains("Hu") || name.contains("xposed");
}
}


但是由于手机原因打印不出log....这里就只能用模拟器掩饰(演示)了。

这里可以看到利用XPosed已经成功hook到了系统服务,并打印出了Log。



好了,到这里我们就编写好了Hook系统的PackManager里面的方法的模块了。

接下来只需要添加XPosed入口和Xml中配置XPosed的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android