diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus.kt index 5dbbf467..30be6095 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus.kt @@ -29,6 +29,10 @@ package com.highcapable.yukihookapi.hook.xposed.bridge.status import com.highcapable.yukihookapi.YukiHookAPI +import com.highcapable.yukihookapi.hook.core.finder.members.MethodFinder +import com.highcapable.yukihookapi.hook.factory.method +import com.highcapable.yukihookapi.hook.factory.toClass +import com.highcapable.yukihookapi.hook.log.YLog /** * 这是一个 Xposed 模块 Hook 状态类 @@ -54,8 +58,11 @@ internal object YukiXposedModuleStatus { internal const val GET_EXECUTOR_VERSION_NAME_METHOD_NAME = "-_-_" internal const val GET_EXECUTOR_VERSION_CODE_METHOD_NAME = "___-" - /** [YukiXposedModuleStatus_Impl] 完整类名 */ - internal const val IMPL_CLASS_NAME = "com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiXposedModuleStatus_Impl" + /** + * 获取 YukiXposedModuleStatus 完整类名 + * @return [String] + */ + internal val className get() = runCatching { YukiXposedModuleStatus_Impl.className }.getOrNull() ?: "" /** * 获取当前模块的激活状态 @@ -63,7 +70,7 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.isModuleActive]、[YukiHookAPI.Status.isXposedModuleActive]、[YukiHookAPI.Status.isTaiChiModuleActive] 判断模块激活状态 * @return [Boolean] */ - internal val isActive get() = runCatching { YukiXposedModuleStatus_Impl.isActive() }.getOrNull() ?: false + internal val isActive get() = classMethod(IS_ACTIVE_METHOD_NAME).boolean() /** * 获取当前 Hook Framework 是否支持资源钩子 (Resources Hook) @@ -71,7 +78,7 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.isSupportResourcesHook] 判断支持状态 * @return [Boolean] */ - internal val isSupportResourcesHook get() = runCatching { YukiXposedModuleStatus_Impl.isSupportResourcesHook() }.getOrNull() ?: false + internal val isSupportResourcesHook get() = classMethod(IS_SUPPORT_RESOURCES_HOOK_METHOD_NAME).boolean() /** * 获取当前 Hook Framework 名称 @@ -79,7 +86,7 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.Executor.name] 获取 * @return [String] 模块未激活会返回 unknown */ - internal val executorName get() = runCatching { YukiXposedModuleStatus_Impl.getExecutorName() }.getOrNull() ?: "unknown" + internal val executorName get() = classMethod(GET_EXECUTOR_NAME_METHOD_NAME).string().ifBlank { "unknown" } /** * 获取当前 Hook Framework 的 API 版本 @@ -87,7 +94,7 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.Executor.apiLevel] 获取 * @return [Int] 模块未激活会返回 -1 */ - internal val executorApiLevel get() = runCatching { YukiXposedModuleStatus_Impl.getExecutorApiLevel() }.getOrNull() ?: -1 + internal val executorApiLevel get() = classMethod(GET_EXECUTOR_API_LEVEL_METHOD_NAME).int().takeIf { it > 0 } ?: -1 /** * 获取当前 Hook Framework 版本名称 @@ -95,7 +102,7 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.Executor.versionName] 获取 * @return [Int] 模块未激活会返回 unknown */ - internal val executorVersionName get() = runCatching { YukiXposedModuleStatus_Impl.getExecutorVersionName() }.getOrNull() ?: "unknown" + internal val executorVersionName get() = classMethod(GET_EXECUTOR_VERSION_NAME_METHOD_NAME).string().ifBlank { "unknown" } /** * 获取当前 Hook Framework 版本号 @@ -103,5 +110,14 @@ internal object YukiXposedModuleStatus { * 请使用 [YukiHookAPI.Status.Executor.versionCode] 获取 * @return [Int] 模块未激活会返回 -1 */ - internal val executorVersionCode get() = runCatching { YukiXposedModuleStatus_Impl.getExecutorVersionCode() }.getOrNull() ?: -1 + internal val executorVersionCode get() = classMethod(GET_EXECUTOR_VERSION_CODE_METHOD_NAME).int().takeIf { it > 0 } ?: -1 + + /** + * 通过 [className] 获取方法实例 + * @param name 方法名称 + * @return [MethodFinder.Result.Instance] + */ + private fun classMethod(name: String) = className.toClass().method { this.name = name }.ignored().onNoSuchMethod { + YLog.innerW("Failed to initialize YukiXposedModuleStatus", it) + }.get() } \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt index def6e974..49bebc7d 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt @@ -228,7 +228,7 @@ internal object AppParasitics { } }) if (YukiHookAPI.Configs.isEnableHookModuleStatus.not()) return - YukiXposedModuleStatus.IMPL_CLASS_NAME.toClassOrNull(loader)?.apply { + YukiXposedModuleStatus.className.toClassOrNull(loader)?.apply { if (type != HookEntryType.RESOURCES) { YukiHookHelper.hook(method { name = YukiXposedModuleStatus.IS_ACTIVE_METHOD_NAME }, object : YukiMemberReplacement() { 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 4bd9e5b7..d3c54525 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 @@ -280,6 +280,12 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { packageName = PackageName.YukiXposedModuleStatus_Impl, content = data.sources()[ClassName.YukiXposedModuleStatus_Impl] ) + /** 插入 YukiXposedModuleStatus_Impl_Impl 代码 */ + createCodeFile( + fileName = ClassName.YukiXposedModuleStatus_Impl_Impl, + packageName = PackageName.YukiXposedModuleStatus_Impl, + content = data.sources()[ClassName.YukiXposedModuleStatus_Impl_Impl] + ) /** 插入 HandlerDelegateImpl_Impl 代码 */ createCodeFile( fileName = ClassName.HandlerDelegateImpl_Impl, 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 4112c634..07e74df6 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 @@ -54,6 +54,7 @@ object ClassName { const val YukiHookAPI_Impl = "YukiHookAPI_Impl" const val ModuleApplication_Impl = "ModuleApplication_Impl" const val YukiXposedModuleStatus_Impl = "YukiXposedModuleStatus_Impl" + const val YukiXposedModuleStatus_Impl_Impl = "YukiXposedModuleStatus_Impl_Impl" const val HandlerDelegateImpl_Impl = "HandlerDelegateImpl_Impl" const val HandlerDelegateClass = "HandlerDelegate" const val IActivityManagerProxyImpl_Impl = "IActivityManagerProxyImpl_Impl" @@ -162,49 +163,68 @@ fun GenerateData.sources() = mapOf( package ${PackageName.YukiXposedModuleStatus_Impl} + """.trimIndent() + "\n\n" + createCommentContent(ClassName.YukiXposedModuleStatus_Impl) + "\n" + """ + object ${ClassName.YukiXposedModuleStatus_Impl} { + + val className get() = "${PackageName.YukiXposedModuleStatus_Impl}.${tailPackageName(ClassName.YukiXposedModuleStatus_Impl_Impl)}" + } + """.trimIndent(), + ClassName.YukiXposedModuleStatus_Impl_Impl to """ + @file:Suppress("ClassName") + + package ${PackageName.YukiXposedModuleStatus_Impl} + import android.util.Log import androidx.annotation.Keep """.trimIndent() + "\n\n" + createCommentContent(ClassName.YukiXposedModuleStatus_Impl) + "\n" + """ @Keep - object ${ClassName.YukiXposedModuleStatus_Impl} { + object ${tailPackageName(ClassName.YukiXposedModuleStatus_Impl_Impl)} { + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.IS_ACTIVE_METHOD_NAME}") - fun isActive(): Boolean { - placeholderExecution() + fun function${(1000..99999).random()}(): Boolean { + phe() return false } + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.IS_SUPPORT_RESOURCES_HOOK_METHOD_NAME}") - fun isSupportResourcesHook(): Boolean { - placeholderExecution() + fun function${(1000..99999).random()}(): Boolean { + phe() return false } + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.GET_EXECUTOR_NAME_METHOD_NAME}") - fun getExecutorName(): String { - placeholderExecution() + fun function${(1000..99999).random()}(): String { + phe() return "unknown" } + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.GET_EXECUTOR_API_LEVEL_METHOD_NAME}") - fun getExecutorApiLevel(): Int { - placeholderExecution() + fun function${(1000..99999).random()}(): Int { + phe() return -1 } + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.GET_EXECUTOR_VERSION_NAME_METHOD_NAME}") - fun getExecutorVersionName(): String { - placeholderExecution() + fun function${(1000..99999).random()}(): String { + phe() return "unknown" } + @JvmStatic @JvmName("${YukiXposedModuleStatusJvmName.GET_EXECUTOR_VERSION_CODE_METHOD_NAME}") - fun getExecutorVersionCode(): Int { - placeholderExecution() + fun function${(1000..99999).random()}(): Int { + phe() return -1 } - private fun placeholderExecution() { + @JvmStatic + @JvmName("_${(1000..99999).random()}") + private fun phe() { /** Consume a long method body */ if (System.currentTimeMillis() == 0L) Log.d("${(1000..9999).random()}", "${(100000..999999).random()}") } diff --git a/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus_Impl.kt b/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus_Impl.kt index 7db81b94..9f0218b1 100644 --- a/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus_Impl.kt +++ b/yukihookapi-stub/src/main/java/com/highcapable/yukihookapi/hook/xposed/bridge/status/YukiXposedModuleStatus_Impl.kt @@ -35,64 +35,9 @@ package com.highcapable.yukihookapi.hook.xposed.bridge.status */ object YukiXposedModuleStatus_Impl { - private const val IS_ACTIVE_METHOD_NAME = "__--" - private const val IS_SUPPORT_RESOURCES_HOOK_METHOD_NAME = "_--_" - private const val GET_EXECUTOR_NAME_METHOD_NAME = "_-_-" - private const val GET_EXECUTOR_API_LEVEL_METHOD_NAME = "-__-" - private const val GET_EXECUTOR_VERSION_NAME_METHOD_NAME = "-_-_" - private const val GET_EXECUTOR_VERSION_CODE_METHOD_NAME = "___-" - /** - * 此方法经过 Hook 后返回 true 即模块已激活 - * - * 返回值将在每次编译时自动生成 - * @return [Boolean] - */ - @JvmName(IS_ACTIVE_METHOD_NAME) - fun isActive(): Boolean = error("Stub!") - - /** - * 此方法经过 Hook 后返回 true 即当前 Hook Framework 支持资源钩子 (Resources Hook) - * - * 返回值将在每次编译时自动生成 - * @return [Boolean] - */ - @JvmName(IS_SUPPORT_RESOURCES_HOOK_METHOD_NAME) - fun isSupportResourcesHook(): Boolean = error("Stub!") - - /** - * 此方法经过 Hook 后返回当前 Hook Framework 名称 - * - * 返回值将在每次编译时自动生成 + * 获取 YukiXposedModuleStatus 完整类名 * @return [String] */ - @JvmName(GET_EXECUTOR_NAME_METHOD_NAME) - fun getExecutorName(): String = error("Stub!") - - /** - * 此方法经过 Hook 后返回当前 Hook Framework 的 API 版本 - * - * 返回值将在每次编译时自动生成 - * @return [Int] - */ - @JvmName(GET_EXECUTOR_API_LEVEL_METHOD_NAME) - fun getExecutorApiLevel(): Int = error("Stub!") - - /** - * 此方法经过 Hook 后返回当前 Hook Framework 版本名称 - * - * 返回值将在每次编译时自动生成 - * @return [String] - */ - @JvmName(GET_EXECUTOR_VERSION_NAME_METHOD_NAME) - fun getExecutorVersionName(): String = error("Stub!") - - /** - * 此方法经过 Hook 后返回当前 Hook Framework 版本号 - * - * 返回值将在每次编译时自动生成 - * @return [Int] - */ - @JvmName(GET_EXECUTOR_VERSION_CODE_METHOD_NAME) - fun getExecutorVersionCode(): Int = error("Stub!") + val className: String = error("Stub!") } \ No newline at end of file