5.1 插件编写

编写 Lposed 插件可以使用 AndroidStudio 也可以使用 Idle, 前提是你的 Idle 有安装安卓组件,本文使用 Idle 进行讲解,默认你已经安装好了 Lposed 框架,如果没有安装好,可以自行百度进行安装!

创建项目

首先创建一个 Android 项目

需要选择 AndroidEmpty Activity

点击下一步,配置好包名等一些信息后点击创建

创建好之后可以看到项目结构如下:

声明模块

进入到 app/src/main/AndroidManifest.xml下按照图示位置输入以下代码

<!--        声明这是一个 Xposed 模块-->
<meta-data
        android:name="xposedmodule"
        android:value="true"/>

<!--        这个是 Xposed 模块的显示信息-->
<meta-data
        android:name="xposeddescription"
        android:value="这是一个Xposed例程"/>

<!--        这个是 Xposed 小版本-->
<meta-data
        android:name="xposedminversion"
        android:value="53"/>

安装依赖

进入到 app/libs 目录下, 将 Lsposedjar 包放置进去

进入到 app/build.gradle 文件下声明依赖编译

compileOnly files('libs/LSPosed-api-1.0-SNAPSHOT.jar')

编写案例

打开 app/src/main/res/layout/activity_main.xml 文件, 创建一个按钮

进入到 com/example/xposeddemo/MainActivity.kt 内粘贴以下代码:

package com.example.xposeddemo

import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {
    private var button: Button? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button = findViewById<View>(R.id.button) as Button
        button!!.setOnClickListener { Toast.makeText(this@MainActivity, toastMessage(), Toast.LENGTH_SHORT).show() }
    }

    fun toastMessage(): String {
        return "我未被劫持"
    }
}

上面的代码表示找到这个 button, 当点击 button 的时候就调用 toastMessage 方法弹出消息。然后运行 app 看看效果,前提是你要连上你的手机哦

发现 app 已经创建好了,当我们点击这个 button 的时候就会提示:我未被劫持

Hook

现在我们已经有了 app,所以我们可以编写代码进行劫持

首先创建一个类 com/example/xposeddemo/MyHook.java, 名字自己定

创建完毕之后我们需要继承 de.robv.android.xposed.IXposedHookLoadPackage 这个类,并且实现 handleLoadPackage 方法

package com.example.xposeddemo;

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

public class MyHook implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

    }
}

然后我们可以在 handleLoadPackage 这个方法里面进行 hook, 代码如下:

package com.example.xposeddemo;

import 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;

import java.util.Objects;

public class MyHook implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        //  先判断包名
        if (Objects.equals(loadPackageParam.packageName, "com.example.xposeddemo")) {
            XposedBridge.log("找到包名为: " + loadPackageParam.packageName + "应用了!, 准备进行 Hook");
            ClassLoader classLoader = loadPackageParam.classLoader;
            XposedBridge.log("获取当前 ClassLoader: " + classLoader.toString());

            Class<?> clazz = classLoader.loadClass("com.example.xposeddemo.MainActivity");
            XposedBridge.log("找到 MainActivity 这个类: " + clazz.toString());

            XposedHelpers.findAndHookMethod(clazz, "toastMessage", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam<?> param) throws Throwable {
                    XposedBridge.log("成功 Hook MainActivity 的  toastMessage 方法");
                    super.beforeHookedMethod(param);
                }

                @Override
                protected void afterHookedMethod(MethodHookParam<?> param) throws Throwable {
                    param.setResult("你已被劫持");
                }
            });


        }
    }
}

然后进入 main 目录下创建一个 assets 文件夹

在该文件夹下创建一个 xposed_init 文件,文件内写上你的 hook 类的引用地址

准备完毕,我们再次运行安装 app 到手机上,这个时候会发现提示模块未激活

去启用一下该模块,因为本文中 hook 的是自己,所以我就随便选一个 app了,自己在开发的时候可以选择响应的应用

可以看到该模块已经被启用了

此时我们重新打开我们的应用,点击按钮,发现输出结果已经变成我们 hook 的结果了:你已被劫持

看一下 Lsposed 里面发现我们打印的日志也输出了

补充

  • loadPackageParam 里面可以获取包名和 ClassLoader, 一般都会先用 if 进行过滤

  • 可以使用 classLoader.loadClass 加载类

  • hook 方法可以使用 XposedHelpers.findAndHookMethod, 第一个参数是类,第二是是方法名,第三个是回调函数 XC_MethodHook

  • 通过 param.setResult 可以设置方法返回值

最后更新于

这有帮助吗?