Fix Xposed Module load scope single process multiple package names problem and make PackageParam to multiple instances in YukiXposedModule

This commit is contained in:
2023-01-20 23:45:04 +08:00
parent 3e55d6178d
commit 3b56218fd2
3 changed files with 33 additions and 4 deletions

View File

@@ -46,6 +46,7 @@ import com.highcapable.yukihookapi.hook.core.finder.classes.DexClassFinder
import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool
import com.highcapable.yukihookapi.hook.core.finder.type.factory.ClassConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.ClassConditions
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.log.yLoggerW
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
import com.highcapable.yukihookapi.hook.utils.value import com.highcapable.yukihookapi.hook.utils.value
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule
@@ -427,7 +428,21 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
* 你可以在 Hooker 中继续装载 Hooker * 你可以在 Hooker 中继续装载 Hooker
* @param hooker Hook 子类 * @param hooker Hook 子类
*/ */
fun loadHooker(hooker: YukiBaseHooker) = hooker.assignInstance(packageParam = this) fun loadHooker(hooker: YukiBaseHooker) {
hooker.wrapper?.also {
if (it.packageName.isNotBlank() && it.type != HookEntryType.ZYGOTE)
if (it.packageName == wrapper?.packageName)
hooker.assignInstance(packageParam = this)
else yLoggerW(
msg = "This Hooker \"${hooker::class.java.name}\" is singleton or reused, " +
"but the current process has multiple package name \"${wrapper?.packageName}\", " +
"the original is \"${it.packageName}\"\n" +
"Make sure your Hooker supports multiple instances for this situation\n" +
"The process with package name \"${wrapper?.packageName}\" will be ignored"
)
else hooker.assignInstance(packageParam = this)
} ?: hooker.assignInstance(packageParam = this)
}
/** /**
* 通过 [appClassLoader] 按指定条件查找并得到当前 Hook APP Dex 中的 [Class] * 通过 [appClassLoader] 按指定条件查找并得到当前 Hook APP Dex 中的 [Class]

View File

@@ -54,6 +54,12 @@ internal class PackageParamWrapper internal constructor(
var appResources: YukiResources? = null var appResources: YukiResources? = null
) { ) {
/**
* 获取当前包装实例的名称 ID
* @return [String]
*/
internal val wrapperNameId get() = if (type == HookEntryType.ZYGOTE) "android-zygote" else packageName
/** /**
* 获取当前正在进行的 Hook 进程是否正确 * 获取当前正在进行的 Hook 进程是否正确
* *

View File

@@ -57,8 +57,8 @@ internal object YukiXposedModule : IYukiXposedModuleLifecycle {
/** 当前 Hook 进程是否正处于 Zygote */ /** 当前 Hook 进程是否正处于 Zygote */
private var isInitializingZygote = false private var isInitializingZygote = false
/** 当前 [PackageParam] 实例 */ /** 当前 [PackageParam] 实例数组 */
private val packageParam = PackageParam() private val packageParams = HashMap<String, PackageParam>()
/** 已在 [PackageParam] 中被装载的 APP 包名 */ /** 已在 [PackageParam] 中被装载的 APP 包名 */
private val loadedPackageNames = HashSet<String>() private val loadedPackageNames = HashSet<String>()
@@ -126,6 +126,14 @@ internal object YukiXposedModule : IYukiXposedModuleLifecycle {
return false return false
} }
/**
* 实例化当前 [PackageParamWrapper] 到 [PackageParam]
*
* 如果实例不存在将会自动创建一个新实例
* @return [PackageParam]
*/
private fun PackageParamWrapper.instantiate() = packageParams[wrapperNameId] ?: PackageParam().apply { packageParams[wrapperNameId] = this }
/** /**
* 创建、修改 [PackageParamWrapper] * 创建、修改 [PackageParamWrapper]
* *
@@ -206,7 +214,7 @@ internal object YukiXposedModule : IYukiXposedModuleLifecycle {
else null else null
}?.also { }?.also {
runCatching { runCatching {
if (it.isCorrectProcess) packageParamCallback?.invoke(packageParam.assign(it).apply { YukiHookAPI.printSplashInfo() }) if (it.isCorrectProcess) packageParamCallback?.invoke(it.instantiate().assign(it).apply { YukiHookAPI.printSplashInfo() })
if (it.type != HookEntryType.ZYGOTE && it.packageName == modulePackageName) if (it.type != HookEntryType.ZYGOTE && it.packageName == modulePackageName)
AppParasitics.hookModuleAppRelated(it.appClassLoader, it.type) AppParasitics.hookModuleAppRelated(it.appClassLoader, it.type)
if (it.type == HookEntryType.PACKAGE) AppParasitics.registerToAppLifecycle(it.packageName) if (it.type == HookEntryType.PACKAGE) AppParasitics.registerToAppLifecycle(it.packageName)