300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > xposed框架定位模块_Xposed模块开发基本方法记录

xposed框架定位模块_Xposed模块开发基本方法记录

时间:2021-08-01 06:36:11

相关推荐

xposed框架定位模块_Xposed模块开发基本方法记录

由于某些课程实验的要求,需要通过xposed框架对某应用进行hook操作,笔者选用了开源且免费的xposed框架进行实现。虽然网上存在一些利用xposed实现特定功能的文章资源,但大多均将xposed模块的构建作为一个小节内容一笔带过,而且介绍的内容随着考虑的因素、使用的编辑环境不同也大有区别,使得笔者在实际构建过程中往往提心吊胆,出现了错误也不知道如何去改正。故而这里特将笔者最近摸索和学习到的简单xposed构建的知识记录,以供查阅和参考。

Xposed 框架

想要使用Xposed模块实现特定的功能,必须依赖Xposed框架,正如 apk 的运行需要Android系统提供支持一样,Xposed模块任务的完成也离不开Xposed框架的支持,Xposed框架提供了Xposed模块运行所必需的环境和功能接口,同时也可以对系统上已安装的模块进行禁用、卸载等管理。故而在想通过Xposed模块完成一定任务之前,必须安装Xposed框架。

注意:由于Xposed框架安装时需要将系统文件夹/system/bin的部分文件进行替换和备份,故而手机需要具备root权限。

Xposed 模块

下面以Android Studio 3.0.1为例,总结下简单的Xposed模块的编写所需的配置和注意事项。

项目创建

Xposed模块实际上是作为一种较为特殊的apk安装在系统上,由于Xposed 模块的功能通常借助于其他应用和系统资源实现,其一般没有应用界面,故而创建一个没有活动的项目即可。

A.在Android Studio中,点击 file -> new -> new project 进行新项目的创建。指定应用名称、公司域名、存储位置和包名等信息,这里需要注意应用名和包名这两个名字;

B.勾选 Phone and Tablet 选项,选择该 Xposed 模块( 实际就是apk)将要运行的 Android 环境所对应的 API。注意这里的API指定的是Android环境与apk之间交互的接口,只有该API与之后apk实际运行的Android环境相匹配,apk才能正确的安装和运行。如笔者的 Xposed 模块将要运行在 Android 4.4上,则应该选择 Android 4.4 对应的API 19.

C.在接下来的界面中,选择“ add no activity ”即不添加活动( Xposed 模块不需要活动 ),即可完成项目的创建。

项目配置

Xposed模块被视为一种特殊的apk,故而在创建项目之外,还需要针对其进行 Xposed 模块相关的配置。

A. 切换目录结构。点击界面左上方的竖式 Project,展开项目界面,将项目结构从 Android 切换至 Project 模式,方便之后的编辑;

B.添加 Xposed API依赖。Xposed 模块的功能借助 Xposed 框架实现,Xposed 模块通过对应的 Xposed 框架 API 来使用 Xposed 框架提供的功能。想要使用 Xposed 框架 API,则必须提供对应的库( 名为 XposedBridge API jar)的路径等信息。(以下信息来自 Using the Xposed Framework API )

*针对 Android Studio

Android Studio 中使用gradle进行项目的构建,故而想要使用 Xposed 框架 API 对应的库,则需要在 gradle 的配置文件中进行指定。在 应用名(test) -> app -> build.gradle 中加入以下内容:

1 repositories {//通常新项目的 build.gradle 中不包含有repositories块,直接在空白处增加1-3行即可

2 jcenter(); }3

4 dependencies {//通常 build.gradle 文件中已包含dependncies块,所以只需将第6行的内容添加进已有的 dependencies 中即可

5 provided 'de.robv.android.xposed:api:53'

6 provided 'de.robv.android.xposed:api:53:sources' //该行是可选的,用于下载API相关的文档等信息

7 }

其中,第2行表示将 jcenter 作为代码仓库,可在上面引用开源项目,而第 6 行则指定引用项目的项目名和版本信息。

第6行的声明需要注意两点:

a) 使用 provided 关键字而不是 compile,后者会将引用的 Xposed 框架 API 类打包至生成的 apk 中,而这些类在安装好的 Xposed 框架中是已经存在的,所以可能会产生冲突,而 provided 关键字则仅保留对 API 的引用,实现具体功能的类则由安装好的 Xposed 框架提供;

b)使用系统对应的 Xposed 框架 api 版本,不同的 Xposed 框架 API 在不同的 Android 环境中发挥作用。如Android 4.x 环境则只能选择 API 53。

*针对 eclipse

eclipse 环境下无法通过指定 jcenter 中的开源项目来实现对其的引用,所以必须在实际的项目中手动添加所需引用的库文件 XposedBridge API jar 的路径,在这里手动下载所需的 API 版本,将其复制到项目的文件夹下( 注意不要放置在项目本身已经有的 lib / libs 文件夹下,原因与Android Studio环境下使用 provided 而不是 compile 一致),选中 jar 包 右键 -> Build Path -> add to build path 即可。

C.Android Studio 环境下需要禁用 Instant run 。在 File -> Settings -> Build, Execution, Deployment -> Instant Run 中取消其勾选,否则源程序中的类会由一个 stub 应用加载,而不是直接包含在 apk 文件中,而 Xposed 框架目前无法处理这样的情况。

D.修改 AndroidManifest.xml 文件中的属性。在 应用名(test) -> app -> src -> main 文件夹中找到 AndroidManifest.xml,修改其中的属性,使得我们最终生成的 apk 能够被 Xposed 框架识别。请保证最终文件的部分内容为以下格式。

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" > //App相关的信息

android:name="xposedmodule" //标志该 apk 为一个 Xposed 模块,供 Xposed 框架识别

android:value="true" />

android:name="xposedminversion"android:value="53" /> //xposed最小版本号,请与(2)步中选用的api版本保持一致

android:name="xposeddescription"android:value="hook a function" /> //针对该模块的描述,会在Xposed框架的模块管理界面中显示出来,便于模块管理

完成上述步骤后,则可将项目文件打包成 apk ( Android Studio 下打包 apk 的简单步骤可以参见这里),并在手机中安装。安装成功后,在 Xposed 框架的模块管理界面会出现该模块对应的管理项,证明对 Xposed 模块的配置是成功的。勾选对应的模块,并重启设备,重启之后该模块则开始发挥功能。当然目前我们并没有实现任何功能。

简单示例

在完成 Xposed 框架的配置后可在该项目中进行框架功能的编写。在应用名(test) -> app -> src -> main -> java 目录下,可以看到 Android Studio 已经自动根据我们在创建项目时指定的包名生成了一个包( package )的条目,如笔者项目中的包名为 xposed.test(见创建项目时的界面截图),选中该包右键 -> new -> java ->class ,创建自己的一个 class ,如 test.class 。用户可在该 class 中实现简单的xposed hook功能。

( 以下部分不涉及具体的实现原理,仅提供函数的简单功能的描述,更多关于Xposed 框架API的功能可在这里查看)

一个 Xposed 模块可以有多个不同的入口,其中实现的方法既可以在 Android 系统启动时被调用,也可在一个应用程序包被加载时被调用,想要在不同的时期被调用,则该功能类需要实现不同的接口。

Xposed公共接口package:de.robv.android.xposed.IXposedHookZygoteInit

interface :IXposedHookZygoteInit//在Android系统启动时被调用,作用于初始的zygote进程,可用于实现应用于所有应用的hook

package:de.robv.android.xposed.IXposedHookLoadPackage

interface:IXposedHookLoadPackage//当指定应用被加载时被调用,一般用于hook特定应用的方法

package:de.robv.android.xposed.IXposedHookInitPackageResources

interface:IXposedHookInitPackageResources//指定应用的资源进行初始化时被调用,一般用于资源的替换

以实现 IXposedHookLoadPackage 接口的模块为例,实现一个简单的hook功能。

通常使用 findAndHookMethod 方法来定位待 hook 的类中的方法(官方解释在这里)

findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback)className:被hook的方法所在类的完整名称,包括 包名 + 类名classLoader:可通过 lpparam.classLoader 获得methodName:被hook的方法的名,注意如有混淆,则应该用混淆后的名字object... 与为被hook的方法的参数对应Callback :指定该方法被调用时,需要被执行的回调

例如,想要hook如下代码,即hook包 com.test.example 中的类 a 下的 b 方法

packagecom.test.examplepublic classa{public int b(String s, inti, MyClass m)

{}

}

则对应的 findAndHookMethod方法应该写作

findAndHookMethod("com.test.example.a", lpparam.classLoader,"b", String.class, int.class, "com.test.example.MyClass", newXC_MethodHook() {

@Overrideprotected void beforeHookedMethod(MethodHookParam param) throwsThrowable {dosomthing

}

});

这里需要注意:

(1)对于待hook函数中的java自带类型的参数,如 int 和 String,则应使用 int.class 和 String.class作为findAndHookMethod的参数

(2)若待Hook函数中包含有形如 MyClass 这样的自定义类型的参数,则直接使用该类型的完整路径名即可,如 "com.test.example.MyClass"

在 findAndHookMethod方法的参数中,直接定义了一个 XC_MethodHook 回调,其中一般有两个方法可供使用者重新定义。

@Overrideprotected void beforeHookedMethod(MethodHookParam param) throwsThrowable {//该方法在被hook函数之前被调用

}

@Overrideprotected void afterHookedMethod(MethodHookParam param) throwsThrowable {//该方法在被hook函数之后被调用

}

以下代码实现了微信的一个日志函数的简单 hook 。

1 package xposed.xposed_wechat_log;//实现的类所在的包

2

3 import android.util.Log;//系统提供的Log方法的包

4 import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;//findAndHookMethod方法所在的包

5 importde.robv.android.xposed.IXposedHookLoadPackage;6 importde.robv.android.xposed.XC_MethodHook;7 importde.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;8

9 public class test implements IXposedHookLoadPackage {//test类实现了IXposedHookLoadPackage接口

10 @Override11 public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {//handleLoadPackage 在任意包被加载时被调用,参数lpparam,包含有加载的 app 的信息

12 if ( lpparam.packageName.equals("com.tencent.mm")) { //可通过 lpparam 中包含的包信息对包进行筛选,如这里表示 com.tencent.mm 包加载时,才执行下一步操作

13 findAndHookMethod("com.tencent.mm.sdk.platformtools.x",lpparam.classLoader, "d" , String.class, String.class, Object[].class,14 newXC_MethodHook() {15 @Override16 protected void beforeHookedMethod(MethodHookParam param) throwsThrowable {17 String str0 = (String) param.args[0];//可通过 param.args[i]获得 hook 方法的参数

18 String str1 = (String) param.args[1];19 Object[] obj2= (Object[]) param.args[2];20 String str = obj2 == null ?str1 : String.format(str1, obj2);21

22 if( str==null)23 str = "";24

25 Log.e( "Xposed_hook_d"+str0,str);26 super.beforeHookedMethod(param);27 }28 });29 }30 }31 }

simple_hook

完成上述模块功能的编写后,需在 应用名(test) -> app -> src -> main 目录下新建一个 assets 目录,并在该目录下建立一个名为 exposed_init 的文本文件。该文件中记录模块中所有实现了Xposed 功能接口的类的完整路径名,每一行书只写一个这样的路径。

如在上述实例模块中,test 类实现了接口 IXposedHookLoadPackage,则 exposed_init 文件中应该有以下内容:

xposed.test.test//其中 xposed.test 为包名,test为实现接口的类名

所有实现了 Xposed 接口的类均要在该文件中记录,以供 Xposed 框架进行处理。

之后即可打包完成的项目,将其安装至设备上进行验证了。

参考资料:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。