From 056d6d81d958813a1a407adc69bc22b470909e64 Mon Sep 17 00:00:00 2001 From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com> Date: Fri, 21 Nov 2025 20:58:00 +0100 Subject: [PATCH] merge changes from KettuXposed and bump to 1.2.1 only issue is not working recovery menu, but who cares? --- app/build.gradle.kts | 4 +- .../kotlin/ShiggyXposed/xposed/xposed/Main.kt | 26 +++---- .../xposed/xposed/modules/CacheModule.kt | 26 +++---- .../xposed/modules/FixResourcesModule.kt | 2 +- .../xposed/modules/HookScriptLoaderModule.kt | 37 ++++------ .../xposed/xposed/modules/LogBoxModule.kt | 2 +- .../xposed/modules/PayloadGlobalModule.kt | 9 +-- .../xposed/modules/appearance/FontsModule.kt | 10 ++- .../modules/appearance/SysColorsModule.kt | 9 +-- .../xposed/modules/appearance/ThemesModule.kt | 11 ++- .../bridge/AdditionalBridgeMethodsModule.kt | 2 +- .../xposed/modules/bridge/BridgeModule.kt | 70 +++++++++++-------- .../no_track/BlockCrashReportingModule.kt | 44 +++++++----- .../no_track/BlockDeepLinksTrackingModule.kt | 2 +- 14 files changed, 131 insertions(+), 123 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e19e78e..b86ee1e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "ShiggyXposed.xposed" minSdk = 24 targetSdk = 36 - versionCode = 1200 - versionName = "1.2.0" + versionCode = 1210 + versionName = "1.2.1" } buildTypes { diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/Main.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/Main.kt index 1fae929..8d3b261 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/Main.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/Main.kt @@ -35,24 +35,24 @@ object HookStateHolder { class Main : Module(), IXposedHookLoadPackage, IXposedHookZygoteInit { private var hooked = false - private val modules = mutableListOf( - HookScriptLoaderModule(), - BridgeModule(), - AdditionalBridgeMethodsModule(), + private val modules = mutableListOf( + HookScriptLoaderModule, + BridgeModule, + AdditionalBridgeMethodsModule, PluginsModule(), UpdaterModule, - FixResourcesModule(), - BlockDeepLinksTrackingModule(), - BlockCrashReportingModule(), - LogBoxModule(), - CacheModule(), - FontsModule(), - ThemesModule(), - SysColorsModule() + FixResourcesModule, + BlockDeepLinksTrackingModule, + BlockCrashReportingModule, + LogBoxModule, + CacheModule, + FontsModule, + ThemesModule, + SysColorsModule ) init { - modules.add(PayloadGlobalModule(modules)) + modules += PayloadGlobalModule(modules) } override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) { diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/CacheModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/CacheModule.kt index 5c81d6d..01b4971 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/CacheModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/CacheModule.kt @@ -33,30 +33,30 @@ import java.io.* * The caches are versioned and tied to the app version code. When the app is updated, * the caches are invalidated and new cache files are created. */ -class CacheModule : Module() { - private companion object { - const val CACHE_DIR = "Shiggy" +object CacheModule : Module() { + + private const val CACHE_DIR = "revenge" + + private const val MODULES_CACHE_PREFIX = "modules" + private const val ASSETS_CACHE_PREFIX = "assets" - const val MODULES_CACHE_PREFIX = "modules" - const val ASSETS_CACHE_PREFIX = "assets" - } private lateinit var modulesCache: ModulesCache private lateinit var assetsCache: AssetsCache override fun onContext(context: Context) = with(context) { - val ShiggyCacheDir = File(cacheDir, CACHE_DIR).apply { asDir() } + val revengeCacheDir = File(cacheDir, CACHE_DIR).apply { asDir() } val (_, _, _, versionCode) = getAppInfo() val modulesCacheFile = File( - ShiggyCacheDir, "$MODULES_CACHE_PREFIX.$versionCode" + revengeCacheDir, "$MODULES_CACHE_PREFIX.$versionCode" ).apply { asFile() } val assetsCacheFile = File( - ShiggyCacheDir, "$ASSETS_CACHE_PREFIX.$versionCode" + revengeCacheDir, "$ASSETS_CACHE_PREFIX.$versionCode" ).apply { asFile() } - BridgeModule.registerMethod("Shiggy.caches.modules.read") { + BridgeModule.registerMethod("revenge.caches.modules.read") { if (::modulesCache.isInitialized) modulesCache.toMap() else ModulesCache.loadFromFileOrNull(modulesCacheFile) ?.let { modulesCache = it @@ -64,7 +64,7 @@ class CacheModule : Module() { } } - BridgeModule.registerMethod("Shiggy.caches.modules.write") { + BridgeModule.registerMethod("revenge.caches.modules.write") { val (blacklist, finds) = it @Suppress("UNCHECKED_CAST") modulesCache = ModulesCache( @@ -73,7 +73,7 @@ class CacheModule : Module() { Log.i("Modules cache saved: ${modulesCacheFile.absolutePath} (blacklisted: ${blacklist.size}, finds: ${finds.size})") } - BridgeModule.registerMethod("Shiggy.caches.assets.read") { + BridgeModule.registerMethod("revenge.caches.assets.read") { if (::assetsCache.isInitialized) assetsCache.toMap() else AssetsCache.loadFromFileOrNull(assetsCacheFile) ?.let { assetsCache = it @@ -81,7 +81,7 @@ class CacheModule : Module() { } } - BridgeModule.registerMethod("Shiggy.caches.assets.write") { + BridgeModule.registerMethod("revenge.caches.assets.write") { val (data) = it @Suppress("UNCHECKED_CAST") assetsCache = diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/FixResourcesModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/FixResourcesModule.kt index 23c7659..15cfbf5 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/FixResourcesModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/FixResourcesModule.kt @@ -8,7 +8,7 @@ import ShiggyXposed.xposed.Module /** * Hooks [Resources.getIdentifier] to fix resource package name mismatch. */ -class FixResourcesModule : Module() { +object FixResourcesModule : Module() { override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) = with(packageParam) { if (packageName != TARGET_PACKAGE) { Resources::class.java.hookMethod( diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/HookScriptLoaderModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/HookScriptLoaderModule.kt index 806502c..0a0dd84 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/HookScriptLoaderModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/HookScriptLoaderModule.kt @@ -9,7 +9,7 @@ import ShiggyXposed.xposed.Constants import ShiggyXposed.xposed.HookStateHolder import ShiggyXposed.xposed.Module import ShiggyXposed.xposed.Utils.Log -import ShiggyXposed.xposed.modules.HookScriptLoaderModule.Companion.PRELOADS_DIR +import ShiggyXposed.xposed.modules.HookScriptLoaderModule.PRELOADS_DIR import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.runBlocking @@ -24,16 +24,14 @@ import java.lang.reflect.Method * The main bundle should be placed in the [Constants.CACHE_DIR] directory named [Constants.MAIN_SCRIPT_FILE]. * If the bundle file does not exist, it will attempt to load `assets://Shiggy.bundle` from the module's assets. */ -class HookScriptLoaderModule : Module() { +object HookScriptLoaderModule : Module() { private lateinit var preloadsDir: File private lateinit var mainScript: File private lateinit var modulePath: String private lateinit var resources: XModuleResources - companion object { - const val PRELOADS_DIR = "preloads" - } + const val PRELOADS_DIR = "preloads" override fun onInit(startupParam: IXposedHookZygoteInit.StartupParam) { this@HookScriptLoaderModule.modulePath = startupParam.modulePath @@ -47,26 +45,20 @@ class HookScriptLoaderModule : Module() { mainScript = File(cacheDir, Constants.MAIN_SCRIPT_FILE).apply { asFile() } listOf( + "com.facebook.react.runtime.ReactInstance\$loadJSBundle$1", "com.facebook.react.runtime.ReactInstance$1", // TODO: Remove once Discord fully switches to Bridgeless "com.facebook.react.bridge.CatalystInstanceImpl" - ).mapNotNull { classLoader.safeLoadClass(it) } - .forEach { hook(it) } + ).mapNotNull { classLoader.safeLoadClass(it) }.forEach { hook(it) } } - private fun hook(instance: Class<*>) { + private fun hook(instance: Class<*>) = runCatching { val loadScriptFromAssets = instance.method( - "loadScriptFromAssets", - AssetManager::class.java, - String::class.java, - Boolean::class.javaPrimitiveType + "loadScriptFromAssets", AssetManager::class.java, String::class.java, Boolean::class.javaPrimitiveType ) val loadScriptFromFile = instance.method( - "loadScriptFromFile", - String::class.java, - String::class.java, - Boolean::class.javaPrimitiveType + "loadScriptFromFile", String::class.java, String::class.java, Boolean::class.javaPrimitiveType ) loadScriptFromAssets.hook { @@ -82,6 +74,8 @@ class HookScriptLoaderModule : Module() { runCustomScripts(loadScriptFromFile, loadScriptFromAssets) } } + }.onFailure { + Log.e("Failed to hook script loading methods in ${instance.name}:", it) } private fun HookScope.runCustomScripts(loadScriptFromFile: Method, loadScriptFromAssets: Method) { @@ -99,25 +93,20 @@ class HookScriptLoaderModule : Module() { Log.i("Loading script: ${file.absolutePath}") XposedBridge.invokeOriginalMethod( - loadScriptFromFile, - thisObject, - arrayOf(file.absolutePath, file.absolutePath, loadSynchronously) + loadScriptFromFile, thisObject, arrayOf(file.absolutePath, file.absolutePath, loadSynchronously) ) Unit } try { - preloadsDir.walk() - .filter { it.isFile } - .forEach(runScriptFile) + preloadsDir.walk().filter { it.isFile }.forEach(runScriptFile) if (mainScript.exists()) runScriptFile(mainScript) else { Log.i("Main script does not exist, falling back") - if (!::resources.isInitialized) resources = - XModuleResources.createInstance(modulePath, null) + if (!::resources.isInitialized) resources = XModuleResources.createInstance(modulePath, null) XposedBridge.invokeOriginalMethod( loadScriptFromAssets, diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/LogBoxModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/LogBoxModule.kt index 664512d..351e7c8 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/LogBoxModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/LogBoxModule.kt @@ -21,7 +21,7 @@ import java.net.HttpURLConnection import java.net.URL import ShiggyXposed.xposed.Utils.Companion.reloadApp -class LogBoxModule : Module() { +object LogBoxModule : Module() { lateinit var packageParam: XC_LoadPackage.LoadPackageParam private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/PayloadGlobalModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/PayloadGlobalModule.kt index bc0a7b2..956cfc2 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/PayloadGlobalModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/PayloadGlobalModule.kt @@ -8,7 +8,7 @@ import ShiggyXposed.xposed.BuildConfig import ShiggyXposed.xposed.Constants import ShiggyXposed.xposed.Module import ShiggyXposed.xposed.Utils.Companion.JSON -import ShiggyXposed.xposed.modules.HookScriptLoaderModule.Companion.PRELOADS_DIR +import ShiggyXposed.xposed.modules.HookScriptLoaderModule.PRELOADS_DIR import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put import java.io.File @@ -28,7 +28,8 @@ class PayloadGlobalModule(private val modules: List) : Module() { override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) = with(packageParam) { val catalystInstance = classLoader.safeLoadClass("com.facebook.react.bridge.CatalystInstanceImpl") - val reactInstance = classLoader.safeLoadClass("com.facebook.react.runtime.ReactInstance$1") + val scriptLoader = classLoader.safeLoadClass("com.facebook.react.runtime.ReactInstance\$loadJSBundle$1") + ?: classLoader.safeLoadClass("com.facebook.react.runtime.ReactInstance$1") val setGlobalVariable: (XC_MethodHook.MethodHookParam, String, String) -> Unit = { param, key, json -> runCatching { @@ -43,7 +44,7 @@ class PayloadGlobalModule(private val modules: List) : Module() { writeText("this[${JSON.encodeToString(key)}]=$json") XposedBridge.invokeOriginalMethod( - reactInstance!!.method( + scriptLoader!!.method( "loadScriptFromFile", String::class.java, String::class.java, @@ -64,7 +65,7 @@ class PayloadGlobalModule(private val modules: List) : Module() { build() } - listOf(catalystInstance, reactInstance).forEach { if (it != null) hook(it, hook) } + listOf(catalystInstance, scriptLoader).forEach { if (it != null) hook(it, hook) } } private fun hook(instance: Class<*>, hook: XC_MethodHook) { diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/FontsModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/FontsModule.kt index f751a97..ec6111e 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/FontsModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/FontsModule.kt @@ -35,12 +35,10 @@ data class FontDefinition( val main: Map, ) -class FontsModule : Module() { - private companion object { - val EXTENSIONS = arrayOf("", "_bold", "_italic", "_bold_italic") - val FILE_EXTENSIONS = arrayOf(".ttf", ".otf") - const val FONTS_ASSET_PATH = "fonts/" - } +object FontsModule : Module() { + private val EXTENSIONS = arrayOf("", "_bold", "_italic", "_bold_italic") + private val FILE_EXTENSIONS = arrayOf(".ttf", ".otf") + private const val FONTS_ASSET_PATH = "fonts/" private lateinit var fontsDir: File private lateinit var fontsDownloadsDir: File diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/SysColorsModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/SysColorsModule.kt index 3a40a6b..31833e1 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/SysColorsModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/SysColorsModule.kt @@ -7,13 +7,14 @@ import android.os.Build import androidx.core.content.ContextCompat import ShiggyXposed.xposed.Module import kotlinx.serialization.json.* +import java.lang.ref.WeakReference -class SysColorsModule : Module() { - private lateinit var context: Context +object SysColorsModule : Module() { + private lateinit var context: WeakReference private fun isSupported() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S override fun buildPayload(builder: JsonObjectBuilder) { - context = AndroidAppHelper.currentApplication() + context = WeakReference(AndroidAppHelper.currentApplication()) val accents = arrayOf("accent1", "accent2", "accent3", "neutral1", "neutral2") val shades = arrayOf(0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000) @@ -36,7 +37,7 @@ class SysColorsModule : Module() { } private fun convertToColor(id: Int): String { - val clr = if (isSupported()) ContextCompat.getColor(context, id) else 0 + val clr = if (isSupported()) ContextCompat.getColor(context.get()!!, id) else 0 return String.format("#%06X", 0xFFFFFF and clr) } } diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/ThemesModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/ThemesModule.kt index a1dbed9..4c55133 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/ThemesModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/appearance/ThemesModule.kt @@ -34,15 +34,14 @@ data class Theme( val id: String, val selected: Boolean, val data: ThemeData ) -class ThemesModule : Module() { +object ThemesModule : Module() { private lateinit var param: XC_LoadPackage.LoadPackageParam private var theme: Theme? = null private val rawColorMap = mutableMapOf() - private companion object { - const val THEME_FILE = "current-theme.json" - } + private const val THEME_FILE = "current-theme.json" + @ExperimentalSerializationApi override fun buildPayload(builder: JsonObjectBuilder) { @@ -62,7 +61,7 @@ class ThemesModule : Module() { hookTheme() } - private fun File.isValidish(): Boolean { + private fun File.isValidThemeFile(): Boolean { if (!this.exists()) return false val text = this.readText() @@ -71,7 +70,7 @@ class ThemesModule : Module() { private fun getTheme(): Theme? { val themeFile = File(param.appInfo.dataDir, "${Constants.FILES_DIR}/${THEME_FILE}").apply { asFile() } - if (!themeFile.isValidish()) return null + if (!themeFile.isValidThemeFile()) return null return try { val themeText = themeFile.readText() diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/AdditionalBridgeMethodsModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/AdditionalBridgeMethodsModule.kt index fd46843..6d21887 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/AdditionalBridgeMethodsModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/AdditionalBridgeMethodsModule.kt @@ -11,7 +11,7 @@ import ShiggyXposed.xposed.Module import ShiggyXposed.xposed.Utils import java.io.File -class AdditionalBridgeMethodsModule : Module() { +object AdditionalBridgeMethodsModule : Module() { override fun onContext(context: Context) = with(context) { BridgeModule.registerMethod("Shiggy.fs.getConstants") { mapOf( diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/BridgeModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/BridgeModule.kt index 8cd801b..d5808aa 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/BridgeModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/bridge/BridgeModule.kt @@ -45,43 +45,28 @@ typealias BridgeMethodArgs = ArrayList * } * ``` */ -class BridgeModule : Module() { +object BridgeModule : Module() { private lateinit var readableMapGetString: Method private lateinit var readableMapToHashMap: Method private lateinit var argumentsMakeNative: Method - companion object { - private const val CALL_DATA_KEY = "Shiggy" - private const val METHOD_NAME_KEY = "method" - private const val METHOD_ARGS_KEY = "args" + private const val CALL_DATA_KEY = "Shiggy" + private const val METHOD_NAME_KEY = "method" + private const val METHOD_ARGS_KEY = "args" - private val methods: MutableMap = mutableMapOf("Shiggy.info" to { - mapOf( - "name" to Constants.LOADER_NAME, "version" to BuildConfig.VERSION_CODE - ) - }, "Shiggy.test" to { - mapOf( - "string" to "string", - "number" to 7256, - "array" to listOf("testing", 527737, listOf(true)), - "object" to mapOf("nested" to true), - "boolean" to false, - "args" to it, - ) - }) + private val methods: MutableMap = mutableMapOf() - /** - * Registers a bridge method that can be called from JavaScript. - * - * If the method is already registered, it will be overwritten. - * - * @param name The name of the method to register. - * @param callback The callback to invoke when the method is called. - */ - fun registerMethod(name: String, callback: BridgeMethodCallback) { - if (methods.containsKey(name)) Log.w("Bridge method already exists and will be overridden: $name") - methods[name] = callback - } + /** + * Registers a bridge method that can be called from JavaScript. + * + * If the method is already registered, it will be overwritten. + * + * @param name The name of the method to register. + * @param callback The callback to invoke when the method is called. + */ + fun registerMethod(name: String, callback: BridgeMethodCallback) { + if (methods.containsKey(name)) Log.w("Bridge method already exists and will be overridden: $name") + methods[name] = callback } override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) = with(packageParam) { @@ -112,9 +97,32 @@ class BridgeModule : Module() { } } + // Clear methods every package load. Plugins should re-register on each load. + methods.clear() + registerDefaultMethods() + return@with } + private fun registerDefaultMethods() { + methods["Shiggy.info"] = { + mapOf( + "name" to Constants.LOADER_NAME, "version" to BuildConfig.VERSION_CODE + ) + } + + methods["Shiggy.test"] = { + mapOf( + "string" to "string", + "number" to 7256, + "array" to listOf("testing", 527737, listOf(true)), + "object" to mapOf("nested" to true), + "boolean" to false, + "args" to it, + ) + } + } + private fun Any?.toNativeObject(): Any? = argumentsMakeNative.invoke( null, when (this) { Unit -> null diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockCrashReportingModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockCrashReportingModule.kt index fb70a90..a808a86 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockCrashReportingModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockCrashReportingModule.kt @@ -9,26 +9,38 @@ import ShiggyXposed.xposed.Utils.Log * Hooks Discord's crash reporting to disable Sentry initialization. * While Discord doesn't have Sentry auto-initialization on by default, we still hook the content provider just to be safe. */ -class BlockCrashReportingModule : Module() { +object BlockCrashReportingModule : Module() { override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) = with(packageParam) { val crashReportingClass = classLoader.safeLoadClass("com.discord.crash_reporting.CrashReporting") - crashReportingClass?.hookMethod( - "init", Context::class.java, String::class.java - ) { - before { - Log.i("Blocked CrashReporting initialization") - result = null + crashReportingClass?.apply { + // Hooking this will result in a crash after a few seconds, since Discord expects initialization to complete when setting a Sentry tag. + // So we also hook isDisabled to make sure those calls are no-ops. + hookMethod( + "init", Context::class.java, String::class.java + ) { + before { + Log.i("Blocked CrashReporting initialization") + result = null + } } - } - - val sentryInitProviderClass = classLoader.safeLoadClass("io.sentry.android.core.SentryInitProvider") - sentryInitProviderClass?.hookMethod("onCreate") { - before { - Log.i("Blocked SentryInitProvider initialization") - result = true + runCatching { + hookMethod("isDisabled") { + before { + Log.i("Forced CrashReporting.isDisabled() to true") + result = true + } + } } - } - return@with + val sentryInitProviderClass = classLoader.safeLoadClass("io.sentry.android.core.SentryInitProvider") + sentryInitProviderClass?.hookMethod("onCreate") { + before { + Log.i("Blocked SentryInitProvider initialization") + result = true + } + } + + return@with + } } } diff --git a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockDeepLinksTrackingModule.kt b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockDeepLinksTrackingModule.kt index df5ecb2..454028f 100644 --- a/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockDeepLinksTrackingModule.kt +++ b/app/src/main/kotlin/ShiggyXposed/xposed/xposed/modules/no_track/BlockDeepLinksTrackingModule.kt @@ -8,7 +8,7 @@ import ShiggyXposed.xposed.Utils.Log /** * Hooks Discord's deep links tracking to disable AppsFlyer initialization. */ -class BlockDeepLinksTrackingModule : Module() { +object BlockDeepLinksTrackingModule : Module() { override fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) = with(packageParam) { val deepLinksClass = classLoader.safeLoadClass("com.discord.deep_link.DeepLinks") deepLinksClass?.hookMethod(