Fix BridgeService
This commit is contained in:
parent
f09af4bce4
commit
a8b165c5cd
3 changed files with 39 additions and 98 deletions
|
|
@ -37,7 +37,7 @@ val buildToolsVer by extra("33.0.1")
|
|||
|
||||
val appVerName by extra("3.1.0-beta")
|
||||
val configVerCode by extra(90)
|
||||
val serviceVerCode by extra(94)
|
||||
val serviceVerCode by extra(95)
|
||||
val minBackupVerCode by extra(65)
|
||||
|
||||
val androidSourceCompatibility = JavaVersion.VERSION_11
|
||||
|
|
|
|||
|
|
@ -2,12 +2,9 @@ package icu.nullptr.hidemyapplist.xposed
|
|||
|
||||
import android.content.pm.IPackageManager
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.os.Parcel
|
||||
import com.github.kyuubiran.ezxhelper.utils.argTypes
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||
import com.github.kyuubiran.ezxhelper.utils.method
|
||||
import com.github.kyuubiran.ezxhelper.utils.staticMethod
|
||||
import icu.nullptr.hidemyapplist.common.BuildConfig
|
||||
import icu.nullptr.hidemyapplist.common.Constants
|
||||
|
||||
|
|
@ -17,7 +14,7 @@ object BridgeService {
|
|||
|
||||
private var appUid = 0
|
||||
|
||||
fun start(pms: IPackageManager) {
|
||||
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)
|
||||
|
|
@ -27,69 +24,40 @@ object BridgeService {
|
|||
return
|
||||
}
|
||||
logD(TAG, "Client uid: $appUid")
|
||||
doHooks()
|
||||
logI(TAG, "Bridge service initialized")
|
||||
}
|
||||
|
||||
private fun doHooks() {
|
||||
logD(TAG, "Hook binder transact")
|
||||
Binder::class.java.method(
|
||||
"execTransact",
|
||||
argTypes = argTypes(Int::class.java, Long::class.java, Long::class.java, Int::class.java)
|
||||
).hookBefore { param ->
|
||||
logI(TAG, "Initialize service proxy")
|
||||
pms.javaClass.findMethod(true) {
|
||||
name == "onTransact"
|
||||
}.hookBefore { param ->
|
||||
val code = param.args[0] as Int
|
||||
val dataObj = param.args[1] as Long
|
||||
val replyObj = param.args[2] as Long
|
||||
val flags = param.args[3] as Int
|
||||
if (code == Constants.TRANSACTION) {
|
||||
param.result = execTransact(code, dataObj, replyObj, flags)
|
||||
}
|
||||
val data = param.args[1] as Parcel
|
||||
val reply = param.args[2] as Parcel?
|
||||
if (myTransact(code, data, reply)) param.result = true
|
||||
}
|
||||
}
|
||||
|
||||
private val fromNativePointerMethod by lazy {
|
||||
Parcel::class.java.staticMethod("obtain", argTypes = argTypes(Long::class.java))
|
||||
}
|
||||
|
||||
private fun execTransact(code: Int, dataObj: Long, replyObj: Long, flags: Int): Boolean {
|
||||
val data = fromNativePointerMethod.invoke(null, dataObj) as Parcel? ?: return false
|
||||
val reply = fromNativePointerMethod.invoke(null, replyObj) as Parcel?
|
||||
|
||||
val res = try {
|
||||
onTransact(code, data, reply, flags)
|
||||
} catch (e: Exception) {
|
||||
if (flags and IBinder.FLAG_ONEWAY != 0) {
|
||||
logW(TAG, "Caught an exception from the binder stub implementation.")
|
||||
} else if (reply != null) {
|
||||
reply.setDataPosition(0)
|
||||
reply.writeException(e)
|
||||
private fun myTransact(code: Int, data: Parcel, reply: Parcel?): Boolean {
|
||||
if (code == Constants.TRANSACTION) {
|
||||
if (Binder.getCallingUid() == appUid) {
|
||||
logD(TAG, "Transaction from client")
|
||||
runCatching {
|
||||
data.enforceInterface(Constants.DESCRIPTOR)
|
||||
when (data.readInt()) {
|
||||
Constants.ACTION_GET_BINDER -> {
|
||||
reply?.writeNoException()
|
||||
reply?.writeStrongBinder(HMAService.instance)
|
||||
return true
|
||||
}
|
||||
else -> logW(TAG, "Unknown action")
|
||||
}
|
||||
}.onFailure {
|
||||
logE(TAG, "Transaction error", it)
|
||||
}
|
||||
} else {
|
||||
logW(TAG, "Someone else trying to get my binder?")
|
||||
}
|
||||
false
|
||||
} finally {
|
||||
data.setDataPosition(0)
|
||||
reply?.setDataPosition(0)
|
||||
}
|
||||
if (res) {
|
||||
data.recycle()
|
||||
reply?.recycle()
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
private fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {
|
||||
data.enforceInterface(Constants.DESCRIPTOR)
|
||||
return when (data.readInt()) {
|
||||
Constants.ACTION_GET_BINDER -> {
|
||||
if (Binder.getCallingUid() == appUid && HMAService.instance != null) {
|
||||
reply?.writeNoException()
|
||||
reply?.writeStrongBinder(HMAService.instance!!.asBinder())
|
||||
true
|
||||
} else {
|
||||
logW(TAG, "Invalid connection")
|
||||
false
|
||||
}
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,16 @@
|
|||
package icu.nullptr.hidemyapplist.xposed
|
||||
|
||||
import android.content.pm.IPackageManager
|
||||
import android.os.ServiceManager
|
||||
import android.util.Log
|
||||
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||
import com.github.kyuubiran.ezxhelper.utils.getFieldByDesc
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookAfter
|
||||
import com.github.kyuubiran.ezxhelper.utils.hookAllConstructorAfter
|
||||
import com.github.kyuubiran.ezxhelper.utils.*
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
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"
|
||||
|
||||
private fun waitSystemService(name: String) {
|
||||
while (ServiceManager.getService(name) == null) {
|
||||
try {
|
||||
logD(TAG, "service $name is not started, wait 1s")
|
||||
Thread.sleep(1000)
|
||||
} catch (e: InterruptedException) {
|
||||
logE(TAG, Log.getStackTraceString(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class XposedEntry : IXposedHookZygoteInit, IXposedHookLoadPackage {
|
||||
|
||||
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
||||
|
|
@ -44,30 +27,20 @@ class XposedEntry : IXposedHookZygoteInit, IXposedHookLoadPackage {
|
|||
EzXHelperInit.initHandleLoadPackage(lpparam)
|
||||
logI(TAG, "Hook entry")
|
||||
|
||||
var pms: IPackageManager? = null
|
||||
var serviceManagerHook: XC_MethodHook.Unhook? = null
|
||||
serviceManagerHook = findMethod("android.os.ServiceManager") {
|
||||
name == "addService"
|
||||
}.hookAfter { param ->
|
||||
}.hookBefore { param ->
|
||||
if (param.args[0] == "package") {
|
||||
pms = param.args[1] as IPackageManager
|
||||
logI(TAG, "Got pms: $pms")
|
||||
serviceManagerHook?.unhook()
|
||||
}
|
||||
}
|
||||
|
||||
logD(TAG, "ServiceManager hook installed")
|
||||
thread {
|
||||
runCatching {
|
||||
waitSystemService("package")
|
||||
logI(TAG, "PackageManagerService ready, load bridge service")
|
||||
if (pms != null) {
|
||||
BridgeService.start(pms!!)
|
||||
} else {
|
||||
logE(TAG, "Package service started, but instance is not captured")
|
||||
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)
|
||||
}
|
||||
}.onFailure {
|
||||
logE(TAG, "System service crashed", it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue