Try to improve getPackagesHoldingPermissions performance, fix logging
This commit is contained in:
parent
8e09530de5
commit
f13dff47c2
5 changed files with 259 additions and 4 deletions
|
|
@ -19,6 +19,7 @@ import icu.nullptr.hidemyapplist.xposed.hook.IFrameworkHook
|
|||
import icu.nullptr.hidemyapplist.xposed.hook.PlatformCompatHook
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsHookTarget28
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsHookTarget30
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsHookTarget31
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsHookTarget33
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsHookTarget34
|
||||
import icu.nullptr.hidemyapplist.xposed.hook.PmsPackageEventsHook
|
||||
|
|
@ -145,6 +146,8 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
frameworkHooks.add(PmsHookTarget34(this))
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
frameworkHooks.add(PmsHookTarget33(this))
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
frameworkHooks.add(PmsHookTarget31(this))
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
frameworkHooks.add(PmsHookTarget30(this))
|
||||
} else {
|
||||
|
|
@ -222,15 +225,15 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
if (caller == null || query == null) return 0
|
||||
val appConfig = config.scope[caller] ?: return 0
|
||||
if (!appConfig.hideInstallationSource) return 0
|
||||
logD(TAG, "@shouldHideInstallationSource $caller -> $query")
|
||||
logD(TAG, "@shouldHideInstallationSource $caller: $query")
|
||||
if (caller == query && appConfig.excludeTargetInstallationSource) return 0
|
||||
|
||||
try {
|
||||
val uid = Utils.getPackageUidCompat(pms, query, 0L, user.hashCode())
|
||||
logD(TAG, "@shouldHideInstallationSource UID for $caller (${user.hashCode()}) -> $query: $uid")
|
||||
logD(TAG, "@shouldHideInstallationSource UID for $caller, ${user.hashCode()}: $query, $uid")
|
||||
if (uid < 0) return 0 // invalid package installation source request
|
||||
} catch (e: Throwable) {
|
||||
logD(TAG, "@shouldHideInstallationSource UID error for $caller (${user.hashCode()})", e)
|
||||
logD(TAG, "@shouldHideInstallationSource UID error for $caller, ${user.hashCode()}", e)
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ class Utils4Xposed {
|
|||
}
|
||||
|
||||
fun getCallingApps(service: HMAService): Array<String> {
|
||||
val callingUid = Binder.getCallingUid()
|
||||
return getCallingApps(service, Binder.getCallingUid())
|
||||
}
|
||||
|
||||
fun getCallingApps(service: HMAService, callingUid: Int): Array<String> {
|
||||
if (callingUid == Constants.UID_SYSTEM) return arrayOf()
|
||||
return Utils.binderLocalScope {
|
||||
service.pms.getPackagesForUid(callingUid)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package icu.nullptr.hidemyapplist.xposed.hook
|
||||
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.kyuubiran.ezxhelper.utils.findConstructor
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import com.github.kyuubiran.ezxhelper.utils.paramCount
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
|
|
@ -50,6 +52,57 @@ class PmsHookTarget30(service: HMAService) : PmsHookTargetBase(service) {
|
|||
|
||||
override fun load() {
|
||||
logI(TAG, "Load hook")
|
||||
|
||||
/*
|
||||
findMethodOrNull("com.android.server.pm.PackageManagerService") {
|
||||
name == "checkPermission"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[1] as String
|
||||
val callingApps = Utils4Xposed.getCallingApps(service)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@checkPermission - PkgMgr: insecure query from $caller to $targetApp")
|
||||
param.result = PackageManager.PERMISSION_DENIED
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
findMethodOrNull("com.android.server.pm.permission.PermissionManagerService", findSuper = true) {
|
||||
name == "checkPermission"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[1] as String
|
||||
val callingApps = Utils4Xposed.getCallingApps(service)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@checkPermission - PkgMgr: insecure query from $caller to $targetApp")
|
||||
param.result = PackageManager.PERMISSION_DENIED
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
findMethodOrNull("com.android.server.pm.PackageManagerService", findSuper = true) {
|
||||
name == "getPackageSetting"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[0] as String
|
||||
val callingUid = Binder.getCallingUid()
|
||||
val callingApps = Utils4Xposed.getCallingApps(service, callingUid)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@getPackageSetting - PkgMgr: insecure query from $caller to $targetApp")
|
||||
param.result = null
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
|
||||
hooks += findMethod("com.android.server.pm.AppsFilter") {
|
||||
name == "shouldFilterApplication"
|
||||
}.hookBefore { param ->
|
||||
|
|
|
|||
|
|
@ -0,0 +1,152 @@
|
|||
package icu.nullptr.hidemyapplist.xposed.hook
|
||||
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.kyuubiran.ezxhelper.utils.findConstructor
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import com.github.kyuubiran.ezxhelper.utils.paramCount
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
import icu.nullptr.hidemyapplist.common.Constants.VENDING_PACKAGE_NAME
|
||||
import icu.nullptr.hidemyapplist.common.Utils
|
||||
import icu.nullptr.hidemyapplist.xposed.HMAService
|
||||
import icu.nullptr.hidemyapplist.xposed.Utils4Xposed
|
||||
import icu.nullptr.hidemyapplist.xposed.logD
|
||||
import icu.nullptr.hidemyapplist.xposed.logE
|
||||
import icu.nullptr.hidemyapplist.xposed.logI
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
class PmsHookTarget31(service: HMAService) : PmsHookTargetBase(service) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "PmsHookTarget31"
|
||||
}
|
||||
|
||||
override val fakeSystemPackageInstallInfo: Any by lazy {
|
||||
findConstructor(
|
||||
"android.content.pm.InstallSourceInfo"
|
||||
) {
|
||||
paramCount == 4
|
||||
}.newInstance(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
)
|
||||
}
|
||||
|
||||
override val fakeUserPackageInstallInfo: Any by lazy {
|
||||
findConstructor(
|
||||
"android.content.pm.InstallSourceInfo"
|
||||
) {
|
||||
paramCount == 4
|
||||
}.newInstance(
|
||||
VENDING_PACKAGE_NAME,
|
||||
psSigningInfo,
|
||||
VENDING_PACKAGE_NAME,
|
||||
VENDING_PACKAGE_NAME,
|
||||
)
|
||||
}
|
||||
|
||||
override fun load() {
|
||||
logI(TAG, "Load hook")
|
||||
|
||||
/*
|
||||
findMethodOrNull("com.android.server.pm.PackageManagerService") {
|
||||
name == "checkPermission"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[1] as String
|
||||
val callingApps = Utils4Xposed.getCallingApps(service)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@checkPermission - PkgMgr: insecure query from $caller to $targetApp")
|
||||
param.result = PackageManager.PERMISSION_DENIED
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
findMethodOrNull("com.android.server.pm.permission.PermissionManagerService", findSuper = true) {
|
||||
name == "checkPermission"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[0] as String
|
||||
val callingApps = Utils4Xposed.getCallingApps(service)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@checkPermission - PermMgr: insecure query from $caller to $targetApp")
|
||||
param.result = PackageManager.PERMISSION_DENIED
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
findMethodOrNull("com.android.server.pm.PackageManagerService\$ComputerTracker") {
|
||||
name == "getPackageSetting"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[0] as String
|
||||
val callingUid = Binder.getCallingUid()
|
||||
val callingApps = Utils4Xposed.getCallingApps(service, callingUid)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@getPackageSetting - Computer: insecure query from $caller to $targetApp")
|
||||
param.result = null
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
|
||||
findMethodOrNull("com.android.server.pm.PackageManagerService\$ComputerTracker") {
|
||||
name == "getPackageSettingInternal"
|
||||
}?.hookBefore { param ->
|
||||
val targetApp = param.args[0] as String
|
||||
val callingUid = param.args[1] as Int
|
||||
val callingApps = Utils4Xposed.getCallingApps(service, callingUid)
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
logD(TAG, "@getPackageSettingInternal - Computer: insecure query from $caller to $targetApp")
|
||||
param.result = null
|
||||
service.filterCount++
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}?.let {
|
||||
hooks += it
|
||||
}
|
||||
|
||||
hooks += findMethod("com.android.server.pm.AppsFilter") {
|
||||
name == "shouldFilterApplication"
|
||||
}.hookBefore { param ->
|
||||
runCatching {
|
||||
val callingUid = param.args[0] as Int
|
||||
if (callingUid == Constants.UID_SYSTEM) return@hookBefore
|
||||
val callingApps = Utils.binderLocalScope {
|
||||
service.pms.getPackagesForUid(callingUid)
|
||||
} ?: return@hookBefore
|
||||
val targetApp = Utils4Xposed.getPackageNameFromPackageSettings(param.args[2])
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
param.result = true
|
||||
service.filterCount++
|
||||
val last = lastFilteredApp.getAndSet(caller)
|
||||
if (last != caller) logI(TAG, "@shouldFilterApplication: query from $caller")
|
||||
logD(TAG, "@shouldFilterApplication caller: $callingUid $caller, target: $targetApp")
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
logE(TAG, "Fatal error occurred, disable hooks", it)
|
||||
unload()
|
||||
}
|
||||
}
|
||||
|
||||
super.load()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,17 +3,24 @@ package icu.nullptr.hidemyapplist.xposed.hook
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.util.ArrayMap
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookAfter
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import de.robv.android.xposed.XposedHelpers
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
import icu.nullptr.hidemyapplist.common.Constants.VENDING_PACKAGE_NAME
|
||||
import icu.nullptr.hidemyapplist.common.Utils
|
||||
import icu.nullptr.hidemyapplist.xposed.HMAService
|
||||
import icu.nullptr.hidemyapplist.xposed.Utils4Xposed
|
||||
import icu.nullptr.hidemyapplist.xposed.logD
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
abstract class PmsHookTargetBase(protected val service: HMAService) : IFrameworkHook {
|
||||
private val TAG by lazy { this::class.java.simpleName }
|
||||
|
||||
protected val hooks = mutableListOf<XC_MethodHook.Unhook>()
|
||||
protected var lastFilteredApp: AtomicReference<String?> = AtomicReference(null)
|
||||
|
||||
|
|
@ -30,6 +37,43 @@ abstract class PmsHookTargetBase(protected val service: HMAService) : IFramework
|
|||
abstract val fakeUserPackageInstallInfo: Any?
|
||||
|
||||
override fun load() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
hooks += findMethod("com.android.server.pm.ComputerEngine") {
|
||||
name == "getPackageStates"
|
||||
}.hookAfter { param ->
|
||||
val callingUid = Binder.getCallingUid()
|
||||
if (callingUid == Constants.UID_SYSTEM) return@hookAfter
|
||||
|
||||
val callingApps = Utils4Xposed.getCallingApps(service)
|
||||
for (caller in callingApps) {
|
||||
if (service.isHookEnabled(caller)) {
|
||||
logD(TAG, "@getPackageStates: incoming query from $caller")
|
||||
|
||||
val result = param.result as ArrayMap<*, *>
|
||||
val markedToRemove = mutableListOf<Any>()
|
||||
|
||||
for (pair in result.entries) {
|
||||
val value = pair.value
|
||||
val packageName = XposedHelpers.callMethod(value, "getPackageName") as String
|
||||
if (service.shouldHide(caller, packageName)) {
|
||||
markedToRemove.add(pair.key)
|
||||
}
|
||||
}
|
||||
|
||||
if (markedToRemove.isNotEmpty()) {
|
||||
val copyResult = ArrayMap(result)
|
||||
copyResult.removeAll(markedToRemove)
|
||||
logD(TAG, "@getPackageStates: removed ${markedToRemove.size} entries from $caller; ${result.size}, ${copyResult.size}")
|
||||
param.result = copyResult
|
||||
service.filterCount++
|
||||
|
||||
return@hookAfter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
findMethodOrNull(service.pms::class.java, findSuper = true) {
|
||||
name == "getInstallSourceInfo"
|
||||
|
|
|
|||
Loading…
Reference in a new issue