Workaround package visibility gap in getArchivedPackage()
This is just one of the many exploits that AOSP suffers from. Since this issue is fixed by me in AOSP, we might as well address it here too. Please note: Only way to "reliably" achieve package visibility is to install it in a separate user. HMA is just a workaround.
This commit is contained in:
parent
6fead425fe
commit
3f0f1854ef
2 changed files with 98 additions and 1 deletions
|
|
@ -118,7 +118,9 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
|
|||
if (it.flags and ApplicationInfo.FLAG_SYSTEM != 0) it.packageName else null
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
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.R) {
|
||||
frameworkHooks.add(PmsHookTarget30(this))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
package icu.nullptr.hidemyapplist.xposed.hook
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
import icu.nullptr.hidemyapplist.xposed.*
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
class PmsHookTarget34(private val service: HMAService) : IFrameworkHook {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "PmsHookTarget34"
|
||||
}
|
||||
|
||||
private val getPackagesForUidMethod by lazy {
|
||||
findMethod("com.android.server.pm.Computer") {
|
||||
name == "getPackagesForUid"
|
||||
}
|
||||
}
|
||||
|
||||
private var hook: XC_MethodHook.Unhook? = null
|
||||
private var exphook: XC_MethodHook.Unhook? = null
|
||||
private var lastFilteredApp: AtomicReference<String?> = AtomicReference(null)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun load() {
|
||||
logI(TAG, "Load hook")
|
||||
hook = findMethod("com.android.server.pm.AppsFilterImpl", findSuper = true) {
|
||||
name == "shouldFilterApplication"
|
||||
}.hookBefore { param ->
|
||||
runCatching {
|
||||
val snapshot = param.args[0]
|
||||
val callingUid = param.args[1] as Int
|
||||
if (callingUid == Constants.UID_SYSTEM) return@hookBefore
|
||||
val callingApps = Utils.binderLocalScope {
|
||||
getPackagesForUidMethod.invoke(snapshot, callingUid) as Array<String>?
|
||||
} ?: return@hookBefore
|
||||
val targetApp = Utils.getPackageNameFromPackageSettings(param.args[3]) // PackageSettings <- PackageStateInternal
|
||||
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()
|
||||
}
|
||||
}
|
||||
// AOSP exploit - https://github.com/aosp-mirror/platform_frameworks_base/commit/5bc482bd99ea18fe0b4064d486b29d5ae2d65139
|
||||
// Only 14 QPR2+ has this method
|
||||
exphook = findMethodOrNull("com.android.server.pm.PackageManagerService", findSuper = true) {
|
||||
name == "getArchivedPackageInternal"
|
||||
}?.hookBefore { param ->
|
||||
runCatching {
|
||||
val callingUid = Binder.getCallingUid()
|
||||
if (callingUid == Constants.UID_SYSTEM) return@hookBefore
|
||||
val callingApps = Utils.binderLocalScope {
|
||||
service.pms.getPackagesForUid(callingUid)
|
||||
} ?: return@hookBefore
|
||||
val targetApp = param.args[0].toString()
|
||||
for (caller in callingApps) {
|
||||
if (service.shouldHide(caller, targetApp)) {
|
||||
param.result = null
|
||||
service.filterCount++
|
||||
val last = lastFilteredApp.getAndSet(caller)
|
||||
if (last != caller) logI(TAG, "@getArchivedPackageInternal: query from $caller")
|
||||
logD(TAG, "@getArchivedPackageInternal caller: $callingUid $caller, target: $targetApp")
|
||||
return@hookBefore
|
||||
}
|
||||
}
|
||||
}.onFailure {
|
||||
logE(TAG, "Fatal error occurred, disable hooks", it)
|
||||
unload()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun unload() {
|
||||
hook?.unhook()
|
||||
hook = null
|
||||
exphook?.unhook()
|
||||
exphook = null
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue