diff --git a/gradle/sweet-dependency/sweet-dependency-config.yaml b/gradle/sweet-dependency/sweet-dependency-config.yaml index 0a10d561..495d9fc0 100644 --- a/gradle/sweet-dependency/sweet-dependency-config.yaml +++ b/gradle/sweet-dependency/sweet-dependency-config.yaml @@ -7,6 +7,7 @@ repositories: scope: PLUGINS google: maven-central: + jit-pack: rovo89-xposed-api: scope: LIBRARIES url: https://api.xposed.info/ @@ -41,6 +42,11 @@ libraries: version: 82 repositories: rovo89-xposed-api + com.github.tiann: + FreeReflection: + version: 3.1.0 + repositories: + jit-pack com.google.devtools.ksp: symbol-processing-api: version-ref: ::kotlin-ksp diff --git a/yukihookapi-core/build.gradle.kts b/yukihookapi-core/build.gradle.kts index 4a5a5ed0..504cf214 100644 --- a/yukihookapi-core/build.gradle.kts +++ b/yukihookapi-core/build.gradle.kts @@ -36,6 +36,7 @@ android { dependencies { compileOnly(de.robv.android.xposed.api) compileOnly(projects.yukihookapiStub) + implementation(com.github.tiann.freeReflection) implementation(androidx.core.core.ktx) implementation(androidx.appcompat.appcompat) implementation(androidx.preference.preference.ktx) diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/application/ModuleApplication.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/application/ModuleApplication.kt index d7ba4080..203b3042 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/application/ModuleApplication.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/application/ModuleApplication.kt @@ -33,7 +33,7 @@ import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.xposed.application.ModuleApplication.Companion.appContext import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel import com.highcapable.yukihookapi.hook.xposed.proxy.IYukiHookXposedInit -import com.highcapable.yukihookapi.thirdparty.me.weishu.reflection.Reflection +import me.weishu.reflection.Reflection /** * 这是对使用 [YukiHookAPI] Xposed 模块实现中的一个扩展功能 diff --git a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/YukiHookXposedProcessor.kt b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/YukiHookXposedProcessor.kt index 7f0b1871..4bd9e5b7 100644 --- a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/YukiHookXposedProcessor.kt +++ b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/YukiHookXposedProcessor.kt @@ -316,20 +316,6 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { packageName = data.entryPackageName, content = data.sources()[ClassName.XposedInit_Impl] ) - /* 插入 FreeReflection 代码 */ - createCodeFile( - fileName = ClassName.BootstrapClass, - packageName = PackageName.BootstrapReflectionClass, - content = data.sources()[ClassName.BootstrapClass], - extensionName = JAVA_FILE_EXT_NAME - ) - /* 插入 FreeReflection 代码 */ - createCodeFile( - fileName = ClassName.Reflection, - packageName = PackageName.BootstrapReflectionClass, - content = data.sources()[ClassName.Reflection], - extensionName = JAVA_FILE_EXT_NAME - ) } /** diff --git a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt index 7826f2cc..4112c634 100644 --- a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt +++ b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi/factory/CodeSourceFileFactory.kt @@ -45,7 +45,6 @@ object PackageName { const val HandlerDelegateClass = "com.highcapable.yukihookapi.hook.xposed.parasitic.activity.delegate" const val IActivityManagerProxyImpl_Impl = "com.highcapable.yukihookapi.hook.xposed.parasitic.activity.delegate.impl" const val IActivityManagerProxyClass = "com.highcapable.yukihookapi.hook.xposed.parasitic.activity.delegate" - const val BootstrapReflectionClass = "com.highcapable.yukihookapi.thirdparty.me.weishu.reflection" } /** @@ -61,8 +60,6 @@ object ClassName { const val IActivityManagerProxyClass = "IActivityManagerProxy" const val XposedInit = "xposed_init" const val XposedInit_Impl = "xposed_init_Impl" - const val BootstrapClass = "BootstrapClass" - const val Reflection = "Reflection" } /** @@ -384,143 +381,5 @@ fun GenerateData.sources() = mapOf( if (resparam != null && isZygoteCalled) callOnXposedModuleLoaded(resparam = resparam) } } - """.trimIndent(), - ClassName.BootstrapClass to ("package ${PackageName.BootstrapReflectionClass};\n" + - "\n" + - "import static android.os.Build.VERSION.SDK_INT;\n" + - "\n" + - "import android.os.Build;\n" + - "import android.util.Log;\n" + - "\n" + - "import androidx.annotation.Keep;\n" + - "\n" + - "import java.lang.reflect.Method;\n" + - "\n" + - createCommentContent(currrentClassTag = ClassName.BootstrapClass) + - "@Keep\n" + - "public final class BootstrapClass {\n" + - "\n" + - " private static final String TAG = \"BootstrapClass\";\n" + - " private static Object sVmRuntime;\n" + - " private static Method setHiddenApiExemptions;\n" + - "\n" + - " static {\n" + - " if (SDK_INT >= Build.VERSION_CODES.P) {\n" + - " try {\n" + - " Method forName = Class.class.getDeclaredMethod(\"forName\", String.class);\n" + - " Method getDeclaredMethod = Class.class.getDeclaredMethod(\"getDeclaredMethod\", String.class, Class[].class);\n" + - " Class vmRuntimeClass = (Class) forName.invoke(null, \"dalvik.system.VMRuntime\");\n" + - " Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, \"getRuntime\", null);\n" + - " setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, \"setHiddenApiExemptions\", new Class[]{String[].class});\n" + - " sVmRuntime = getRuntime.invoke(null);\n" + - " } catch (Throwable e) {\n" + - " Log.w(TAG, \"reflect bootstrap failed:\", e);\n" + - " }\n" + - " }\n" + - " }\n" + - "\n" + - " public static boolean exempt(String method) {\n" + - " return exempt(new String[]{method});\n" + - " }\n" + - "\n" + - " public static boolean exempt(String... methods) {\n" + - " if (sVmRuntime == null || setHiddenApiExemptions == null) {\n" + - " return false;\n" + - " }\n" + - " try {\n" + - " setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods});\n" + - " return true;\n" + - " } catch (Throwable e) {\n" + - " return false;\n" + - " }\n" + - " }\n" + - "\n" + - " public static boolean exemptAll() {\n" + - " return exempt(new String[]{\"L\"});\n" + - " }\n" + - "}"), - ClassName.Reflection to ("package ${PackageName.BootstrapReflectionClass};\n" + - "\n" + - "import static android.os.Build.VERSION.SDK_INT;\n" + - "import static com.highcapable.yukihookapi.thirdparty.me.weishu.reflection.BootstrapClass.exemptAll;\n" + - "\n" + - "import android.content.Context;\n" + - "import android.text.TextUtils;\n" + - "import android.util.Base64;\n" + - "\n" + - "import androidx.annotation.Keep;\n" + - "\n" + - "import java.io.File;\n" + - "import java.io.FileOutputStream;\n" + - "import java.lang.reflect.Method;\n" + - "\n" + - "import dalvik.system.DexFile;\n" + - "\n" + - createCommentContent(currrentClassTag = ClassName.Reflection) + - "@Keep\n" + - "public class Reflection {\n" + - "\n" + - " private static final String TAG = \"Reflection\";\n" + - " private static final String DEX = \"ZGV4CjAzNQCXDT0vQ44GJqsrjm32y0qlQmxUevbk56r0CwAAcAAAAHhWNBIAAAAAAAAAADwLAABDAAAAcAAAABMAAAB8AQAACwAAAMgBAAAMAAAATAIAAA8AAACsAgAAAwAAACQDAABwCAAAhAMAAIQDAACGAwAAiwMAAJUDAACdAwAArQMAALkDAADJAwAA3gMAAPADAAD3AwAA/wMAAAIEAAAGBAAACgQAABAEAAATBAAAGAQAADMEAABZBAAAdQQAAIkEAADYBAAAJgUAAHAFAACDBQAAmQUAAK0FAADBBQAA1QUAAOwFAAAIBgAAFAYAACUGAAAuBgAAMwYAADYGAABEBgAAUgYAAFYGAABZBgAAXQYAAHEGAACGBgAAmwYAAKQGAAC9BgAAwAYAAMgGAADTBgAA3AYAAO0GAAABBwAAFAcAACAHAAAoBwAANQcAAE8HAABXBwAAYAcAAHsHAACEBwAAkAcAAKgHAAC6BwAAwgcAANAHAAALAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAaAAAAGwAAABwAAAAdAAAAHgAAACMAAAAnAAAAKQAAACoAAAArAAAADAAAAAAAAAD4BwAADQAAAAAAAAAMCAAADgAAAAAAAAAACAAADwAAAAIAAAAAAAAAEAAAAAkAAAAUCAAAEAAAAA0AAADoBwAAIwAAAA4AAAAAAAAAJgAAAA4AAADgBwAAJwAAAA8AAAAAAAAAKAAAAA8AAADgBwAAKAAAAA8AAADwBwAAAgAAAD8AAAADAAAAIQAAAAUACgAEAAAABQAKAAUAAAAFAA8ACQAAAAUACgAKAAAABQAAACQAAAAFAAoAJQAAAAYACgAiAAAABgAJAD0AAAAGAA0APgAAAAcACgAiAAAAAQADADMAAAAEAAIALgAAAAUABgADAAAABgAGAAIAAAAGAAYAAwAAAAYACQAvAAAABgAKAC8AAAAGAAgAMAAAAAcABgADAAAABwABAEAAAAAHAAAAQQAAAAgABQA0AAAACQAGAAMAAAALAAcANwAAAA0ABAA2AAAABQAAABEAAAAJAAAAAAAAAAgAAAAAAAAA7AoAAB8IAAAGAAAAEQAAAAkAAAAAAAAABwAAAAAAAAACCwAAHAgAAAcAAAABAAAACQAAAAAAAAAgAAAAAAAAACULAAArCAAAAAADMS4wAAg8Y2xpbml0PgAGPGluaXQ+AA5BUFBMSUNBVElPTl9JRAAKQlVJTERfVFlQRQAOQm9vdHN0cmFwQ2xhc3MAE0Jvb3RzdHJhcENsYXNzLmphdmEAEEJ1aWxkQ29uZmlnLmphdmEABURFQlVHAAZGTEFWT1IAAUkAAklJAAJJTAAESUxMTAABTAADTExMABlMYW5kcm9pZC9jb250ZW50L0NvbnRleHQ7ACRMYW5kcm9pZC9jb250ZW50L3BtL0FwcGxpY2F0aW9uSW5mbzsAGkxhbmRyb2lkL29zL0J1aWxkJFZFUlNJT047ABJMYW5kcm9pZC91dGlsL0xvZzsATUxjb20vaGlnaGNhcGFibGUveXVraWhvb2thcGkvdGhpcmRwYXJ0eS9tZS93ZWlzaHUvZnJlZXJlZmxlY3Rpb24vQnVpbGRDb25maWc7AExMY29tL2hpZ2hjYXBhYmxlL3l1a2lob29rYXBpL3RoaXJkcGFydHkvbWUvd2Vpc2h1L3JlZmxlY3Rpb24vQm9vdHN0cmFwQ2xhc3M7AEhMY29tL2hpZ2hjYXBhYmxlL3l1a2lob29rYXBpL3RoaXJkcGFydHkvbWUvd2Vpc2h1L3JlZmxlY3Rpb24vUmVmbGVjdGlvbjsAEUxqYXZhL2xhbmcvQ2xhc3M7ABRMamF2YS9sYW5nL0NsYXNzPCo+OwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZhL2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABpMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwAKUmVmbGVjdGlvbgAPUmVmbGVjdGlvbi5qYXZhAAdTREtfSU5UAANUQUcAAVYADFZFUlNJT05fQ09ERQAMVkVSU0lPTl9OQU1FAAJWTAABWgACWkwAEltMamF2YS9sYW5nL0NsYXNzOwATW0xqYXZhL2xhbmcvT2JqZWN0OwATW0xqYXZhL2xhbmcvU3RyaW5nOwAHY29udGV4dAAXZGFsdmlrLnN5c3RlbS5WTVJ1bnRpbWUAAWUABmV4ZW1wdAAJZXhlbXB0QWxsAAdmb3JOYW1lAA9mcmVlLXJlZmxlY3Rpb24AEmdldEFwcGxpY2F0aW9uSW5mbwARZ2V0RGVjbGFyZWRNZXRob2QACmdldFJ1bnRpbWUABmludm9rZQALbG9hZExpYnJhcnkAGG1lLndlaXNodS5mcmVlcmVmbGVjdGlvbgAGbWV0aG9kAAdtZXRob2RzABlyZWZsZWN0IGJvb3RzdHJhcCBmYWlsZWQ6AAdyZWxlYXNlAApzVm1SdW50aW1lABZzZXRIaWRkZW5BcGlFeGVtcHRpb25zABB0YXJnZXRTZGtWZXJzaW9uAAZ1bnNlYWwADHVuc2VhbE5hdGl2ZQAOdm1SdW50aW1lQ2xhc3MAAQAAAAoAAAACAAAACgAQAAEAAAASAAAAAQAAAAAAAAADAAAACgAKAAwAAAABAAAAAQAAAAIAAAAJABEAARcGBhc4FzwfFwAEARcBARcfAAAAAAAABgAHDgAWAAcOav8DATIOARUQAwI1DvAEBEMJGgESDwMDNg4BGw+pBQIFAwUEGR4DAC8NAA4ABw4ALAE6Bw4ANgE7ByydGuIBAQMALw0eAEgABw4ADQAHDgATAS0HHXIZa1oAAAEAAQABAAAANAgAAAQAAABwEAwAAAAOAAoAAAADAAEAOQgAAHsAAABgBQEAEwYcADRlbQAcBQgAGgYxABIXI3cQABIIHAkKAE0JBwhuMAsAZQcMARwFCAAaBjQAEicjdxAAEggcCQoATQkHCBIYHAkQAE0JBwhuMAsAZQcMAhIFEhYjZhEAEgcaCC0ATQgGB24wDgBRBgwEHwQIABIlI1URABIGGgc1AE0HBQYSFhIHTQcFBm4wDgBCBQwDHwMNABIlI1URABIGGgc+AE0HBQYSFhIXI3cQABIIHAkSAE0JBwhNBwUGbjAOAEIFDAUfBQ0AaQUKABIFEgYjZhEAbjAOAFMGDAVpBQkADgANABoFBgAaBjsAcTABAGUAKPcAAAYAAABrAAEAAQEMcgEAAQABAAAAaAgAAAQAAABwEAwAAAAOAAMAAQABAAAAbQgAAAsAAAASECMAEgASAU0CAAFxEAYAAAAKAA8AAAAIAAEAAwABAHMIAAAdAAAAEhESAmIDCQA4AwYAYgMKADkDBAABIQ8BYgMKAGIECQASFSNVEQASBk0HBQZuMA4AQwUo8g0AASEo7wAADAAAAA0AAQABAQwaAwAAAAEAAACDCAAADQAAABIQIwASABIBGgIPAE0CAAFxEAYAAAAKAA8AAAABAAEAAQAAAIgIAAAEAAAAcBAMAAAADgAEAAEAAQAAAI0IAAAeAAAAEgBgAQEAEwIcADUhAwAPAHEABwAAAAoBOQH7/xoAMgBxEA0AAABuEAAAAwAMAFIAAABxEAoAAAAKACjqBgABAAIZARkBGQEZARkBGQKBgASYEQMABQAIGgEKAQoDiIAEsBEBgYAExBMBCdwTAYkBhBQBCdwUAQADAAsaCIGABIgVAQmgFQGKAgAAAAAPAAAAAAAAAAEAAAAAAAAAAQAAAEMAAABwAAAAAgAAABMAAAB8AQAAAwAAAAsAAADIAQAABAAAAAwAAABMAgAABQAAAA8AAACsAgAABgAAAAMAAAAkAwAAAiAAAEMAAACEAwAAARAAAAcAAADgBwAABSAAAAMAAAAcCAAAAxAAAAEAAAAwCAAAAyAAAAgAAAA0CAAAASAAAAgAAACYCAAAACAAAAMAAADsCgAAABAAAAEAAAA8CwAA\";\n" + - "\n" + - " private static native int unsealNative(int targetSdkVersion);\n" + - "\n" + - " public static int unseal(Context context) {\n" + - " if (SDK_INT < 28) {\n" + - " // Below Android P, ignore\n" + - " return 0;\n" + - " }\n" + - " // try exempt API first.\n" + - " if (exemptAll()) {\n" + - " return 0;\n" + - " }\n" + - " if (unsealByDexFile(context)) {\n" + - " return 0;\n" + - " }\n" + - " return -1;\n" + - " }\n" + - "\n" + - " @SuppressWarnings({\"deprecation\", \"ResultOfMethodCallIgnored\"})\n" + - " private static boolean unsealByDexFile(Context context) {\n" + - " byte[] bytes = Base64.decode(DEX, Base64.NO_WRAP);\n" + - " File codeCacheDir = getCodeCacheDir(context);\n" + - " if (codeCacheDir == null) {\n" + - " return false;\n" + - " }\n" + - " File code = new File(codeCacheDir, \"__temp_\" + System.currentTimeMillis() + \".dex\");\n" + - " try {\n" + - " try (FileOutputStream fos = new FileOutputStream(code)) {\n" + - " fos.write(bytes);\n" + - " }\n" + - " DexFile dexFile = new DexFile(code);\n" + - " // This class is hardcoded in the dex, Don't use BootstrapClass.class to reference it\n" + - " // it maybe obfuscated!!\n" + - " Class bootstrapClass = dexFile.loadClass(\"com.highcapable.yukihookapi.thirdparty.me.weishu.reflection.BootstrapClass\", null);\n" + - " Method exemptAll = bootstrapClass.getDeclaredMethod(\"exemptAll\");\n" + - " return (boolean) exemptAll.invoke(null);\n" + - " } catch (Throwable e) {\n" + - " e.printStackTrace();\n" + - " return false;\n" + - " } finally {\n" + - " if (code.exists()) {\n" + - " code.delete();\n" + - " }\n" + - " }\n" + - " }\n" + - "\n" + - " private static File getCodeCacheDir(Context context) {\n" + - " if (context != null) {\n" + - " return context.getCodeCacheDir();\n" + - " }\n" + - " String tmpDir = System.getProperty(\"java.io.tmpdir\");\n" + - " if (TextUtils.isEmpty(tmpDir)) {\n" + - " return null;\n" + - " }\n" + - " File tmp = new File(tmpDir);\n" + - " if (!tmp.exists()) {\n" + - " return null;\n" + - " }\n" + - " return tmp;\n" + - " }\n" + - "}") + """.trimIndent() ) \ No newline at end of file diff --git a/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/thirdparty/me/weishu/reflection/Reflection.java b/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/thirdparty/me/weishu/reflection/Reflection.java deleted file mode 100644 index 33ef03de..00000000 --- a/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/thirdparty/me/weishu/reflection/Reflection.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. - * Copyright (C) 2019-2022 HighCapable - * https://github.com/fankes/YukiHookAPI - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This file is Created by weishu on 2018/6/7. - * This file is Forked from https://github.com/tiann/FreeReflection and make it to stub - */ -package com.highcapable.yukihookapi.thirdparty.me.weishu.reflection; - -import android.content.Context; - -/** - * FreeReflection 注入 Stub - */ -@SuppressWarnings("unused") -public class Reflection { - - /** - * 调用启动方法 - *

- * 方法内容将在每次编译时自动生成 - * - * @param context The Base Context - * @return int - */ - public static int unseal(Context context) { - throw new RuntimeException("Stub!"); - } -} \ No newline at end of file