feat: allow no condition finding and ignore member access exception

This commit is contained in:
2023-10-03 23:22:50 +08:00
parent 8c8cfc5498
commit 5c415c8d61
2 changed files with 38 additions and 22 deletions

View File

@@ -57,6 +57,7 @@ import com.highcapable.yukihookapi.hook.utils.factory.takeIf
import com.highcapable.yukihookapi.hook.utils.factory.value
import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics
import dalvik.system.BaseDexClassLoader
import java.lang.reflect.AccessibleObject
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
@@ -297,9 +298,10 @@ internal object ReflectionTool {
* @throws IllegalStateException 如果未设置任何条件或 [FieldRulesData.type] 目标类不存在
* @throws NoSuchFieldError 如果找不到 [Field]
*/
internal fun findFields(classSet: Class<*>?, rulesData: FieldRulesData) = rulesData.createResult {
internal fun findFields(classSet: Class<*>?, rulesData: FieldRulesData) = rulesData.createResult { hasCondition ->
if (type == UndefinedType) error("Field match type class is not found")
if (classSet == null) return@createResult mutableListOf()
if (hasCondition.not()) return@createResult classSet.existFields?.toList()?.toAccessibleMembers() ?: mutableListOf()
mutableListOf<Field>().also { fields ->
classSet.existFields?.also { declares ->
var iType = -1
@@ -346,10 +348,10 @@ internal object ReflectionTool {
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { fields.add(instance.apply { isAccessible = true }) }
}.finally { fields.add(instance) }
}
}
}.takeIf { it.isNotEmpty() } ?: findSuperOrThrow(classSet)
}.takeIf { it.isNotEmpty() }?.toAccessibleMembers() ?: findSuperOrThrow(classSet)
}
/**
@@ -360,9 +362,10 @@ internal object ReflectionTool {
* @throws IllegalStateException 如果未设置任何条件或 [MethodRulesData.paramTypes] 以及 [MethodRulesData.returnType] 目标类不存在
* @throws NoSuchMethodError 如果找不到 [Method]
*/
internal fun findMethods(classSet: Class<*>?, rulesData: MethodRulesData) = rulesData.createResult {
internal fun findMethods(classSet: Class<*>?, rulesData: MethodRulesData) = rulesData.createResult { hasCondition ->
if (returnType == UndefinedType) error("Method match returnType class is not found")
if (classSet == null) return@createResult mutableListOf()
if (hasCondition.not()) return@createResult classSet.existMethods?.toList()?.toAccessibleMembers() ?: mutableListOf()
paramTypes?.takeIf { it.isNotEmpty() }
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Method match paramType[$p] class is not found") }
mutableListOf<Method>().also { methods ->
@@ -457,10 +460,10 @@ internal object ReflectionTool {
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { methods.add(instance.apply { isAccessible = true }) }
}.finally { methods.add(instance) }
}
}
}.takeIf { it.isNotEmpty() } ?: findSuperOrThrow(classSet)
}.takeIf { it.isNotEmpty() }?.toAccessibleMembers() ?: findSuperOrThrow(classSet)
}
/**
@@ -471,8 +474,9 @@ internal object ReflectionTool {
* @throws IllegalStateException 如果未设置任何条件或 [ConstructorRulesData.paramTypes] 目标类不存在
* @throws NoSuchMethodError 如果找不到 [Constructor]
*/
internal fun findConstructors(classSet: Class<*>?, rulesData: ConstructorRulesData) = rulesData.createResult {
internal fun findConstructors(classSet: Class<*>?, rulesData: ConstructorRulesData) = rulesData.createResult { hasCondition ->
if (classSet == null) return@createResult mutableListOf()
if (hasCondition.not()) return@createResult classSet.existConstructors?.toList()?.toAccessibleMembers() ?: mutableListOf()
paramTypes?.takeIf { it.isNotEmpty() }
?.forEachIndexed { p, it -> if (it == UndefinedType) error("Constructor match paramType[$p] class is not found") }
mutableListOf<Constructor<*>>().also { constructors ->
@@ -533,10 +537,10 @@ internal object ReflectionTool {
})
}
orderIndex.compare(index, declares.lastIndex()) { and(it) }
}.finally { constructors.add(instance.apply { isAccessible = true }) }
}.finally { constructors.add(instance) }
}
}
}.takeIf { it.isNotEmpty() } ?: findSuperOrThrow(classSet)
}.takeIf { it.isNotEmpty() }?.toAccessibleMembers() ?: findSuperOrThrow(classSet)
}
/**
@@ -567,16 +571,14 @@ internal object ReflectionTool {
* @return [T]
* @throws IllegalStateException 如果没有 [BaseRulesData.isInitialize]
*/
private inline fun <reified T, R : BaseRulesData> R.createResult(result: R.() -> T): T {
when (this) {
is FieldRulesData -> isInitialize.not()
is MethodRulesData -> isInitialize.not()
is ConstructorRulesData -> isInitialize.not()
is ClassRulesData -> isInitialize.not()
else -> true
}.takeIf { it }?.also { error("You must set a condition when finding a $objectName") }
return result(this)
}
private inline fun <reified T, R : BaseRulesData> R.createResult(result: R.(hasCondition: Boolean) -> T) =
result(when (this) {
is FieldRulesData -> isInitialize
is MethodRulesData -> isInitialize
is ConstructorRulesData -> isInitialize
is ClassRulesData -> isInitialize
else -> false
})
/**
* 在 [Class.getSuperclass] 中查找或抛出异常
@@ -695,6 +697,20 @@ internal object ReflectionTool {
YLog.innerW("Failed to get the declared Constructors in [$this] because got an exception", it)
}.getOrNull()
/**
* 批量允许访问内部方法
* @return [MutableList]<[T]>
*/
private inline fun <reified T : AccessibleObject> List<T>.toAccessibleMembers() =
mutableListOf<T>().also { list ->
forEach { member ->
runCatching {
member.isAccessible = true
list.add(member)
}.onFailure { YLog.innerW("Failed to access [$member] because got an exception", it) }
}
}
/**
* 判断两个方法、构造方法类型数组是否相等
*

View File

@@ -333,21 +333,21 @@ inline fun Class<*>.hasModifiers(conditions: ModifierConditions) = conditions(Mo
* @param initiate 查找方法体
* @return [FieldFinder.Result]
*/
inline fun Class<*>.field(initiate: FieldConditions) = FieldFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.field(initiate: FieldConditions = {}) = FieldFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到方法
* @param initiate 查找方法体
* @return [MethodFinder.Result]
*/
inline fun Class<*>.method(initiate: MethodConditions) = MethodFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.method(initiate: MethodConditions = {}) = MethodFinder(classSet = this).apply(initiate).build()
/**
* 查找并得到构造方法
* @param initiate 查找方法体
* @return [ConstructorFinder.Result]
*/
inline fun Class<*>.constructor(initiate: ConstructorConditions = { emptyParam() }) = ConstructorFinder(classSet = this).apply(initiate).build()
inline fun Class<*>.constructor(initiate: ConstructorConditions = {}) = ConstructorFinder(classSet = this).apply(initiate).build()
/**
* 获得当前 [Class] 的泛型父类