Skip to content

Commit

Permalink
No transaction hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-TSNG committed Jul 17, 2023
1 parent 721dcb8 commit f809e78
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 91 deletions.
8 changes: 0 additions & 8 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ android {
buildConfig = true
viewBinding = true
}

applicationVariants.all {
kotlin {
sourceSets.getByName(name) {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}
}
}

kotlin {
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
</intent-filter>
</activity-alias>

<provider
android:name="icu.nullptr.hidemyapplist.service.ServiceProvider"
android:authorities="com.tsng.hidemyapplist.ServiceProvider"
android:exported="true"
tools:ignore="ExportedContentProvider" />

<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-7935522387526005~2750782344" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package icu.nullptr.hidemyapplist.service

import android.os.IBinder
import android.os.IBinder.DeathRecipient
import android.os.Parcel
import android.os.RemoteException
Expand All @@ -13,7 +14,7 @@ import java.lang.reflect.Proxy

object ServiceClient : IHMAService, DeathRecipient {

private const val TAG = "ServiceHelper"
private const val TAG = "ServiceClient"

private class ServiceProxy(private val obj: IHMAService) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method, args: Array<out Any?>?): Any? {
Expand All @@ -27,14 +28,16 @@ object ServiceClient : IHMAService, DeathRecipient {
@Volatile
private var service: IHMAService? = null

override fun binderDied() {
service = null
Log.e(TAG, "Binder died")
fun linkService(binder: IBinder) {
service = Proxy.newProxyInstance(
javaClass.classLoader,
arrayOf(IHMAService::class.java),
ServiceProxy(IHMAService.Stub.asInterface(binder))
) as IHMAService
binder.linkToDeath(this, 0)
}

override fun asBinder() = service?.asBinder()

private fun getService(): IHMAService? {
private fun getServiceLegacy(): IHMAService? {
if (service != null) return service
val pm = ServiceManager.getService("package")
val data = Parcel.obtain()
Expand Down Expand Up @@ -65,21 +68,28 @@ object ServiceClient : IHMAService, DeathRecipient {
return service
}

override fun getServiceVersion() = getService()?.serviceVersion ?: 0
override fun binderDied() {
service = null
Log.e(TAG, "Binder died")
}

override fun asBinder() = service?.asBinder()

override fun getServiceVersion() = getServiceLegacy()?.serviceVersion ?: 0

override fun getFilterCount() = getService()?.filterCount ?: 0
override fun getFilterCount() = getServiceLegacy()?.filterCount ?: 0

override fun getLogs() = getService()?.logs
override fun getLogs() = getServiceLegacy()?.logs

override fun clearLogs() {
getService()?.clearLogs()
getServiceLegacy()?.clearLogs()
}

override fun syncConfig(json: String) {
getService()?.syncConfig(json)
getServiceLegacy()?.syncConfig(json)
}

override fun stopService(cleanEnv: Boolean) {
getService()?.stopService(cleanEnv)
getServiceLegacy()?.stopService(cleanEnv)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package icu.nullptr.hidemyapplist.service

import android.content.ContentProvider
import android.content.ContentValues
import android.net.Uri
import android.os.Bundle

class ServiceProvider : ContentProvider() {

override fun onCreate() = false

override fun query(p0: Uri, p1: Array<out String>?, p2: String?, p3: Array<out String>?, p4: String?) = null

override fun getType(p0: Uri) = null

override fun insert(p0: Uri, p1: ContentValues?) = null

override fun delete(p0: Uri, p1: String?, p2: Array<out String>?) = 0

override fun update(p0: Uri, p1: ContentValues?, p2: String?, p3: Array<out String>?) = 0

override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
if (callingPackage != "android" || extras == null) return null
val binder = extras.getBinder("binder") ?: return null
ServiceClient.linkService(binder)
return Bundle()
}
}
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ val minSdkVer by extra(24)
val targetSdkVer by extra(34)
val buildToolsVer by extra("34.0.0")

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

val androidSourceCompatibility = JavaVersion.VERSION_17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
public class Constants {

public static final String APP_PACKAGE_NAME = "com.tsng.hidemyapplist";

public static final String PROVIDER_AUTHORITY = 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 UPDATE_URL_BASE = "https://api.nullptr.icu/android/hide-my-applist/static/";
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package icu.nullptr.hidemyapplist.xposed

import android.app.ActivityManagerHidden
import android.content.AttributionSource
import android.content.pm.IPackageManager
import android.os.Build
import android.os.Bundle
import android.os.ServiceManager
import icu.nullptr.hidemyapplist.common.BuildConfig
import icu.nullptr.hidemyapplist.common.Constants
import rikka.hidden.compat.ActivityManagerApis
import rikka.hidden.compat.adapter.UidObserverAdapter

object UserService {

private const val TAG = "HMA-UserService"

private var appUid = 0

private val uidObserver = object : UidObserverAdapter() {
override fun onUidActive(uid: Int) {
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
}
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)
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
provider.call("android", null, Constants.PROVIDER_AUTHORITY, "", null, extras)
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
provider.call("android", Constants.PROVIDER_AUTHORITY, "", null, extras)
} else {
provider.call("android", "", null, extras)
}
if (reply == null) {
logE(TAG, "Failed to send binder to app")
return
}
logI(TAG, "Send binder to app")
} catch (e: Throwable) {
logE(TAG, "onUidActive", e)
}
}
}

fun register(pms: IPackageManager) {
logI(TAG, "Initialize HMAService - Version ${BuildConfig.SERVICE_VERSION}")
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)) {
logE(TAG, "Fatal: App signature mismatch")
return
}
logD(TAG, "Client uid: $appUid")
logI(TAG, "Register observer")

waitSystemService("activity")
ActivityManagerApis.registerUidObserver(
uidObserver,
ActivityManagerHidden.UID_OBSERVER_ACTIVE,
ActivityManagerHidden.PROCESS_STATE_UNKNOWN,
null
)
}

private fun waitSystemService(name: String) {
while (ServiceManager.getService(name) == null) {
Thread.sleep(1000)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import de.robv.android.xposed.IXposedHookZygoteInit
import de.robv.android.xposed.XC_MethodHook
import de.robv.android.xposed.callbacks.XC_LoadPackage
import icu.nullptr.hidemyapplist.common.Constants
import kotlin.concurrent.thread

private const val TAG = "HMA-XposedEntry"

@Suppress("unused")
class XposedEntry : IXposedHookZygoteInit, IXposedHookLoadPackage {

override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
Expand All @@ -35,11 +37,13 @@ class XposedEntry : IXposedHookZygoteInit, IXposedHookLoadPackage {
serviceManagerHook?.unhook()
val pms = param.args[1] as IPackageManager
logD(TAG, "Got pms: $pms")
runCatching {
BridgeService.register(pms)
logI(TAG, "Bridge service injected")
}.onFailure {
logE(TAG, "System service crashed", it)
thread {
runCatching {
UserService.register(pms)
logI(TAG, "User service started")
}.onFailure {
logE(TAG, "System service crashed", it)
}
}
}
}
Expand Down

0 comments on commit f809e78

Please sign in to comment.