Xposed学习-常用方法介绍
XposedHelpers提供的一些API方法
findAndHookMethod(Class<?> clazz, String methodName, Object… parameterTypesAndCallback)
这个方法是你需要hook某个方法用到,填入的参数分别是:1、方法所在的类,2、类加载器(classload),3、方法名,4、方法中的参数类型,5、回调对象。
/**
* 参数一: 该方法所在类的路径
* 参数二:classload
* 参数三:方法命
* 参数四:该方法中传入的参数类型(有多少个参数就写多少个)
* 最后一个参数是回调
*
* 例中方法 setTextMsg(String str),所在类是com.qin.sendmsgplugins.hook.MainActivity中
*/
XposedHelpers.findAndHookMethod("com.qin.sendmsgplugins.hook.MainActivity", loadPackageParam.classLoader, "setTextMsg", String.class, new XC_MethodHook() {
/**
*该方法hook目标方法执行前回调,意思就是在setTextMsg执行之前 回调,其中,参数param指的是目标方法的相关参数、回调、方法等信息。
* @param param
* @throws Throwable
*/
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
//修改这个方法的输出值,有两个方法可以实现
// 1 : 直接修改传入的值
param.args[0] = "此方法已经被我hook,str的值修改成功";
// 2 : 修改该方法的返回值
param.setResult("此方法已经被我hook,str的值修改成功");
// 得到调用该方法的对象
Object boject = param.thisObject;
}
/**
* 该方法是在hook目标方法执行前回调,意思就是在setTextMsg执行之后 回调,其中,参数param指的是目标方法的相关参数、回调、方法等信息。
* @param param
* @throws Throwable
*/
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
在对调的方法中返回的是MethodHookParam对象参数,该对象中包含了原始方法传入的参数存在了args[]数组中,通过param.args[]来取得,对象中还包含了hook的方法的返回值,通过param.getResult()取得,还有一个比较值得关注的是thisObject 通过这个参数得到的是调用该hook方法的对象。
findAndHookConstructor(Class<?> clazz, String methodName, Object… parameterTypesAndCallback)
这个方法同findAndHookMethod相同,都是hook方法,唯一的区别是这个方法是hook构造方法。
findClass(String className,ClassLoader classLoader):
该方法是用来获取class实例,传入的参数依次是:类名(完整路径名)、类加载器。
Class clazz = XposedHelpers.findClass("com.text.xxx",loadPackageParam.classLoader);
callMethod(Object obj, String methodName, Object… args) 调用指定的方法,填入的参数依次是:方法所在的class实例、方法名、需要传递进去的参数。
// 获取class 实例
Class clazz = XposedHelpers.findClass("com.text.xxx",loadPackageParam.classLoader);
// 调用实例中的 setTextMsg(String str) 方法
XposedHelpers.callMethod(clazz,"setTextMsg","传递进去的string参数");
newInstance(Class<?> clazz, Object… args) 构造对象,填入的参数依次是:class实例、构造对象所需要的参数
// 获取class 实例
Class clazz = XposedHelpers.findClass("com.text.xxx",loadPackageParam.classLoader);
// 构造对象
Object object = XposedHelpers.newInstance(clazz,123);
XposedHelpers中还提供通过反射获取/设置类中的成员的值的方法:
setXXXField(Object obj, String fieldName, Object value)
getXXXField(Object obj, String fieldName)
// 获取class 实例
Class clazz = XposedHelpers.findClass("com.text.xxx",loadPackageParam.classLoader);
// 设置类中 String str = "hello"的值
XposedHelpers.setObjectField(clazz,"str","你好");
// 获取类中 String str = "hello"的值
XposedHelpers.getObjectField(clazz,"str");
基本上常用的api就上面介绍这些,有缺漏的后面在补足。
hook中值得注意的事项
1:在hook某个APP时候,经常能遇到内部类,常规的hook一个类的写法是findclass(“com.xxx.a.b”,classload),例如在b类中存在一个内部类c,如果想要hook这个类拿到它的实例需要通过$符号链接内部类:
// 获取class 实例
Class clazz = XposedHelpers.findClass("com.xxx.a.b$c",classLoader);
2:XPOSED 不能够hook接口和抽象方法、如果是动态加载的代码也是不能够hook的。
3:写在hook模块代码和本身应用个人理解是不在同一个进程中的,虽然说是写在同一个项目中但其实是两个部分,比如说一个状态值boolean b = false,通过按钮改变了他的状态 b = true,但是当你在hook模块中获取这个状态值得到的是b = false,所以本应用如果需要跟hook模块部分进行通讯只能是通过: 文件、数据库、SharedPreferences 还可以通过在hook模块入口动态注册一个广播,通过发送广播形式也是可以传递数据。
小结
本篇大概介绍了hook中常用到的api和一些需要注意事项,下一篇打算讲讲在hook中一些实用的工具和方法,能够帮助我们快速找到hook点。