xposed hook java_[原创]Android Hook 系列教程(一) Xposed Hook 原理分析

章节内容

一. Android Hook 系列教程(一) Xposed Hook 原理分析

二. Android Hook 系列教程(二) 自己写APK实现Hook Java层函数

三. Android Hook 系列教程(三) Cydia Hook Native 原理分析

四. Android Hook 系列教程(四) 自己写APK实现Hook Native层函数

五. Android Hook 系列教程(五) 更多Hook方法

六. Andoird Hook 系列教程(六) Hook的总结

源代码下载

Java层:https://github.com/rovo89/XposedBridge

Native层:https://github.com/rovo89/Xposed

开始

一个好的开始等于成功了一半.

为了分析Xposed Hook是怎么实现的,选取了findAndHookMethod函数作为研究对象.

在分析过程中,我们应该做到有详有略,我将以关键代码(略过对分析目的无关紧要的部分,留下必须部分).

当然在关键代码后面会贴出全部代码以供参照.

Jave层分析

findAndHookMethod

从源代码:XposedHelpers.java处找到findAndHookMethod

findAndHookMethod关键代码

public static XC_MethodHook.Unhook findAndHookMethod(Class> clazz, String methodName, Object... parameterTypesAndCallback) {

...

XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];//获取回调函数

Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));//获取Method

return XposedBridge.hookMethod(m, callback);

}

public static XC_MethodHook.Unhook findAndHookMethod(Class> clazz, String methodName, Object... parameterTypesAndCallback) {

if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook))

throw new IllegalArgumentException("no callback defined");

XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];//获取回调函数

Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));//获取Method

return XposedBridge.hookMethod(m, callback);

}

上面的代码都很容易懂,简单说一下几个函数

getParameterClasses

功能:把函数所有参数转换为Class>数组返回.

比如参数列表为

String.class,int.class,"java.util.Map",回调函数

返回结果相当于

Class> []={

String.class,

int.class,

Map.class

};

findMethodExact

功能:根据方法名和方法参数类获取Method

关键代码:

public static Method findMethodExact(Class> clazz, String methodName, Class>... parameterTypes) {

...

Method method = clazz.getDeclaredMethod(methodName, parameterTypes);//获取方法声明

method.setAccessible(true);

methodCache.put(fullMethodName, method);

return method;

}

完整代码:

public static Method findMethodExact(Class> clazz, String methodName, Class>... parameterTypes) {

String fullMethodName = clazz.getName() + '#' + methodName + getParametersString(parameterTypes) + "#exact";

if (methodCache.containsKey(fullMethodName)) {

Method method = methodCache.get(fullMethodName);

if (method == null)

throw new NoSuchMethodError(fullMethodName);

return method;

}

try {

Method method = clazz.getDeclaredMethod(methodName, parameterTypes);//获取方法声明

method.setAccessible(true);

methodCache.put(fullMethodName, method);

return method;

} catch (NoSuchMethodException e) {

methodCache.put(fullMethodName, null);

throw new NoSuchMethodError(fullMethodName);

}

}

让我们继续跟进hookMethod

hookMethod

功能:把方法的参数类型,返回类型,回调函数记录到AdditionalHookInfo类里

并通过hookMethodNative方法进入Native层进行Hook.

在这个方法里面差不多都是关键代码,也就不省略,全部贴出.

​ 完整代码:

public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_MethodHook callback) {

/*检测是否是支持的Method类型*/

if (!(hookMethod instanceof Method) && !(hookMethod instanceof Constructor>)) {

throw new IllegalArgumentException("Only methods and constructors can be hooked: " + hookMethod.toString());

} else if (hookMethod.getDeclaringClass().isInterface()) {

throw new IllegalArgumentException("Cannot hook interfaces: " + hookMethod.toString());

} else if (Modifier.isAbstract(hookMethod.getModifiers())) {

throw new IllegalArgumentException("Cannot hook abstract methods: " + hookMethod.toString());

}

boolean newMethod = false;

CopyOnWriteSortedSet callbacks;

synchronized (sHookedMethodCallbacks) {

callbacks = sHookedMethodCallbacks.get(hookMethod);

if (callbacks == null) {//如果为null则函数没有被Hook,否则已经Hook

callbacks = new CopyOnWriteSortedSet<>();

sHookedMethodCallbacks.put(hookMethod, callbacks);

newMethod = true;

}

}

callbacks.add(callback);//记录回调函数

if (newMethod) {//建立新Hook

Class> declaringClass = hookMethod.getDeclaringClass();//获取类声明

int slot;

Class>[] parameterTypes;

Class> returnType;

if (runtime == RUNTIME_ART) {//判断是否是ART模式

slot = 0;

parameterTypes 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值