感覺好久沒更新xposed教程了。應該有兩個月了,主要是工作太忙,沒有時間寫部落格。這節主要講解XposedHelpers類的一些用法,對前面內容有遺忘的可以再回過去預習下。
更多精彩內容可以關注我的部落格:www.wrbug.com
XposedHelpers類是幹嘛的?
在XposedHelpers類的頂部有一句註釋
/**
* Helpers that simplify hooking and calling methods/constructors, getting and settings fields, ...
*/
public final class XposedHelpers {
}複製程式碼
大概意思是可以hook活著呼叫方法/建構函式。獲取該類的欄位等。這裡需要用到反射的姿勢。不瞭解的可以先看看反射相關的。XposedHelpers提供了非常方便的或者這些引數的方法。
XposedHelpers方法說明
//className 完整類名,classLoader 類載入器(app應用的類載入器)
public static Class<?> findClass(String className, ClassLoader classLoader)
public static Class<?> findClassIfExists(String className, ClassLoader classLoader)複製程式碼
獲取class的方法。其中findclass方法在未找到時丟擲異常,findClassIfExists則返回null
// clazz 通過findClass獲取,呼叫findFieldRecursiveImpl獲取
public static Field findField(Class<?> clazz, String fieldName)
public static Field findFieldIfExists(Class<?> clazz, String fieldName)
private static Field findFieldRecursiveImpl(Class<?> clazz, String fieldName) throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
while (true) {
clazz = clazz.getSuperclass();
if (clazz == null || clazz.equals(Object.class))
break;
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException ignored) {}
}
throw e;
}
}
public static Field findFirstFieldByExactType(Class<?> clazz, Class<?> type)
//獲取例項欄位的引用
public static Object getObjectField(Object obj, String fieldName)複製程式碼
獲取Field的方法,具體實現是在findFieldRecursiveImpl方法裡面獲取,外部不能訪問,Field是通過getDeclaredField獲取,所以只能獲取static型別的欄位。indFirstFieldByExactType()方法是匹配Field的classType,如果型別一樣,則返回該欄位,該方法的侷限性是隻能獲取到第一個匹配到的欄位,後面相同型別的無法獲取
public static Method findMethodExact(Class<?> clazz, String methodName, Object... parameterTypes)
public static Method findMethodExactIfExists(Class<?> clazz, String methodName, Object... parameterTypes)複製程式碼
獲取Method方法,還有些其他的方法這裡省略,也只能獲取靜態方法
public static Constructor<?> findConstructorExact(Class<?> clazz, Object... parameterTypes)
public static Constructor<?> findConstructorExactIfExists(Class<?> clazz, Object... parameterTypes)
public static Constructor<?> findConstructorBestMatch(Class<?> clazz, Class<?>... parameterTypes)複製程式碼
獲取Constructor方法,其中Object… parameterTypes 是一個Object的可變陣列,parameterTypes由Class<?>的可變陣列 ,完整類名字串和XC_MethodHook抽象類 組成。XC_MethodHook為可選引數,並且總在最後一個。XC_MethodHook在這裡並無實際意義,Class<?>[] 為相應的建構函式的型別,通過一個例子簡單說明,有一個T類,建構函式有三個引數,可以用以下幾種方式獲取:
public class T {
String str;
Context mContext;
View mView;
public T(String str, Context context, View view) {
this.str = str;
mContext = context;
mView = view;
}
}
//方式1:
Constructor constructor = XposedHelpers.findConstructorExact(clazz, String.class, Context.class, View.class);
//方式2:
Constructor constructor = XposedHelpers.findConstructorExact(T.class, String.class, "android.content.Context", View.class);
//方式3:(XC_MethodHook無實際意義)
Constructor constructor = XposedHelpers.findConstructorExact(T.class, String.class, "android.content.Context", View.class, new XC_MethodHook() {});複製程式碼
public static void setXXXField(Object obj, String fieldName, XXX value)
public static void setStaticXXXField(Class<?> clazz, String fieldName, XXX value)
public static Xxx getXxxField(Object obj, String fieldName)
public static Xxx getStaticXxxField(Class<?> clazzj, String fieldName)複製程式碼
設定或者獲取Field的值,obj為例項,則為設定或者獲取該成員變數的值
public static Object callMethod(Object obj, String methodName, Object... args)
public static Object callMethod(Object obj, String methodName, Class<?>[] parameterTypes, Object... args)
public static Object callStaticMethod(Class<?> clazz, String methodName, Object... args)
public static Object callStaticMethod(Class<?> clazz, String methodName, Class<?>[] parameterTypes, Object... args)複製程式碼
呼叫例項/靜態Method,返回值為方法返回值
public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback)
//通過className和classLoader獲取Class<?> ,再呼叫上面的方法
public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback)複製程式碼
Hook方法的一個方法,其中parameterTypesAndCallback和findConstructorExact方法的parameterTypes類似,不過這裡可變陣列最後一個物件必須為XC_MethodHook物件或者其子類,前面的物件為引數的ClassType或者類字串,在hook成功後,當呼叫hook的方法時,會在XC_MethodHook回撥
public abstract class XC_MethodHook extends XCallback {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
//方法呼叫前的回撥
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//方法呼叫後的回撥
super.afterHookedMethod(param);
}
}
public abstract class XC_MethodReplacement extends XC_MethodHook{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
//帶返回值的方法執行時呼叫
return null;
}
}複製程式碼
可以通過這兩個class進行hook監聽。
本節示例
git提交:45c44ab4be96f012e7c4992bfdcc3bc2d3e458d7
git checkout 45c44ab複製程式碼