前言
最近在整个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/目录呢,虽然也要授权,但是有可能某些应用根本没有这个权限~虽然,方法烂了点,但终归是实现了!