Xposed從入門到棄坑:0x0三、XposedHelpers類解析

感受很久沒更新xposed教程了。應該有兩個月了,主要是工做太忙,沒有時間寫博客。這節主要講解XposedHelpers類的一些用法,對前面內容有遺忘的能夠再回過去預習下。
更多精彩內容能夠關注個人博客:www.wrbug.com
java

XposedHelpers類是幹嗎的?

在XposedHelpers類的頂部有一句註釋android

/** * Helpers that simplify hooking and calling methods/constructors, getting and settings fields, ... */
public final class XposedHelpers {
}複製代碼

大概意思是能夠hook活着調用方法/構造函數。獲取該類的字段等。這裏須要用到反射的姿式。不瞭解的能夠先看看反射相關的。XposedHelpers提供了很是方便的或者這些參數的方法。git

XposedHelpers方法說明

//className 完整類名,classLoader 類加載器(app應用的類加載器)
public static Class<?> findClass(String className, ClassLoader classLoader)

public static Class<?> findClassIfExists(String className, ClassLoader classLoader)複製代碼

獲取class的方法。其中findclass方法在未找到時拋出異常,findClassIfExists則返回nullgithub

// 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,若是類型同樣,則返回該字段,該方法的侷限性是隻能獲取到第一個匹配到的字段,後面相同類型的沒法獲取vim

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類,構造函數有三個參數,能夠用如下幾種方式獲取:app

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爲實例,則爲設置或者獲取該成員變量的值ide

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回調this

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複製代碼
相關文章
相關標籤/搜索