From 084951f4637ab3c4a7efdd30fd8ca8ab659c815d Mon Sep 17 00:00:00 2001 From: Fankesyooni Date: Fri, 15 Apr 2022 04:57:03 +0800 Subject: [PATCH] Fix jar file lost bug --- yukihookapi/build.gradle | 1 - yukihookapi/libs/free-reflection.jar | Bin 6286 -> 0 bytes .../me/weishu/reflection/BootstrapClass.java | 78 ++++++++++++++ .../me/weishu/reflection/Reflection.java | 97 ++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) delete mode 100644 yukihookapi/libs/free-reflection.jar create mode 100644 yukihookapi/src/api/kotlin/me/weishu/reflection/BootstrapClass.java create mode 100644 yukihookapi/src/api/kotlin/me/weishu/reflection/Reflection.java diff --git a/yukihookapi/build.gradle b/yukihookapi/build.gradle index 436618bb..69d2df94 100644 --- a/yukihookapi/build.gradle +++ b/yukihookapi/build.gradle @@ -41,7 +41,6 @@ dependencies { // Used 82 API Version compileOnly 'de.robv.android.xposed:api:82' compileOnly fileTree(include: ['android-stub.jar', 'module-injector.jar'], dir: 'libs') - implementation fileTree(include: ['free-reflection.jar'], dir: 'libs') implementation 'androidx.annotation:annotation:1.3.0' } diff --git a/yukihookapi/libs/free-reflection.jar b/yukihookapi/libs/free-reflection.jar deleted file mode 100644 index e21de47a806360a80c18b8e43607e69aee50f614..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6286 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 J^eO&Y{Trr?tJ?qo diff --git a/yukihookapi/src/api/kotlin/me/weishu/reflection/BootstrapClass.java b/yukihookapi/src/api/kotlin/me/weishu/reflection/BootstrapClass.java new file mode 100644 index 00000000..e3abdc97 --- /dev/null +++ b/yukihookapi/src/api/kotlin/me/weishu/reflection/BootstrapClass.java @@ -0,0 +1,78 @@ +package me.weishu.reflection; + +import static android.os.Build.VERSION.SDK_INT; + +import android.os.Build; +import android.util.Log; + +import androidx.annotation.Keep; + +import java.lang.reflect.Method; + +/** + * @author weishu + * @date 2020/7/13. + */ +@SuppressWarnings("ALL") +@Keep +public final class BootstrapClass { + + private static final String TAG = "BootstrapClass"; + + private static Object sVmRuntime; + private static Method setHiddenApiExemptions; + + static { + if (SDK_INT >= Build.VERSION_CODES.P) { + try { + Method forName = Class.class.getDeclaredMethod("forName", String.class); + Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class); + + Class vmRuntimeClass = (Class) forName.invoke(null, "dalvik.system.VMRuntime"); + Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null); + setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", new Class[]{String[].class}); + sVmRuntime = getRuntime.invoke(null); + } catch (Throwable e) { + Log.w(TAG, "reflect bootstrap failed:", e); + } + } + } + + /** + * make the method exempted from hidden API check. + * + * @param method the method signature prefix. + * @return true if success. + */ + public static boolean exempt(String method) { + return exempt(new String[]{method}); + } + + /** + * make specific methods exempted from hidden API check. + * + * @param methods the method signature prefix, such as "Ldalvik/system", "Landroid" or even "L" + * @return true if success + */ + public static boolean exempt(String... methods) { + if (sVmRuntime == null || setHiddenApiExemptions == null) { + return false; + } + + try { + setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods}); + return true; + } catch (Throwable e) { + return false; + } + } + + /** + * Make all hidden API exempted. + * + * @return true if success. + */ + public static boolean exemptAll() { + return exempt(new String[]{"L"}); + } +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/me/weishu/reflection/Reflection.java b/yukihookapi/src/api/kotlin/me/weishu/reflection/Reflection.java new file mode 100644 index 00000000..30c122dd --- /dev/null +++ b/yukihookapi/src/api/kotlin/me/weishu/reflection/Reflection.java @@ -0,0 +1,97 @@ +package me.weishu.reflection; + +import static android.os.Build.VERSION.SDK_INT; +import static me.weishu.reflection.BootstrapClass.exemptAll; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Base64; + +import androidx.annotation.Keep; + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.reflect.Method; + +import dalvik.system.DexFile; + +/** + * @author weishu + * @date 2018/6/7. + */ +@SuppressWarnings("ALL") +@Keep +public class Reflection { + private static final String TAG = "Reflection"; + + private static final String DEX = "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TGFuZHJvaWQvdXRpbC9Mb2c7ABFMamF2YS9sYW5nL0NsYXNzOwAUTGphdmEvbGFuZy9DbGFzczwqPjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5c3RlbTsAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwAaTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsAJkxtZS93ZWlzaHUvZnJlZXJlZmxlY3Rpb24vQnVpbGRDb25maWc7ACVMbWUvd2Vpc2h1L3JlZmxlY3Rpb24vQm9vdHN0cmFwQ2xhc3M7ACFMbWUvd2Vpc2h1L3JlZmxlY3Rpb24vUmVmbGVjdGlvbjsAClJlZmxlY3Rpb24AD1JlZmxlY3Rpb24uamF2YQAHU0RLX0lOVAADVEFHAAFWAAxWRVJTSU9OX0NPREUADFZFUlNJT05fTkFNRQACVkwAAVoAAlpMABJbTGphdmEvbGFuZy9DbGFzczsAE1tMamF2YS9sYW5nL09iamVjdDsAE1tMamF2YS9sYW5nL1N0cmluZzsAB2NvbnRleHQAF2RhbHZpay5zeXN0ZW0uVk1SdW50aW1lAAFlAAZleGVtcHQACWV4ZW1wdEFsbAAHZm9yTmFtZQAPZnJlZS1yZWZsZWN0aW9uABJnZXRBcHBsaWNhdGlvbkluZm8AEWdldERlY2xhcmVkTWV0aG9kAApnZXRSdW50aW1lAAZpbnZva2UAC2xvYWRMaWJyYXJ5ABhtZS53ZWlzaHUuZnJlZXJlZmxlY3Rpb24ABm1ldGhvZAAHbWV0aG9kcwAZcmVmbGVjdCBib290c3RyYXAgZmFpbGVkOgAHcmVsZWFzZQAKc1ZtUnVudGltZQAWc2V0SGlkZGVuQXBpRXhlbXB0aW9ucwAQdGFyZ2V0U2RrVmVyc2lvbgAEdGhpcwAGdW5zZWFsAAx1bnNlYWxOYXRpdmUADnZtUnVudGltZUNsYXNzAAYABw4AFgAHDmr/AwEyCwEVEAMCNQvwBAREBhcBEg8DAzYLARsPqQUCBQMFBBkeAwAvCgAOAAcOACwBOgcOADYBOwcsnRriAQEDAC8KHgBIAAcOAA0ABw4AEwEtBx1yGWtaAAYXOBc8HxcABAEXAQEXBgEXHwYAAQACGQEZARkBGQEZARkGgYAEiAcDAAUACBoBCgEKB4iABKAHAYGABLQJAQnMCQGJAfQJAQnMCgEAAwALGgyBgAT4CgEJkAsBigIAAAAADgAAAAAAAAABAAAAAAAAAAEAAABEAAAAcAAAAAIAAAATAAAAgAEAAAMAAAALAAAAzAEAAAQAAAAMAAAAUAIAAAUAAAAPAAAAsAIAAAYAAAADAAAAKAMAAAEgAAAIAAAAiAMAAAEQAAAHAAAA3AUAAAIgAABEAAAAFgYAAAMgAAAIAAAAAwoAAAUgAAADAAAAZgoAAAAgAAADAAAAeAoAAAAQAAABAAAAyAoAAA=="; + + private static native int unsealNative(int targetSdkVersion); + + /** + * Begin + * + * @param context The Base Context + */ + public static int unseal(Context context) { + if (SDK_INT < 28) { + // Below Android P, ignore + return 0; + } + + // try exempt API first. + if (exemptAll()) { + return 0; + } + if (unsealByDexFile(context)) { + return 0; + } + + return -1; + } + + private static boolean unsealByDexFile(Context context) { + byte[] bytes = Base64.decode(DEX, Base64.NO_WRAP); + File codeCacheDir = getCodeCacheDir(context); + if (codeCacheDir == null) { + return false; + } + File code = new File(codeCacheDir, System.currentTimeMillis() + ".dex"); + try { + + try (FileOutputStream fos = new FileOutputStream(code)) { + fos.write(bytes); + } + + DexFile dexFile = new DexFile(code); + // This class is hardcoded in the dex, Don't use BootstrapClass.class to reference it + // it maybe obfuscated!! + Class bootstrapClass = dexFile.loadClass("me.weishu.reflection.BootstrapClass", null); + Method exemptAll = bootstrapClass.getDeclaredMethod("exemptAll"); + return (boolean) exemptAll.invoke(null); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } finally { + if (code.exists()) { + //noinspection ResultOfMethodCallIgnored + code.delete(); + } + } + } + + private static File getCodeCacheDir(Context context) { + if (context != null) { + return context.getCodeCacheDir(); + } + String tmpDir = System.getProperty("java.io.tmpdir"); + if (TextUtils.isEmpty(tmpDir)) { + return null; + } + File tmp = new File(tmpDir); + if (!tmp.exists()) { + return null; + } + return tmp; + } +} \ No newline at end of file