工具 Xposed框架
本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.youkuaiyun.com/Rozol/article/details/79779660
- Xposed框架是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务
- 官网(需要翻墙):
http://repo.xposed.info
- 国内第三方网站:
http://xposed.appkg.com
(有广告)http://www.xposed.pro
- 使用该框架手机需要root (也有不root的版本), 该框架还挑手机 (小心强撸灰飞烟灭)
- XposedInstaller-v2.6.1.jar : Android2.3
- XposedInstaller-v2.6.1st.jar : Android4.0.3
- XposedInstaller-v3.0_alpha4.jar : Android5.0/5.1/6.0
- XposedInstaller-v3.1.5.jar : Android7.0/7.1/8.x
- 作者系统:
- Win10
- Android4.4.2
- AndroidStudio2.2
安装
-
- 将apk安装到手机
-
- 点击框架 -> 框架[安装/更新]
-
- 给root权限后, 安装, 并重启
编写模块 (AndroidStudio)
1.
api下载:https://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067
2.
创建项目3.
添加jar包- 把下载的jar包放到
app/lib
目录下 build.gradle引入
dependencies { // ... provided fileTree(dir: 'lib', include: ['XposedBridgeApi-54.jar']) }
- 把下载的jar包放到
4.
编写代码- 创建 类 实现
implements IXposedHookLoadPackage
接口 (其他代码放到 编写代码 里讲)
public class Hook implements IXposedHookLoadPackage { private final String packageName = "me.luzhuo.xposeddemo"; @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { // 系统加载的应用包名, 可以用于过滤 if(!packageName.equals(loadPackageParam.packageName)) return; // 使用 XposedHelpers 类实现拦截操作 } }
- 创建 类 实现
5.
编写xposed_init
- 在
/app/src/main/assets
目录下创建文件xposed_init
- 编写模块入口(全类名):
me.luzhuo.xposeddemo.Hook
- 在
6.
编写清单文件(去掉//注释)<application ... > // 将Android作为Xposed中的一个模块 <meta-data android:name="xposedmodule" android:value="true"/> // 模块描述 <meta-data android:name="xposeddescription" android:value="X测试"/> // xposed的jar包最低版本号 <meta-data android:name="xposedminversion" android:value="54"/> <activity> ... </activity> </application>
7.
安装应用到手机8.
手机打开Xposed Installer
- 选择
模块
, 把自己刚安装的模块给√上
- 选择
9.
重启手机 (每次修改完代码安装到手机时后, 都要重启)
编写代码
Bean类
public class Person { private String name = "pname"; private int age = 11; public void setName(String name){ this.name = name; } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public int getAge(){ return this.age; } }
测试的MainActivity
android:text="修改数值" public void value(View view){ Person person = new Person(); person.setName("abc"); person.setAge(21); Log.i(TAG, "person-name: " + person.getName()); Log.i(TAG, "person-age: " + person.getAge()); }
修改设置数值
代码 (放在
handleLoadPackage
回调里)// 使用 XposedHelpers 类实现拦截操作 // public void setName(String name) hook_method("me.luzhuo.xposeddemo.bean.Person", "setName", loadPackageParam, String.class, new XC_MethodHook() { /** * 拦截之前 */ @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); // 获取传入的参数值 Log.i(TAG, "before-setname: " + param.args[0]); // 修改传入的参数值 param.args[0] = "before-hookname"; } }); // public int getAge() hook_method("me.luzhuo.xposeddemo.bean.Person", "getAge", loadPackageParam, new XC_MethodHook() { /** * 拦截之后 */ @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { super.afterHookedMethod(param); // 获取返回结果的值 Log.i(TAG, "after-getage: " + param.getResult()); // 修改返回结果的值 param.setResult(123); } });
打印
// 修改设置值 要在拦截之前 //I/Hook: before-setname: abc //I/MainActivity: person-name: before-hookname // 修改返回值 要在拦截之后 //I/Hook: after-getage: 21 //I/MainActivity: person-age: 321
通过上述打印, 可知两个方法的值都已被修改, 大家可能会发现
XposedHelpers
类哪去了, 拿去重新封装了/** * hook操作 * @param className 期望被hoot的全类名 * @param methodName 期望被hoot的方法名 * @param parameterTypesAndCallback 参数类型 和 hoot回调 */ private void hook_method(String className, String methodName, XC_LoadPackage.LoadPackageParam loadPackageParam, Object... parameterTypesAndCallback){ try{ // 根据hoot类的名称寻找方法 XposedHelpers.findAndHookMethod(className, loadPackageParam.classLoader, methodName, parameterTypesAndCallback); }catch (Exception e){ XposedBridge.log(e); } }