Xposed是Android平台上的一个常用的HOOK框架,可以在不改变程序源代码的前提下,影响程序的运行。一个支持Xposed的Android应用程序被称为一个Xposed模块,用户可以在Xposed中安装各种各样的Xposed模块,在启用或关闭Xposed模块之后,需要重新引导系统才能生效。
因为Xposed运行在root环境的,在手机使用需要刷机,一般测试在模拟器安装即可。在模拟器上安装Xposed 框架,可以在官网下载:
https://repo.xposed.info/module/de.robv.android.xposed.installer
https://forum.xda-developers.com/attachment.php?attachmentid=4393082&d=1516301692
下载之后,按照提示安装就好,这非常容易。安装好之后,如下所示:
Xposed模块是使用Java语言开发的,建议使用Android Studio来开发Xposed模块,因为用Eclipse开发很不方便。开发模块之前,你需要拥有Android的开发基础,所谓磨刀不误砍柴工。小白建议先看完以下4篇文章,你会对Android开发有更清晰的认识。
Android开发系列:1.安卓操作系统架构与应用程序组件
Android开发系列:2.使用Android Studio搭建Android开发环境
Android开发系列:3.利用Android Studio开发一个demo应用
Android开发系列:4.利用 Android Studio开发看美女应用
使用Android Studio创建一个demo应用,然后去编辑app文件夹下的build.gradle文件,添加以下语句,这是为了自动添加Xposed依赖库。
compileOnly 'de.robv.android.xposed:api:82'
compileOnly 'de.robv.android.xposed:api:82:sources'
编辑AndroidManifest.xml文件,在
在main目录下新建assets文件夹,在其下新建一个文本文件,命名为xposed_init,这个文件用于配置Xposed的入口类名,在这个文件中直接写入实现了IXposedHookLoadPackage接口的类名,我这里是com.sy.xposedtest.HookShowLoan,到目前准备工作就完了,下面我们就要去编写Xposed模块了。
Xposed最常用的功能就是修改函数的行为,看下面这个例子。首先看这个APP,正常运行如下所示。我们将要编写一个Xposed模块来挂钩这个函数,来影响它的运行。
该APP待挂钩函数源码:
新建一个Java类HookShowLoan(上文提到的入口类),它实现了IXposedHookLoadPackage接口。该接口提供了一个名为handleLoadPackage的方法,这个方法在Android系统每次加载一个包的时候都会被调用。因此不能在此方法写太多耗时的操作,不然会很卡。
以上问题其实很容易解决,我们只需要加以判断,取出我们关心的包。
if(loadPackageParam.packageName.equals("com.example.demo")){
//……
}
HOOK无参数的方法,XposedHelpers.findAndHookMethod()方法一般四个参数,分别为完整类名、ClassLoader对象、方法名以及一个回调接口
XposedHelpers.findAndHookMethod("com.example.demo.MortgageActivity", loadPackageParam.classLoader,
"showLoan", new XC_MethodHook() {
//……
});
HOOK有参数的方法,比如要传入两个int参数,则:
XposedHelpers.findAndHookMethod("com.example.demo.MortgageActivity", loadPackageParam.classLoader,
"showLoan", int.class, int.class, new XC_MethodHook() {
//……
});
需要注意new XC_MethodHook()有两个重要的内部函数beforeHookedMethod()和afterHookedMethod(),通过重写它们可以实现对任意方法的挂钩,它们的区别在于Hook前调用还是后调用。
我们还要借助param.setResult()方法来修改函数的返回值,在一些情况下,我们通过修改返回值可以绕过一些权限的检测或者对应用进行破解。
最终编写的Xposed模块源码如下:
package com.sy.xposedtest;
import android.util.Log;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class HookShowLoan implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable{
Log.i("package",loadPackageParam.packageName);
//判断当前加载的包,是否是我们关心的
if(loadPackageParam.packageName.equals("com.example.demo")){
XposedHelpers.findAndHookMethod("com.example.demo.MortgageActivity", loadPackageParam.classLoader,
"showLoan", new XC_MethodHook() {
//在Hook指定的方法之前调用此方法
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.i("before","beforeHookedMethod is start.");
super.beforeHookedMethod(param);
double total = 66.6;
param.setResult(total);
}
//在Hook指定的方法之后调用此方法
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//super.afterHookedMethod(param);
}
});
}
}
}
编译后在模拟器安装,Xposed可以直接检测出来,在模块里勾选,然后重启系统。不得不说,这也是Xposed一大缺陷,修改编译模块都需要重启系统,才能生效。
重启系统后,打开贷款APP,可以看到它已经被挂钩了。
查看日志,也可以看到确实进入了beforeHookedMethod()方法中。
源码下载:https://gitee.com/southwind0/xposedtest