Added support multi-user apps debug info and add appUserId function in PackageParam

This commit is contained in:
2022-07-31 22:35:56 +08:00
parent 191dc8d918
commit 4848463969
7 changed files with 76 additions and 12 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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"
/**

View File

@@ -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 查找条件实现类
*/

View File

@@ -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)
}
/**

View File

@@ -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] 实例
*

View File

@@ -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 当前包名