mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Added support multi-user apps debug info and add appUserId function in PackageParam
This commit is contained in:
@@ -40,6 +40,22 @@ val appInfo: ApplicationInfo
|
||||
|
||||
> 获取当前 Hook APP 的 `ApplicationInfo`。
|
||||
|
||||
### appUserId [field]
|
||||
|
||||
```kotlin
|
||||
val appUserId: Int
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 获取当前 Hook APP 的用户 ID。
|
||||
|
||||
机主为 `0`,应用双开 (分身) 或工作资料因系统环境不同 ID 也各不相同。
|
||||
|
||||
### appContext [field]
|
||||
|
||||
```kotlin
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## YukiResourcesHookCreater [class]
|
||||
|
||||
```kotlin
|
||||
class YukiResourcesHookCreater(private val packageParam: PackageParam, internal val hookResources: HookResources)
|
||||
class YukiResourcesHookCreater(internal val packageParam: PackageParam, internal val hookResources: HookResources)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
@@ -51,7 +51,7 @@ injectResource(tag = "KuriharaYuki") {
|
||||
### ResourcesHookCreater [class]
|
||||
|
||||
```kotlin
|
||||
inner class ResourcesHookCreater internal constructor(private val tag: String)
|
||||
inner class ResourcesHookCreater internal constructor(private val tag: String, private val packageName: String)
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
@@ -498,6 +498,20 @@ fun mipmap()
|
||||
|
||||
> 设置 Resources 类型为位图(Mipmap)。
|
||||
|
||||
##### array [method]
|
||||
|
||||
```kotlin
|
||||
fun array()
|
||||
```
|
||||
|
||||
**变更记录**
|
||||
|
||||
`v1.0.93` `新增`
|
||||
|
||||
**功能描述**
|
||||
|
||||
> 设置 Resources 类型为数组(Array)。
|
||||
|
||||
#### Result [class]
|
||||
|
||||
```kotlin
|
||||
|
@@ -543,7 +543,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
||||
onHookingFailureCallback?.invoke(it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (isNotIgnoredNoSuchMemberFailure) yLoggerE(
|
||||
msg = "[$packageName] " + (if (isHookMemberSetup)
|
||||
msg = "$hostTagName " + (if (isHookMemberSetup)
|
||||
"Hooked Member with a finding error by $hookClass [$tag]"
|
||||
else "Hooked Member cannot be non-null by $hookClass [$tag]"),
|
||||
e = findingThrowable ?: it
|
||||
@@ -583,7 +583,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
||||
if (isMemberNotFound) onNoSuchMemberFailureCallback?.invoke(it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if ((isNotIgnoredHookingFailure && isMemberNotFound.not()) || (isNotIgnoredNoSuchMemberFailure && isMemberNotFound))
|
||||
yLoggerE(msg = "[$packageName] Hooked All Members with an error in $hookClass [$tag]", e = it)
|
||||
yLoggerE(msg = "$hostTagName Hooked All Members with an error in $hookClass [$tag]", e = it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
||||
* @param msg 调试日志内容
|
||||
*/
|
||||
private fun onHookLogMsg(msg: String) {
|
||||
if (YukiHookAPI.Configs.isDebug) yLoggerI(msg = "[$packageName] $msg")
|
||||
if (YukiHookAPI.Configs.isDebug) yLoggerI(msg = "$hostTagName $msg")
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -600,7 +600,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
||||
* @param throwable 异常信息
|
||||
*/
|
||||
private fun onHookFailureMsg(throwable: Throwable) =
|
||||
yLoggerE(msg = "[$packageName] Try to hook ${hookClass.instance ?: hookClass.name}[$member] got an Exception [$tag]", e = throwable)
|
||||
yLoggerE(msg = "$hostTagName Try to hook ${hookClass.instance ?: hookClass.name}[$member] got an Exception [$tag]", e = throwable)
|
||||
|
||||
/**
|
||||
* 判断是否没有设置 Hook 过程中的任何异常拦截
|
||||
@@ -614,6 +614,12 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
||||
*/
|
||||
internal val isNotIgnoredNoSuchMemberFailure get() = onNoSuchMemberFailureCallback == null && isNotIgnoredHookingFailure
|
||||
|
||||
/**
|
||||
* 获取 Hook APP (宿主) 标签
|
||||
* @return [String]
|
||||
*/
|
||||
internal val hostTagName get() = if (packageParam.appUserId != 0) "[$packageName][${packageParam.appUserId}]" else "[$packageName]"
|
||||
|
||||
override fun toString() = "[tag] $tag [priority] $priority [class] $hookClass [member] $member $allMethodsName [mode] $hookMemberMode"
|
||||
|
||||
/**
|
||||
|
@@ -45,7 +45,7 @@ import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiResources
|
||||
* @param packageParam 需要传入 [PackageParam] 实现方法调用
|
||||
* @param hookResources 要 Hook 的 [HookResources] 实例
|
||||
*/
|
||||
class YukiResourcesHookCreater(private val packageParam: PackageParam, @PublishedApi internal val hookResources: HookResources) {
|
||||
class YukiResourcesHookCreater(@PublishedApi internal val packageParam: PackageParam, @PublishedApi internal val hookResources: HookResources) {
|
||||
|
||||
/** 设置要 Hook 的 Resources */
|
||||
@PublishedApi
|
||||
@@ -58,7 +58,7 @@ class YukiResourcesHookCreater(private val packageParam: PackageParam, @Publishe
|
||||
* @return [ResourcesHookCreater.Result]
|
||||
*/
|
||||
inline fun injectResource(tag: String = "Default", initiate: ResourcesHookCreater.() -> Unit) =
|
||||
ResourcesHookCreater(tag).apply(initiate).apply { preHookResources[toString()] = this }.build()
|
||||
ResourcesHookCreater(tag, packageParam.exhibitName).apply(initiate).apply { preHookResources[toString()] = this }.build()
|
||||
|
||||
/**
|
||||
* Hook 执行入口
|
||||
@@ -78,8 +78,9 @@ class YukiResourcesHookCreater(private val packageParam: PackageParam, @Publishe
|
||||
*
|
||||
* 查找和处理需要 Hook 的 Resources
|
||||
* @param tag 当前设置的标签
|
||||
* @param packageName 当前 Hook 的 APP 包名
|
||||
*/
|
||||
inner class ResourcesHookCreater @PublishedApi internal constructor(private val tag: String) {
|
||||
inner class ResourcesHookCreater @PublishedApi internal constructor(private val tag: String, private val packageName: String) {
|
||||
|
||||
/** 是否已经执行 Hook */
|
||||
private var isHooked = false
|
||||
@@ -231,9 +232,15 @@ class YukiResourcesHookCreater(private val packageParam: PackageParam, @Publishe
|
||||
* @param msg 调试日志内容
|
||||
*/
|
||||
private fun onHookLogMsg(msg: String) {
|
||||
if (YukiHookAPI.Configs.isDebug) yLoggerI(msg = "[${packageParam.exhibitName}] $msg")
|
||||
if (YukiHookAPI.Configs.isDebug) yLoggerI(msg = "$hostTagName $msg")
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Hook APP (宿主) 标签
|
||||
* @return [String]
|
||||
*/
|
||||
private val hostTagName get() = if (packageParam.appUserId != 0) "[$packageName][${packageParam.appUserId}]" else "[$packageName]"
|
||||
|
||||
/**
|
||||
* Resources 查找条件实现类
|
||||
*/
|
||||
|
@@ -187,7 +187,7 @@ abstract class BaseFinder(
|
||||
/** 存在日志时输出日志 */
|
||||
internal fun printLogIfExist() {
|
||||
if (loggingContent != null) yLoggerE(
|
||||
msg = "${hookInstance?.packageName?.let { "[$it] " } ?: ""}NoSuch$tag happend in [$classSet] ${loggingContent?.first} [${hookTag}]",
|
||||
msg = "${hookInstance?.hostTagName?.let { "$it " } ?: ""}NoSuch$tag happend in [$classSet] ${loggingContent?.first} [${hookTag}]",
|
||||
e = loggingContent?.second
|
||||
)
|
||||
/** 仅输出一次 - 然后清掉日志 */
|
||||
@@ -200,7 +200,7 @@ abstract class BaseFinder(
|
||||
*/
|
||||
internal fun onHookLogMsg(msg: String) {
|
||||
if (YukiHookAPI.Configs.isDebug && YukiHookBridge.hasXposedBridge)
|
||||
hookInstance?.also { yLoggerI(msg = "[${it.packageName}] $msg") } ?: yLoggerI(msg = msg)
|
||||
hookInstance?.also { yLoggerI(msg = "${it.hostTagName} $msg") } ?: yLoggerI(msg = msg)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -84,6 +84,14 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper:
|
||||
*/
|
||||
val appInfo get() = wrapper?.appInfo ?: YukiHookAppHelper.currentApplicationInfo() ?: ApplicationInfo()
|
||||
|
||||
/**
|
||||
* 获取当前 Hook APP 的用户 ID
|
||||
*
|
||||
* 机主为 0 - 应用双开 (分身) 或工作资料因系统环境不同 ID 也各不相同
|
||||
* @return [Int]
|
||||
*/
|
||||
val appUserId get() = YukiHookBridge.findUserId(packageName)
|
||||
|
||||
/**
|
||||
* 获取当前 Hook APP 的 [Application] 实例
|
||||
*
|
||||
|
@@ -35,6 +35,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import com.highcapable.yukihookapi.YukiHookAPI
|
||||
@@ -174,6 +175,18 @@ object YukiHookBridge {
|
||||
*/
|
||||
internal val hasXposedBridge get() = executorVersion >= 0
|
||||
|
||||
/**
|
||||
* 获取指定 [packageName] 的用户 ID
|
||||
*
|
||||
* 机主为 0 - 应用双开 (分身) 或工作资料因系统环境不同 ID 也各不相同
|
||||
* @param packageName 当前包名
|
||||
* @return [Int]
|
||||
*/
|
||||
internal fun findUserId(packageName: String) = runCatching {
|
||||
YukiHookHelper.findMethod(UserHandleClass, name = "getUserId", IntType)
|
||||
.invoke(null, systemContext.packageManager.getApplicationInfo(packageName, PackageManager.GET_ACTIVITIES).uid) as? Int ?: 0
|
||||
}.getOrNull() ?: 0
|
||||
|
||||
/**
|
||||
* 自动忽略 MIUI 系统可能出现的日志收集注入实例
|
||||
* @param packageName 当前包名
|
||||
|
Reference in New Issue
Block a user