package andhook.lib; import android.util.Log; import android.util.Pair; import i.am.jaggu; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.concurrent.ConcurrentHashMap; public final class HookHelper { public static final String constructorName = "<init>"; private static final ConcurrentHashMap<Pair<String, String>, Integer> sBackups = new ConcurrentHashMap<>(); @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Hook { Class<?> clazz() default Hook.class; String name() default ""; boolean need_origin() default true; String value() default ""; } public static void applyHooks(Class<?> cls) { applyHooks(cls, cls.getClassLoader()); } public static void applyHooks(Class<?> cls, ClassLoader classLoader) { String decode = jaggu.base.decode("2208017E580B08"); Method[] declaredMethods = cls.getDeclaredMethods(); for (Method method : declaredMethods) { Hook hook = (Hook) method.getAnnotation(Hook.class); if (hook != null) { String name = hook.name(); if (name.isEmpty()) { name = method.getName(); } Class<?> clazz = hook.clazz(); if (clazz == Hook.class) { try { clazz = classLoader.loadClass(hook.value()); } catch (Exception e) { Log.e(decode, e.getMessage(), e); } } Class<?>[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length < 1) { Log.e(decode, jaggu.base.decode("1608004E470100445D544253130247465D410C55044445")); } else { int length = parameterTypes.length - 1; Class[] clsArr = new Class[length]; System.arraycopy(parameterTypes, 1, clsArr, 0, length); Member findConstructorHierarchically = isConstructor(clazz, name) ? findConstructorHierarchically(clazz, clsArr) : findMethodHierarchically(clazz, name, clsArr); if (findConstructorHierarchically != null) { if (Modifier.isStatic(findConstructorHierarchically.getModifiers())) { AndHook.ensureClassInitialized(clazz); } if (hook.need_origin()) { hook(findConstructorHierarchically, method); } else { AndHook.hookNoBackup(findConstructorHierarchically, method); } } } } } } public static Class<?> findClass(String str) { return findClass(str, AndHook.class.getClassLoader()); } public static Class<?> findClass(String str, ClassLoader classLoader) { try { return classLoader.loadClass(str); } catch (Exception e) { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A520043445710045B0F0114055F55124441") + str + jaggu.base.decode("43090B16740802434B7C0D5305004646") + classLoader, e); return null; } } public static Constructor<?> findConstructorHierarchically(Class<?> cls, Class<?>... clsArr) { Constructor<?> constructor = null; Class<?> cls2 = cls; do { try { constructor = cls2.getDeclaredConstructor(clsArr); continue; } catch (NoSuchMethodException unused) { cls2 = cls2.getSuperclass(); if (cls2 == null) { break; } } } while (constructor == null); if (constructor != null) { constructor.setAccessible(true); } else { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A520043445710045B0F0114055C5A1243134307115C42435D50135A5C02151616") + cls.getName()); } return constructor; } public static Field findFieldHierarchically(Class<?> cls, String str) { Field field = null; Class<?> cls2 = cls; do { try { field = cls2.getDeclaredField(str); continue; } catch (NoSuchFieldException unused) { cls2 = cls2.getSuperclass(); if (cls2 == null) { break; } } } while (field == null); if (field != null) { field.setAccessible(true); } else { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A520043445710045B0F0114005A510D5341") + str + jaggu.base.decode("43090316540802434B10") + cls.getName()); } return field; } public static Method findMethodHierarchically(Class<?> cls, String str, Class<?>... clsArr) { Method method = null; Class<?> cls2 = cls; do { try { method = cls2.getDeclaredMethod(str, clsArr); continue; } catch (NoSuchMethodException unused) { cls2 = cls2.getSuperclass(); if (cls2 == null) { break; } } } while (method == null); if (method != null) { method.setAccessible(true); } else { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A520043445710045B0F01140B564009580516") + str + jaggu.base.decode("43090316540802434B10") + cls.getName()); } return method; } private static int getBackupSlot(int i2) { StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[4]; String className = stackTraceElement.getClassName(); if (jaggu.base.decode("000908185614131E4C5909460E0E1A0B5C50045B4F7E").equals(className)) { stackTraceElement = Thread.currentThread().getStackTrace()[5]; className = stackTraceElement.getClassName(); } ConcurrentHashMap<Pair<String, String>, Integer> concurrentHashMap = sBackups; Integer num = concurrentHashMap.get(Pair.create(className, stackTraceElement.getMethodName() + i2)); if (num != null) { return num.intValue(); } StringBuilder sb = new StringBuilder(); sb.append(jaggu.base.decode("0D094554560708454810045D140B5046555B1317")); sb.append(className); String decode = jaggu.base.decode("23"); sb.append(decode); sb.append(stackTraceElement.getMethodName()); sb.append(decode); sb.append(i2); Log.e(jaggu.base.decode("2208017E580B08"), sb.toString()); return -1; } public static void hook(Class<?> cls, String str, String str2, Method method) { if (uniqueKey(method) != null) { warnKnownIssue(method); int backup = AndHook.backup(cls, str, str2); if (backup != -1 && saveBackupSlot(Integer.valueOf(backup), method)) { AndHook.hook(cls, str, str2, method, backup); } } } public static void hook(Member member, Method method) { if (uniqueKey(method) != null) { warnKnownIssue(method); int backup = AndHook.backup(member); if (backup != -1 && saveBackupSlot(Integer.valueOf(backup), method)) { AndHook.hook(member, method, backup); } } } public static boolean invokeBooleanOrigin(Object obj, Object... objArr) { return AndHook.invokeBooleanMethod(getBackupSlot(objArr.length), obj, objArr); } public static byte invokeByteOrigin(Object obj, Object... objArr) { return AndHook.invokeByteMethod(getBackupSlot(objArr.length), obj, objArr); } public static char invokeCharOrigin(Object obj, Object... objArr) { return AndHook.invokeCharMethod(getBackupSlot(objArr.length), obj, objArr); } public static double invokeDoubleOrigin(Object obj, Object... objArr) { return AndHook.invokeDoubleMethod(getBackupSlot(objArr.length), obj, objArr); } public static float invokeFloatOrigin(Object obj, Object... objArr) { return AndHook.invokeFloatMethod(getBackupSlot(objArr.length), obj, objArr); } public static int invokeIntOrigin(Object obj, Object... objArr) { return AndHook.invokeIntMethod(getBackupSlot(objArr.length), obj, objArr); } public static long invokeLongOrigin(Object obj, Object... objArr) { return AndHook.invokeLongMethod(getBackupSlot(objArr.length), obj, objArr); } public static <T> T invokeObjectOrigin(Object obj, Object... objArr) { return (T) AndHook.invoke(getBackupSlot(objArr.length), obj, objArr); } public static short invokeShortOrigin(Object obj, Object... objArr) { return AndHook.invokeShortMethod(getBackupSlot(objArr.length), obj, objArr); } public static void invokeVoidOrigin(Object obj, Object... objArr) { AndHook.invokeVoidMethod(getBackupSlot(objArr.length), obj, objArr); } private static boolean isConstructor(Class<?> cls, String str) { String name = cls.getName(); if (!str.equals(jaggu.base.decode("5F0F0B5F435A"))) { if (!name.endsWith(jaggu.base.decode("4D") + str)) { StringBuilder sb = new StringBuilder(); sb.append(jaggu.base.decode("47")); sb.append(str); return name.endsWith(sb.toString()); } } } private static boolean saveBackupSlot(Integer num, Method method) { Pair<String, String> uniqueKey = uniqueKey(method); if (uniqueKey == null) { return false; } sBackups.put(uniqueKey, num); Log.i(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("10071353534401515B5B174241035B1413") + ((String) uniqueKey.first) + jaggu.base.decode("23") + ((String) uniqueKey.second) + jaggu.base.decode("4F46165A5810430D18") + num); return true; } public static void setObjectField(Object obj, String str, Object obj2) { Field findFieldHierarchically = findFieldHierarchically(obj.getClass(), str); if (findFieldHierarchically != null) { try { findFieldHierarchically.set(obj, obj2); } catch (Exception e) { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A520043445710115715455D0840400059025344035A550F5616") + str, e); } } } public static void setStaticObjectField(Class<?> cls, String str, Object obj) { Field findFieldHierarchically = findFieldHierarchically(cls, str); if (findFieldHierarchically != null) { try { findFieldHierarchically.set(null, obj); } catch (Exception e) { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("05070C5A5200434457101157154547125240085441500D005F5443") + str + jaggu.base.decode("43000A4417070F514B4342") + cls.getName(), e); } } } private static Pair<String, String> uniqueKey(Method method) { String name = method.getDeclaringClass().getName(); StringBuilder sb = new StringBuilder(); sb.append(method.getName()); sb.append(method.getParameterTypes().length - 1); Pair<String, String> create = Pair.create(name, sb.toString()); if (!sBackups.containsKey(create)) { return create; } Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("0713155A5E0702445D10095718455114415B1316415708175651074B165B565F08030109")); return null; } private static void warnKnownIssue(Method method) { if (!Modifier.isStatic(method.getModifiers()) || method.getParameterTypes().length < 1 || method.getParameterTypes()[0].isPrimitive()) { Log.e(jaggu.base.decode("2208017E580B08"), jaggu.base.decode("0E03115E580043") + method.getDeclaringClass().getName() + jaggu.base.decode("23") + method.getName() + jaggu.base.decode("430B10454344015518431653150C5746525A0517084217455559114142135842041308535910435D4D431612030014255F5512445D095A455C42437D54595C531747")); } } }