通过jadx-gui 打开 demo APP,查看代码,进行xposed Hook Api 实验
Xposed Hook Api 笔记 Api说明 1.IXposedHookLoadPackage.java 加载回调接口,在xposed入口类继承,实现handleLoadPackage方法
handleLoadPackage (XC_LoadPackage.LoadPackageParam loadPackageParam) 这个方法用于在加载应用程序的包的时候执行用户的操作 参数: LoadPackageParam loadPackageParam: 这个参数包含了加载的应用程序的一些基本信息
2.IXposedHookInitPackageResources.java 加载回调接口,用于修改app的资源文件,在xposed入口类继承,实现handleInitPackageResources(InitPackageResourcesParam resparam)方法
handleInitPackageResources (InitPackageResourcesParam resparam) 这个方法用于在加载应用程序的包的时候执行用户的操作参数: InitPackageResourcesParam resparam: 这个参数包含了加载的应用程序的一些资源基本信息
3.XposedHelpers.java 一些辅助方法,简化连接和调用方法/构造函数,获取和设置字段,这里直说重要的方法
findAndHookMethod (String className, ClassLoader classLoader, String methodName, Object… parameterTypesAndCallback) hook一个类中的方法参数: className: 要hook的方法的所在类 classloader: 要hook的包的classLoader,一般都写loadPackageParam.classLoader methodName: 要hook的方法 parameterTypesAndCallback: 方法的参数和监听器。
callMethod (Object obj, String methodName, Object… args) 在目标app中调用方法 参数: Object: 要调用方法的所在类 methodName: 要调用的方法名称 args: 方法的参数
findClass (String className, ClassLoader classLoader) 获取class类实例参数: className: 类名 classLoader: 类加载器
4.XposedBridge.java
log (String text) 在Xposed的app的日志功能里输出日志和/data/xposed/debug.log 这个文件中参数: text: 要输出的内容
导入库 1 2 3 4 5 6 7 8 9 10 11 12 13 package com.example.testxp;import android.util.Log;import java.security.PublicKey;import java.util.Map;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.LoadPackageParam;
构造函数 通过特定的类加载器加载要hook的类,通过反射找到被hook的成员。工具类XposedHelpers提供了一些工具方法来简化find过程;XposedBridge的hook*方法用于处理hook并执行回调。
XposedHelpers静态方法
描述
findClass
使用classLoader加载class
findField*
通过反射查找类的数据成员并设置可访问性(setAccessible(true))
findMethod*
通过反射查找类的成员函数并设置可访问性
findConstructor*
通过反射查找类的构造函数并设置可访问性
setStatic*
通过反射设置类静态变量的值
set*
通过反射设置对象数据成员的值
findAndHook*
查找并hook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Hello implements IXposedHookLoadPackage { public void handleLoadPackage (final LoadPackageParam lpparam) throws Throwable { Log.d("KeyboArd" , "hook..." ); if (lpparam.packageName.equals("com.xiaojianbang.xposeddemo" )){ final Class clazz = XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo" ,lpparam.classLoader); XposedHelpers.setStaticIntField(clazz,"staticInt" ,10000 ); XposedHelpers.setStaticObjectField(clazz,"Tag" ,"KeyboArd" ); XposedHelpers.findAndHookConstructor(clazz,new XC_MethodHook(){ public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"无参构造函数前" ); } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"无参构造函数后" ); } }); XposedHelpers.findAndHookConstructor(clazz, String.class, new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { param.args[0 ]= "Wrpzkb" ; } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"有参构造函数后" ); } });
Throwable基本方法
getMessage()
•获取异常信息,返回字符串。
toString()
•获取异常类名和异常信息,返回字符串。
printStackTrace()
•获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
printStackTrace(PrintStream s)
•通常用该方法将异常内容保存在日志文件中,以便查阅。
throws和throw
throws
•用在方法声明后面,跟的是异常类名
•可以跟多个异常类名,用逗号隔开
•表示抛出异常,由该方法的调用者来处理
•throws表示出现异常的一种可能性,并不一定会发生这些异常
java
中字符串也算对象,所以要用equals
来比较字符串。
这里首先判断包名是否等于com.xiaojianbang.xposeddemo
,findclass
搜索类,通过classLoader
加载class,通过反射设置修改staticint
的值和Tag
的字符串。
1 2 3 4 if (lpparam.packageName.equals("com.xiaojianbang.xposeddemo" )){ final Class clazz = XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo" ,lpparam.classLoader); XposedHelpers.setStaticIntField(clazz,"staticInt" ,10000 ); XposedHelpers.setStaticObjectField(clazz,"Tag" ,"KeyboArd" );
XC_MethodHook
回调方法:
beforeHookedMethod
(MethodHookParam param):被hook方法调用前执行,调用param.setResult可以跳过被hook的方法。afterHookedMethod
(MethodHookParam param): 被hook方法调用后执行,调用param.setResult更改被hook方法的执行结果。replaceHookedMethod
继承自XC_MethodReplacement,能替换Hook的方法
MethodHookParam param
回调参数:
对于回调过来的参数MethodHookParam param
一般有以下2种用处: 1.param.args[0]:得到被拦截方法的第一个参数,返回值是Object 2.param.getResult():得到被拦截方法的执行结果,返回值是Object
Constructor
构造的意思
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 XposedHelpers.findAndHookConstructor(clazz,new XC_MethodHook(){ public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"无参构造函数前" ); } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"无参构造函数后" ); } }); XposedHelpers.findAndHookConstructor(clazz, String.class, new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { param.args[0 ]= "Wrpzkb" ; } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"有参构造函数后" ); } });
生成软件,看下输出的值。
Hook 函数 findAndHookMethod
有两种,一种是传入类的字节码,要HOOK的方法名,和方法列表和一个回调函数,有三个… 说明是可变参数。
1 2 3 public static Unhook findAndHookMethod (Class<?> clazz, String methodName, Object... parameterTypesAndCallback) { throw new RuntimeException("Stub!" ); }
一种是传入类名字符串,类加载器,方法名和方法列表和一个回调函数
1 2 3 public static Unhook findAndHookMethod (String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) { throw new RuntimeException("Stub!" ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 XposedHelpers.findAndHookMethod(clazz, "publicFunc" , String.class, new XC_MethodHook(){ public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"" +param.args[0 ]); Log.d("KeyboArd" ,"publicFunc is hooked before" ); } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"" +param.getResult()); Log.d("KeyboArd" ,"public is hooked after" ); } });
要被Hook的函数:
多参数函数Hook Class.forName
要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。并返回与该类相关的Class对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 XposedHelpers.findAndHookMethod(clazz, "complexParameterFunc" , "java.lang.String" , "[[Ljava.land.String;" , Map.class, Class.forName("java.util.ArrayList" ), new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"complexParameterFunc is hooked before1" ); } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"complexParamterFunc is hooked after1" ); } });
另一种写法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 XposedHelpers.findAndHookMethod(clazz, "complexParameterFunc" , String.class, String[][].class, Map.class, ArrayList.class, new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"complexParameterFunc is hooked before1" ); } public void afterHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"complexParamterFunc is hooked after1" ); } });
其他类Hook
1 2 3 4 5 6 7 8 9 10 Class cls = Class.forName("com.xiaojianbang.xposeddemo.Animal" ,true ,lpparam.classLoader); XposedHelpers.findAndHookMethod(clazz, "Inner" , cls, String.class, new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"这是自定义类参数的Hook Class.forName1" ); } });
另一种写法 1 2 3 4 5 6 7 8 9 10 final Class cls = XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Animal" ,lpparam.classLoader); XposedHelpers.findAndHookMethod(clazz, "Inner" , cls, String.class, new XC_MethodHook() { public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"这是自定义类参数的Hook Class.forName1" ); } });
替换 1 2 3 4 5 6 XposedHelpers.findAndHookMethod(clazz, "replaceFunc" , new XC_MethodReplacement() { public Object replaceHookedMethod (MethodHookParam methodHookParam) throws Throwable { Log.d("KeyboArd" ,"这是替换之后的输出" ); return null ; } });
内部类 getIntField
获取字段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 XposedHelpers.findAndHookMethod( XposedHelpers.findClass("com.xiaojianbang.xposeddemo.Demo$InnerClass" , lpparam.classLoader), "innerFunc" , String.class, new XC_MethodHook(){ public void beforeHookedMethod (MethodHookParam param) throws Throwable { Log.d("KeyboArd" ,"qian" ); XposedHelpers.callMethod(clazz.newInstance(),"refl" ); Log.d("KeyboArd" ,"hou" ); int aa = XposedHelpers.getIntField(param.thisObject,"innerPublicInt" ); StringBuilder sb = new StringBuilder(); Log.d("KeyboArd" ,"" +aa); } });
结尾 Xposed 的API学习到此结束🔚
准备上班,做检疫人员,唉,又要去面对jiangxi人了,看见就烦,每天都十万个为什么。
为什么给你看身份证
为什么给你看出入证
为什么要戴口罩
为什么要给你看车尾箱
真是牛逼。
想知道这么多为什么,就多读点书。garbage人