From a9e5c0780f1cbd8b0ca5c12d4394d5572c778b77 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Thu, 15 Sep 2022 02:21:08 +0800 Subject: [PATCH] Modify move NameConditions, ModifierRules to finder/base/rules and renamed and replace them with a new method of use --- docs/api/document.md | 2 +- docs/api/public/ConstructorFinder.md | 8 +- docs/api/public/FieldFinder.md | 12 +- docs/api/public/MethodFinder.md | 14 +- docs/api/public/ModifierRules.md | 304 +-------------- docs/api/public/NameConditions.md | 225 ----------- docs/api/public/NameRules.md | 23 ++ docs/api/public/ReflectionFactory.md | 8 +- .../core/finder/base/data/BaseRulesData.kt | 33 +- .../hook/core/finder/base/rules/CountRules.kt | 81 ++++ .../core/finder/base/rules/ModifierRules.kt | 223 +++++++++++ .../hook/core/finder/base/rules/NameRules.kt | 124 ++++++ .../core/finder/members/ConstructorFinder.kt | 14 +- .../hook/core/finder/members/FieldFinder.kt | 16 +- .../hook/core/finder/members/MethodFinder.kt | 22 +- .../members/data/ConstructorRulesData.kt | 4 +- .../finder/members/data/FieldRulesData.kt | 2 +- .../finder/members/data/MemberRulesData.kt | 4 +- .../finder/members/data/MethodRulesData.kt | 6 +- .../hook/core/finder/tools/ReflectionTool.kt | 60 ++- .../hook/core/finder/type/ModifierRules.kt | 311 --------------- .../hook/core/finder/type/NameConditions.kt | 367 ------------------ .../finder/type/factory/TypeAliasFactory.kt | 13 +- .../hook/factory/ReflectionFactory.kt | 13 +- 24 files changed, 600 insertions(+), 1289 deletions(-) delete mode 100644 docs/api/public/NameConditions.md create mode 100644 docs/api/public/NameRules.md create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/CountRules.kt create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/ModifierRules.kt create mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/NameRules.kt delete mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/ModifierRules.kt delete mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/NameConditions.kt diff --git a/docs/api/document.md b/docs/api/document.md index 20ef111a..14c30c3a 100644 --- a/docs/api/document.md +++ b/docs/api/document.md @@ -70,7 +70,7 @@ [filename](public/ModifierRules.md ':include') -[filename](public/NameConditions.md ':include') +[filename](public/NameRules.md ':include') [filename](public/HookClass.md ':include') diff --git a/docs/api/public/ConstructorFinder.md b/docs/api/public/ConstructorFinder.md index 39ac8f79..d0480698 100644 --- a/docs/api/public/ConstructorFinder.md +++ b/docs/api/public/ConstructorFinder.md @@ -43,7 +43,7 @@ var paramCount: Int ### modifiers *- method* ```kotlin -inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition +fun modifiers(conditions: ModifierConditions): IndexTypeCondition ``` **变更记录** @@ -54,6 +54,10 @@ inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition 将方法体进行 inline +`v1.0.93` `修改` + +合并到 `ModifierConditions` + **功能描述** > 设置 `Constructor` 标识符筛选条件。 @@ -141,7 +145,7 @@ fun paramCount(numRange: IntRange): IndexTypeCondition ### paramCount *- method* ```kotlin -fun paramCount(conditions: IntConditions): IndexTypeCondition +fun paramCount(conditions: CountConditions): IndexTypeCondition ``` **变更记录** diff --git a/docs/api/public/FieldFinder.md b/docs/api/public/FieldFinder.md index 8a6a7cd1..e809b121 100644 --- a/docs/api/public/FieldFinder.md +++ b/docs/api/public/FieldFinder.md @@ -69,7 +69,7 @@ var type: Any? ### modifiers *- method* ```kotlin -inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition +fun modifiers(conditions: ModifierConditions): IndexTypeCondition ``` **变更记录** @@ -80,6 +80,10 @@ inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition 将方法体进行 inline +`v1.0.93` `修改` + +合并到 `ModifierConditions` + **功能描述** > 设置 `Field` 标识符筛选条件。 @@ -123,13 +127,17 @@ fun name(value: String): IndexTypeCondition ### name *- method* ```kotlin -inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition +fun name(conditions: NameConditions): IndexTypeCondition ``` **变更记录** `v1.0.88` `新增` +`v1.0.93` `修改` + +合并到 `NameConditions` + **功能描述** > 设置 `Field` 名称条件。 diff --git a/docs/api/public/MethodFinder.md b/docs/api/public/MethodFinder.md index 7b533b50..0dd83029 100644 --- a/docs/api/public/MethodFinder.md +++ b/docs/api/public/MethodFinder.md @@ -77,7 +77,7 @@ var returnType: Any? ### modifiers *- method* ```kotlin -inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition +fun modifiers(conditions: ModifierConditions): IndexTypeCondition ``` **变更记录** @@ -88,6 +88,10 @@ inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition 将方法体进行 inline +`v1.0.93` `修改` + +合并到 `ModifierConditions` + **功能描述** > 设置 `Method` 标识符筛选条件。 @@ -169,13 +173,17 @@ fun name(value: String): IndexTypeCondition ### name *- method* ```kotlin -inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition +fun name(conditions: NameConditions): IndexTypeCondition ``` **变更记录** `v1.0.88` `新增` +`v1.0.93` `修改` + +合并到 `NameConditions` + **功能描述** > 设置 `Method` 名称条件。 @@ -225,7 +233,7 @@ fun paramCount(numRange: IntRange): IndexTypeCondition ### paramCount *- method* ```kotlin -fun paramCount(conditions: IntConditions): IndexTypeCondition +fun paramCount(conditions: CountConditions): IndexTypeCondition ``` **变更记录** diff --git a/docs/api/public/ModifierRules.md b/docs/api/public/ModifierRules.md index 35af2d48..205c243c 100644 --- a/docs/api/public/ModifierRules.md +++ b/docs/api/public/ModifierRules.md @@ -1,7 +1,7 @@ ## ModifierRules *- class* ```kotlin -class ModifierRules internal constructor() +class ModifierRules private constructor() ``` **变更记录** @@ -12,306 +12,12 @@ class ModifierRules internal constructor() 新增 `Class` 的描述符判断 -**功能描述** +作为 lambda 整体判断条件使用 -> 这是一个 `Class`、`Member` 描述符定义类。 +移动到 base 包名 -可对 R8 混淆后的 `Class`、`Member` 进行更加详细的定位。 - -### ~~asPublic *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asPrivate *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asProtected *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asStatic *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asFinal *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asSynchronized *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asVolatile *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asTransient *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asNative *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asInterface *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asAbstract *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### ~~asStrict *- method*~~ - -**变更记录** - -`v1.0.67` `新增` - -`v1.0.93` `作废` - -请将开头的 `as` 修改为 `is` - -### isPublic *- method* - -```kotlin -fun isPublic() -``` - -**变更记录** - -`v1.0.93` `新增` +私有化构造方法 **功能描述** -> 添加描述 `Class`、`Member` 类型包含 `public`。 - -### isPrivate *- method* - -```kotlin -fun isPrivate() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `private`。 - -### isProtected *- method* - -```kotlin -fun isProtected() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `protected`。 - -### isStatic *- method* - -```kotlin -fun isStatic() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `static`。 - -对于任意的静态 `Class`、`Member` 可添加此描述进行确定。 - -!> 特别注意 Kotlin -> Jvm 后的 `object` 类中的方法并不是静态的。 - -### isFinal *- method* - -```kotlin -fun isFinal() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `final`。 - -!> 特别注意在 Kotlin -> Jvm 后没有 `open` 标识的 `Class`、`Member` 和没有任何关联的 `Class`、`Member` 都将为 `final`。 - -### isSynchronized *- method* - -```kotlin -fun isSynchronized() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `synchronized`。 - -### isVolatile *- method* - -```kotlin -fun isVolatile() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `volatile`。 - -### isTransient *- method* - -```kotlin -fun isTransient() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `transient`。 - -### isNative *- method* - -```kotlin -fun isNative() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `native`。 - -对于任意 JNI 对接的 `Class`、`Member` 可添加此描述进行确定。 - -### isInterface *- method* - -```kotlin -fun isInterface() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `interface`。 - -### isAbstract *- method* - -```kotlin -fun isAbstract() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `abstract`。 - -对于任意的抽象 `Class`、`Member` 可添加此描述进行确定。 - -### isStrict *- method* - -```kotlin -fun isStrict() -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 添加描述 `Class`、`Member` 类型包含 `strict`。 \ No newline at end of file +!> 新的功能已转移到新文档,这里仅保留文字说明记录。 \ No newline at end of file diff --git a/docs/api/public/NameConditions.md b/docs/api/public/NameConditions.md deleted file mode 100644 index 5d971baf..00000000 --- a/docs/api/public/NameConditions.md +++ /dev/null @@ -1,225 +0,0 @@ -## NameConditions *- class* - -```kotlin -class NameConditions internal constructor() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 这是一个模糊 `Class`、`Member` 名称匹配实现类。 - -可对 R8 混淆后的 `Class`、`Member` 进行更加详细的定位。 - -### equalsOf *- method* - -```kotlin -fun equalsOf(other: String, isIgnoreCase: Boolean) -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 完全字符匹配。 - -可以重复使用,最终会选择完全匹配的一个。 - -### startsWith *- method* - -```kotlin -fun startsWith(prefix: String, startIndex: Int, isIgnoreCase: Boolean) -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 起始字符匹配。 - -可以重复使用,最终会选择完全匹配的一个。 - -### endsWith *- method* - -```kotlin -fun endsWith(suffix: String, isIgnoreCase: Boolean) -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 结束字符匹配。 - -可以重复使用,最终会选择完全匹配的一个。 - -### contains *- method* - -```kotlin -fun contains(other: String, isIgnoreCase: Boolean) -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 包含字符匹配。 - -可以重复使用,最终会选择完全匹配的一个。 - -### matches *- method* - -```kotlin -fun matches(regex: String) -``` - -```kotlin -fun matches(regex: Regex) -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 正则字符匹配。 - -可以重复使用,最终会选择完全匹配的一个。 - -### length *- method* - -```kotlin -fun length(num: Int) -``` - -```kotlin -fun length(numRange: IntRange) -``` - -```kotlin -fun length(conditions: IntConditions) -``` - -**变更记录** - -`v1.0.93` `新增` - -**功能描述** - -> 字符长度与范围及条件匹配。 - -不可重复使用,重复使用旧的条件会被当前条件替换。 - -### thisSynthetic0 *- method* - -```kotlin -fun thisSynthetic0() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为匿名类的主类调用对象。 - -### onlySymbols *- method* - -```kotlin -fun onlySymbols() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有符号。 - -### onlyLetters *- method* - -```kotlin -fun onlyLetters() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有字母。 - -### onlyNumbers *- method* - -```kotlin -fun onlyNumbers() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有数字。 - -### onlyLettersNumbers *- method* - -```kotlin -fun onlyLettersNumbers() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有字母或数字。 - -### onlyLowercase *- method* - -```kotlin -fun onlyLowercase() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有小写字母。 - -在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符。 - -### onlyUppercase *- method* - -```kotlin -fun onlyUppercase() -``` - -**变更记录** - -`v1.0.88` `新增` - -**功能描述** - -> 标识为只有大写字母。 - -在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符。 \ No newline at end of file diff --git a/docs/api/public/NameRules.md b/docs/api/public/NameRules.md new file mode 100644 index 00000000..219dc9cc --- /dev/null +++ b/docs/api/public/NameRules.md @@ -0,0 +1,23 @@ +## NameRules *- class* + +```kotlin +class NameRules private constructor() +``` + +**变更记录** + +`v1.0.88` `新增` + +`v1.0.93` `修改` + +`NameConditions` 更名为 `NameRules` + +作为 lambda 整体判断条件使用 + +移动到 base 包名 + +私有化构造方法 + +**功能描述** + +!> 新的功能已转移到新文档,这里仅保留文字说明记录。 \ No newline at end of file diff --git a/docs/api/public/ReflectionFactory.md b/docs/api/public/ReflectionFactory.md index 8ff09c55..cd20fa17 100644 --- a/docs/api/public/ReflectionFactory.md +++ b/docs/api/public/ReflectionFactory.md @@ -369,7 +369,7 @@ inline fun Class<*>.hasConstructor(initiate: ConstructorConditions): Boolean ### Member.hasModifiers *- ext-method* ```kotlin -inline fun Member.hasModifiers(initiate: ModifierRules.() -> Unit): Boolean +inline fun Member.hasModifiers(conditions: ModifierConditions): Boolean ``` **变更记录** @@ -380,6 +380,10 @@ inline fun Member.hasModifiers(initiate: ModifierRules.() -> Unit): Boolean 将方法体进行 inline +`v1.0.93` `修改` + +合并到 `ModifierConditions` + **功能描述** > 查询 `Member` 中匹配的描述符。 @@ -387,7 +391,7 @@ inline fun Member.hasModifiers(initiate: ModifierRules.() -> Unit): Boolean ### Class.hasModifiers *- ext-method* ```kotlin -inline fun Class<*>.hasModifiers(initiate: ModifierRules.() -> Unit): Boolean +inline fun Class<*>.hasModifiers(conditions: ModifierConditions): Boolean ``` **变更记录** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt index e7223ea7..c8623af4 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/data/BaseRulesData.kt @@ -27,22 +27,49 @@ */ package com.highcapable.yukihookapi.hook.core.finder.base.data -import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules +import com.highcapable.yukihookapi.hook.core.finder.base.rules.CountRules +import com.highcapable.yukihookapi.hook.core.finder.base.rules.ModifierRules +import com.highcapable.yukihookapi.hook.core.finder.base.rules.NameRules +import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions import java.lang.reflect.Member /** * 这是 [Class] 与 [Member] 规则查询数据基本类实现 - * @param modifiers 描述符 + * @param modifiers 描述符条件 * @param orderIndex 字节码、数组顺序下标 * @param matchIndex 字节码、数组筛选下标 */ @PublishedApi internal abstract class BaseRulesData internal constructor( - var modifiers: ModifierRules? = null, + var modifiers: ModifierConditions? = null, var orderIndex: Pair? = null, var matchIndex: Pair? = null ) { + /** + * [String] 转换为 [NameRules] + * @return [NameRules] + */ + internal fun String.cast() = NameRules.with(this) + + /** + * [Int] 转换为 [CountRules] + * @return [CountRules] + */ + internal fun Int.cast() = CountRules.with(this) + + /** + * [Class] 转换为 [ModifierRules] + * @return [ModifierRules] + */ + internal fun Class<*>.cast() = ModifierRules.with(this) + + /** + * [Member] 转换为 [ModifierRules] + * @return [ModifierRules] + */ + internal fun Member.cast() = ModifierRules.with(this) + /** * 获取规则对象名称 * @return [String] diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/CountRules.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/CountRules.kt new file mode 100644 index 00000000..0c39942f --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/CountRules.kt @@ -0,0 +1,81 @@ +/* + * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. + * Copyright (C) 2019-2022 HighCapable + * https://github.com/fankes/YukiHookAPI + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file is Created by fankes on 2022/9/14. + */ +@file:Suppress("unused") + +package com.highcapable.yukihookapi.hook.core.finder.base.rules + +import java.lang.reflect.Member + +/** + * 这是一个模糊 [Class]、[Member] 数组 (下标) 个数条件实现类 + * + * 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位 + */ +class CountRules private constructor(private val instance: Int) { + + @PublishedApi + internal companion object { + + /** + * 创建实例 + * @param instance 实例对象 + * @return [CountRules] + */ + @PublishedApi + internal fun with(instance: Int) = CountRules(instance) + } + + /** + * 是否为 0 + * @return [Boolean] + */ + fun Int.isZero() = this == 0 + + /** + * 大于 [count] + * @param count 目标对象 + * @return [Boolean] + */ + fun Int.moreThan(count: Int) = this > count + + /** + * 小于 [count] + * @param count 目标对象 + * @return [Boolean] + */ + fun Int.lessThan(count: Int) = this < count + + /** + * 在 [countRange] 区间 A ≤ this ≤ B + * @param countRange 区间 + * @return [Boolean] + */ + fun Int.inInterval(countRange: IntRange) = this in countRange + + override fun toString() = "CountRules [$instance]" +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/ModifierRules.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/ModifierRules.kt new file mode 100644 index 00000000..cdb283ca --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/ModifierRules.kt @@ -0,0 +1,223 @@ +/* + * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. + * Copyright (C) 2019-2022 HighCapable + * https://github.com/fankes/YukiHookAPI + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file is Created by fankes on 2022/3/27. + * This file is Modified by fankes on 2022/9/14. + */ +@file:Suppress("unused") + +package com.highcapable.yukihookapi.hook.core.finder.base.rules + +import java.lang.reflect.Field +import java.lang.reflect.Member +import java.lang.reflect.Method +import java.lang.reflect.Modifier + +/** + * 这是一个 [Class]、[Member] 描述符条件实现类 + * + * 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位 + */ +class ModifierRules private constructor(private val instance: Any) { + + @PublishedApi + internal companion object { + + /** + * 创建实例 + * @param instance 实例对象 + * @return [ModifierRules] + */ + @PublishedApi + internal fun with(instance: Any) = ModifierRules(instance) + } + + /** + * [Class]、[Member] 类型是否包含 public + * + * 如下所示 ↓ + * + * public class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isPublic get() = Modifier.isPublic(modifiers) + + /** + * [Class]、[Member] 类型是否包含 private + * + * 如下所示 ↓ + * + * private class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isPrivate get() = Modifier.isPrivate(modifiers) + + /** + * [Class]、[Member] 类型是否包含 protected + * + * 如下所示 ↓ + * + * protected class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isProtected get() = Modifier.isProtected(modifiers) + + /** + * [Class]、[Member] 类型是否包含 static + * + * 对于任意的静态 [Class]、[Member] 可添加此描述进行确定 + * + * 如下所示 ↓ + * + * static class/void/int/String... + * + * ^^^ + * + * - ❗注意 Kotlin → Jvm 后的 object 类中的方法并不是静态的 + * @return [Boolean] + */ + val isStatic get() = Modifier.isStatic(modifiers) + + /** + * [Class]、[Member] 类型是否包含 final + * + * 如下所示 ↓ + * + * final class/void/int/String... + * + * ^^^ + * + * - ❗注意 Kotlin → Jvm 后没有 open 标识的 [Class]、[Member] 和没有任何关联的 [Class]、[Member] 都将为 final + * @return [Boolean] + */ + val isFinal get() = Modifier.isFinal(modifiers) + + /** + * [Class]、[Member] 类型是否包含 synchronized + * + * 如下所示 ↓ + * + * synchronized class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isSynchronized get() = Modifier.isSynchronized(modifiers) + + /** + * [Field] 类型是否包含 volatile + * + * 如下所示 ↓ + * + * volatile int/String... + * + * ^^^ + * @return [Boolean] + */ + val isVolatile get() = Modifier.isVolatile(modifiers) + + /** + * [Field] 类型是否包含 transient + * + * 如下所示 ↓ + * + * transient int/String... + * + * ^^^ + * @return [Boolean] + */ + val isTransient get() = Modifier.isTransient(modifiers) + + /** + * [Method] 类型是否包含 native + * + * 对于任意 JNI 对接的 [Method] 可添加此描述进行确定 + * + * 如下所示 ↓ + * + * native void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isNative get() = Modifier.isNative(modifiers) + + /** + * [Class] 类型是否包含 interface + * + * 如下所示 ↓ + * + * interface ... + * + * ^^^ + * @return [Boolean] + */ + val isInterface get() = Modifier.isInterface(modifiers) + + /** + * [Class]、[Member] 类型是否包含 abstract + * + * 对于任意的抽象 [Class]、[Member] 可添加此描述进行确定 + * + * 如下所示 ↓ + * + * abstract class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isAbstract get() = Modifier.isAbstract(modifiers) + + /** + * [Class]、[Member] 类型是否包含 strictfp + * + * 如下所示 ↓ + * + * strictfp class/void/int/String... + * + * ^^^ + * @return [Boolean] + */ + val isStrict get() = Modifier.isStrict(modifiers) + + /** + * 获取当前对象的类型描述符 + * @return [Int] + */ + private val modifiers + get() = when (instance) { + is Member -> instance.modifiers + is Class<*> -> instance.modifiers + else -> 0 + } + + override fun toString() = "ModifierRules [$instance]" +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/NameRules.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/NameRules.kt new file mode 100644 index 00000000..b00fb159 --- /dev/null +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/base/rules/NameRules.kt @@ -0,0 +1,124 @@ +/* + * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. + * Copyright (C) 2019-2022 HighCapable + * https://github.com/fankes/YukiHookAPI + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file is Created by fankes on 2022/5/16. + * This file is Modified by fankes on 2022/9/14. + */ +@file:Suppress("unused", "MemberVisibilityCanBePrivate") + +package com.highcapable.yukihookapi.hook.core.finder.base.rules + +import java.lang.reflect.Member + +/** + * 这是一个模糊 [Class]、[Member] 名称条件实现类 + * + * 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位 + */ +class NameRules private constructor(private val instance: String) { + + @PublishedApi + internal companion object { + + /** + * 创建实例 + * @param instance 实例对象 + * @return [NameRules] + */ + @PublishedApi + internal fun with(instance: String) = NameRules(instance) + } + + /** + * 是否为匿名类的主类调用对象名称 + * + * 它的名称形态通常为:this$[index] + * @param index 下标 - 默认 0 + * @return [Boolean] + */ + fun String.isSynthetic(index: Int = 0) = this == "this$$index" + + /** + * 是否只有符号 + * + * 筛选仅包含 _、-、?、!、,、.、<、> 等符号以及特殊符号 + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlySymbols() = matches("[*,.:~`'\"|/\\\\?!^()\\[\\]{}%@#$&\\-_+=<>]+".toRegex()) + + /** + * 是否只有字母 + * + * 在没有 [isOnlyLowercase] 以及 [isOnlyUppercase] 的条件下筛选仅包含 26 个大小写英文字母 + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlyLetters() = matches("[a-zA-Z]+".toRegex()) + + /** + * 是否只有数字 + * + * 筛选仅包含 0-9 阿拉伯数字 + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlyNumbers() = matches("[0-9]+".toRegex()) + + /** + * 是否只有字母或数字 + * + * 融合条件 [isOnlyLetters] 和 [isOnlyNumbers] + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlyLettersNumbers() = matches("[a-zA-Z0-9]+".toRegex()) + + /** + * 是否只有小写字母 + * + * 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符 + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlyLowercase() = matches("[a-z]+".toRegex()) + + /** + * 是否只有大写字母 + * + * 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符 + * + * 你可以使用 [matches] 方法进行更详细的正则匹配 + * @return [Boolean] + */ + fun String.isOnlyUppercase() = matches("[A-Z]+".toRegex()) + + override fun toString() = "NameRules [$instance]" +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt index e978498f..51414359 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/ConstructorFinder.kt @@ -35,15 +35,15 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.MemberBaseFinder import com.highcapable.yukihookapi.hook.core.finder.members.data.ConstructorRulesData -import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool import com.highcapable.yukihookapi.hook.core.finder.type.factory.ConstructorConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions import com.highcapable.yukihookapi.hook.factory.checkingInternal import com.highcapable.yukihookapi.hook.factory.hasExtends import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.VagueType -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions import com.highcapable.yukihookapi.hook.utils.runBlocking import com.highcapable.yukihookapi.hook.utils.unit import java.lang.reflect.Constructor @@ -90,11 +90,11 @@ class ConstructorFinder @PublishedApi internal constructor( * 设置 [Constructor] 标识符筛选条件 * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition { - rulesData.modifiers = ModifierRules().apply(initiate) + fun modifiers(conditions: ModifierConditions): IndexTypeCondition { + rulesData.modifiers = conditions return IndexTypeCondition(IndexConfigType.MATCH) } @@ -188,14 +188,14 @@ class ConstructorFinder @PublishedApi internal constructor( * 使用示例如下 ↓ * * ```kotlin - * paramCount { it > 5 && it != 0 } + * paramCount { it >= 5 || it.isZero() } * ``` * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - fun paramCount(conditions: IntConditions): IndexTypeCondition { + fun paramCount(conditions: CountConditions): IndexTypeCondition { rulesData.paramCountConditions = conditions return IndexTypeCondition(IndexConfigType.MATCH) } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt index edb366db..03b02365 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/FieldFinder.kt @@ -36,10 +36,10 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.MemberBaseFinder import com.highcapable.yukihookapi.hook.core.finder.members.data.FieldRulesData -import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules -import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool import com.highcapable.yukihookapi.hook.core.finder.type.factory.FieldConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import com.highcapable.yukihookapi.hook.factory.checkingInternal import com.highcapable.yukihookapi.hook.factory.current import com.highcapable.yukihookapi.hook.factory.hasExtends @@ -103,11 +103,11 @@ class FieldFinder @PublishedApi internal constructor( * - 可不设置筛选条件 * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition { - rulesData.modifiers = ModifierRules().apply(initiate) + fun modifiers(conditions: ModifierConditions): IndexTypeCondition { + rulesData.modifiers = conditions return IndexTypeCondition(IndexConfigType.MATCH) } @@ -137,11 +137,11 @@ class FieldFinder @PublishedApi internal constructor( * - ❗若不填写名称则必须存在一个其它条件 * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition { - rulesData.nameConditions = NameConditions().apply(initiate) + fun name(conditions: NameConditions): IndexTypeCondition { + rulesData.nameConditions = conditions return IndexTypeCondition(IndexConfigType.MATCH) } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt index fe6ae116..d53fb8ad 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/MethodFinder.kt @@ -35,16 +35,16 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.base.MemberBaseFinder import com.highcapable.yukihookapi.hook.core.finder.members.data.MethodRulesData -import com.highcapable.yukihookapi.hook.core.finder.type.ModifierRules -import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool +import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.MethodConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import com.highcapable.yukihookapi.hook.factory.checkingInternal import com.highcapable.yukihookapi.hook.factory.hasExtends import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.type.defined.UndefinedType import com.highcapable.yukihookapi.hook.type.defined.VagueType -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions import com.highcapable.yukihookapi.hook.utils.runBlocking import com.highcapable.yukihookapi.hook.utils.unit import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper @@ -120,11 +120,11 @@ class MethodFinder @PublishedApi internal constructor( * - 可不设置筛选条件 * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - inline fun modifiers(initiate: ModifierRules.() -> Unit): IndexTypeCondition { - rulesData.modifiers = ModifierRules().apply(initiate) + fun modifiers(conditions: ModifierConditions): IndexTypeCondition { + rulesData.modifiers = conditions return IndexTypeCondition(IndexConfigType.MATCH) } @@ -194,11 +194,11 @@ class MethodFinder @PublishedApi internal constructor( * - ❗若不填写名称则必须存在一个其它条件 * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - inline fun name(initiate: NameConditions.() -> Unit): IndexTypeCondition { - rulesData.nameConditions = NameConditions().apply(initiate) + fun name(conditions: NameConditions): IndexTypeCondition { + rulesData.nameConditions = conditions return IndexTypeCondition(IndexConfigType.MATCH) } @@ -246,14 +246,14 @@ class MethodFinder @PublishedApi internal constructor( * 使用示例如下 ↓ * * ```kotlin - * paramCount { it > 5 && it != 0 } + * paramCount { it >= 5 || it.isZero() } * ``` * * - ❗存在多个 [BaseFinder.IndexTypeCondition] 时除了 [order] 只会生效最后一个 * @param conditions 条件方法体 * @return [BaseFinder.IndexTypeCondition] */ - fun paramCount(conditions: IntConditions): IndexTypeCondition { + fun paramCount(conditions: CountConditions): IndexTypeCondition { rulesData.paramCountConditions = conditions return IndexTypeCondition(IndexConfigType.MATCH) } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt index 66d53134..d1ae9ed1 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/ConstructorRulesData.kt @@ -27,7 +27,7 @@ */ package com.highcapable.yukihookapi.hook.core.finder.members.data -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions import java.lang.reflect.Constructor /** @@ -42,7 +42,7 @@ internal class ConstructorRulesData internal constructor( var paramTypes: Array>? = null, var paramCount: Int = -1, var paramCountRange: IntRange = IntRange.EMPTY, - var paramCountConditions: IntConditions? = null + var paramCountConditions: CountConditions? = null ) : MemberRulesData() { override val objectName get() = "Constructor" diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt index 8206b472..ded1d48f 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/FieldRulesData.kt @@ -27,7 +27,7 @@ */ package com.highcapable.yukihookapi.hook.core.finder.members.data -import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import java.lang.reflect.Field /** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt index 4c72fe1b..e06e9690 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MemberRulesData.kt @@ -28,7 +28,7 @@ package com.highcapable.yukihookapi.hook.core.finder.members.data import com.highcapable.yukihookapi.hook.core.finder.base.data.BaseRulesData -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions import java.lang.reflect.Member /** @@ -43,7 +43,7 @@ internal open class MemberRulesData internal constructor( var isFindInSuper: Boolean = false, var matchCount: Int = -1, var matchCountRange: IntRange = IntRange.EMPTY, - var matchCountConditions: IntConditions? = null + var matchCountConditions: CountConditions? = null ) : BaseRulesData() { override val objectName get() = "Member" diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt index 04b4ba1b..f614b492 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/members/data/MethodRulesData.kt @@ -27,8 +27,8 @@ */ package com.highcapable.yukihookapi.hook.core.finder.members.data -import com.highcapable.yukihookapi.hook.core.finder.type.NameConditions -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.CountConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.NameConditions import java.lang.reflect.Method /** @@ -48,7 +48,7 @@ internal class MethodRulesData internal constructor( var paramTypes: Array>? = null, var paramCount: Int = -1, var paramCountRange: IntRange = IntRange.EMPTY, - var paramCountConditions: IntConditions? = null, + var paramCountConditions: CountConditions? = null, var returnType: Any? = null ) : MemberRulesData() { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt index 26ba7585..4354baa3 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/tools/ReflectionTool.kt @@ -28,7 +28,6 @@ package com.highcapable.yukihookapi.hook.core.finder.tools import com.highcapable.yukihookapi.hook.core.finder.base.data.BaseRulesData -import com.highcapable.yukihookapi.hook.core.finder.classes.data.ClassRulesData import com.highcapable.yukihookapi.hook.core.finder.members.data.ConstructorRulesData import com.highcapable.yukihookapi.hook.core.finder.members.data.FieldRulesData import com.highcapable.yukihookapi.hook.core.finder.members.data.MemberRulesData @@ -107,8 +106,8 @@ internal object ReflectionTool { var iNameCds = -1 val iLType = type?.let(matchIndex) { e -> declares.filter { e == it.type }.lastIndex } ?: -1 val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.filter { e == it.name }.lastIndex } ?: -1 - val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 - val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { e.contains(it.name) }.lastIndex } ?: -1 + val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e(it.cast()) }.lastIndex } ?: -1 + val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { it.name.let { n -> e(n.cast(), n) } }.lastIndex } ?: -1 declares.forEachIndexed { index, instance -> conditions { type?.also { @@ -124,13 +123,13 @@ internal object ReflectionTool { }) } modifiers?.also { - and(it.contains(instance).let { hold -> + and(it(instance.cast()).let { hold -> if (hold) iModify++ hold && matchIndex.compare(iModify, iLModify) }) } nameConditions?.also { - and(it.contains(instance.name).let { hold -> + and(instance.name.let { n -> it(n.cast(), n) }.let { hold -> if (hold) iNameCds++ hold && matchIndex.compare(iNameCds, iLNameCds) }) @@ -171,11 +170,11 @@ internal object ReflectionTool { val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() } ?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1 val iLParamCountCds = paramCountConditions - ?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1 + ?.let(matchIndex) { e -> declares.filter { it.parameterTypes.size.let { s -> e(s.cast(), s) } }.lastIndex } ?: -1 val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { paramTypesEq(e, it.parameterTypes) }.lastIndex } ?: -1 val iLName = name.takeIf(matchIndex) { it.isNotBlank() }?.let { e -> declares.filter { e == it.name }.lastIndex } ?: -1 - val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 - val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { e.contains(it.name) }.lastIndex } ?: -1 + val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e(it.cast()) }.lastIndex } ?: -1 + val iLNameCds = nameConditions?.let(matchIndex) { e -> declares.filter { it.name.let { n -> e(n.cast(), n) } }.lastIndex } ?: -1 declares.forEachIndexed { index, instance -> conditions { name.takeIf { it.isNotBlank() }?.also { @@ -203,7 +202,7 @@ internal object ReflectionTool { }) } paramCountConditions?.also { - and(it(instance.parameterTypes.size).let { hold -> + and(instance.parameterTypes.size.let { s -> it(s.cast(), s) }.let { hold -> if (hold) iParamCountCds++ hold && matchIndex.compare(iParamCountCds, iLParamCountCds) }) @@ -215,13 +214,13 @@ internal object ReflectionTool { }) } modifiers?.also { - and(it.contains(instance).let { hold -> + and(it(instance.cast()).let { hold -> if (hold) iModify++ hold && matchIndex.compare(iModify, iLModify) }) } nameConditions?.also { - and(it.contains(instance.name).let { hold -> + and(instance.name.let { n -> it(n.cast(), n) }.let { hold -> if (hold) iNameCds++ hold && matchIndex.compare(iNameCds, iLNameCds) }) @@ -257,9 +256,9 @@ internal object ReflectionTool { val iLParamCountRange = paramCountRange.takeIf(matchIndex) { it.isEmpty().not() } ?.let { e -> declares.filter { it.parameterTypes.size in e }.lastIndex } ?: -1 val iLParamCountCds = paramCountConditions - ?.let(matchIndex) { e -> declares.filter { e(it.parameterTypes.size) }.lastIndex } ?: -1 + ?.let(matchIndex) { e -> declares.filter { it.parameterTypes.size.let { s -> e(s.cast(), s) } }.lastIndex } ?: -1 val iLParamTypes = paramTypes?.let(matchIndex) { e -> declares.filter { paramTypesEq(e, it.parameterTypes) }.lastIndex } ?: -1 - val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e.contains(it) }.lastIndex } ?: -1 + val iLModify = modifiers?.let(matchIndex) { e -> declares.filter { e(it.cast()) }.lastIndex } ?: -1 declares.forEachIndexed { index, instance -> conditions { paramCount.takeIf { it >= 0 }?.also { @@ -275,7 +274,7 @@ internal object ReflectionTool { }) } paramCountConditions?.also { - and(it(instance.parameterTypes.size).let { hold -> + and(instance.parameterTypes.size.let { s -> it(s.cast(), s) }.let { hold -> if (hold) iParamCountCds++ hold && matchIndex.compare(iParamCountCds, iLParamCountCds) }) @@ -287,7 +286,7 @@ internal object ReflectionTool { }) } modifiers?.also { - and(it.contains(instance).let { hold -> + and(it(instance.cast()).let { hold -> if (hold) iModify++ hold && matchIndex.compare(iModify, iLModify) }) @@ -332,7 +331,6 @@ internal object ReflectionTool { 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) @@ -373,33 +371,33 @@ internal object ReflectionTool { private fun BaseRulesData.throwNotFoundError(instanceSet: Any?): Nothing = when (this) { is FieldRulesData -> throw createException( instanceSet, name = "Field", - "name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}]", + name.takeIf { it.isNotBlank() }?.let { "name:[$it]" } ?: "", nameConditions?.let { "nameConditions:$it" } ?: "", - "type:[${type ?: "unspecified"}]", - "modifiers:${modifiers ?: "[]"}", + type?.let { "type:[$it]" } ?: "", + modifiers?.let { "modifiers:[existed]" } ?: "", orderIndex?.let { it.takeIf { it.second }?.let { e -> "orderIndex:[${e.first}]" } ?: "orderIndex:[last]" } ?: "", matchIndex?.let { it.takeIf { it.second }?.let { e -> "matchIndex:[${e.first}]" } ?: "matchIndex:[last]" } ?: "" ) is MethodRulesData -> throw createException( instanceSet, name = "Method", - "name:[${name.takeIf { it.isNotBlank() } ?: "unspecified"}]", + name.takeIf { it.isNotBlank() }?.let { "name:[$it]" } ?: "", nameConditions?.let { "nameConditions:$it" } ?: "", - "paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}]", - "paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}]", - "paramCountConditions:[${paramCountConditions?.let { "existed" } ?: "unspecified"}]", - "paramTypes:[${paramTypes.typeOfString()}]", - "returnType:[${returnType ?: "unspecified"}]", - "modifiers:${modifiers ?: "[]"}", + paramCount.takeIf { it >= 0 }?.let { "paramCount:[$it]" } ?: "", + paramCountRange.takeIf { it.isEmpty().not() }?.let { "paramCountRange:[$it]" } ?: "", + paramCountConditions?.let { "paramCountConditions:[existed]" } ?: "", + paramTypes?.typeOfString()?.let { "paramTypes:[$it]" } ?: "", + returnType?.let { "returnType:[$it]" } ?: "", + modifiers?.let { "modifiers:[existed]" } ?: "", orderIndex?.let { it.takeIf { it.second }?.let { e -> "orderIndex:[${e.first}]" } ?: "orderIndex:[last]" } ?: "", matchIndex?.let { it.takeIf { it.second }?.let { e -> "matchIndex:[${e.first}]" } ?: "matchIndex:[last]" } ?: "" ) is ConstructorRulesData -> throw createException( instanceSet, name = "Constructor", - "paramCount:[${paramCount.takeIf { it >= 0 } ?: "unspecified"}]", - "paramCountRange:[${paramCountRange.takeIf { it.isEmpty().not() } ?: "unspecified"}]", - "paramCountConditions:[${paramCountConditions?.let { "existed" } ?: "unspecified"}]", - "paramTypes:[${paramTypes.typeOfString()}]", - "modifiers:${modifiers ?: "[]"}", + paramCount.takeIf { it >= 0 }?.let { "paramCount:[$it]" } ?: "", + paramCountRange.takeIf { it.isEmpty().not() }?.let { "paramCountRange:[$it]" } ?: "", + paramCountConditions?.let { "paramCountConditions:[existed]" } ?: "", + paramTypes?.typeOfString()?.let { "paramTypes:[$it]" } ?: "", + modifiers?.let { "modifiers:[existed]" } ?: "", orderIndex?.let { it.takeIf { it.second }?.let { e -> "orderIndex:[${e.first}]" } ?: "orderIndex:[last]" } ?: "", matchIndex?.let { it.takeIf { it.second }?.let { e -> "matchIndex:[${e.first}]" } ?: "matchIndex:[last]" } ?: "" ) diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/ModifierRules.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/ModifierRules.kt deleted file mode 100644 index dba889b8..00000000 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/ModifierRules.kt +++ /dev/null @@ -1,311 +0,0 @@ -/* - * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. - * Copyright (C) 2019-2022 HighCapable - * https://github.com/fankes/YukiHookAPI - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This file is Created by fankes on 2022/3/27. - */ -@file:Suppress("unused", "MemberVisibilityCanBePrivate") - -package com.highcapable.yukihookapi.hook.core.finder.type - -import java.lang.reflect.Member -import java.lang.reflect.Modifier - -/** - * 这是一个 [Class]、[Member] 描述符定义类 - * - * 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位 - */ -class ModifierRules @PublishedApi internal constructor() { - - /** 描述声明使用 */ - private var isPublic = false - - /** 描述声明使用 */ - private var isPrivate = false - - /** 描述声明使用 */ - private var isProtected = false - - /** 描述声明使用 */ - private var isStatic = false - - /** 描述声明使用 */ - private var isFinal = false - - /** 描述声明使用 */ - private var isSynchronized = false - - /** 描述声明使用 */ - private var isVolatile = false - - /** 描述声明使用 */ - private var isTransient = false - - /** 描述声明使用 */ - private var isNative = false - - /** 描述声明使用 */ - private var isInterface = false - - /** 描述声明使用 */ - private var isAbstract = false - - /** 描述声明使用 */ - private var isStrict = false - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isPublic] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isPublic()")) - fun asPublic() = isPublic() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isPrivate] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isPrivate()")) - fun asPrivate() = isPrivate() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isProtected] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isProtected()")) - fun asProtected() = isProtected() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isStatic] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isStatic()")) - fun asStatic() = isStatic() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isFinal] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isFinal()")) - fun asFinal() = isFinal() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isSynchronized] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isSynchronized()")) - fun asSynchronized() = isSynchronized() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isVolatile] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isVolatile()")) - fun asVolatile() = isVolatile() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isTransient] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isTransient()")) - fun asTransient() = isTransient() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isNative] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isNative()")) - fun asNative() = isNative() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isInterface] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isInterface()")) - fun asInterface() = isInterface() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isAbstract] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isAbstract()")) - fun asAbstract() = isAbstract() - - /** - * - ❗此方法已弃用 - 在之后的版本中将直接被删除 - * - * - ❗请现在转移到 [isStrict] - */ - @Deprecated(message = "请使用新的命名方法", replaceWith = ReplaceWith(expression = "isStrict()")) - fun asStrict() = isStrict() - - /** 添加描述 [Class]、[Member] 类型包含 public */ - fun isPublic() { - isPublic = true - } - - /** 添加描述 [Class]、[Member] 类型包含 private */ - fun isPrivate() { - isPrivate = true - } - - /** 添加描述 [Class]、[Member] 类型包含 protected */ - fun isProtected() { - isProtected = true - } - - /** - * 添加描述 [Class]、[Member] 类型包含 static - * - * 对于任意的静态 [Class]、[Member] 可添加此描述进行确定 - * - * - ❗注意 Kotlin → Jvm 后的 object 类中的方法并不是静态的 - */ - fun isStatic() { - isStatic = true - } - - /** - * 添加描述 [Class]、[Member] 类型包含 final - * - * - ❗注意 Kotlin → Jvm 后没有 open 标识的 [Class]、[Member] 和没有任何关联的 [Class]、[Member] 都将为 final - */ - fun isFinal() { - isFinal = true - } - - /** 添加描述 [Class]、[Member] 类型包含 synchronized */ - fun isSynchronized() { - isSynchronized = true - } - - /** 添加描述 [Class]、[Member] 类型包含 volatile */ - fun isVolatile() { - isVolatile = true - } - - /** 添加描述 [Class]、[Member] 类型包含 transient */ - fun isTransient() { - isTransient = true - } - - /** - * 添加描述 [Class]、[Member] 类型包含 native - * - * 对于任意 JNI 对接的 [Class]、[Member] 可添加此描述进行确定 - */ - fun isNative() { - isNative = true - } - - /** 添加描述 [Class]、[Member] 类型包含 interface */ - fun isInterface() { - isInterface = true - } - - /** - * 添加描述 [Class]、[Member] 类型包含 abstract - * - * 对于任意的抽象 [Class]、[Member] 可添加此描述进行确定 - */ - fun isAbstract() { - isAbstract = true - } - - /** 添加描述 [Class]、[Member] 类型包含 strict */ - fun isStrict() { - isStrict = true - } - - /** - * 对比 [Class]、[Member] 类型是否符合条件 - * @param reflects 实例 - 只能是 [Class] or [Member] - * @return [Boolean] 是否符合条件 - */ - @PublishedApi - internal fun contains(reflects: Any): Boolean { - var conditions = true - Reflects(reflects).also { - if (isPublic) conditions = Modifier.isPublic(it.modifiers) - if (isPrivate) conditions = conditions && Modifier.isPrivate(it.modifiers) - if (isProtected) conditions = conditions && Modifier.isProtected(it.modifiers) - if (isStatic) conditions = conditions && Modifier.isStatic(it.modifiers) - if (isFinal) conditions = conditions && Modifier.isFinal(it.modifiers) - if (isSynchronized) conditions = conditions && Modifier.isSynchronized(it.modifiers) - if (isVolatile) conditions = conditions && Modifier.isVolatile(it.modifiers) - if (isTransient) conditions = conditions && Modifier.isTransient(it.modifiers) - if (isNative) conditions = conditions && Modifier.isNative(it.modifiers) - if (isInterface) conditions = conditions && Modifier.isInterface(it.modifiers) - if (isAbstract) conditions = conditions && Modifier.isAbstract(it.modifiers) - if (isStrict) conditions = conditions && Modifier.isStrict(it.modifiers) - } - return conditions - } - - override fun toString(): String { - var conditions = "" - if (isPublic) conditions += " " - if (isPrivate) conditions += " " - if (isProtected) conditions += " " - if (isStatic) conditions += " " - if (isFinal) conditions += " " - if (isSynchronized) conditions += " " - if (isVolatile) conditions += " " - if (isTransient) conditions += " " - if (isNative) conditions += " " - if (isInterface) conditions += " " - if (isAbstract) conditions += " " - if (isStrict) conditions += " " - return "[${conditions.trim()}]" - } - - /** - * 实例化反射对象接口实现类 - * @param reflects 反射对象实例 - */ - private class Reflects(private val reflects: Any) { - - /** - * 获取当前对象的类型描述符 - * @return [Int] - */ - val modifiers - get() = when (reflects) { - is Member -> reflects.modifiers - is Class<*> -> reflects.modifiers - else -> error("Invalid reflects type") - } - } -} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/NameConditions.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/NameConditions.kt deleted file mode 100644 index f2078d3f..00000000 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/NameConditions.kt +++ /dev/null @@ -1,367 +0,0 @@ -/* - * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. - * Copyright (C) 2019-2022 HighCapable - * https://github.com/fankes/YukiHookAPI - * - * MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This file is Created by fankes on 2022/5/16. - */ -@file:Suppress("unused", "MemberVisibilityCanBePrivate") - -package com.highcapable.yukihookapi.hook.core.finder.type - -import com.highcapable.yukihookapi.hook.core.finder.type.factory.IntConditions -import java.lang.reflect.Field -import java.lang.reflect.Member -import java.lang.reflect.Method - -/** - * 这是一个模糊 [Class]、[Member] 名称匹配实现类 - * - * 可对 R8 混淆后的 [Class]、[Member] 进行更加详细的定位 - */ -class NameConditions @PublishedApi internal constructor() { - - /** 完全字符匹配条件数组 */ - private var cdsEqualsOfs = ArrayList>() - - /** 起始字符匹配条件数组 */ - private var cdsStartsWiths = ArrayList>() - - /** 结束字符匹配条件数组 */ - private var cdsEndsWiths = ArrayList>() - - /** 包含字符匹配条件数组 */ - private var cdsContains = ArrayList>() - - /** 正则字符匹配条件数组 */ - private var cdsMatches = ArrayList() - - /** 字符长度匹配条件 */ - private var cdsLength = -1 - - /** 字符长度范围匹配条件 */ - private var cdsLengthRange = IntRange.EMPTY - - /** 字符长度条件匹配条件 */ - private var cdsLengthConditions: IntConditions? = null - - /** 标识为匿名类的主类调用对象条件 */ - private var isThisSynthetic0 = false - - /** 标识为只有符号条件 */ - private var isOnlySymbols = false - - /** 标识为只有字母条件 */ - private var isOnlyLetters = false - - /** 标识为只有数字条件 */ - private var isOnlyNumbers = false - - /** 标识为只有字母或数字条件 */ - private var isOnlyLettersNumbers = false - - /** 标识为只有小写字母条件 */ - private var isOnlyLowercase = false - - /** 标识为只有大写字母条件 */ - private var isOnlyUppercase = false - - /** - * 完全字符匹配 - * - * 例如匹配 "catMonitor" 可设置为 ↓ - * - * ```kotlin - * equalsOf(other = "catMonitor") - * ``` - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * - * 例如匹配 "cargoSale" or "catMonitor" 可设置为 ↓ - * - * ```kotlin - * name { - * equalsOf(other = "cargoSale") - * equalsOf(other = "catMonitor") - * } - * ``` - * @param other 字符匹配 - * @param isIgnoreCase 是否忽略字符中的大小写 - 默认否 - */ - fun equalsOf(other: String, isIgnoreCase: Boolean = false) { - cdsEqualsOfs.add(Pair(other, isIgnoreCase)) - } - - /** - * 起始字符匹配 - * - * 例如匹配 "catMonitor" 可设置为 ↓ - * - * ```kotlin - * startsWith(prefix = "cat") - * ``` - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * - * 例如匹配 "cargoSale" or "catMonitor" 可设置为 ↓ - * - * ```kotlin - * name { - * startsWith(prefix = "cargo") - * startsWith(prefix = "cat") - * } - * ``` - * @param prefix 起始字符匹配 - * @param startIndex 起始字符下标 - 默认从 0 开始 - * @param isIgnoreCase 是否忽略字符中的大小写 - 默认否 - */ - fun startsWith(prefix: String, startIndex: Int = 0, isIgnoreCase: Boolean = false) { - cdsStartsWiths.add(Triple(prefix, startIndex, isIgnoreCase)) - } - - /** - * 结束字符匹配 - * - * 例如匹配 "catMonitor" 可设置为 ↓ - * - * ```kotlin - * endsWith(suffix = "Monitor") - * ``` - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * - * 例如匹配 "cargoSale" or "catMonitor" 可设置为 ↓ - * - * ```kotlin - * name { - * endsWith(suffix = "Sale") - * endsWith(suffix = "Monitor") - * } - * ``` - * @param suffix 结束字符匹配 - * @param isIgnoreCase 是否忽略字符中的大小写 - 默认否 - */ - fun endsWith(suffix: String, isIgnoreCase: Boolean = false) { - cdsEndsWiths.add(Pair(suffix, isIgnoreCase)) - } - - /** - * 包含字符匹配 - * - * 例如匹配 catMonitor 可设置为 ↓ - * - * ```kotlin - * contains(other = "atMoni") - * ``` - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * - * 例如匹配 "cargoSale" or "catMonitor" 可设置为 ↓ - * - * ```kotlin - * name { - * contains(other = "goSal") - * contains(other = "atMoni") - * } - * ``` - * @param other 包含字符匹配 - * @param isIgnoreCase 是否忽略字符中的大小写 - 默认否 - */ - fun contains(other: String, isIgnoreCase: Boolean = false) { - cdsContains.add(Pair(other, isIgnoreCase)) - } - - /** - * 正则字符匹配 - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * @param regex 正则字符 - */ - fun matches(regex: String) { - cdsMatches.add(regex.toRegex()) - } - - /** - * 正则字符匹配 - * - * - 可以重复使用 - 最终会选择完全匹配的一个 - * @param regex 正则字符 - */ - fun matches(regex: Regex) { - cdsMatches.add(regex) - } - - /** - * 字符长度匹配 - * - * - 不可重复使用 - 重复使用旧的条件会被当前条件替换 - * @param num 预期的长度 - */ - fun length(num: Int) { - cdsLength = num - } - - /** - * 字符长度范围匹配 - * - * - 不可重复使用 - 重复使用旧的条件会被当前条件替换 - * @param numRange 预期的长度范围 - */ - fun length(numRange: IntRange) { - cdsLengthRange = numRange - } - - /** - * 字符长度条件匹配 - * - * - 不可重复使用 - 重复使用旧的条件会被当前条件替换 - * @param conditions 条件方法体 - */ - fun length(conditions: IntConditions) { - cdsLengthConditions = conditions - } - - /** - * 标识为匿名类的主类调用对象 - * - * 它的名称形态通常为:this$0 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun thisSynthetic0() { - isThisSynthetic0 = true - } - - /** - * 标识为只有符号 - * - * 筛选仅包含 _、-、?、!、,、.、<、> 等符号以及特殊符号 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlySymbols() { - isOnlySymbols = true - } - - /** - * 标识为只有字母 - * - * 在没有 [onlyLowercase] 以及 [onlyUppercase] 的条件下筛选仅包含 26 个大小写英文字母 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlyLetters() { - isOnlyLetters = true - } - - /** - * 标识为只有数字 - * - * 筛选仅包含 0-9 阿拉伯数字 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlyNumbers() { - isOnlyNumbers = true - } - - /** - * 标识为只有字母或数字 - * - * 融合条件 [onlyLetters] 和 [onlyNumbers] - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlyLettersNumbers() { - isOnlyLettersNumbers = true - } - - /** - * 标识为只有小写字母 - * - * 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlyLowercase() { - isOnlyLowercase = true - } - - /** - * 标识为只有大写字母 - * - * 在没有其它条件的情况下设置此条件允许判断对象存在字母以外的字符 - * - * 你可以使用 [matches] 方法进行更详细的正则匹配 - */ - fun onlyUppercase() { - isOnlyUppercase = true - } - - /** - * 对比 [Class]、[Member] 名称是否符合条件 - * @param symbolName 符号名称 - 可以使用 [Class.getName]、[Class.getSimpleName]、[Field.getName]、[Method.getName] 获取 - * @return [Boolean] 是否符合条件 - */ - @PublishedApi - internal fun contains(symbolName: String): Boolean { - var conditions = true - if (isThisSynthetic0) conditions = conditions && symbolName == "this$0" - if (isOnlySymbols) conditions = conditions && symbolName.matches("[*,.:~`'\"|/\\\\?!^()\\[\\]{}%@#$&\\-_+=<>]+".toRegex()) - if (isOnlyLetters) conditions = conditions && symbolName.matches("[a-zA-Z]+".toRegex()) - if (isOnlyNumbers) conditions = conditions && symbolName.matches("[0-9]+".toRegex()) - if (isOnlyLettersNumbers) conditions = conditions && symbolName.matches("[a-zA-Z0-9]+".toRegex()) - if (isOnlyLowercase) conditions = conditions && symbolName.matches("[a-z]+".toRegex()) - if (isOnlyUppercase) conditions = conditions && symbolName.matches("[A-Z]+".toRegex()) - cdsEqualsOfs.takeIf { it.isNotEmpty() }?.also { conditions = conditions && it.any { e -> symbolName.equals(e.first, e.second) } } - cdsStartsWiths.takeIf { it.isNotEmpty() } - ?.also { conditions = conditions && it.any { e -> symbolName.startsWith(e.first, e.second, e.third) } } - cdsEndsWiths.takeIf { it.isNotEmpty() }?.also { conditions = conditions && it.any { e -> symbolName.endsWith(e.first, e.second) } } - cdsContains.takeIf { it.isNotEmpty() }?.also { conditions = conditions && it.any { e -> symbolName.contains(e.first, e.second) } } - cdsMatches.takeIf { it.isNotEmpty() }?.also { conditions = conditions && it.any { e -> symbolName.matches(e) } } - cdsLength.takeIf { it >= 0 }?.also { conditions = conditions && symbolName.length == it } - cdsLengthRange.takeIf { it.isEmpty().not() }?.also { conditions = conditions && symbolName.length in it } - cdsLengthConditions?.also { conditions = conditions && it(symbolName.length) } - return conditions - } - - override fun toString(): String { - var conditions = "" - if (isThisSynthetic0) conditions += " " - if (isOnlySymbols) conditions += " " - if (isOnlyLetters) conditions += " " - if (isOnlyNumbers) conditions += " " - if (isOnlyLettersNumbers) conditions += " " - if (isOnlyLowercase) conditions += " " - if (isOnlyUppercase) conditions += " " - if (cdsEqualsOfs.isNotEmpty()) conditions += " " - if (cdsStartsWiths.isNotEmpty()) conditions += " " - if (cdsEndsWiths.isNotEmpty()) conditions += " " - if (cdsContains.isNotEmpty()) conditions += " " - if (cdsMatches.isNotEmpty()) conditions += " " - if (cdsLength >= 0) conditions += " " - if (cdsLengthRange.isEmpty().not()) conditions += " " - if (cdsLengthConditions != null) conditions += " " - return "[${conditions.trim()}]" - } -} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/factory/TypeAliasFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/factory/TypeAliasFactory.kt index d0897ed6..6c5f9999 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/factory/TypeAliasFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/type/factory/TypeAliasFactory.kt @@ -27,6 +27,9 @@ */ package com.highcapable.yukihookapi.hook.core.finder.type.factory +import com.highcapable.yukihookapi.hook.core.finder.base.rules.CountRules +import com.highcapable.yukihookapi.hook.core.finder.base.rules.ModifierRules +import com.highcapable.yukihookapi.hook.core.finder.base.rules.NameRules import com.highcapable.yukihookapi.hook.core.finder.members.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.members.FieldFinder import com.highcapable.yukihookapi.hook.core.finder.members.MethodFinder @@ -40,5 +43,11 @@ internal typealias MethodConditions = MethodFinder.() -> Unit /** 定义 [ConstructorFinder] 方法体类型 */ internal typealias ConstructorConditions = ConstructorFinder.() -> Unit -/** 定义 [Int] 方法体类型 */ -internal typealias IntConditions = (Int) -> Boolean \ No newline at end of file +/** 定义 [NameRules] 方法体类型 */ +internal typealias NameConditions = NameRules.(String) -> Boolean + +/** 定义 [CountRules] 方法体类型 */ +internal typealias CountConditions = CountRules.(Int) -> Boolean + +/** 定义 [ModifierRules] 方法体类型 */ +internal typealias ModifierConditions = ModifierRules.() -> Boolean \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt index e746996d..20b44cf7 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/ReflectionFactory.kt @@ -31,14 +31,15 @@ package com.highcapable.yukihookapi.hook.factory import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.bean.CurrentClass +import com.highcapable.yukihookapi.hook.core.finder.base.rules.ModifierRules import com.highcapable.yukihookapi.hook.core.finder.members.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.members.FieldFinder 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.core.finder.type.factory.ConstructorConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.FieldConditions import com.highcapable.yukihookapi.hook.core.finder.type.factory.MethodConditions +import com.highcapable.yukihookapi.hook.core.finder.type.factory.ModifierConditions import com.highcapable.yukihookapi.hook.xposed.bridge.status.YukiHookModuleStatus import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics import java.lang.reflect.Constructor @@ -136,19 +137,17 @@ inline fun Class<*>.hasConstructor(initiate: ConstructorConditions = { emptyPara /** * 查询 [Member] 中匹配的描述符 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [Boolean] 是否存在 - * todo 这个也要改 */ -inline fun Member.hasModifiers(initiate: ModifierRules.() -> Unit) = ModifierRules().apply(initiate).contains(this) +inline fun Member.hasModifiers(conditions: ModifierConditions) = conditions(ModifierRules.with(this)) /** * 查询 [Class] 中匹配的描述符 - * @param initiate 方法体 + * @param conditions 条件方法体 * @return [Boolean] 是否存在 - * todo 这个也要改 */ -inline fun Class<*>.hasModifiers(initiate: ModifierRules.() -> Unit) = ModifierRules().apply(initiate).contains(this) +inline fun Class<*>.hasModifiers(conditions: ModifierConditions) = conditions(ModifierRules.with(this)) /** * 查找并得到变量