1. Xposed插件Hello World
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>
新建assets文件夹,并在该文件夹中新建xposed_init文件,在文件中添加启动的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,安装完成如下:
打开一个virtualxposed下的一个apk,然后可以查看下日志,发现已经有了我们加上的log信息
至此,最简单的xposed插件已经开发完成了,我们就可以hook我们需要hook的东西了。
2. Xposed的一些类的介绍
- IXposedHookLoadPackage.java
加载回调接口,在xposed入口类继承,实现handleLoadPackage方法。
handleLoadPackage
| 用于在加载应用程序的包的时候执行用户的操作
|
LoadPackageParam loadPackageParam
| 包含了加载的应用程序的一些基本信息
|
- IXposedHookInitPackageResources.java
加载回调接口,用于修改app的资源文件,在xposed入口类继承,实现handleInitPackageResources(InitPackageResourcesParam resparam)方法
handleInitPackageResources
| 用于在加载应用程序的包的时候执行用户的操作
|
InitPackageResourcesParam resparam
| 包含了加载的应用程序的一些资源基本信息
|
一些辅助方法,简化连接和调用方法/构造函数,获取和设置字段
findAndHookMethod
| hook一个类中的方法
|
className
| 要hook的方法的所在类
|
classloader
| 要hook的包的classLoader,一般都写loadPackageParam.classLoader
|
methodName
| 要hook的方法
|
parameterTypesAndCallback
| 方法的参数和监听器
|
callMethod
| 在目标app中调用方法
|
Object
| 要调用方法的所在类
|
methodName
| 要调用的方法名称
|
args
| 方法的参数
|
findClass
| 获取class类实例
|
className
| 类名
|
classLoader
| 类加载器
|
log
| 在Xposed的app的日志功能里输出日志
|
text
| 要输出的内容
|
3. Hook掉加固后的ApkTest的点击
首页显示如下:
通过上一篇文章,我们已经反编译了加固的ApkTest,得知其中的“Hello, I am ApkTest”是通过方法showStr来获取的。button点击是通过gotoSecondActivity方法来跳转的,接下来我们分别来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
}
})
}
})
然后我们编译安装后,就可以去查看对应的效果了:
很明显我们成功了,显示内容被更改了,变成我们需要的内容
- 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()
}
}
})
}
})
再安装看下效果:
已经得到了我们需要的答案,至此,简单的xposed插件开发也完成了,我们在不修改原有apk的一行代码,就能控制原有apk,当然一些登录啊,vip啊都可以通过这个来实现,还有些比如支付宝的能量收取,微信的抢红包也都有类似的插件。不过我们主要是为了学习技术,可不能用在非法的事情上,要不然迟早一天251等着你!
详细代码看这里: MyXposed
关于Android的加固,脱壳反编译以及xposed插件学习也就告一小段落,之后Android安全方向的学习还有很远很远的路。比如:基础算法和安全协议;Android系统结构深入分析,自定义 ClassLoader,自定义注解和元注解原理分析;Android 漏洞分析和挖掘;虚拟机技术、系统源码分析、刷机机制介绍、制作ROM刷机包等等。