Skip to content

Commit

Permalink
Rewrite hook for force mount data (#297)
Browse files Browse the repository at this point in the history
* Update dependencies

* Rewrite hook for force mount data

The previous hook point is for startViaZygote(), but the logic in
ProcessList.java to determine whether a process is safe to apply
force mount is complex, and current implementation has already
caused issues. Change the hook point to PlatformCompat and force
return true for all sdk level, then we can let system server apply
the correct logic.

Vold app data isolation does not have sdk level check, so don't
touch it, unlink current code.
  • Loading branch information
aviraxp authored Oct 1, 2024
1 parent 1b2a52e commit 88f82c9
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ jobs:
- name: Gradle wrapper validation
uses: gradle/wrapper-validation-action@v1

- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
java-version: '21'

- name: Write key
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
- name: Gradle wrapper validation
uses: gradle/wrapper-validation-action@v1

- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'temurin'

- name: Write properties
Expand Down
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ android {
}

kotlin {
jvmToolchain(17)
jvmToolchain(21)
}

autoResConfig {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">

<property
android:name="android.adservices.AD_SERVICES_CONFIG"
android:resource="@xml/gma_ad_services_config"
tools:replace="android:resource" />

<activity
android:name="icu.nullptr.hidemyapplist.ui.activity.AboutActivity"
android:theme="@style/AppTheme.About" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ object PackageHelper {
mutableMapOf<String, PackageCache>().also {
for (packageInfo in packages) {
if (packageInfo.packageName in Constants.packagesShouldNotHide) continue
val label = pm.getApplicationLabel(packageInfo.applicationInfo).toString()
val icon = hmaApp.appIconLoader.loadIcon(packageInfo.applicationInfo)
it[packageInfo.packageName] = PackageCache(packageInfo, label, icon)
packageInfo.applicationInfo?.let { appInfo ->
val label = pm.getApplicationLabel(appInfo).toString()
val icon = hmaApp.appIconLoader.loadIcon(appInfo)
it[packageInfo.packageName] = PackageCache(packageInfo, label, icon)
}
}
}
}
Expand Down Expand Up @@ -110,6 +112,6 @@ object PackageHelper {
}

fun isSystem(packageName: String): Boolean = runBlocking {
packageCache.first()[packageName]!!.info.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0
packageCache.first()[packageName]?.info?.applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0
}
}
8 changes: 4 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ val gitCommitCount = "git rev-list HEAD --count".execute().toInt()
val gitCommitHash = "git rev-parse --verify --short HEAD".execute()

val minSdkVer by extra(24)
val targetSdkVer by extra(34)
val buildToolsVer by extra("34.0.0")
val targetSdkVer by extra(35)
val buildToolsVer by extra("35.0.0")

val appVerName by extra("3.2")
val configVerCode by extra(90)
val serviceVerCode by extra(96)
val minBackupVerCode by extra(65)

val androidSourceCompatibility = JavaVersion.VERSION_17
val androidTargetCompatibility = JavaVersion.VERSION_17
val androidSourceCompatibility = JavaVersion.VERSION_21
val androidTargetCompatibility = JavaVersion.VERSION_21

val localProperties = Properties()
localProperties.load(file("local.properties").inputStream())
Expand Down
2 changes: 1 addition & 1 deletion common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ android {
}

kotlin {
jvmToolchain(17)
jvmToolchain(21)
}

dependencies {
Expand Down
33 changes: 16 additions & 17 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
[versions]
agp = "8.3.2"
kotlin = "1.9.0"
rxhttp = "3.0.6"
hidden-api = "4.2.0"
agp = "8.6.1"
kotlin = "2.0.20"
rxhttp = "3.3.0"
hidden-api = "4.3.3"

[plugins]
agp-app = { id = "com.android.application", version.ref = "agp" }
agp-lib = { id = "com.android.library", version.ref = "agp" }
kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version = "1.9.0-1.0.11" }
gms = { id = "com.google.gms.google-services", version = "4.3.15" }
nav-safeargs-kotlin = { id = "androidx.navigation.safeargs.kotlin", version = "2.6.0" }
ksp = { id = "com.google.devtools.ksp", version = "2.0.20-1.0.25" }
gms = { id = "com.google.gms.google-services", version = "4.4.2" }
nav-safeargs-kotlin = { id = "androidx.navigation.safeargs.kotlin", version = "2.8.1" }
autoresconfig = { id = "dev.rikka.tools.autoresconfig", version = "1.2.2" }
materialthemebuilder = { id = "dev.rikka.tools.materialthemebuilder", version = "1.3.3" }
refine = { id = "dev.rikka.tools.refine", version = "4.3.0" }

[libraries]
androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version = "2.5.3" }
androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version = "2.5.3" }
androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version = "1.2.0" }
androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version = "2.8.1" }
androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version = "2.8.1" }
androidx-preference-ktx = { module = "androidx.preference:preference-ktx", version = "1.2.1" }
androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.1.0" }
com-android-tools-build-apksig = { module = "com.android.tools.build:apksig", version.ref = "agp" }
com-drakeet-about = { module = "com.drakeet.about:about", version = "2.5.2" }
Expand All @@ -29,17 +29,16 @@ com-github-kyuubiran-ezxhelper = { module = "com.github.kyuubiran:EzXHelper", ve
com-github-liujingxing-rxhttp = { module = "com.github.liujingxing.rxhttp:rxhttp", version.ref = "rxhttp" }
com-github-liujingxing-rxhttp-compiler = { module = "com.github.liujingxing.rxhttp:rxhttp-compiler", version.ref = "rxhttp" }
com-github-liujingxing-rxhttp-converter-serialization = { module = "com.github.liujingxing.rxhttp:converter-serialization", version.ref = "rxhttp" }
com-github-topjohnwu-libsu-core = { module = "com.github.topjohnwu.libsu:core", version = "5.0.3" }
com-google-android-material = { module = "com.google.android.material:material", version = "1.7.0" }
com-google-android-gms-play-services-ads = { module = "com.google.android.gms:play-services-ads", version = "22.2.0" }
com-google-firebase-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx", version = "21.2.0" }
com-google-firebase-bom = { module = "com.google.firebase:firebase-bom", version = "32.1.1" }
com-github-topjohnwu-libsu-core = { module = "com.github.topjohnwu.libsu:core", version = "6.0.0" }
com-google-android-material = { module = "com.google.android.material:material", version = "1.12.0" }
com-google-android-gms-play-services-ads = { module = "com.google.android.gms:play-services-ads", version = "23.4.0" }
com-google-firebase-bom = { module = "com.google.firebase:firebase-bom", version = "33.3.0" }
com-google-firebase-analytics-ktx = { module = "com.google.firebase:firebase-analytics-ktx" }
com-squareup-okhttp3 = { module = "com.squareup.okhttp3:okhttp", version = "4.10.0" }
com-squareup-okhttp3 = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }
de-robv-android-xposed-api = { module = "de.robv.android.xposed:api", version = "82" }
dev-rikka-hidden-compat = { module = "dev.rikka.hidden:compat", version.ref = "hidden-api" }
dev-rikka-hidden-stub = { module = "dev.rikka.hidden:stub", version.ref = "hidden-api" }
dev-rikka-rikkax-material = { module = "dev.rikka.rikkax.material:material", version = "2.7.0" }
dev-rikka-rikkax-material-preference = { module = "dev.rikka.rikkax.material:material-preference", version = "2.0.0" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.5.1" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.7.1" }
me-zhanghai-android-appiconloader = { module = "me.zhanghai.android.appiconloader:appiconloader", version = "1.5.0" }
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion xposed/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ android {
}

kotlin {
jvmToolchain(17)
jvmToolchain(21)
}

afterEvaluate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class HMAService(val pms: IPackageManager) : IHMAService.Stub() {
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
frameworkHooks.add(ZygoteArgsHook(this))
frameworkHooks.add(PlatformCompatHook(this))
}

frameworkHooks.forEach(IFrameworkHook::load)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ object UserService {
val service = HMAService(pms)
appUid = Utils.getPackageUidCompat(service.pms, Constants.APP_PACKAGE_NAME, 0, 0)
val appPackage = Utils.getPackageInfoCompat(service.pms, Constants.APP_PACKAGE_NAME, 0, 0)
if (!Utils.verifyAppSignature(appPackage.applicationInfo.sourceDir)) {
if (!Utils.verifyAppSignature(appPackage.applicationInfo?.sourceDir.toString())) {
logE(TAG, "Fatal: App signature mismatch")
return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
package icu.nullptr.hidemyapplist.xposed.hook

import android.annotation.TargetApi
import android.content.pm.ApplicationInfo
import android.os.Build
import com.github.kyuubiran.ezxhelper.utils.findMethod
import com.github.kyuubiran.ezxhelper.utils.hookBefore
import de.robv.android.xposed.XC_MethodHook
import icu.nullptr.hidemyapplist.common.CommonUtils
import icu.nullptr.hidemyapplist.common.Constants.*
import icu.nullptr.hidemyapplist.xposed.HMAService
import icu.nullptr.hidemyapplist.xposed.logE
import icu.nullptr.hidemyapplist.xposed.logI

@TargetApi(Build.VERSION_CODES.S)
class ZygoteArgsHook(private val service: HMAService) : IFrameworkHook {
class PlatformCompatHook(private val service: HMAService) : IFrameworkHook {

companion object {
private const val TAG = "ZygoteArgsHook"
private const val TAG = "PlatformCompatHook"
private val sAppDataIsolationEnabled = CommonUtils.isAppDataIsolationEnabled
private val sVoldAppDataIsolationEnabled = CommonUtils.isVoldAppDataIsolationEnabled
}

private var hook: XC_MethodHook.Unhook? = null
Expand All @@ -26,19 +25,18 @@ class ZygoteArgsHook(private val service: HMAService) : IFrameworkHook {
if (!service.config.forceMountData) return
logI(TAG, "Load hook")
logI(TAG, "App data isolation enabled: $sAppDataIsolationEnabled")
logI(TAG, "Vold app data isolation enabled: $sVoldAppDataIsolationEnabled")
hook = findMethod("android.os.ZygoteProcess") {
name == "startViaZygote"
hook = findMethod("com.android.server.compat.PlatformCompat") {
name == "isChangeEnabled"
}.hookBefore { param ->
runCatching {
val uid = param.args[2] as Int
if (uid == UID_SYSTEM) return@hookBefore
val apps = service.pms.getPackagesForUid(uid) ?: return@hookBefore
val changeId = param.args[0] as Long
val appInfo = param.args[1] as ApplicationInfo
if (changeId.toInt() != 143937733) return@hookBefore
val apps = service.pms.getPackagesForUid(appInfo.uid) ?: return@hookBefore
for (app in apps) {
if (service.isHookEnabled(app)) {
if (sAppDataIsolationEnabled) param.args[20] = true // boolean bindMountAppsData
if (sVoldAppDataIsolationEnabled) param.args[21] = true // boolean bindMountAppStorageDirs
logI(TAG, "@startViaZygote force mount data: $uid $app")
if (sAppDataIsolationEnabled) param.result = true
logI(TAG, "@startViaZygote force mount data: ${appInfo.uid} $app")
return@hookBefore
}
}
Expand Down

0 comments on commit 88f82c9

Please sign in to comment.