Xposed Hook小demo

2,165 阅读1分钟

刷入Xposed的流程就不讲了. 网上到处是, 这里只说代码上怎么实现

1. 新建一个Android项目

没有啥好说的

2. AndroidManfiest修改

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.plbear.xposeddemo">

    <application
        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">
        <!-- 是否是xposed模块,xposed根据这个来判断是否是模块 -->
        <meta-data
            android:name="xposedmodule"
            android:value="true" />

        <!-- 模块描述,显示在xposed模块列表那里第二行 -->
        <meta-data
            android:name="xposeddescription"
            android:value="XposedDemo" />

        <!-- 最低xposed版本号(lib文件名可知) -->
        <meta-data
            android:name="xposedminversion"
            android:value="54" />
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

3. 增加HookMain文件

package com.plbear.xposeddemo

import android.util.Log
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

/**
 * created by yanyongjun on 2020-03-31
 */
class HookMain : IXposedHookLoadPackage {
    companion object {
        var classLoader: ClassLoader? = null
    }

    override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
        if (lpparam == null) return
        if (lpparam.packageName != "com.plbear.hookdemo") return
        classLoader = lpparam.classLoader
        val clz = XposedHelpers.findClass("com.plbear.hookdemo.MainActivity", classLoader)
        XposedBridge.hookAllMethods(clz, "cal", object : XC_MethodHook() {
            override fun afterHookedMethod(param: MethodHookParam?) {
                super.afterHookedMethod(param)
                Log.e("yanlog", param?.result.toString())
            }

            override fun beforeHookedMethod(param: MethodHookParam?) {
                param?.args?.forEach {
                    Log.e("yanlog", it.toString())
                }
                super.beforeHookedMethod(param)
            }
        })
    }
}

注意这里只是一个简单的实现, 后面可以更抽象一下

增加xposed_init文件

增加一个assests目录, 里面新建一个xposed_init文件, 内容是

com.plbear.xposeddemo.HookMain

到这里, 我们在Xposed中激活模块后, 重启就可以了.

主动调用App代码

            val mainClazz = XposedHelpers.findClass("com.plbear.hookdemo.MainActivity", HookMain.classLoader)
            val mainActivity = mainClazz.newInstance()
            val result = XposedHelpers.callMethod(mainActivity, "cal", 1, 2)
            Log.e("yanlog", result.toString())

这里有一个坑要注意, Hook的代码并不在UI进程中, 所以, 如果上面主动调用放在UI进程中调用, 会不成功的.