Some optimizations and fixes
- Avoid HMA wake up at background due to uid listener - Add appUid checker for register to detect mismatching package name changes - Remove signature verifier codes - Other fixes and improvements
This commit is contained in:
parent
bf5a600b53
commit
62677a7bd8
12 changed files with 44 additions and 88 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
<provider
|
||||
android:name="icu.nullptr.hidemyapplist.service.ServiceProvider"
|
||||
android:authorities="org.frknkrc44.hma_oss.ServiceProvider"
|
||||
android:authorities="${applicationId}.ServiceProvider"
|
||||
android:exported="true"
|
||||
tools:ignore="ExportedContentProvider" />
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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\"")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<BasePreset>()
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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 <T> binderLocalScope(block: () -> T): T {
|
||||
val identity = Binder.clearCallingIdentity()
|
||||
val result = block()
|
||||
|
|
|
|||
|
|
@ -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") {
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue