Xposed模块编写

Xposed模块编写

简介

Xpose模块原理是部署在ROOT后的安卓手机上,通过替换/system/bin/app_process程序来控制zygote进程,使得app_process在启动过程中加载XposedBridge.jar包,从而对zygote进程以及其创建的Dalvik虚拟机的劫持。可以使得在不修改apk源码的情况下,通过自己编写的模块来影响程序运行的框架服务,例如自动抢红包、微信消息自动回复等功能

Xposed模块与其他Android程序不同的区别如下

1
2
3
4
1.让手机的xposed框架知道该程序为xposed模块
2.xposed模块需要包含由xposed的api的jar包,以实现hook操作
3.该模块中需要有对目标程序进行Hook操作的方法
4.手机上的xposed框架知道该xposed模块中的哪一个方法实现H

需要准备的工具如下

1
2
3
4
1、androidManifest.xml
2、XposedBridgeApi-xx.jar和build.gradle
3、实现hook操作的具体代码
4、xposed_init

编写AndroidManifest.xml

新建项目并将其设置为Project模式,然后将AndroidManifest.xml修改添加xposed模块信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<meta-data

android:name="xposedmodule"

android:value="true" />

<meta-data

android:name="xposeddescription"

android:value="这是一个Xposed demo" />

<meta-data

android:name="xposedminversion"

android:value="89" />

添加如下所示

运行该项目后在xpose模块中可以看到该模块,说明xposed框架已认出我们写的程序。

引入XposedBridgeApi.jar

xposed模块主要是用来hook其他程序的各种程序,该包就是使得模块具有该模块具有这本事。

下载对应xposed版本的xposedapi-xx.jar包放入项目的app/libs文件夹下,然后右键”Add As Library”自行添加jar包

实现hook操作

我们先编写个简单的hook代码,在日志中记录下加载app的名字,在logcat中输出,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.myapplication;


import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class HookDemo implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {

XposedBridge.log("Loaded app: " + lpparam.packageName);

}
}

添加入口点

添加入口点是告诉XposedBridge的hook入口在哪里,在app/src/main文件夹下创建assets文件夹,在其下创建文件xposed_init,该文件每行包含一个class的全限定名

重启手机使得模块生效,可以在日志中看到我们自定义的字符串信息

案例

修改MainActivity代码,生成个按钮点击显示”这是一条信息?”字符串,MainActivity.java程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private Button button;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(MainActivity.this, toastMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String toastMessage() {
return "这是一条信息?";
}
}

设置该程序的页面设计效果,在/app/src/res文件夹下新建layout文件夹,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="1dp"
android:layout_marginBottom="90dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintEnd_toEndOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

程序运行后效果如下

接下来我们编写xposed模块,实现对这个弹窗内容的修改,在MainActivity.java同目录下新建HookDemo类,来实现toastMessage函数的返回值,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mport de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

public class HookDemo implements IXposedHookLoadPackage {
public void handleLoadPackage(LoadPackageParam loadPackageParam) throws Throwable {
if (loadPackageParam.packageName.equals("com.example.myapplication")) {
Class clazz;
clazz = loadPackageParam.classLoader.loadClass(
"com.example.myapplication.MainActivity");
XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
param.setResult("你已被劫持");
}
});
}

}
}

由代码可知,我们是通过IXposedHookLoadPackage接口中的handleLoadPackage方法来实现Hook并篡改程序的输出结果的。代码中“com.example.myapplication ”是目标程序的包名,”com.example.myapplication.MainActivity” 是想要Hook的类, “toastMessage”是想要Hook的方法。我们在afterHookedMethod方法(用来定义Hook了目标方法之后的操作)中,修改了toastMessage()方法的返回值为“你已被劫持”。

接下来添加xposed入口点,在main文件夹下新建assets文件夹,且在其下新建txt文档xposed_init,每行代表一个Hook类

将其安装到手机中,在xposed框架上找到并打上勾,重启后观察是否弹窗提示信息已经变了

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021-2024 John Doe
  • 访问人数: | 浏览次数:

让我给大家分享喜悦吧!

微信