前言
最近在整个frida-server持久化的插件,顺便学习了下Xposed插件的开发。
导入Xposed的api库
app/build.gradle
dependencies {
compileOnly 'de.robv.android.xposed:api:82'
}
注意点:不能改成implementation,否则无法正确排除 Xposed API 类,从而导致它们被打包进 APK,这样的话模块就不生效了,官方文档显示要 provided,但已被废弃,也不能使用!
更新settings.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven { url 'https://api.xposed.info/' }
}
}
修改AndroidManifest.xml文件
在Application标签里面加4个meta-data
<!-- 是否是xposed模块,xposed根据这个来判断是否是模块 -->
<meta-data
android:name="xposedmodule"
android:value="true" />
<!-- 模块描述,显示在xposed模块列表那里第二行 -->
<meta-data
android:name="xposeddescription"
android:value="测试Xposed模块" />
<!-- 最低xposed版本号(lib文件名可知) -->
<meta-data
android:name="xposedminversion"
android:value="30" />
<!-- 模块作用域 -->
<meta-data
android:name="xposedscope"
android:resource="@array/xposedscope"/>
创建模块作用域文件
在res/values目录下新建arrays.xml
<resources>
<string-array name="xposedscope" >
<!-- 模块的作用域应用的包名,一行一个 -->
<item>com.daowuya.nb</item>
</string-array>
</resources>
在包名文件夹下新建模块入口类
- 包名文件夹:com.daowuya.hookall
- 模块入口类:XposedEntry
package com.daowuya.hookall;
import android.util.Log;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class XposedEntry implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
// 仅在 Xposed 环境下运行时加载 MainHook
Log.d("XposedEntry","模块被加载了");
MainHook.initXposedHooks(lpparam);
}
}
PS:由于怕Xposed环境和Java环境冲突,我把两个环境分开了
编写具体的HOOK实现代码
在包名文件夹下新建MainHook,新建函数initXposedHooks,此时将功能都写在这里头就行了
package com.daowuya.hookall;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class MainHook {
public static void initXposedHooks(final XC_LoadPackage.LoadPackageParam lpparam) {
}
}
创建xposed_init文件
在main目录下创建assets目录,在assets目录下创建xposed_init文件,不要后缀名。这个就是模块的入口,将上面入口类的完整路径填进去就行了
com.daowuya.hookall.XposedEntry
Hook模板
我在github上fork了个,有兴趣的初学者可以在这个demo上开发
点击跳转:XposedProjectTemplate
关于模块界面数据与Xposed的hook代码的交互
这个问题我尝试了两天了,最终想了个解决方式。
首先说明下前后来由:
- 在MainHook类里定义了全局变量,这个变量用于存储界面数据
- 在Xposed可以访问这个全局变量
- 但是不足点就是,这个变量在hook外区域被修改后,在hook区域内不生效,依旧是原始的值
- 查了多方面的资料,发现由于是Xposed环境与java环境不通,并且不同应用之间虽然都被hook,但是变量的修改也都不互通
后面我就想了个法子,用shell去读取/data/local/tmp/文件不就得了,只是要给被hook的应用授权root罢了~
那为啥不读取/sdcard/目录呢,虽然也要授权,但是有可能某些应用根本没有这个权限~虽然,方法烂了点,但终归是实现了!