From e9d28847d6aabf278d2c4264833018a0849f6b29 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Fri, 30 Sep 2022 01:30:43 +0800 Subject: [PATCH] Added excludeHostClasses, excludeModuleClasses function in ModuleClassLoader --- docs-source/src/.vuepress/configs/template.ts | 1 + .../parasitic/reference/ModuleClassLoader.md | 75 +++++++++++++++++++ .../parasitic/reference/ModuleClassLoader.md | 67 +++++++++++++++++ .../parasitic/reference/ModuleClassLoader.kt | 54 +++++++++++-- 4 files changed, 190 insertions(+), 7 deletions(-) create mode 100644 docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md create mode 100644 docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md diff --git a/docs-source/src/.vuepress/configs/template.ts b/docs-source/src/.vuepress/configs/template.ts index 96992ae5..dbf77d05 100644 --- a/docs-source/src/.vuepress/configs/template.ts +++ b/docs-source/src/.vuepress/configs/template.ts @@ -38,6 +38,7 @@ const navigationLinks = { baseApiPath + 'hook/xposed/parasitic/activity/base/ModuleAppActivity', baseApiPath + 'hook/xposed/parasitic/activity/base/ModuleAppCompatActivity', baseApiPath + 'hook/xposed/parasitic/context/wrapper/ModuleContextThemeWrapper', + baseApiPath + 'hook/xposed/parasitic/reference/ModuleClassLoader', baseApiPath + 'hook/xposed/bridge/dummy/YukiModuleResources', baseApiPath + 'hook/xposed/bridge/dummy/YukiResources', baseApiPath + 'hook/xposed/bridge/dummy/YukiResForwarder', diff --git a/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md new file mode 100644 index 00000000..8500d322 --- /dev/null +++ b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md @@ -0,0 +1,75 @@ +--- +pageClass: code-page +--- + +::: warning + +The English translation of this page has not been completed, you are welcome to contribute translations to us. + +You can use the **Chrome Translation Plugin** to translate entire pages for reference. + +::: + +# ModuleClassLoader - class + +```kotlin:no-line-numbers +class ModuleClassLoader private constructor() : ClassLoader +``` + +**Change Records** + +`v1.1.2` `added` + +**Function Illustrate** + +> 自动处理 (Xposed) 宿主环境与模块环境的 `ClassLoader`。 + +## companion object - object + +**Change Records** + +`v1.1.2` `added` + +### excludeHostClasses - method + +```kotlin:no-line-numbers +fun excludeHostClasses(vararg name: String) +``` + +**Change Records** + +`v1.1.2` `added` + +**Function Illustrate** + +> 添加到 Hook APP (宿主) `Class` 排除列表。 + +排除列表中的 `Class` 将会使用宿主的 `ClassLoader` 进行装载。 + +::: danger + +排除列表仅会在 (Xposed) 宿主环境生效。 + +::: + +### excludeModuleClasses - method + +```kotlin:no-line-numbers +fun excludeModuleClasses(vararg name: String) +``` + +**Change Records** + +`v1.1.2` `added` + +**Function Illustrate** + +> 添加到模块 `Class` 排除列表。 + +排除列表中的 `Class` 将会使用模块 (当前宿主环境的模块注入进程) 的 `ClassLoader` 进行装载。 + +::: danger + +排除列表仅会在 (Xposed) 宿主环境生效。 + +::: \ No newline at end of file diff --git a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md new file mode 100644 index 00000000..ee8750c6 --- /dev/null +++ b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.md @@ -0,0 +1,67 @@ +--- +pageClass: code-page +--- + +# ModuleClassLoader - class + +```kotlin:no-line-numbers +class ModuleClassLoader private constructor() : ClassLoader +``` + +**变更记录** + +`v1.1.2` `新增` + +**功能描述** + +> 自动处理 (Xposed) 宿主环境与模块环境的 `ClassLoader`。 + +## companion object - object + +**变更记录** + +`v1.1.2` `新增` + +### excludeHostClasses - method + +```kotlin:no-line-numbers +fun excludeHostClasses(vararg name: String) +``` + +**变更记录** + +`v1.1.2` `新增` + +**功能描述** + +> 添加到 Hook APP (宿主) `Class` 排除列表。 + +排除列表中的 `Class` 将会使用宿主的 `ClassLoader` 进行装载。 + +::: danger + +排除列表仅会在 (Xposed) 宿主环境生效。 + +::: + +### excludeModuleClasses - method + +```kotlin:no-line-numbers +fun excludeModuleClasses(vararg name: String) +``` + +**变更记录** + +`v1.1.2` `新增` + +**功能描述** + +> 添加到模块 `Class` 排除列表。 + +排除列表中的 `Class` 将会使用模块 (当前宿主环境的模块注入进程) 的 `ClassLoader` 进行装载。 + +::: danger + +排除列表仅会在 (Xposed) 宿主环境生效。 + +::: \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.kt index 4c5acf8f..ab6eb250 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/reference/ModuleClassLoader.kt @@ -26,6 +26,8 @@ * This file is Created by fankes on 2022/8/8. * Thanks for providing https://github.com/cinit/QAuxiliary/blob/main/app/src/main/java/io/github/qauxv/lifecycle/Parasitics.java */ +@file:Suppress("unused") + package com.highcapable.yukihookapi.hook.xposed.parasitic.reference import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge @@ -35,26 +37,64 @@ import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics /** * 自动处理 (Xposed) 宿主环境与模块环境的 [ClassLoader] */ -internal class ModuleClassLoader private constructor() : ClassLoader(AppParasitics.baseClassLoader) { +class ModuleClassLoader private constructor() : ClassLoader(AppParasitics.baseClassLoader) { - internal companion object { + companion object { /** 当前 [ModuleClassLoader] 单例 */ private var instance: ModuleClassLoader? = null + /** 排除的 Hook APP (宿主) [Class] 类名数组 */ + private val excludeHostClasses = HashSet() + + /** 排除的模块 [Class] 类名数组 */ + private val excludeModuleClasses = HashSet() + /** * 获取 [ModuleClassLoader] 单例 * @return [ModuleClassLoader] */ internal fun instance() = instance ?: ModuleClassLoader().apply { instance = this } + + /** + * 添加到 Hook APP (宿主) [Class] 排除列表 + * + * 排除列表中的 [Class] 将会使用宿主的 [ClassLoader] 进行装载 + * + * - ❗排除列表仅会在 (Xposed) 宿主环境生效 + * @param name 需要添加的 [Class] 完整类名 + */ + fun excludeHostClasses(vararg name: String) { + excludeHostClasses.addAll(name.toList()) + } + + /** + * 添加到模块 [Class] 排除列表 + * + * 排除列表中的 [Class] 将会使用模块 (当前宿主环境的模块注入进程) 的 [ClassLoader] 进行装载 + * + * - ❗排除列表仅会在 (Xposed) 宿主环境生效 + * @param name 需要添加的 [Class] 完整类名 + */ + fun excludeModuleClasses(vararg name: String) { + excludeModuleClasses.addAll(name.toList()) + } + + init { + excludeHostClasses.add("androidx.lifecycle.ReportFragment") + } } + /** 默认 [ClassLoader] */ + private val baseLoader get() = AppParasitics.baseClassLoader + override fun loadClass(name: String, resolve: Boolean): Class<*> { - if (YukiHookBridge.hasXposedBridge.not()) return AppParasitics.baseClassLoader.loadClass(name) - return YukiHookAppHelper.currentApplication()?.classLoader?.let { loader -> - runCatching { if (name == "androidx.lifecycle.ReportFragment") return@let loader.loadClass(name) } - runCatching { return@let AppParasitics.baseClassLoader.loadClass(name) } - runCatching { AppParasitics.baseClassLoader.loadClass(name) }.getOrNull() ?: loader.loadClass(name) + if (YukiHookBridge.hasXposedBridge.not()) return baseLoader.loadClass(name) + return YukiHookAppHelper.currentApplication()?.classLoader?.let { hostLoader -> + excludeHostClasses.takeIf { it.isNotEmpty() }?.forEach { runCatching { if (name == it) return@let hostLoader.loadClass(name) } } + excludeModuleClasses.takeIf { it.isNotEmpty() }?.forEach { runCatching { if (name == it) return@let baseLoader.loadClass(name) } } + runCatching { return@let baseLoader.loadClass(name) } + runCatching { baseLoader.loadClass(name) }.getOrNull() ?: hostLoader.loadClass(name) } ?: super.loadClass(name, resolve) } } \ No newline at end of file