1. Xposed插件Hello World

  • 新建工程:MyXposed
  • 引入xposed:
provided 'de.robv.android.xposed:api:82'
provided 'de.robv.android.xposed:api:82:sources'

​官方链接​

  • 修改AndroidManifest
    在AndroidManifest中修改如下:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<!-- 应用为模块 -->
<meta-data
android:name="xposedmodule"
android:value="true" />

<!-- 版本信息 -->
<meta-data
android:name="xposedminversion"
android:value="82" />

<!-- 模块描述 -->
<meta-data
android:name="xposeddescription"
android:value="Xposed Test" />
</application>
  • 新建xpose_init

新建assets文件夹,并在该文件夹中新建xposed_init文件,在文件中添加启动的main:

com.jared.myxposed.Main
  • 新建Main

在对应的包名下新建Main类,添加代码如下:

class Main : IXposedHookLoadPackage {
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
XposedBridge.log("Main: " + lpparam?.packageName)
XposedBridge.log("Hook已经成功了")
}
}

这里打印了包名。

  • 编译安装

因为android studio运行需要MainActivity,所以在工程下命令行运行

./gradlew app:assembleDebug

virtualxposed下安装MyXposed,安装完成如下:


Android开发学习之路--XPosed插件开发_sed

打开一个virtualxposed下的一个apk,然后可以查看下日志,发现已经有了我们加上的log信息


Android开发学习之路--XPosed插件开发_java_02

至此,最简单的xposed插件已经开发完成了,我们就可以hook我们需要hook的东西了。

2. Xposed的一些类的介绍

  • IXposedHookLoadPackage.java

加载回调接口,在xposed入口类继承,实现handleLoadPackage方法。

handleLoadPackage

用于在加载应用程序的包的时候执行用户的操作

LoadPackageParam loadPackageParam

包含了加载的应用程序的一些基本信息

  • IXposedHookInitPackageResources.java

加载回调接口,用于修改app的资源文件,在xposed入口类继承,实现handleInitPackageResources(InitPackageResourcesParam resparam)方法

handleInitPackageResources

用于在加载应用程序的包的时候执行用户的操作

InitPackageResourcesParam resparam

包含了加载的应用程序的一些资源基本信息

  • XposedHelpers.java

一些辅助方法,简化连接和调用方法/构造函数,获取和设置字段

findAndHookMethod

hook一个类中的方法

className

要hook的方法的所在类

classloader

要hook的包的classLoader,一般都写loadPackageParam.classLoader

methodName

要hook的方法

parameterTypesAndCallback

方法的参数和监听器

callMethod

在目标app中调用方法

Object

要调用方法的所在类

methodName

要调用的方法名称

args

方法的参数

findClass

获取class类实例

className

类名

classLoader

类加载器

  • XposedBridge.java

log

在Xposed的app的日志功能里输出日志

text

要输出的内容

  • XC_MethodHook中定义了回调方法:

3. Hook掉加固后的ApkTest的点击

  • 承接反编译

首页显示如下:


Android开发学习之路--XPosed插件开发_java_03

通过上一篇文章,我们已经反编译了加固的ApkTest,得知其中的“Hello, I am ApkTest”是通过方法showStr来获取的。button点击是通过gotoSecondActivity方法来跳转的,接下来我们分别来hook这两个方法。

  • hook显示内容

现在我们来hook下这个方法的内容。按照要求我们如下操作:

XposedHelpers.findAndHookMethod(hookclass, "showStr",
object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
val result = "你被劫持了哦!!!!"
param?.result = result
}
})

但是运行后发现根本找不到类,因为是加固的apk,所以我们需要先hook application后再去hook对应的类和方法,修改代码如下:

XposedHelpers.findAndHookMethod(
Application::class.java,
"attach",
Context::class.java,
object : XC_MethodHook() {
@Throws(Throwable::class)
override fun afterHookedMethod(param: MethodHookParam?) {
val cl = (param!!.args[0] as Context).classLoader
var hookclass: Class<*>? = null
try {
hookclass = cl.loadClass("com.jared.apktest.MainActivity")
} catch (e: Exception) {
Log.e("MyXposed", "寻找com.jared.apktest.MainActivity报错", e)
return
}

Log.i("MyXposed", "寻找com.jared.apktest.MainActivity成功")
XposedHelpers.findAndHookMethod(hookclass, "showStr",
object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
val result = "你被劫持了哦!!!!"
param?.result = result
}
})
}
})

然后我们编译安装后,就可以去查看对应的效果了:


Android开发学习之路--XPosed插件开发_sed_04

很明显我们成功了,显示内容被更改了,变成我们需要的内容

  • hook按钮点击
    既然有了前一步的铺垫,那么这里就十分简单了,我们直接hook掉
    gotoSecondActivity方法,在方法执行后谈一个吐司,表示我们已经hook成功了,代码如下:
XposedHelpers.findAndHookMethod(
Application::class.java,
"attach",
Context::class.java,
object : XC_MethodHook() {
@Throws(Throwable::class)
override fun afterHookedMethod(param: MethodHookParam?) {
val cl = (param!!.args[0] as Context).classLoader
var hookclass: Class<*>? = null
try {
hookclass = cl.loadClass("com.jared.apktest.MainActivity")
} catch (e: Exception) {
Log.e("MyXposed", "寻找com.jared.apktest.MainActivity报错", e)
return
}

Log.i("MyXposed", "寻找com.jared.apktest.MainActivity成功")
XposedHelpers.findAndHookMethod(hookclass, "gotoSecondActivity",
object : XC_MethodHook() {

override fun afterHookedMethod(param: MethodHookParam?) {
super.afterHookedMethod(param)
param?.thisObject?.let {
Toast.makeText(it as Context, "你被劫持了哦!!!!", Toast.LENGTH_SHORT).show()
}
}
})
}
})

再安装看下效果:


Android开发学习之路--XPosed插件开发_android_05

已经得到了我们需要的答案,至此,简单的xposed插件开发也完成了,我们在不修改原有apk的一行代码,就能控制原有apk,当然一些登录啊,vip啊都可以通过这个来实现,还有些比如支付宝的能量收取,微信的抢红包也都有类似的插件。不过我们主要是为了学习技术,可不能用在非法的事情上,要不然迟早一天251等着你!

详细代码看这里: ​​MyXposed​

关于Android的加固,脱壳反编译以及xposed插件学习也就告一小段落,之后Android安全方向的学习还有很远很远的路。比如:基础算法和安全协议;Android系统结构深入分析,自定义 ClassLoader,自定义注解和元注解原理分析;Android 漏洞分析和挖掘;虚拟机技术、系统源码分析、刷机机制介绍、制作ROM刷机包等等。