diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b2d9a3f..947d01f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -10,8 +10,11 @@ plugins { alias(libs.plugins.nav.safeargs.kotlin) } + +val appPackageName: String by rootProject.extra + android { - namespace = "org.frknkrc44.hma_oss" + namespace = appPackageName buildFeatures { buildConfig = true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6ddd65a..8dee963 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -40,7 +40,7 @@ diff --git a/build.gradle.kts b/build.gradle.kts index 7f09b48..b684e57 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -59,6 +59,9 @@ val serviceVerCode by extra(98) @Suppress("unused") val minBackupVerCode by extra(65) +@Suppress("unused") +val appPackageName by extra("org.frknkrc44.hma_oss") + val androidSourceCompatibility = JavaVersion.VERSION_21 val androidTargetCompatibility = JavaVersion.VERSION_21 diff --git a/common/build.gradle.kts b/common/build.gradle.kts index f95259c..9699e56 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -8,9 +8,11 @@ plugins { val configVerCode: Int by rootProject.extra val serviceVerCode: Int by rootProject.extra val minBackupVerCode: Int by rootProject.extra +val appPackageName: String by rootProject.extra +val appVerName: String by rootProject.extra android { - namespace = "org.frknkrc44.hma_oss.common" + namespace = "$appPackageName.common" buildFeatures { aidl = true @@ -21,6 +23,8 @@ android { buildConfigField("int", "CONFIG_VERSION", configVerCode.toString()) buildConfigField("int", "SERVICE_VERSION", serviceVerCode.toString()) buildConfigField("int", "MIN_BACKUP_VERSION", minBackupVerCode.toString()) + buildConfigField("String", "APP_PACKAGE_NAME", "\"$appPackageName\"") + buildConfigField("String", "APP_VERSION_NAME", "\"$appVerName\"") } } diff --git a/common/src/main/java/icu/nullptr/hidemyapplist/common/AppPresets.kt b/common/src/main/java/icu/nullptr/hidemyapplist/common/AppPresets.kt index e817141..34af98d 100644 --- a/common/src/main/java/icu/nullptr/hidemyapplist/common/AppPresets.kt +++ b/common/src/main/java/icu/nullptr/hidemyapplist/common/AppPresets.kt @@ -12,7 +12,6 @@ import icu.nullptr.hidemyapplist.common.app_presets.RootAppsPreset import icu.nullptr.hidemyapplist.common.app_presets.SuspiciousAppsPreset import icu.nullptr.hidemyapplist.common.app_presets.XposedModulesPreset -// TODO: Update presets when package added/removed class AppPresets private constructor() { private val presetList = mutableListOf() diff --git a/common/src/main/java/icu/nullptr/hidemyapplist/common/Constants.java b/common/src/main/java/icu/nullptr/hidemyapplist/common/Constants.java index 5bbfc05..b321ffd 100644 --- a/common/src/main/java/icu/nullptr/hidemyapplist/common/Constants.java +++ b/common/src/main/java/icu/nullptr/hidemyapplist/common/Constants.java @@ -1,12 +1,12 @@ package icu.nullptr.hidemyapplist.common; +import org.frknkrc44.hma_oss.common.BuildConfig; + import java.util.Set; public class Constants { - public static final String APP_PACKAGE_NAME = "org.frknkrc44.hma_oss"; - - public static final String PROVIDER_AUTHORITY = APP_PACKAGE_NAME + ".ServiceProvider"; + public static final String PROVIDER_AUTHORITY = BuildConfig.APP_PACKAGE_NAME + ".ServiceProvider"; public static final String GMS_PACKAGE_NAME = "com.google.android.gms"; public static final String GSF_PACKAGE_NAME = "com.google.android.gsf"; public static final String VENDING_PACKAGE_NAME = "com.android.vending"; diff --git a/common/src/main/java/icu/nullptr/hidemyapplist/common/Utils.kt b/common/src/main/java/icu/nullptr/hidemyapplist/common/Utils.kt index 1d7b2a9..753de93 100644 --- a/common/src/main/java/icu/nullptr/hidemyapplist/common/Utils.kt +++ b/common/src/main/java/icu/nullptr/hidemyapplist/common/Utils.kt @@ -21,19 +21,6 @@ object Utils { return buffer.toString() } - fun verifyAppSignature(path: String): Boolean { - /* - val verifier = ApkVerifier.Builder(File(path)) - .setMinCheckedPlatformVersion(24) - .build() - val result = verifier.verify() - if (!result.isVerified) return false - val mainCert = result.signerCertificates[0] - return mainCert.encoded.contentEquals(Magic.magicNumbers) - */ - return true - } - fun binderLocalScope(block: () -> T): T { val identity = Binder.clearCallingIdentity() val result = block() diff --git a/common/src/main/java/icu/nullptr/hidemyapplist/common/app_presets/XposedModulesPreset.kt b/common/src/main/java/icu/nullptr/hidemyapplist/common/app_presets/XposedModulesPreset.kt index 2882f6b..0c1eeb5 100644 --- a/common/src/main/java/icu/nullptr/hidemyapplist/common/app_presets/XposedModulesPreset.kt +++ b/common/src/main/java/icu/nullptr/hidemyapplist/common/app_presets/XposedModulesPreset.kt @@ -1,7 +1,6 @@ package icu.nullptr.hidemyapplist.common.app_presets import android.content.pm.ApplicationInfo -import icu.nullptr.hidemyapplist.common.CommonUtils import java.util.zip.ZipFile class XposedModulesPreset() : BasePreset("xposed") { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 13c7777..1bd522e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,6 @@ androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fr androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version = "2.8.8" } 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" } com-drakeet-multitype = { module = "com.drakeet.multitype:multitype", version = "4.3.0" } com-github-kirich1409-viewbindingpropertydelegate = { module = "com.github.kirich1409:viewbindingpropertydelegate", version = "1.5.9" } diff --git a/xposed/build.gradle.kts b/xposed/build.gradle.kts index f691c1d..0a2d570 100644 --- a/xposed/build.gradle.kts +++ b/xposed/build.gradle.kts @@ -1,16 +1,13 @@ -import com.android.ide.common.signing.KeystoreHelper -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import java.io.PrintStream -import java.util.Locale - plugins { alias(libs.plugins.agp.lib) alias(libs.plugins.refine) alias(libs.plugins.kotlin) } +val appPackageName: String by rootProject.extra + android { - namespace = "org.frknkrc44.hma_oss.xposed" + namespace = "$appPackageName.xposed" buildFeatures { buildConfig = false @@ -21,51 +18,10 @@ kotlin { jvmToolchain(21) } -afterEvaluate { - //noinspection WrongGradleMethod - android.libraryVariants.forEach { variant -> - val variantCapped = variant.name.replaceFirstChar { it.titlecase(Locale.ROOT) } - val variantLowered = variant.name.lowercase(Locale.ROOT) - - val outSrcDir = layout.buildDirectory.dir("generated/source/signInfo/${variantLowered}") - val outSrc = outSrcDir.get().file("icu/nullptr/hidemyapplist/Magic.java") - val signInfoTask = tasks.register("generate${variantCapped}SignInfo") { - outputs.file(outSrc) - doLast { - val sign = android.buildTypes[variantLowered].signingConfig - outSrc.asFile.parentFile.mkdirs() - val certificateInfo = KeystoreHelper.getCertificateInfo( - sign?.storeType, - sign?.storeFile, - sign?.storePassword, - sign?.keyPassword, - sign?.keyAlias - ) - PrintStream(outSrc.asFile).apply { - println("package icu.nullptr.hidemyapplist;") - println("public final class Magic {") - print("public static final byte[] magicNumbers = {") - val bytes = certificateInfo.certificate.encoded - print(bytes.joinToString(",") { it.toString() }) - println("};") - println("}") - } - } - } - variant.registerJavaGeneratingTask(signInfoTask, outSrcDir.get().asFile) - - val kotlinCompileTask = tasks.findByName("compile${variantCapped}Kotlin") as KotlinCompile - kotlinCompileTask.dependsOn(signInfoTask) - val srcSet = objects.sourceDirectorySet("magic", "magic").srcDir(outSrcDir) - kotlinCompileTask.source(srcSet) - } -} - dependencies { implementation(projects.common) implementation(libs.androidx.annotation.jvm) - implementation(libs.com.android.tools.build.apksig) implementation(libs.com.github.kyuubiran.ezxhelper) implementation(libs.dev.rikka.hidden.compat) compileOnly(libs.de.robv.android.xposed.api) diff --git a/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/UserService.kt b/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/UserService.kt index 86f7332..64a993d 100644 --- a/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/UserService.kt +++ b/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/UserService.kt @@ -28,19 +28,18 @@ object UserService { if (uid != appUid) return try { val provider = ActivityManagerApis.getContentProviderExternal(Constants.PROVIDER_AUTHORITY, 0, null, null) - if (provider == null) { - logE(TAG, "Failed to get provider") - return + assert (provider != null) { + "Failed to get provider" } val extras = Bundle() extras.putBinder("binder", HMAService.instance) val reply = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val attr = AttributionSource.Builder(1000).setPackageName("android").build() - provider.call(attr, Constants.PROVIDER_AUTHORITY, "", null, extras) + provider?.call(attr, Constants.PROVIDER_AUTHORITY, "", null, extras) } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) { - provider.call("android", null, Constants.PROVIDER_AUTHORITY, "", null, extras) + provider?.call("android", null, Constants.PROVIDER_AUTHORITY, "", null, extras) } else { - provider.call("android", Constants.PROVIDER_AUTHORITY, "", null, extras) + provider?.call("android", Constants.PROVIDER_AUTHORITY, "", null, extras) } if (reply == null) { logE(TAG, "Failed to send binder to app") @@ -54,14 +53,19 @@ object UserService { } fun register(pms: IPackageManager) { - logI(TAG, "Initialize HMAService - Version ${BuildConfig.SERVICE_VERSION}") + logI(TAG, "Initialize HMAService - Version ${BuildConfig.APP_VERSION_NAME}") 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.toString())) { - logE(TAG, "Fatal: App signature mismatch") + + try { + appUid = Utils.getPackageUidCompat(service.pms, BuildConfig.APP_PACKAGE_NAME, 0, 0) + assert(appUid >= 0) { + "App UID cannot be -1 or lower" + } + } catch (e: Throwable) { + logE(TAG, "Fatal: Cannot get package details\nCompile this app from source with your changes", e) return } + logD(TAG, "Client uid: $appUid") logI(TAG, "Register observer") @@ -69,7 +73,7 @@ object UserService { ActivityManagerApis.registerUidObserver( uidObserver, ActivityManagerHidden.UID_OBSERVER_ACTIVE, - ActivityManagerHidden.PROCESS_STATE_UNKNOWN, + ActivityManagerHidden.PROCESS_STATE_TOP, null ) } diff --git a/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/hook/ActivityHook.kt b/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/hook/ActivityHook.kt index 2ad01cb..1fc317c 100644 --- a/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/hook/ActivityHook.kt +++ b/xposed/src/main/java/icu/nullptr/hidemyapplist/xposed/hook/ActivityHook.kt @@ -16,13 +16,15 @@ import icu.nullptr.hidemyapplist.xposed.logI class ActivityHook(private val service: HMAService) : IFrameworkHook { companion object { private const val TAG = "ActivityHook" - private val fakeReturnCode = getStaticIntField( - findClass( - "android.app.ActivityManager", - InitFields.ezXClassLoader - ), - "START_INTENT_NOT_RESOLVED" - ) + private val fakeReturnCode by lazy { + getStaticIntField( + findClass( + "android.app.ActivityManager", + InitFields.ezXClassLoader + ), + "START_INTENT_NOT_RESOLVED" + ) + } } private var hook: XC_MethodHook.Unhook? = null