This commit is contained in:
2022-02-04 01:53:49 +08:00
parent 341bfd8cdb
commit 539b3452b3
4 changed files with 241 additions and 136 deletions

View File

@@ -30,17 +30,17 @@
package com.highcapable.yukihookapi.hook.core package com.highcapable.yukihookapi.hook.core
import com.highcapable.yukihookapi.annotation.DoNotUseMethod import com.highcapable.yukihookapi.annotation.DoNotUseMethod
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
import com.highcapable.yukihookapi.hook.log.loggerE import com.highcapable.yukihookapi.hook.log.loggerE
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
import com.highcapable.yukihookapi.param.HookParam import com.highcapable.yukihookapi.param.HookParam
import com.highcapable.yukihookapi.param.PackageParam import com.highcapable.yukihookapi.param.PackageParam
import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.XC_MethodReplacement import de.robv.android.xposed.XC_MethodReplacement
import de.robv.android.xposed.XposedBridge import de.robv.android.xposed.XposedBridge
import java.lang.reflect.Constructor
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.Member import java.lang.reflect.Member
import java.lang.reflect.Method
/** /**
* YukiHook 核心类实现方法 * YukiHook 核心类实现方法
@@ -122,7 +122,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
*/ */
fun method(initiate: MethodFinder.() -> Unit) { fun method(initiate: MethodFinder.() -> Unit) {
runCatching { runCatching {
member = MethodFinder().apply(initiate).find() member = MethodFinder(hookClass).apply(initiate).find()
}.onFailure { }.onFailure {
isStopHookMode = true isStopHookMode = true
onNoSuchMemberCallback?.invoke(it) onNoSuchMemberCallback?.invoke(it)
@@ -139,7 +139,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
*/ */
fun constructor(initiate: ConstructorFinder.() -> Unit) { fun constructor(initiate: ConstructorFinder.() -> Unit) {
runCatching { runCatching {
member = ConstructorFinder().apply(initiate).find() member = ConstructorFinder(hookClass).apply(initiate).find()
}.onFailure { }.onFailure {
isStopHookMode = true isStopHookMode = true
onNoSuchMemberCallback?.invoke(it) onNoSuchMemberCallback?.invoke(it)
@@ -155,13 +155,13 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
*/ */
fun HookParam.field(initiate: FieldFinder.() -> Unit) = fun HookParam.field(initiate: FieldFinder.() -> Unit) =
try { try {
FieldFinder().apply(initiate).find() FieldFinder(hookClass).apply(initiate).find()
} catch (e: Throwable) { } catch (e: Throwable) {
isStopHookMode = true isStopHookMode = true
onNoSuchMemberCallback?.invoke(e) onNoSuchMemberCallback?.invoke(e)
onFailureCallback?.invoke(e) onFailureCallback?.invoke(e)
if (onNoSuchMemberCallback == null && onFailureCallback == null) onHookFailureMsg(e) if (onNoSuchMemberCallback == null && onFailureCallback == null) onHookFailureMsg(e)
FieldFinder().Result() FieldFinder(hookClass).Result()
} }
/** /**
@@ -335,135 +335,6 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
override fun toString() = "$member#YukiHook" override fun toString() = "$member#YukiHook"
/**
* [Field] 查找类
*
* 可通过指定类型查找指定变量
*/
inner class FieldFinder {
/** 当前找到的 [Field] */
private var fieldInstance: Field? = null
/** 变量名 */
var name = ""
/** 变量类型 */
var type: Class<*>? = null
/**
* 得到变量处理结果
* @return [Result]
* @throws NoSuchFieldError 如果找不到变量
*/
@DoNotUseMethod
fun find(): Result {
fieldInstance = when {
name.isBlank() -> error("Field name cannot be empty")
else -> ReflectionUtils.findFieldIfExists(hookClass, type?.name, name)
}
return Result()
}
/**
* Field 查找结果实现类
*
* 可在这里处理找到的 [fieldInstance]
*/
inner class Result {
/**
* 设置变量实例
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
* @param any 设置的实例内容
*/
fun set(instance: Any? = null, any: Any?) = fieldInstance?.set(instance, any)
/**
* 得到变量实例
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
* @return [Field] or null
*/
fun <T> get(instance: Any? = null) = fieldInstance?.get(instance) as? T?
/**
* 得到变量本身
* @return [Field] or null
*/
fun find() = fieldInstance
}
}
/**
* [Method] 查找类
*
* 可通过指定类型查找指定方法
*/
inner class MethodFinder {
/** 方法参数 */
private var params: Array<out Class<*>>? = null
/** 方法名 */
var name = ""
/** 方法返回值 */
var returnType: Class<*>? = null
/**
* 方法参数
* @param param 参数数组
*/
fun param(vararg param: Class<*>) {
params = param
}
/**
* 得到方法 - 不能在外部调用
* @return [Method]
* @throws NoSuchMethodError 如果找不到方法
*/
@DoNotUseMethod
fun find(): Method =
when {
name.isBlank() -> error("Method name cannot be empty")
else ->
if (params != null)
ReflectionUtils.findMethodBestMatch(hookClass, returnType, name, *params!!)
else ReflectionUtils.findMethodNoParam(hookClass, returnType, name)
}
}
/**
* [Constructor] 查找类
*
* 可通过指定类型查找指定构造类
*/
inner class ConstructorFinder {
/** 方法参数 */
private var params: Array<out Class<*>>? = null
/**
* 方法参数
* @param param 参数数组
*/
fun param(vararg param: Class<*>) {
params = param
}
/**
* 得到构造类 - 不能在外部调用
* @return [Constructor]
* @throws NoSuchMethodError 如果找不到构造类
*/
@DoNotUseMethod
fun find(): Constructor<*> =
if (params != null)
ReflectionUtils.findConstructorExact(hookClass, *params!!)
else ReflectionUtils.findConstructorExact(hookClass)
}
/** /**
* 监听 Hook 结果实现类 * 监听 Hook 结果实现类
* *

View File

@@ -0,0 +1,65 @@
/**
* MIT License
*
* Copyright (C) 2022 HighCapable
*
* This file is part of YukiHookAPI.
*
* 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/2/4.
*/
@file:Suppress("unused")
package com.highcapable.yukihookapi.hook.core.finder
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
import java.lang.reflect.Constructor
/**
* [Constructor] 查找类
*
* 可通过指定类型查找指定构造类
* @param hookClass 当前被 Hook 的 [Class]
*/
class ConstructorFinder(private val hookClass: Class<*>) {
/** 方法参数 */
private var params: Array<out Class<*>>? = null
/**
* 方法参数
* @param param 参数数组
*/
fun param(vararg param: Class<*>) {
params = param
}
/**
* 得到构造类 - 不能在外部调用
* @return [Constructor]
* @throws NoSuchMethodError 如果找不到构造类
*/
@DoNotUseMethod
fun find(): Constructor<*> =
if (params != null)
ReflectionUtils.findConstructorExact(hookClass, *params!!)
else ReflectionUtils.findConstructorExact(hookClass)
}

View File

@@ -0,0 +1,94 @@
/**
* MIT License
*
* Copyright (C) 2022 HighCapable
*
* This file is part of YukiHookAPI.
*
* 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/2/4.
*/
@file:Suppress("unused", "UNCHECKED_CAST")
package com.highcapable.yukihookapi.hook.core.finder
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
import java.lang.reflect.Field
/**
* Field 查找结果实现类
*
* 可在这里处理找到的 [fieldInstance]
* @param hookClass 当前被 Hook 的 [Class]
*/
class FieldFinder(private val hookClass: Class<*>) {
/** 当前找到的 [Field] */
private var fieldInstance: Field? = null
/** 变量名 */
var name = ""
/** 变量类型 */
var type: Class<*>? = null
/**
* 得到变量处理结果
* @return [Result]
* @throws NoSuchFieldError 如果找不到变量
*/
@DoNotUseMethod
fun find(): Result {
fieldInstance = when {
name.isBlank() -> error("Field name cannot be empty")
else -> ReflectionUtils.findFieldIfExists(hookClass, type?.name, name)
}
return Result()
}
/**
* Field 查找结果实现类
*
* 可在这里处理找到的 [fieldInstance]
*/
inner class Result {
/**
* 设置变量实例
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
* @param any 设置的实例内容
*/
fun set(instance: Any? = null, any: Any?) = fieldInstance?.set(instance, any)
/**
* 得到变量实例
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
* @return [Field] or null
*/
fun <T> get(instance: Any? = null) = fieldInstance?.get(instance) as? T?
/**
* 得到变量本身
* @return [Field] or null
*/
fun find() = fieldInstance
}
}

View File

@@ -0,0 +1,75 @@
/**
* MIT License
*
* Copyright (C) 2022 HighCapable
*
* This file is part of YukiHookAPI.
*
* 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/2/4.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.yukihookapi.hook.core.finder
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
import java.lang.reflect.Method
/**
* [Method] 查找类
*
* 可通过指定类型查找指定方法
* @param hookClass 当前被 Hook 的 [Class]
*/
class MethodFinder(private val hookClass: Class<*>) {
/** 方法参数 */
private var params: Array<out Class<*>>? = null
/** 方法名 */
var name = ""
/** 方法返回值 */
var returnType: Class<*>? = null
/**
* 方法参数
* @param param 参数数组
*/
fun param(vararg param: Class<*>) {
params = param
}
/**
* 得到方法 - 不能在外部调用
* @return [Method]
* @throws NoSuchMethodError 如果找不到方法
*/
@DoNotUseMethod
fun find(): Method =
when {
name.isBlank() -> error("Method name cannot be empty")
else ->
if (params != null)
ReflectionUtils.findMethodBestMatch(hookClass, returnType, name, *params!!)
else ReflectionUtils.findMethodNoParam(hookClass, returnType, name)
}
}