commit d8e98d575bca8cca12c3cfa163ec89cb2abee5fd
parent 4b93ec7181d02dd11d27039adea082ac91870eaa
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Thu, 27 Jun 2024 23:06:29 +0200
fix(core/xposed_loader): prevent loading in sub processes
Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
Diffstat:
2 files changed, 83 insertions(+), 77 deletions(-)
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt
@@ -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 {
- syncRemote()
- }.onFailure {
- log.error("Failed to sync remote", it)
- }
+ 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")
- }
- }.onSuccess {
- isBridgeInitialized = true
- }.onFailure {
- appContext.logCritical("Failed to initialize bridge", it)
- InAppOverlay.showCrashOverlay("SnapEnhance failed to initialize. Please check logs for more details.", 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("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("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("onPause") {
+ appContext.bridgeClient.closeOverlay()
+ appContext.isMainActivityPaused = true
+ }
- hookMainActivity("onNewIntent") { param ->
- appContext.actionManager.onNewIntent(param.argNullable(0))
- }
+ hookMainActivity("onNewIntent") { param ->
+ appContext.actionManager.onNewIntent(param.argNullable(0))
+ }
- hookMainActivity("onResume") {
- if (appContext.isMainActivityPaused.also {
- appContext.isMainActivityPaused = false
- }) {
- appContext.reloadConfig()
- appContext.executeAsync {
- syncRemote()
+ 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)
}
}
}
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/XposedLoader.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/XposedLoader.kt
@@ -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))
+ }
}
}
\ No newline at end of file