Xposed框架开发入门(二)--使用Xposed框架实现Activity跳转拦截
2017-04-12 23:38
316 查看
接着上一篇Xposed框架入门开发(一)继续,在上一篇中已经说了,第二篇主要介绍的是Xposed框架开发的基础的应用。在接下来的文章中,主要以一个Activity的跳转APP为例, 示范Xposed框架的基本使用方法。
效果如下:
新建两个Activity:Layout1Activity和Layout2Activity,直接在onCreate()的setContentView设置layout1和layout2。
在activity_main.xml中设置两个button,通过这两个button分别跳转到activity1和activity2。
效果如下:
此时在MainActivity中设置对应的点击事件。这里先新建一个util包,在其下新建一个ButtonListener.java类,该类实现了OnClickListener接口,重写了onClick方法,用来设置点击事件,代码如下:
这个类非常重要,因为我们接下来的跳转拦截时就是对点击事件进行hook,修改目标activity的参数,达到跳转到我们设置的activity中,从而实现跳转拦截。
然后在MainActivity.java中设置点击事件,代码如下:
OK,到这里我们Activity跳转的应用就完成了,运行程序,结果如下:
可以看到点击“跳转Activity_01”后跳转到Activity_01,点击“跳转Activity_02”后跳转到Activity_02.
同时最终项目目录结构如下:
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元素:
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核心代码的编写。
项目的目录结构如下,所有需要改动的地方都在图中标识出。
可以发现,其跳转的目标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方法的定义:
可以看到它的参数列表为:
所以,我们的Hook函数如下:
其中,使用if(loadPackageParam.packageName.equals(“com.zhayh.xposeddemo”))来找到要hook的应用,然后使用XposedHelpers.findAndHookConstructor进行hook。
添加Hook具体代码,代码逻辑为:
具体代码为:
其中,由于在进行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。
将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框架在实际应用中的使用。
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框架在实际应用中的使用。
相关文章推荐
- 使用gazebo实现turtlebot入门级开发
- 一步一步使用Unity3d工具实现AR开发入门
- Androidk开发入门之使用AIDL实现进程通信
- eclipse插件开发入门——使用command实现在资源管理器中定位资源
- JAVAWEB开发之mybatis详解(一)——mybatis的入门(实现增删改查操作)、自定义别名、抽取代码块以及动态SQL的使用
- JAVAWEB开发之mybatis详解(一)——mybatis的入门(实现增删改查操作)、自定义别名、抽取代码块以及动态SQL的使用
- Android开发-如何在Window使用AndroidStudio开发工具实现JNI的开发—入门教程
- nutch安装,使用,二次开发入门 ( by quqi99 )
- Eclipse入门—使用指南及开发Eclipse插件
- 70-316 使用Microsoft Visual C# .NET and Microsoft Visual Studio .NET 开发及实现基于Windows的应用程序 考点整理
- 使用DriverStudio开发WDM设备驱动程序入门
- FleaPHP 开发指南 - 8. 如何使用 RBAC 组件实现访问控制
- [J2EE从入门到精通第4讲]使用Struts开发Web应用程序(上)
- Eclipse入门—使用指南及开发Eclipse插件
- 使用DriverStudio开发WDM设备驱动程序入门
- 使用MapX开发实现若干小功能
- 项目开发技巧(四):使用JspSmartupload实现文件上传下载(一):JspSmart之upload组件源码及使用
- J2ME技术入门之二——J2ME开发环境的安装和使用
- 使用C#开发SmartPhone程序入门
- 新手入门:J2ME开发环境的安装和使用