Modify move classOf to toClass function in ReflectionFactory

This commit is contained in:
2022-09-06 01:52:18 +08:00
parent 5eff2262c5
commit c20b297006
10 changed files with 75 additions and 56 deletions

View File

@@ -551,7 +551,7 @@ fun findClass(vararg name: String, loader: ClassLoader?): VariousClass
> 通过完整包名+名称查找需要被 Hook 的 `Class`。 > 通过完整包名+名称查找需要被 Hook 的 `Class`。
!> 使用此方法会得到一个 `HookClass` 仅用于 Hook若想查找 `Class` 请使用 `classOf``toAppClass` 功能。 !> 使用此方法会得到一个 `HookClass` 仅用于 Hook若想查找 `Class` 请使用 `toClass``toAppClass` 功能。
**功能示例** **功能示例**

View File

@@ -108,28 +108,38 @@ val Class<*>.hasExtends: Boolean
> 当前 `Class` 是否有继承关系,父类是 `Any` 将被认为没有继承关系。 > 当前 `Class` 是否有继承关系,父类是 `Any` 将被认为没有继承关系。
### classOf *- method* ### ~~classOf *- method*~~ <!-- {docsify-ignore} -->
```kotlin
fun classOf(name: String, loader: ClassLoader?): Class<*>
```
**变更记录** **变更记录**
`v1.0` `添加` `v1.0` `添加`
`v1.0.93` `移除`
请转到 `toClass(...)` 方法
### String.toClass *- ext-method*
```kotlin
fun String.toClass(loader: ClassLoader?): Class<*>
```
**变更记录**
`v1.0.93` `新增`
**功能描述** **功能描述**
> 通过字符串使用指定的 `ClassLoader` 转换为实体类。 > 通过字符串类名转换为 `loader` 中的实体类。
**功能示例** **功能示例**
你可以直接填写你要查找的目标 `Class`,必须在当前 `ClassLoader` 下存在。 你可以直接填写你要查找的目标 `Class`,必须在默认 `ClassLoader` 下存在。
> 示例如下 > 示例如下
```kotlin ```kotlin
classOf(name = "com.example.demo.DemoClass") "com.example.demo.DemoClass".toClass()
``` ```
你还可以自定义 `Class` 所在的 `ClassLoader` 你还可以自定义 `Class` 所在的 `ClassLoader`
@@ -138,7 +148,7 @@ classOf(name = "com.example.demo.DemoClass")
```kotlin ```kotlin
val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader
classOf(name = "com.example.demo.DemoClass", customClassLoader) "com.example.demo.DemoClass".toClass(customClassLoader)
``` ```
### classOf *- method* ### classOf *- method*

View File

@@ -660,7 +660,7 @@ Test(true).doTask("task_name")
> 示例如下 > 示例如下
```kotlin ```kotlin
classOf("com.demo.Test") "com.demo.Test".toClass()
.getDeclaredConstructor(Boolean::class.java) .getDeclaredConstructor(Boolean::class.java)
.apply { isAccessible = true } .apply { isAccessible = true }
.newInstance(true) .newInstance(true)
@@ -679,7 +679,7 @@ classOf("com.demo.Test")
> 示例如下 > 示例如下
```kotlin ```kotlin
classOf("com.demo.Test").buildOfAny(true) { param(BooleanType) }?.current { "com.demo.Test".toClass().buildOfAny(true) { param(BooleanType) }?.current {
method { method {
name = "doTask" name = "doTask"
param(StringType) param(StringType)
@@ -916,7 +916,7 @@ public class BTest {
```kotlin ```kotlin
// 首先查询到这个 Class // 首先查询到这个 Class
val currentClass = if("com.demo.ATest".hasClass) classOf("com.demo.ATest") else classOf("com.demo.BTest") val currentClass = if("com.demo.ATest".hasClass()) "com.demo.ATest".toClass() else "com.demo.BTest".toClass()
// 然后再查询这个方法并调用 // 然后再查询这个方法并调用
currentClass.method { currentClass.method {
name = "doTask" name = "doTask"

View File

@@ -27,7 +27,7 @@
*/ */
package com.highcapable.yukihookapi.hook.bean package com.highcapable.yukihookapi.hook.bean
import com.highcapable.yukihookapi.hook.factory.classOf import com.highcapable.yukihookapi.hook.factory.toClass
/** /**
* 这是一个不确定性 [Class] 类名装载器 * 这是一个不确定性 [Class] 类名装载器
@@ -48,7 +48,7 @@ class VariousClass(vararg var name: String) {
if (name.isNotEmpty()) run { if (name.isNotEmpty()) run {
name.forEach { name.forEach {
runCatching { runCatching {
finalClass = classOf(it, loader) finalClass = it.toClass(loader)
return@run return@run
} }
} }

View File

@@ -29,7 +29,7 @@ package com.highcapable.yukihookapi.hook.core.finder.base
import com.highcapable.yukihookapi.annotation.YukiPrivateApi import com.highcapable.yukihookapi.annotation.YukiPrivateApi
import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.bean.VariousClass
import com.highcapable.yukihookapi.hook.factory.classOf import com.highcapable.yukihookapi.hook.factory.toClass
import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.UndefinedType
import java.lang.reflect.Member import java.lang.reflect.Member
import kotlin.math.abs import kotlin.math.abs
@@ -113,7 +113,7 @@ abstract class BaseFinder {
internal fun Any?.compat(tag: String, loader: ClassLoader?) = when (this) { internal fun Any?.compat(tag: String, loader: ClassLoader?) = when (this) {
null -> null null -> null
is Class<*> -> this is Class<*> -> this
is String -> runCatching { classOf(name = this, loader) }.getOrNull() ?: UndefinedType is String -> runCatching { toClass(loader) }.getOrNull() ?: UndefinedType
is VariousClass -> runCatching { get(loader) }.getOrNull() ?: UndefinedType is VariousClass -> runCatching { get(loader) }.getOrNull() ?: UndefinedType
else -> error("$tag match type \"$javaClass\" not allowed") else -> error("$tag match type \"$javaClass\" not allowed")
} as Class<*>? } as Class<*>?

View File

@@ -74,24 +74,31 @@ enum class MembersType {
val Class<*>.hasExtends get() = superclass.name != "java.lang.Object" val Class<*>.hasExtends get() = superclass.name != "java.lang.Object"
/** /**
* 通过字符串转换为实体类 * 通过字符串类名转换为 [loader] 中的实体类
* @param name [Class] 的完整包名+名称 *
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 可不填 * - ❗此方法已弃用 - 在之后的版本中将直接被删除
*
* - ❗请现在转移到 [toClass]
* @return [Class] * @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader] * @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/ */
fun classOf(name: String, loader: ClassLoader? = null): Class<*> { @Deprecated(message = "请使用新的命名方法", ReplaceWith(expression = "name.toClass(loader)"))
val hashCode = ("[$name][$loader]").hashCode() fun classOf(name: String, loader: ClassLoader? = null) = name.toClass(loader)
/**
* 通过字符串类名转换为 [loader] 中的实体类
* @param loader [Class] 所在的 [ClassLoader] - 默认空 - 不填使用默认 [ClassLoader]
* @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/
fun String.toClass(loader: ClassLoader? = null): Class<*> {
val hashCode = ("[$this][$loader]").hashCode()
return ReflectsCacheStore.findClass(hashCode) ?: run { return ReflectsCacheStore.findClass(hashCode) ?: run {
when { when {
YukiHookBridge.hasXposedBridge -> YukiHookBridge.hasXposedBridge -> runCatching { YukiHookHelper.findClass(name = this, loader) }.getOrNull()
runCatching { YukiHookHelper.findClass(name, loader) }.getOrNull() ?: (if (loader == null) Class.forName(this) else loader.loadClass(this))
?: when (loader) { loader == null -> Class.forName(this)
null -> Class.forName(name) else -> loader.loadClass(this)
else -> loader.loadClass(name)
}
loader == null -> Class.forName(name)
else -> loader.loadClass(name)
}.also { ReflectsCacheStore.putClass(hashCode, it) } }.also { ReflectsCacheStore.putClass(hashCode, it) }
} }
} }
@@ -102,14 +109,14 @@ fun classOf(name: String, loader: ClassLoader? = null): Class<*> {
* @return [Class] * @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader] * @throws NoClassDefFoundError 如果找不到 [Class] 或设置了错误的 [ClassLoader]
*/ */
inline fun <reified T> classOf(loader: ClassLoader? = null) = loader?.let { classOf(T::class.java.name, loader) } ?: T::class.java inline fun <reified T> classOf(loader: ClassLoader? = null) = loader?.let { T::class.java.name.toClass(loader) } ?: T::class.java
/** /**
* 通过字符串类名使用指定的 [ClassLoader] 查找是否存在 * 通过字符串类名使用指定的 [ClassLoader] 查找是否存在
* @param loader [Class] 所在的 [ClassLoader] - 不填使用默认 [ClassLoader] * @param loader [Class] 所在的 [ClassLoader] - 不填使用默认 [ClassLoader]
* @return [Boolean] 是否存在 * @return [Boolean] 是否存在
*/ */
fun String.hasClass(loader: ClassLoader? = null) = runCatching { classOf(name = this, loader); true }.getOrNull() ?: false fun String.hasClass(loader: ClassLoader? = null) = runCatching { toClass(loader); true }.getOrNull() ?: false
/** /**
* 查找变量是否存在 * 查找变量是否存在

View File

@@ -44,6 +44,7 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator
import com.highcapable.yukihookapi.hook.core.YukiResourcesHookCreator import com.highcapable.yukihookapi.hook.core.YukiResourcesHookCreator
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
import com.highcapable.yukihookapi.hook.factory.classOf import com.highcapable.yukihookapi.hook.factory.classOf
import com.highcapable.yukihookapi.hook.factory.toClass
import com.highcapable.yukihookapi.hook.param.type.HookEntryType import com.highcapable.yukihookapi.hook.param.type.HookEntryType
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
@@ -341,7 +342,7 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
* @return [Class] * @return [Class]
* @throws NoClassDefFoundError 如果找不到 [Class] * @throws NoClassDefFoundError 如果找不到 [Class]
*/ */
fun String.toAppClass() = classOf(name = this, appClassLoader) fun String.toAppClass() = toClass(appClassLoader)
/** /**
* [VariousClass] 转换为当前 Hook APP 的实体类 * [VariousClass] 转换为当前 Hook APP 的实体类
@@ -357,25 +358,25 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
* @param loader [Class] 所在的 [ClassLoader] - 不填使用 [appClassLoader] * @param loader [Class] 所在的 [ClassLoader] - 不填使用 [appClassLoader]
* @return [Boolean] 是否存在 * @return [Boolean] 是否存在
*/ */
fun String.hasClass(loader: ClassLoader? = appClassLoader) = runCatching { classOf(name = this, loader); true }.getOrNull() ?: false fun String.hasClass(loader: ClassLoader? = appClassLoader) = runCatching { toClass(loader); true }.getOrNull() ?: false
/** /**
* 查找并装载 [HookClass] * 查找并装载 [HookClass]
* *
* - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[toAppClass] 功能 * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [toClass]、[toAppClass] 功能
* @param name 类名 * @param name 类名
* @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader] * @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader]
* @return [HookClass] * @return [HookClass]
*/ */
fun findClass(name: String, loader: ClassLoader? = appClassLoader) = fun findClass(name: String, loader: ClassLoader? = appClassLoader) =
runCatching { classOf(name, loader).toHookClass() }.getOrElse { HookClass(name = name, throwable = it) } runCatching { name.toClass(loader).toHookClass() }.getOrElse { HookClass(name = name, throwable = it) }
/** /**
* 查找并装载 [HookClass] * 查找并装载 [HookClass]
* *
* 使用此方法查找将会取 [name] 其中命中存在的第一个 [Class] 作为结果 * 使用此方法查找将会取 [name] 其中命中存在的第一个 [Class] 作为结果
* *
* - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[toAppClass] 功能 * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [toClass]、[toAppClass] 功能
* @param name 可填入多个类名 - 自动匹配 * @param name 可填入多个类名 - 自动匹配
* @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader] * @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader]
* @return [HookClass] * @return [HookClass]

View File

@@ -55,6 +55,7 @@ import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityNodeInfo import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast import android.widget.Toast
import com.highcapable.yukihookapi.hook.factory.classOf import com.highcapable.yukihookapi.hook.factory.classOf
import com.highcapable.yukihookapi.hook.factory.toClass
import org.w3c.dom.UserDataHandler import org.w3c.dom.UserDataHandler
import java.awt.Component import java.awt.Component
@@ -74,7 +75,7 @@ val ContextClass get() = classOf<Context>()
* 获得 [ContextImpl] 类型 * 获得 [ContextImpl] 类型
* @return [Class] * @return [Class]
*/ */
val ContextImplClass get() = classOf(name = "android.app.ContextImpl") val ContextImplClass get() = "android.app.ContextImpl".toClass()
/** /**
* 获得 [ContextWrapper] 类型 * 获得 [ContextWrapper] 类型
@@ -110,13 +111,13 @@ val PackageInfoClass get() = classOf<PackageInfo>()
* 获得 [ApplicationPackageManager] 类型 * 获得 [ApplicationPackageManager] 类型
* @return [Class] * @return [Class]
*/ */
val ApplicationPackageManagerClass get() = classOf(name = "android.app.ApplicationPackageManager") val ApplicationPackageManagerClass get() = "android.app.ApplicationPackageManager".toClass()
/** /**
* 获得 [ActivityThread] 类型 * 获得 [ActivityThread] 类型
* @return [Class] * @return [Class]
*/ */
val ActivityThreadClass get() = classOf(name = "android.app.ActivityThread") val ActivityThreadClass get() = "android.app.ActivityThread".toClass()
/** /**
* 获得 [ActivityManager] 类型 * 获得 [ActivityManager] 类型
@@ -128,49 +129,49 @@ val ActivityManagerClass get() = classOf<ActivityManager>()
* 获得 [IActivityManager] 类型 * 获得 [IActivityManager] 类型
* @return [Class] * @return [Class]
*/ */
val IActivityManagerClass get() = classOf(name = "android.app.IActivityManager") val IActivityManagerClass get() = "android.app.IActivityManager".toClass()
/** /**
* 获得 [ActivityManagerNative] 类型 * 获得 [ActivityManagerNative] 类型
* @return [Class] * @return [Class]
*/ */
val ActivityManagerNativeClass get() = classOf(name = "android.app.ActivityManagerNative") val ActivityManagerNativeClass get() = "android.app.ActivityManagerNative".toClass()
/** /**
* 获得 [IActivityTaskManager] 类型 * 获得 [IActivityTaskManager] 类型
* @return [Class] * @return [Class]
*/ */
val IActivityTaskManagerClass get() = classOf(name = "android.app.IActivityTaskManager") val IActivityTaskManagerClass get() = "android.app.IActivityTaskManager".toClass()
/** /**
* 获得 [ActivityTaskManager] 类型 * 获得 [ActivityTaskManager] 类型
* @return [Class] * @return [Class]
*/ */
val ActivityTaskManagerClass get() = classOf(name = "android.app.ActivityTaskManager") val ActivityTaskManagerClass get() = "android.app.ActivityTaskManager".toClass()
/** /**
* 获得 [IPackageManager] 类型 * 获得 [IPackageManager] 类型
* @return [Class] * @return [Class]
*/ */
val IPackageManagerClass get() = classOf(name = "android.content.pm.IPackageManager") val IPackageManagerClass get() = "android.content.pm.IPackageManager".toClass()
/** /**
* 获得 [ClientTransaction] 类型 * 获得 [ClientTransaction] 类型
* @return [Class] * @return [Class]
*/ */
val ClientTransactionClass get() = classOf(name = "android.app.servertransaction.ClientTransaction") val ClientTransactionClass get() = "android.app.servertransaction.ClientTransaction".toClass()
/** /**
* 获得 [LoadedApk] 类型 * 获得 [LoadedApk] 类型
* @return [Class] * @return [Class]
*/ */
val LoadedApkClass get() = classOf(name = "android.app.LoadedApk") val LoadedApkClass get() = "android.app.LoadedApk".toClass()
/** /**
* 获得 [Singleton] 类型 * 获得 [Singleton] 类型
* @return [Class] * @return [Class]
*/ */
val SingletonClass get() = classOf(name = "android.util.Singleton") val SingletonClass get() = "android.util.Singleton".toClass()
/** /**
* 获得 [Activity] 类型 * 获得 [Activity] 类型
@@ -188,31 +189,31 @@ val LooperClass get() = classOf<Looper>()
* 获得 [Fragment] 类型 - Support * 获得 [Fragment] 类型 - Support
* @return [Class] * @return [Class]
*/ */
val FragmentClass_AndroidSupport get() = classOf(name = "android.support.v4.app.Fragment") val FragmentClass_AndroidSupport get() = "android.support.v4.app.Fragment".toClass()
/** /**
* 获得 [Fragment] 类型 - AndroidX * 获得 [Fragment] 类型 - AndroidX
* @return [Class] * @return [Class]
*/ */
val FragmentClass_AndroidX get() = classOf(name = "androidx.fragment.app.Fragment") val FragmentClass_AndroidX get() = "androidx.fragment.app.Fragment".toClass()
/** /**
* 获得 [FragmentActivity] 类型 - Support * 获得 [FragmentActivity] 类型 - Support
* @return [Class] * @return [Class]
*/ */
val FragmentActivityClass_AndroidSupport get() = classOf(name = "android.support.v4.app.FragmentActivity") val FragmentActivityClass_AndroidSupport get() = "android.support.v4.app.FragmentActivity".toClass()
/** /**
* 获得 [FragmentActivity] 类型 - AndroidX * 获得 [FragmentActivity] 类型 - AndroidX
* @return [Class] * @return [Class]
*/ */
val FragmentActivityClass_AndroidX get() = classOf(name = "androidx.fragment.app.FragmentActivity") val FragmentActivityClass_AndroidX get() = "androidx.fragment.app.FragmentActivity".toClass()
/** /**
* 获得 [DocumentFile] 类型 - AndroidX * 获得 [DocumentFile] 类型 - AndroidX
* @return [Class] * @return [Class]
*/ */
val DocumentFileClass get() = classOf(name = "androidx.documentfile.provider.DocumentFile") val DocumentFileClass get() = "androidx.documentfile.provider.DocumentFile".toClass()
/** /**
* 获得 [Service] 类型 * 获得 [Service] 类型
@@ -592,7 +593,7 @@ val XmlClass get() = classOf<Xml>()
* 获得 [ContrastColorUtil] 类型 * 获得 [ContrastColorUtil] 类型
* @return [Class] * @return [Class]
*/ */
val ContrastColorUtilClass get() = classOf(name = "com.android.internal.util.ContrastColorUtil") val ContrastColorUtilClass get() = "com.android.internal.util.ContrastColorUtil".toClass()
/** /**
* 获得 [StatusBarNotification] 类型 * 获得 [StatusBarNotification] 类型

View File

@@ -284,7 +284,7 @@ internal object AppParasitics {
}?.takeIf { it.isNotBlank() } ?: context.packageManager?.runCatching { }?.takeIf { it.isNotBlank() } ?: context.packageManager?.runCatching {
queryIntentActivities(getLaunchIntentForPackage(context.packageName)!!, 0).first().activityInfo.name queryIntentActivities(getLaunchIntentForPackage(context.packageName)!!, 0).first().activityInfo.name
}?.getOrNull() ?: "" }?.getOrNull() ?: ""
if ((proxyClassName.hasClass(context.classLoader) && classOf(proxyClassName, context.classLoader).hasMethod { if ((proxyClassName.hasClass(context.classLoader) && proxyClassName.toClass(context.classLoader).hasMethod {
name = "setIntent"; param(IntentClass); superClass() name = "setIntent"; param(IntentClass); superClass()
}).not() }).not()
) (if (proxyClassName.isBlank()) error("Cound not got launch intent for package \"${context.packageName}\"") ) (if (proxyClassName.isBlank()) error("Cound not got launch intent for package \"${context.packageName}\"")

View File

@@ -74,7 +74,7 @@ internal class InstrumentationDelegate private constructor(private val baseInsta
baseInstance.newActivity(cl, className, intent) baseInstance.newActivity(cl, className, intent)
} catch (e: Throwable) { } catch (e: Throwable) {
if (className?.startsWith(YukiHookBridge.modulePackageName) == true) if (className?.startsWith(YukiHookBridge.modulePackageName) == true)
classOf(className).buildOf<Activity>() ?: throw e className.toClass().buildOf<Activity>() ?: throw e
else throw e else throw e
} }