您的位置:首页 > 移动开发 > Android开发

Xposed框架开发入门(二)--使用Xposed框架实现Activity跳转拦截

2017-04-12 23:38 316 查看
接着上一篇Xposed框架入门开发(一)继续,在上一篇中已经说了,第二篇主要介绍的是Xposed框架开发的基础的应用。在接下来的文章中,主要以一个Activity的跳转APP为例, 示范Xposed框架的基本使用方法。

1、编写一个简单的Activity跳转的应用

在Android Studio中建立工程XposedDemo,在app中添加两个Activity。首先新建在layout中新建layout1.xml和layout2.xml,向每个layout中添加一个TextView,标明其对应的activity。如下为layout1.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zhayh.xposeddemo.Layout1Activity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_01"
android:text="Activity_01"
android:textSize="40sp"
android:layout_centerInParent="true"/>

</RelativeLayout>


效果如下:



新建两个Activity:Layout1Activity和Layout2Activity,直接在onCreate()的setContentView设置layout1和layout2。

在activity_main.xml中设置两个button,通过这两个button分别跳转到activity1和activity2。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.zhayh.xposeddemo.MainActivity">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_01"
android:text="跳转Activity_01"
android:layout_centerInParent="true"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_02"
android:text="跳转Activity_02"
android:layout_below="@id/btn_01"
android:layout_centerHorizontal="true"/>

</RelativeLayout>


效果如下:



此时在MainActivity中设置对应的点击事件。这里先新建一个util包,在其下新建一个ButtonListener.java类,该类实现了OnClickListener接口,重写了onClick方法,用来设置点击事件,代码如下:

public class ButtonListener implements View.OnClickListener {
private Context context = null;
private Class deste_activity_class = null;

public ButtonListener(Context context,Class dest_activity_class) {
this.context = context;
this.deste_activity_class = dest_activity_class;
}

@Override
public void onClick(View v) {
Intent intent = new Intent(context,deste_activity_class);
context.startActivity(intent);
}
}


这个类非常重要,因为我们接下来的跳转拦截时就是对点击事件进行hook,修改目标activity的参数,达到跳转到我们设置的activity中,从而实现跳转拦截。

然后在MainActivity.java中设置点击事件,代码如下:

public class MainActivity extends Activity {
private Button btn_01 = null;
private Button btn_02 = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btn_01 = (Button) findViewById(R.id.btn_01);
btn_02 = (Button) findViewById(R.id.btn_02);

btn_01.setOnClickListener(new ButtonListener(MainActivity.this,Layout1Activity.class));
btn_02.setOnClickListener(new ButtonListener(MainActivity.this,Layout2Activity.class));
}
}


OK,到这里我们Activity跳转的应用就完成了,运行程序,结果如下:



可以看到点击“跳转Activity_01”后跳转到Activity_01,点击“跳转Activity_02”后跳转到Activity_02.

同时最终项目目录结构如下:



2、Xposed模块基本配置

1、新建Xposed模块项目,在XposedDemo中New Module为“hookjump”,选择Add No Activity(我们这里的Xposed模块不需要Activity),完成项目创建。



2、在Module中创建一个lib文件夹,然后将下载好的XposedBridgeApi.jar(我这里为XposedBridgeApi-54.jar)拷贝到该目录下,然后右键“Add As Library…” 。

这里特别注意是新建一个lib文件夹而不是直接放到工程中已经建立好的libs文件夹,否则不会hook成功。

3、在build.gradle中将在dependencies下自动生成的compile files(‘lib/XposedBridgeApi-54.jar’)改为provided files(‘lib/XposedBridgeApi-54.jar’)



4、在AndroidManifest.xml中添加meta-data元素:

<!--添加标识-->
<meta-data
android:name="xposedmodule"
android:value="true"/>
<!--在Xposed框架模块中的描述信息-->
<meta-data
android:name="xposeddescription"
android:value="Hook Activity Jump Method"/>
<!--导入jar的最低版本-->
<meta-data
android:name="xposedminversion"
android:value="54"/>


5、新建主类Main,该类实现了IXposedHookLoadPackage接口,重写了public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {}方法。我们的Hook的主要操作就是在该方法中进行的。如下所示:



6、在main目录下建立一个assets文件夹,然后在assets中新建xposed_init文件,向其中写入包名+类名,如:



该文件是Xposed模块的入口,其中声明的“packagename+主类”便是声明需要加载到XposedInstaller 的入口类。

到此时一个Xposed模块基本框架就完成了,接下来要进行的就是Hook核心代码的编写。

项目的目录结构如下,所有需要改动的地方都在图中标识出。



3、寻找Hook点,Hook实现Activity跳转拦截

在对一个项目进行hook时,我们首先得知道我们要hook的点是哪里,然后才能进行接下来的操作。首先我们对app进行分析,可以发现点击跳转按钮时会进行Activity间的跳转,那么控制Activity跳转的代码肯定在Button 的点击事件中,对跳转按钮的点击事件进行分析:





可以发现,其跳转的目标Activity便在自定义的OnClickListene的构造方法的第二个参数这里设置 。所以只要在Activity跳转时Hook ButtonListener类的构造方法,将其dest_activity_class改为其他的activity的class便可以实现跳转拦截。

我们这里演示使用hook将两个button的目标activity互换,即点击“跳转Activity_01”后跳转到Activity_02,点击“跳转Activity_02”后跳转到Activity_01.

所以需要在Main方法中找到ButtonListener的构造方法对其进行hook,修改相应的参数。我们这里使用XposeHelper类的findAndHookConstructor方法来hook ButtonListener类的构造方法,从而修改dest_activity_class.

首先点进XposeHelper中查看findAndHookConstructor方法的定义:



可以看到它的参数列表为:

/**
*1、String className:要hook的类的全限定名
*2、ClassLoader classloader:当前的ClassLoader
*3、Object... parameterTypesAndCallback:要hook的构造方法的参数列表
*/


所以,我们的Hook函数如下:



其中,使用if(loadPackageParam.packageName.equals(“com.zhayh.xposeddemo”))来找到要hook的应用,然后使用XposedHelpers.findAndHookConstructor进行hook。

添加Hook具体代码,代码逻辑为:

if(dest_activity_class == Activity_01.class){
dest_activity_class = Activity_02.class
}else if(dest_activity_class == Activity_02.class){
dest_activity_class = Activity_01.class
}else{
error
}


具体代码为:



其中,由于在进行dest_activity_class = Activity_01(2)_calss时,需要将新的Activity的Class传给param.args[1],所以首先应该找到新Activity的Class。对于找到一个只知道类名的类的Class,需要使用XposedHelpers类的findClass(String className,ClassLoader classloader)方法来找到对应的Class。

OK,到这里整个Hook模块便已经编写完毕。运行程序,激活模块后重启,打开原app,运行效果如下:



可以看到成功运行后点击“跳转Activity_01”后实际跳转到了Activity_02,点击“跳转Activity_02”后实际跳转到了Activity_01.

同时,DDMS中的Log输出如下:



可以看到我们已经成功的拦截到了原app的Activity的跳转,同时将目标Activity改为新的Activity。

总结

在这片文章中,主要介绍了Xposed模块开发的基本步骤(5个主要步骤):

将XposedBridgeApi.jar导入到目录下,同时Add As Library…

修改build.gradle,将compile改为provided

在AndroidManifest.xml中添加meta-data元素

新建主类,实现IXposedHookLoadPackage接口,重写handleLoadPackage方法

在main目录下新建assets文件夹,然后在assets中新建xposed_init文件,写入packagename+主类

然后又通过hook一个activity跳转的应用,示例了使用Xposed进行hook的基本用法。

最后给出项目代码的Github地址:https://github.com/zyh16143998882/XposedDemo

在下一篇文章中将会带来“Android某狗输入法用户个人词库的提取”,来示范Xposed框架在实际应用中的使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息