上一篇《Xposed 插件开发之一: Xposed入门》

一、 Api说明

IXposedHookLoadPackage

加载回调接口,在xposed入口类继承,实现handleLoadPackage(XC_LoadPackage.LoadPackageParam) ,这个方法用于在打开app的时候回调,参数LoadPackageParam包含了加载的应用程序的一些基本信息。

IXposedHookInitPackageResources

加载回调接口,用于修改app的资源文件,在xposed入口类继承,实现handleInitPackageResources(InitPackageResourcesParam)方法,用于在加载应用程序的包的时候执行用户的操作 ,参数InitPackageResourcesParam包含了加载的应用程序的一些资源基本信息。

IXposedHookZygoteInit

加载回调接口,在xposed入口类继承,实现initZygote(IXposedHookZygoteInit.StartupParam) ,这个方法用于在开始hookApp的时候回调,参数StartupParam包含了模块app的路径。

XposedHelpers.java

Xposed功能辅助类,里面提供了一些辅助方法,简化连接和调用方法/构造函数,获取和设置字段,这里直说重要的方法

  • findAndHookMethod: hook类中的某个方法
    参数:
    className: 要hook的方法的所在类
    classloader: 要hook的包的classLoader,一般都写loadPackageParam.classLoader
    methodName: 要hook的方法
    parameterTypesAndCallback: 方法的参数和监听器。

  • callMethod: 在目标app中调用方法
    参数:
    Object: 要调用方法的所在类
    methodName: 要调用的方法名称
    args: 方法的参数

  • findClass: 获取class类实例
    参数:
    className: 类名
    classLoader: 类加载器

XposedBridge.java

  • log:在Xposed的app的日志功能里输出日志和/data/xposed/debug.log 这个文件中
    参数
    text: 要输出的内容

二、 Hook过程

Xposed 框架中真正起作用的是对方法的hook,hook到之后,在方法之前之后进行修改添加或者替换,那么寻找正确的目标方法名和所在的类名就很关键了。一般寻找目标方法有两种方法:

  • 开源的直接查看源码,主要是系统应用
  • 反编译查看源码,常见的有apkTool,jadx,jeb

1. Find

通过特定的类加载器加载要hook的类,通过反射找到被hook的成员。工具类XposedHelpers提供了一些工具方法来简化find过程;XposedBridge的hook*方法用于处理hook并执行回调。

XposedHelpers静态方法 描述
findClass 使用classLoader加载class
findField 通过反射查找类的数据成员并设置可访问性(setAccessible(true))
findMethod 通过反射查找类的成员函数并设置可访问性
findConstructor 通过反射查找类的构造函数并设置可访问性
setStatic 通过反射设置类静态变量的值
set 通过反射设置对象数据成员的值
findAndHook 查找并hook

2. Hook

XC_MethodHook中定义了回调方法:

  • beforeHookedMethod(MethodHookParam param):被hook方法调用前执行,调用param.setResult可以跳过被hook的方法。
  • afterHookedMethod(MethodHookParam param): 被hook方法调用后执行,调用param.setResult更改被hook方法的执行结果。
  • replaceHookedMethod: 继承自XC_MethodReplacement,能替换Hook的方法
  • XC_MethodReplacement: 继承自XC_MethodHook,通过在beforeHookedMethod中调用param.setResult实现了方法的替换。
@Override
protected final void beforeHookedMethod(MethodHookParam param) throws Throwable {try {Object result = replaceHookedMethod(param);param.setResult(result);} catch (Throwable t) {param.setThrowable(t);}
}

三、部分注意点和技巧

1. Hook内部类

通过美元符号 $ 连接内部类, 例如:

//获取ItemDecoration的类路径
String clsName = "androidx.recyclerview.widget.RecyclerView$ItemDecoration"

2. hook的方法

只能hook正常的方法,或者实现的方法或者构造方法,不能hook接口和抽象方法

3. context上下文获取

拿到之后可以用静态变量存放起来

try {Class<?> ContextClass = findClass("android.content.ContextWrapper", loadPackageParam.classLoader);findAndHookMethod(ContextClass, "getApplicationContext", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);Context applicationContext = (Context) param.getResult();XposedBridge.log("得到上下文");}});
} catch (Throwable t) {XposedBridge.log("获取上下文出错"+t);
}

4. 获取控件

例如获取一个EditText,上一篇文章的例子,获取TextView,修改字符。。打开被hook的app就会发现文本变成了"我是被Xposed修改的啦"

public class Main implements IXposedHookLoadPackage {@Overridepublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {findAndHookMethod("com.tpnet.companycalc.MainActivity",loadPackageParam.classLoader,"onCreate",Bundle.class,new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {//获取到当前hook的类,这里是MainActivityClass clazz = param.thisObject.getClass();XposedBridge.log("class name:" + clazz.getName());// 输入框不为私有private 可通过以下方式获取//Field field = clazz.getField("tvText");// 密码输入框对象变量名称// 通过反射获取控件,无论parivate或者publicField field = clazz.getDeclaredField("tvText");// 设置访问权限field.setAccessible(true);TextView textView = (TextView) field.get(param.thisObject);String string = textView.getText().toString();XposedBridge.log("原来的字符 : " + string);// 设置属性textView.setText("我是被Xposed修改的啦");}});}
}

5. 参数中有自定义类

通过反射获得得到自定义类

Class<?> hookMessageListenerClass = null;hookMessageListenerClass = lpparam.classLoader.loadClass("org.jivesoftware.smack.MessageListener");findAndHookMethod("org.jivesoftware.smack.ChatManager", lpparam.classLoader, "createChat", String.class , hookMessageListenerClass ,new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {String sendTo = (String) param.args[0];}@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);}
});

6. hook 构造方法

XposedBridge类里面的findAndHookConstructor方法

7.打开Activity

Activity activity = (Activity) param.thisObject;
Intent intent  = new Intent();
intent.setClassName(activity,"com.ushaqi.zhuishushenqi.ui.home.HomeActivity");
activity.startActivity(intent);

8. 自定义接口的处理

当你想调用宿主app里面的一个方法,方法的参数是一个接口,接口不能new的,这时候应该怎么办? 使用Proxy.newProxyInstance

/**
* 生成接口实例
* @param loader 类加载器
* @param interface 接口的Class实例
* @param h 接口回调
* /
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

Xposed 插件开发之二: Xposed的一些知识相关推荐

  1. [Android开发] Xposed 插件开发之三: 编写广告去除插件

    上一篇<Xposed 插件开发之二: Xposed的一些知识> 一. 准备 要去广告的app: 追杀神器3.75 反编译工具: AndroidKiller1.3.1 查看布局工具: UIA ...

  2. Xposed Xposed插件开发

    Xposed插件开发 简单介绍 Xposed,大名鼎鼎得Xposed,是Android平台上最负盛名的一个框架.在这个框架下,我们可以加载很多插件App,这些插件App可以直接或间接操纵系统层面的东西 ...

  3. [免费专栏] Android安全之Android Xposed插件开发,小白都能看得懂的教程

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  4. Xposed插件开发

    Xposed插件开发(一)简单demo xposed下载地址:http://repo.xposed.info/module/de.robv.android.xposed.installer xpose ...

  5. Xposed插件开发手册(1): Xposed框架的安装

    前言 之前我写了一篇文章<定制ROM采坑之路(2):魔趣OS刷入小米5A手机过程详解>,在进行成功刷机后,我尝试将Xposed框架安装到我新刷的系统中了.因为我这里的操作是基于魔趣OS的, ...

  6. Xposed插件开发手册(2):Xposed插件开发入门

    前言 在上一篇文章<Xposed插件开发手册(1): Xposed框架的安装>,我们学习到了Xposed的安装,这篇文章我们就来做一个简单的Xposed模块,劫持我们写的App,整篇文章我 ...

  7. Idea插件开发(二)——插件的创建打包及发布

    Idea插件开发(一)--插件的分类及基础认识 Idea插件开发(二)--插件的创建打包及发布 Idea插件开发(三)--插件JSL的完整开发过程 上一篇简单介绍了插件的基本知识,接下来直接上手开发, ...

  8. android8 检测xposed,Xposed检测与自定义Xposed

    Xposed检测与自定义Xposed 前言: Xposed检测 1.遍历App安装列表检测 2.自造异常检测堆栈信息. 3.检查关键Java方法是否变为native方法 4.反射XposedHelpe ...

  9. Xposed源码剖析——Xposed初始化

    承接上文 http://blog.csdn.net/yzzst/article/details/47829657 之前我们看过了app_main.cpp源码,知道了在其中,启动了XposedBridg ...

最新文章

  1. 揭秘@爱可可:“寂寞呆子”成长记
  2. java有不过_不过而而
  3. 省内转学出错的解决办法
  4. SpringBoot随笔
  5. python实现基于八方向判断的断裂连接
  6. Vue多个组件映射到同一个组件,页面不刷新?
  7. git status清空_本地删除文件后,git status会显示红色的那个文件。
  8. es6 Reflect对象的静态方法
  9. cortex a7 a53_西昊人体工学椅A7开箱测评
  10. C#.NET验证码智能识别学习笔记---03#.Net中@符号的意思
  11. JQuery------jQuery.parseHTML()的使用方法
  12. SpringHttpInvoker解析3-客户端实现
  13. CMMI认证是什么,级别分类有哪些?
  14. 通俗易懂物联网(11):物联网解决方案设计
  15. java 获取剪切板文件_如何在Java程序中读写系统剪切板的数据
  16. ai杀手级_设计师的10个杀手级Adobe Photoshop技巧
  17. html 灯箱效果样式,jQuery灯箱效果插件-Swipebox
  18. MATLAB clc clear
  19. 12C新特性--Application Continuity
  20. PTA习题【python】 6-8 jmu-python-发牌

热门文章

  1. 这10句诗,满满都是“江湖气”!
  2. AI产业链的划分,主要可分为基础层、技术层和应用层
  3. Python之——获取电脑连接过的所有wifi名称和密码
  4. 突然就看懂了《大话西游》
  5. 有人说“星座对自己的运势预测和性格描述很准”。请谈读你的看法。 “星座热”的社会学解读
  6. 2022苏州市人力资源服务业四项评比结果公布,盖雅榜上有名
  7. Parabola 抛物线-简单公式实现
  8. 【电脑自动关机】开机后Mysql再也启动不起来了。问题解决
  9. 总结:阿里云学生服务器地址/条件/续费等问题及解答FAQ
  10. 拼多多销售数据分析主要包含哪些方面的数据?