TikTok.apk(点击下载) / SandHook.java


package com.swift.sandhook;

import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.blacklist.HookBlackList;
import com.swift.sandhook.utils.ClassStatusUtils;
import com.swift.sandhook.utils.FileUtils;
import com.swift.sandhook.utils.ReflectionUtils;
import com.swift.sandhook.utils.Unsafe;
import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.wrapper.HookWrapper;
import i.am.jaggu;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SandHook {
    public static Class artMethodClass;
    static Map<Method, HookWrapper.HookEntity> globalBackupMap = new ConcurrentHashMap();
    static Map<Member, HookWrapper.HookEntity> globalHookEntityMap = new ConcurrentHashMap();
    private static HookModeCallBack hookModeCallBack;
    private static HookResultCallBack hookResultCallBack;
    public static Field nativePeerField;
    public static int testAccessFlag;
    public static Object testOffsetArtMethod1;
    public static Object testOffsetArtMethod2;
    public static Method testOffsetMethod1;
    public static Method testOffsetMethod2;

    @FunctionalInterface
    public interface HookModeCallBack {
        int hookMode(Member member);
    }

    @FunctionalInterface
    public interface HookResultCallBack {
        void hookResult(boolean z, HookWrapper.HookEntity hookEntity);
    }

    static {
        SandHookConfig.libLoader.loadLib();
        init();
    }

    public static native void MakeInitializedClassVisibilyInitialized(long j);

    public static void addHookClass(ClassLoader classLoader, Class... clsArr) throws HookErrorException {
        HookWrapper.addHookClass(classLoader, clsArr);
    }

    public static void addHookClass(Class... clsArr) throws HookErrorException {
        HookWrapper.addHookClass(clsArr);
    }

    public static final Object callOriginByBackup(Method method, Object obj, Object... objArr) throws Throwable {
        HookWrapper.HookEntity hookEntity = globalBackupMap.get(method);
        if (hookEntity == null) {
            return null;
        }
        return callOriginMethod(hookEntity.backupIsStub, hookEntity.target, method, obj, objArr);
    }

    public static final Object callOriginMethod(Member member, Object obj, Object... objArr) throws Throwable {
        HookWrapper.HookEntity hookEntity = globalHookEntityMap.get(member);
        if (hookEntity == null || hookEntity.backup == null) {
            return null;
        }
        return callOriginMethod(hookEntity.backupIsStub, member, hookEntity.backup, obj, objArr);
    }

    public static final Object callOriginMethod(Member member, Method method, Object obj, Object[] objArr) throws Throwable {
        return callOriginMethod(true, member, method, obj, objArr);
    }

    public static final Object callOriginMethod(boolean z, Member member, Method method, Object obj, Object[] objArr) throws Throwable {
        if (!z && SandHookConfig.SDK_INT >= 24) {
            member.getDeclaringClass();
            ensureDeclareClass(member, method);
        }
        if (Modifier.isStatic(member.getModifiers())) {
            try {
                return method.invoke(null, objArr);
            } catch (InvocationTargetException e) {
                if (e.getCause() != null) {
                    throw e.getCause();
                }
                throw e;
            }
        } else {
            try {
                return method.invoke(obj, objArr);
            } catch (InvocationTargetException e2) {
                if (e2.getCause() != null) {
                    throw e2.getCause();
                }
                throw e2;
            }
        }
    }

    public static native boolean canGetObject();

    public static boolean canGetObjectAddress() {
        return Unsafe.support();
    }

    public static native boolean compileMethod(Member member);

    public static native boolean deCompileMethod(Member member, boolean z);

    public static native boolean disableDex2oatInline(boolean z);

    public static native boolean disableVMInline();

    public static final void ensureBackupMethod(Method method) {
        HookWrapper.HookEntity hookEntity;
        if (SandHookConfig.SDK_INT >= 24 && (hookEntity = globalBackupMap.get(method)) != null) {
            ensureDeclareClass(hookEntity.target, method);
        }
    }

    public static native void ensureDeclareClass(Member member, Method method);

    public static native void ensureMethodCached(Method method, Method method2);

    public static long getArtMethod(Member member) {
        return SandHookMethodResolver.getArtMethod(member);
    }

    private static Object[] getFakeArgs(Method method) {
        return new Object[method.getParameterTypes().length];
    }

    public static Field getField(Class cls, String str) throws NoSuchFieldException {
        while (cls != null && cls != Object.class) {
            try {
                Field declaredField = cls.getDeclaredField(str);
                declaredField.setAccessible(true);
                return declaredField;
            } catch (Exception unused) {
                cls = cls.getSuperclass();
            }
        }
        throw new NoSuchFieldException(str);
    }

    public static Object getJavaMethod(String str, String str2) {
        if (str == null) {
            return null;
        }
        try {
            return Class.forName(str).getDeclaredMethod(str2, new Class[0]);
        } catch (ClassNotFoundException unused) {
            return null;
        }
    }

    public static Object getObject(long j) {
        if (j == 0) {
            return null;
        }
        return getObjectNative(getThreadId(), j);
    }

    public static long getObjectAddress(Object obj) {
        return Unsafe.getObjectAddress(obj);
    }

    public static native Object getObjectNative(long j, long j2);

    public static long getThreadId() {
        Field field = nativePeerField;
        if (field == null) {
            return 0;
        }
        try {
            return field.getType() == Integer.TYPE ? (long) nativePeerField.getInt(Thread.currentThread()) : nativePeerField.getLong(Thread.currentThread());
        } catch (IllegalAccessException unused) {
            return 0;
        }
    }

    public static boolean hasJavaArtMethod() {
        if (SandHookConfig.SDK_INT >= 26) {
            return false;
        }
        if (artMethodClass != null) {
            return true;
        }
        try {
            ClassLoader classLoader = SandHookConfig.initClassLoader;
            String decode = jaggu.base.decode("090713571908025E5F1E105707095105471A2045157B01115B5F07");
            if (classLoader == null) {
                artMethodClass = Class.forName(decode);
            } else {
                artMethodClass = Class.forName(decode, true, SandHookConfig.initClassLoader);
            }
            return true;
        } catch (ClassNotFoundException unused) {
            return false;
        }
    }

    public static synchronized void hook(HookWrapper.HookEntity hookEntity) throws HookErrorException {
        int i2;
        synchronized (SandHook.class) {
            if (hookEntity != null) {
                Member member = hookEntity.target;
                Method method = hookEntity.hook;
                Method method2 = hookEntity.backup;
                if (member == null || method == null) {
                    throw new HookErrorException(jaggu.base.decode("0D13095A170D0D404D44"));
                } else if (globalHookEntityMap.containsKey(hookEntity.target)) {
                    throw new HookErrorException(jaggu.base.decode("0E03115E5800430C") + hookEntity.target.toString() + jaggu.base.decode("5D460D57444401555D5E425A0E0A5F035715"));
                } else if (HookBlackList.canNotHook(member)) {
                    throw new HookErrorException(jaggu.base.decode("0E03115E5800430C") + hookEntity.target.toString() + jaggu.base.decode("5D46065759440D5F4C100A5D0E0E184651510256144501455C56435B58135B5C02050E5A5E171711"));
                } else if (!SandHookConfig.delayHook || !PendingHookHandler.canWork() || !ClassStatusUtils.isStaticAndNoInited(hookEntity.target)) {
                    if (hookEntity.initClass) {
                        resolveStaticMethod(member);
                        MakeInitializedClassVisibilyInitialized(getThreadId());
                    }
                    resolveStaticMethod(method2);
                    if (method2 != null && hookEntity.resolveDexCache) {
                        SandHookMethodResolver.resolveMethod(method, method2);
                    }
                    if (member instanceof Method) {
                        ((Method) member).setAccessible(true);
                    }
                    boolean z = false;
                    int hookMode = hookModeCallBack != null ? hookModeCallBack.hookMode(member) : 0;
                    globalHookEntityMap.put(hookEntity.target, hookEntity);
                    if (hookMode != 0) {
                        i2 = hookMethod(member, method, method2, hookMode);
                    } else {
                        HookMode hookMode2 = (HookMode) method.getAnnotation(HookMode.class);
                        i2 = hookMethod(member, method, method2, hookMode2 == null ? 0 : hookMode2.value());
                    }
                    if (i2 > 0 && method2 != null) {
                        method2.setAccessible(true);
                    }
                    hookEntity.hookMode = i2;
                    if (hookResultCallBack != null) {
                        HookResultCallBack hookResultCallBack2 = hookResultCallBack;
                        if (i2 > 0) {
                            z = true;
                        }
                        hookResultCallBack2.hookResult(z, hookEntity);
                    }
                    if (i2 >= 0) {
                        if (hookEntity.backup != null) {
                            globalBackupMap.put(hookEntity.backup, hookEntity);
                        }
                        StringBuilder sb = new StringBuilder();
                        sb.append(jaggu.base.decode("0E03115E5800430C"));
                        sb.append(hookEntity.target.toString());
                        sb.append(jaggu.base.decode("5D460D59580F430C"));
                        sb.append(i2 == 1 ? jaggu.base.decode("0A08095F5901") : jaggu.base.decode("1103155A5607065D5D5E16"));
                        sb.append(jaggu.base.decode("5D461643540706434B11"));
                        HookLog.d(sb.toString());
                        return;
                    }
                    globalHookEntityMap.remove(hookEntity.target);
                    throw new HookErrorException(jaggu.base.decode("0B090A5D17090644505F06125D") + hookEntity.target.toString() + jaggu.base.decode("5D460044450B1110515E425C00115D105615"));
                } else {
                    PendingHookHandler.addPendingHook(hookEntity);
                }
            } else {
                throw new HookErrorException(jaggu.base.decode("0D13095A170C0C5F5310075C150C401F"));
            }
        }
    }

    private static native int hookMethod(Member member, Method method, Method method2, int i2);

    private static boolean init() {
        initTestOffset();
        initThreadPeer();
        SandHookMethodResolver.init();
        return initNative(SandHookConfig.SDK_INT, SandHookConfig.DEBUG);
    }

    public static native boolean initForPendingHook();

    private static native boolean initNative(int i2, boolean z);

    private static void initTestAccessFlag() {
        boolean hasJavaArtMethod = hasJavaArtMethod();
        String decode = jaggu.base.decode("020506534417255C595711");
        if (hasJavaArtMethod) {
            try {
                loadArtMethod();
                testAccessFlag = ((Integer) getField(artMethodClass, decode).get(testOffsetArtMethod1)).intValue();
            } catch (Exception unused) {
            }
        } else {
            testAccessFlag = ((Integer) getField(Method.class, decode).get(testOffsetMethod1)).intValue();
        }
    }

    private static void initTestOffset() {
        ArtMethodSizeTest.method1();
        ArtMethodSizeTest.method2();
        try {
            testOffsetMethod1 = ArtMethodSizeTest.class.getDeclaredMethod(jaggu.base.decode("0E03115E580052"), new Class[0]);
            testOffsetMethod2 = ArtMethodSizeTest.class.getDeclaredMethod(jaggu.base.decode("0E03115E580051"), new Class[0]);
            initTestAccessFlag();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(jaggu.base.decode("30070B527F0B0C5B18590C5B15455114415B13"), e);
        }
    }

    private static void initThreadPeer() {
        try {
            nativePeerField = getField(Thread.class, jaggu.base.decode("0D07115F410133555D42"));
        } catch (NoSuchFieldException unused) {
        }
    }

    public static native boolean is64Bit();

    private static void loadArtMethod() {
        try {
            Field field = getField(Method.class, jaggu.base.decode("0214117B52100B5F5C"));
            testOffsetArtMethod1 = field.get(testOffsetMethod1);
            testOffsetArtMethod2 = field.get(testOffsetMethod2);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e2) {
            e2.printStackTrace();
        }
    }

    public static boolean passApiCheck() {
        return ReflectionUtils.passApiCheck();
    }

    public static boolean resolveStaticMethod(Member member) {
        if (member == null) {
            return true;
        }
        try {
            if ((member instanceof Method) && Modifier.isStatic(member.getModifiers())) {
                ((Method) member).setAccessible(true);
                ((Method) member).invoke(null, getFakeArgs((Method) member));
            }
        } catch (ExceptionInInitializerError unused) {
            return false;
        } catch (Throwable unused2) {
        }
        return true;
    }

    public static native void setHookMode(int i2);

    public static void setHookModeCallBack(HookModeCallBack hookModeCallBack2) {
        hookModeCallBack = hookModeCallBack2;
    }

    public static void setHookResultCallBack(HookResultCallBack hookResultCallBack2) {
        hookResultCallBack = hookResultCallBack2;
    }

    public static native void setInlineSafeCheck(boolean z);

    public static native boolean setNativeEntry(Member member, Member member2, long j);

    public static native void skipAllSafeCheck(boolean z);

    public static boolean tryDisableProfile(String str) {
        if (SandHookConfig.SDK_INT < 24) {
            return false;
        }
        try {
            File file = new File(jaggu.base.decode("4C020442564B0E594B534D42130A520F5F5112180243164A") + SandHookConfig.curUser + jaggu.base.decode("4C") + str + jaggu.base.decode("4C16175F5A0511491640105D07"));
            if (!file.getParentFile().exists()) {
                return false;
            }
            try {
                file.delete();
                file.createNewFile();
            } catch (Throwable unused) {
            }
            FileUtils.chmod(file.getAbsolutePath(), 256);
            return true;
        } catch (Throwable unused2) {
            return false;
        }
    }
}