教你三分钟写个Xposed模块

1,222 阅读2分钟
原文链接: mp.weixin.qq.com

了解Android开发的同学可能听说过Xposed,它的强大可以说是只有你想不到的,没有它做不到的功能。举个例子,它可以修改系统的IMEI,手机号,甚至可以说可以让一台小米手机完全变成一台OPPO。

原理

要知道Xposed是怎么做到的,首先要知道它的原理。它是通过Hook API,替换掉原本的实现逻辑或者数据,来实现自己想要的方法。

看一段代码

XposedHelpers.findAndHookMethod(TelephonyManager.class.getName(), lpparam.classLoader, "getDeviceId", new XC_MethodHook() {    @Override    protected void afterHookedMethod(MethodHookParam param) throws Throwable {        XposedBridge.log("[afterHookedMethod] IMEI");        param.setResult("12345");        super.afterHookedMethod(param);    }});

上面这段代码,把系统 TelephonyManager的 getDeviceId方法所返回的值,改成了 12345,这样我们指定的 app调用 getDeviceId的话,就只能拿到 12345了。

实现

实现很简单,我们只需要定义一个入口类,比如叫 MainHook.java,然后让它实现 IXposedHookLoadPackage接口就可以。

public class MainHook implements IXposedHookLoadPackage{    @Override    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {    ....    }

回调方法 handleLoadPackage会在系统每个app启动的时候回调一下,这时候就给了我们Hook的机会。我们只需要判断 lpparam是否是我们的目标 app,就可以替换任何我们想要的方法。

一个完整的 Hook入口类demo差不多是这样的

public class MainHook implements IXposedHookLoadPackage{    @Override    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {    if(!lpparam.packageName.equals("target.package")){        return;    }    XposedHelpers.findAndHookMethod(TelephonyManager.class.getName(), lpparam.classLoader, "getDeviceId", new XC_MethodHook() {        @Override        protected void afterHookedMethod(MethodHookParam param) throws Throwable {            XposedBridge.log("[afterHookedMethod] IMEI");            param.setResult("12345");            super.afterHookedMethod(param);        }    });    }

上面这个demo,就实现了Hook target.package 这个包名的app的 getDeviceId方法,从而返回我们设定的 12345.