fix(core/xposed_loader): prevent loading in sub processes

Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
rhunk 2024-06-27 23:06:29 +02:00
parent 4b93ec7181
commit d8e98d575b
2 changed files with 89 additions and 83 deletions

View File

@ -1,7 +1,6 @@
package me.rhunk.snapenhance.core
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.res.Resources
import android.os.Build
@ -53,91 +52,88 @@ class SnapEnhance {
}
}
init {
Application::class.java.hook("attach", HookStage.BEFORE) { param ->
appContext = ModContext(
androidContext = param.arg<Context>(0).also { classLoader = it.classLoader }
)
appContext.apply {
bridgeClient = BridgeClient(this)
initConfigListener()
bridgeClient.addOnConnectedCallback {
bridgeClient.registerMessagingBridge(messagingBridge)
coroutineScope.launch {
runCatching {
fun init(context: Context) {
appContext = ModContext(
androidContext = context.also { classLoader = it.classLoader }
)
appContext.apply {
bridgeClient = BridgeClient(this)
initConfigListener()
bridgeClient.addOnConnectedCallback {
bridgeClient.registerMessagingBridge(messagingBridge)
coroutineScope.launch {
runCatching {
syncRemote()
}.onFailure {
log.error("Failed to sync remote", it)
}
}
}
}
runBlocking {
var throwable: Throwable? = null
val canLoad = appContext.bridgeClient.connect { throwable = it }
if (canLoad == null) {
InAppOverlay.showCrashOverlay(
buildString {
append("Snapchat timed out while trying to connect to SnapEnhance\n\n")
append("Make sure you:\n")
append(" - Have installed the latest SnapEnhance version (https://github.com/rhunk/SnapEnhance)\n")
append(" - Disabled battery optimizations\n")
append(" - Excluded SnapEnhance and Snapchat in HideMyApplist")
},
throwable
)
appContext.logCritical("Cannot connect to the SnapEnhance app")
return@runBlocking
}
if (!canLoad) exitProcess(1)
runCatching {
LSPatchUpdater.onBridgeConnected(appContext)
}.onFailure {
appContext.log.error("Failed to init LSPatchUpdater", it)
}
jetpackComposeResourceHook()
runCatching {
measureTimeMillis {
init(this)
}.also {
appContext.log.verbose("init took ${it}ms")
}
hookMainActivity("onPostCreate") {
appContext.mainActivity = this
if (!appContext.mappings.isMappingsLoaded) return@hookMainActivity
appContext.isMainActivityPaused = false
onActivityCreate()
appContext.actionManager.onNewIntent(intent)
}
hookMainActivity("onPause") {
appContext.bridgeClient.closeOverlay()
appContext.isMainActivityPaused = true
}
hookMainActivity("onNewIntent") { param ->
appContext.actionManager.onNewIntent(param.argNullable(0))
}
hookMainActivity("onResume") {
if (appContext.isMainActivityPaused.also {
appContext.isMainActivityPaused = false
}) {
appContext.reloadConfig()
appContext.executeAsync {
syncRemote()
}.onFailure {
log.error("Failed to sync remote", it)
}
}
}
}
runBlocking {
var throwable: Throwable? = null
val canLoad = appContext.bridgeClient.connect { throwable = it }
if (canLoad == null) {
InAppOverlay.showCrashOverlay(
buildString {
append("Snapchat timed out while trying to connect to SnapEnhance\n\n")
append("Make sure you:\n")
append(" - Have installed the latest SnapEnhance version (https://github.com/rhunk/SnapEnhance)\n")
append(" - Disabled battery optimizations\n")
append(" - Excluded SnapEnhance and Snapchat in HideMyApplist")
},
throwable
)
appContext.logCritical("Cannot connect to the SnapEnhance app")
return@runBlocking
}
if (!canLoad) exitProcess(1)
runCatching {
LSPatchUpdater.onBridgeConnected(appContext)
}.onFailure {
appContext.log.error("Failed to init LSPatchUpdater", it)
}
jetpackComposeResourceHook()
runCatching {
measureTimeMillis {
init(this)
}.also {
appContext.log.verbose("init took ${it}ms")
}
}.onSuccess {
isBridgeInitialized = true
}.onFailure {
appContext.logCritical("Failed to initialize bridge", it)
InAppOverlay.showCrashOverlay("SnapEnhance failed to initialize. Please check logs for more details.", it)
}
}
}
hookMainActivity("onCreate") {
val isMainActivityNotNull = appContext.mainActivity != null
appContext.mainActivity = this
if (isMainActivityNotNull || !appContext.mappings.isMappingsLoaded) return@hookMainActivity
appContext.isMainActivityPaused = false
onActivityCreate()
appContext.actionManager.onNewIntent(intent)
}
hookMainActivity("onPause") {
appContext.bridgeClient.closeOverlay()
appContext.isMainActivityPaused = true
}
hookMainActivity("onNewIntent") { param ->
appContext.actionManager.onNewIntent(param.argNullable(0))
}
hookMainActivity("onResume") {
if (appContext.isMainActivityPaused.also {
appContext.isMainActivityPaused = false
}) {
appContext.reloadConfig()
appContext.executeAsync {
syncRemote()
}
}.onSuccess {
isBridgeInitialized = true
}.onFailure {
appContext.logCritical("Failed to initialize bridge", it)
InAppOverlay.showCrashOverlay("SnapEnhance failed to initialize. Please check logs for more details.", it)
}
}
}

View File

@ -1,12 +1,22 @@
package me.rhunk.snapenhance.core
import android.app.Application
import de.robv.android.xposed.IXposedHookLoadPackage
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.callbacks.XC_LoadPackage
import me.rhunk.snapenhance.common.BuildConfig
import me.rhunk.snapenhance.common.Constants
import me.rhunk.snapenhance.core.util.hook.HookStage
import me.rhunk.snapenhance.core.util.hook.hook
class XposedLoader : IXposedHookLoadPackage {
override fun handleLoadPackage(p0: XC_LoadPackage.LoadPackageParam) {
if (p0.packageName != Constants.SNAPCHAT_PACKAGE_NAME) return
SnapEnhance()
// prevent loading in sub-processes
if (p0.processName.contains(":")) return
XposedBridge.log("Loading SnapEnhance v${BuildConfig.VERSION_NAME}#${BuildConfig.GIT_HASH} (package: ${BuildConfig.APPLICATION_ID})")
Application::class.java.hook("attach", HookStage.BEFORE) { param ->
SnapEnhance().init(param.arg(0))
}
}
}