mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Modify move ClassLoader.fetching in PackageParam to ClassLoader.onLoadClass in ReflectionFactory and fix reuse problem
This commit is contained in:
@@ -37,6 +37,7 @@ import com.highcapable.yukihookapi.hook.core.finder.members.MethodFinder
|
||||
import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool
|
||||
import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules
|
||||
import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiHookModuleStatus
|
||||
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
|
||||
import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Member
|
||||
@@ -65,6 +66,18 @@ enum class MembersType {
|
||||
CONSTRUCTOR
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听当前 [ClassLoader] 的 [ClassLoader.loadClass] 方法装载
|
||||
*
|
||||
* - ❗请注意只有当前 [ClassLoader] 有主动使用 [ClassLoader.loadClass] 事件时才能被捕获
|
||||
*
|
||||
* - ❗这是一个实验性功能 - 一般情况下不会用到此方法 - 不保证不会发生错误
|
||||
*
|
||||
* - ❗只能在 (Xposed) 宿主环境使用此功能 - 其它环境下使用将不生效且会打印警告信息
|
||||
* @param result 回调 - ([Class] 实例对象)
|
||||
*/
|
||||
fun ClassLoader.onLoadClass(result: (Class<*>) -> Unit) = AppParasitics.hookClassLoader(loader = this, result)
|
||||
|
||||
/**
|
||||
* 当前 [Class] 是否有继承关系 - 父类是 [Any] 将被认为没有继承关系
|
||||
* @return [Boolean]
|
||||
|
@@ -378,16 +378,6 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
|
||||
*/
|
||||
fun findClass(vararg name: String, loader: ClassLoader? = appClassLoader) = VariousClass(*name).toHookClass(loader)
|
||||
|
||||
/**
|
||||
* 监听并 Hook 当前 [ClassLoader] 的 [ClassLoader.loadClass] 方法
|
||||
*
|
||||
* - ❗请注意只有当前 [ClassLoader] 有主动使用 [ClassLoader.loadClass] 事件时才能被捕获
|
||||
*
|
||||
* - ❗这是一个实验性功能 - 一般情况下不会用到此方法 - 不保证不会发生错误
|
||||
* @param result 回调 - ([Class] 实例对象,[Boolean] 是否 resolve)
|
||||
*/
|
||||
fun ClassLoader.fetching(result: (clazz: Class<*>, resolve: Boolean) -> Unit) = AppParasitics.hookClassLoader(loader = this, result)
|
||||
|
||||
/**
|
||||
* Hook 方法、构造方法
|
||||
*
|
||||
|
@@ -71,6 +71,12 @@ internal object AppParasitics {
|
||||
/** [Activity] 代理是否已经注册 */
|
||||
private var isActivityProxyRegister = false
|
||||
|
||||
/** [ClassLoader] 是否已被 Hook */
|
||||
private var isClassLoaderHooked = false
|
||||
|
||||
/** [ClassLoader] 监听回调数组 */
|
||||
private var classLoaderCallbacks = HashMap<Int, (Class<*>) -> Unit>()
|
||||
|
||||
/**
|
||||
* 当前 Hook APP (宿主) 的全局生命周期 [Application]
|
||||
*
|
||||
@@ -234,16 +240,22 @@ internal object AppParasitics {
|
||||
/**
|
||||
* 监听并 Hook 当前 [ClassLoader] 的 [ClassLoader.loadClass] 方法
|
||||
* @param loader 当前 [ClassLoader]
|
||||
* @param result 回调 - ([Class] 实例对象,[Boolean] 是否 resolve)
|
||||
* @param result 回调 - ([Class] 实例对象)
|
||||
*/
|
||||
internal fun hookClassLoader(loader: ClassLoader?, result: (clazz: Class<*>, resolve: Boolean) -> Unit) {
|
||||
internal fun hookClassLoader(loader: ClassLoader?, result: (Class<*>) -> Unit) {
|
||||
if (loader == null) return
|
||||
if (YukiHookBridge.hasXposedBridge.not()) return yLoggerW(msg = "You can only use hook ClassLoader method in Xposed Environment")
|
||||
classLoaderCallbacks[loader.hashCode()] = result
|
||||
if (isClassLoaderHooked) return
|
||||
runCatching {
|
||||
YukiHookHelper.hook(JavaClassLoader.method { name = "loadClass"; param(StringType, BooleanType) }, object : YukiMemberHook() {
|
||||
override fun afterHookedMember(param: Param) {
|
||||
if (param.instance?.javaClass?.name == loader?.javaClass?.name)
|
||||
(param.result as? Class<*>?)?.also { result(it, param.args?.get(1) as? Boolean ?: false) }
|
||||
param.instance?.also { loader ->
|
||||
(param.result as? Class<*>?)?.also { classLoaderCallbacks[loader.hashCode()]?.invoke(it) }
|
||||
}
|
||||
}
|
||||
})
|
||||
isClassLoaderHooked = true
|
||||
}.onFailure { yLoggerW(msg = "Try to hook ClassLoader failed: $it") }
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user