From 0fe170828e0c7bddc4da465535e4b92748c235d0 Mon Sep 17 00:00:00 2001 From: Cloudburst <18114966+C10udburst@users.noreply.github.com> Date: Mon, 1 Jul 2024 22:55:09 +0200 Subject: [PATCH] - fix latest messenger update - clean urls before opening - add analytics kill --- .../github/cloudburst/messengerex/Module.java | 15 +++++--- .../io/github/cloudburst/messengerex/Utils.kt | 26 +++++++++++++ .../messengerex/patches/Analytics.kt | 35 +++++++++++++++++ .../cloudburst/messengerex/patches/Inbox.kt | 32 ++++++++++++++++ .../{Patches.kt => patches/Messages.kt} | 38 +++---------------- .../cloudburst/messengerex/patches/Patches.kt | 3 ++ 6 files changed, 112 insertions(+), 37 deletions(-) create mode 100644 app/src/main/java/io/github/cloudburst/messengerex/Utils.kt create mode 100644 app/src/main/java/io/github/cloudburst/messengerex/patches/Analytics.kt create mode 100644 app/src/main/java/io/github/cloudburst/messengerex/patches/Inbox.kt rename app/src/main/java/io/github/cloudburst/messengerex/{Patches.kt => patches/Messages.kt} (53%) create mode 100644 app/src/main/java/io/github/cloudburst/messengerex/patches/Patches.kt diff --git a/app/src/main/java/io/github/cloudburst/messengerex/Module.java b/app/src/main/java/io/github/cloudburst/messengerex/Module.java index 90eaadf..7c5edb8 100644 --- a/app/src/main/java/io/github/cloudburst/messengerex/Module.java +++ b/app/src/main/java/io/github/cloudburst/messengerex/Module.java @@ -1,12 +1,16 @@ package io.github.cloudburst.messengerex; -import android.util.Log; +import static io.github.cloudburst.messengerex.UtilsKt.getApkPath; +import static io.github.cloudburst.messengerex.patches.AnalyticsKt.*; +import static io.github.cloudburst.messengerex.patches.InboxKt.*; +import static io.github.cloudburst.messengerex.patches.MessagesKt.*; +import android.util.Log; import org.luckypray.dexkit.DexKitBridge; - import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.callbacks.XC_LoadPackage; + public final class Module implements IXposedHookLoadPackage { private static final String TAG = "MessengerEx"; @@ -17,14 +21,15 @@ public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Th var cl = lpparam.classLoader; System.loadLibrary("dexkit"); - try (DexKitBridge bridge = DexKitBridge.create(lpparam.appInfo.sourceDir)) { + try (DexKitBridge bridge = DexKitBridge.create(getApkPath(lpparam.appInfo))) { if (bridge == null) { Log.e(TAG, "Failed to create DexKitBridge"); return; } - PatchesKt.removeAds(cl, bridge); - PatchesKt.replaceBrowser(cl, bridge); + removeAds(cl, bridge); + replaceBrowser(cl, bridge); + removeServices(cl); } catch (Exception e) { Log.e(TAG, "Failed to find method", e); } diff --git a/app/src/main/java/io/github/cloudburst/messengerex/Utils.kt b/app/src/main/java/io/github/cloudburst/messengerex/Utils.kt new file mode 100644 index 0000000..5e92f53 --- /dev/null +++ b/app/src/main/java/io/github/cloudburst/messengerex/Utils.kt @@ -0,0 +1,26 @@ +package io.github.cloudburst.messengerex + +import android.content.pm.ApplicationInfo +import android.net.Uri + +fun getApkPath(apkinfo: ApplicationInfo): String = apkinfo.splitSourceDirs?.firstOrNull { + it.contains("split_d_longtail_raw_v9") +} ?: apkinfo.sourceDir + +fun removeTrackingUrl(uri: Uri): Uri { + var url = uri + if (url.host == "l.facebook.com" && url.path == "/l.php") { + url = Uri.parse(url.getQueryParameter("u")) + } + val builder = url.buildUpon() + builder.clearQuery() + val cleanQuery = url.queryParameterNames + .filterNot { it.equals("fbclid", ignoreCase = true) } + .filterNot { it.startsWith("utm_", ignoreCase = true) } + .filterNot {it.equals("si", ignoreCase = true)} + .map { it to url.getQueryParameter(it) } + cleanQuery.forEach { (key, value) -> + builder.appendQueryParameter(key, value) + } + return builder.build() +} \ No newline at end of file diff --git a/app/src/main/java/io/github/cloudburst/messengerex/patches/Analytics.kt b/app/src/main/java/io/github/cloudburst/messengerex/patches/Analytics.kt new file mode 100644 index 0000000..2cef952 --- /dev/null +++ b/app/src/main/java/io/github/cloudburst/messengerex/patches/Analytics.kt @@ -0,0 +1,35 @@ +package io.github.cloudburst.messengerex.patches + +import android.util.Log +import de.robv.android.xposed.XC_MethodHook +import de.robv.android.xposed.XposedBridge + +val loggerServices = listOf( + "AlarmBasedUploadService", + "GooglePlayUploadService", + "LollipopUploadService" +) + +fun removeService(cl: ClassLoader, className: String) { + val clazz = cl.loadClass("com.facebook.analytics2.logger.${className}") + val method = clazz.declaredMethods.firstOrNull { + it.name == "onStartCommand" && it.returnType == Int::class.javaPrimitiveType + } ?: return + XposedBridge.hookMethod(method, object : XC_MethodHook() { + override fun beforeHookedMethod(param: MethodHookParam?) { + param?.result = 2 + } + }) + Log.d(TAG, "Removed service $className") +} + + +fun removeServices(cl: ClassLoader) { + loggerServices.forEach { + try { + removeService(cl, it) + } catch (e: Exception) { + XposedBridge.log("Failed to remove service $it. Reason: ${e.message}") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/cloudburst/messengerex/patches/Inbox.kt b/app/src/main/java/io/github/cloudburst/messengerex/patches/Inbox.kt new file mode 100644 index 0000000..689be7a --- /dev/null +++ b/app/src/main/java/io/github/cloudburst/messengerex/patches/Inbox.kt @@ -0,0 +1,32 @@ +package io.github.cloudburst.messengerex.patches + +import android.util.Log +import de.robv.android.xposed.XC_MethodReplacement +import de.robv.android.xposed.XposedBridge +import org.luckypray.dexkit.DexKitBridge +import java.lang.reflect.Modifier + +fun removeAds(cl: ClassLoader, bridge: DexKitBridge) { + try { + val classData = bridge.findClass { + searchPackages("com.facebook.messaging.business.inboxads.plugins.inboxads.itemsupplier") + matcher { + className("com.facebook.messaging.business.inboxads.plugins.inboxads.itemsupplier.InboxAdsItemSupplierImplementation") + } + }.first() + + val method = bridge.findMethod { + searchInClass(listOf(classData)) + matcher { + returnType("void") + usingStrings("ads_load_begin", "inbox_ads_fetch_start") + modifiers(Modifier.PUBLIC or Modifier.STATIC) + } + }.first() + + Log.i(TAG, "Found method: $method") + XposedBridge.hookMethod(method.getMethodInstance(cl), XC_MethodReplacement.DO_NOTHING) + } catch (e: Exception) { + Log.e(TAG, "Failed to remove ads", e) + } +} diff --git a/app/src/main/java/io/github/cloudburst/messengerex/Patches.kt b/app/src/main/java/io/github/cloudburst/messengerex/patches/Messages.kt similarity index 53% rename from app/src/main/java/io/github/cloudburst/messengerex/Patches.kt rename to app/src/main/java/io/github/cloudburst/messengerex/patches/Messages.kt index 0b69451..496673a 100644 --- a/app/src/main/java/io/github/cloudburst/messengerex/Patches.kt +++ b/app/src/main/java/io/github/cloudburst/messengerex/patches/Messages.kt @@ -1,42 +1,15 @@ -package io.github.cloudburst.messengerex +package io.github.cloudburst.messengerex.patches import android.content.Context import android.net.Uri import android.util.Log import androidx.browser.customtabs.CustomTabsIntent import de.robv.android.xposed.XC_MethodHook -import de.robv.android.xposed.XC_MethodReplacement import de.robv.android.xposed.XposedBridge +import io.github.cloudburst.messengerex.removeTrackingUrl import org.luckypray.dexkit.DexKitBridge import java.lang.reflect.Modifier -const val TAG = "MessengerExPatches" - -fun removeAds(cl: ClassLoader, bridge: DexKitBridge) { - try { - val classData = bridge.findClass { - searchPackages("com.facebook.messaging.business.inboxads.plugins.inboxads.itemsupplier") - matcher { - className("com.facebook.messaging.business.inboxads.plugins.inboxads.itemsupplier.InboxAdsItemSupplierImplementation") - } - }.firstOrNull() ?: return - - val method = bridge.findMethod { - searchInClass(listOf(classData)) - matcher { - returnType("void") - usingStrings("ads_load_begin", "inbox_ads_fetch_start") - modifiers(Modifier.PUBLIC or Modifier.STATIC) - } - }.firstOrNull() ?: return - - Log.i(TAG, "Found method: $method") - XposedBridge.hookMethod(method.getMethodInstance(cl), XC_MethodReplacement.DO_NOTHING) - } catch (e: Exception) { - Log.e(TAG, "Failed to remove ads", e) - } -} - fun replaceBrowser(cl: ClassLoader, bridge: DexKitBridge) { try { val method = bridge.findMethod { @@ -47,22 +20,23 @@ fun replaceBrowser(cl: ClassLoader, bridge: DexKitBridge) { addParamType("com.facebook.xapp.messaging.browser.model.MessengerInAppBrowserLaunchParam") modifiers(Modifier.PUBLIC) } - }.firstOrNull() ?: return + }.first() Log.i(TAG, "Found method: $method") XposedBridge.hookMethod(method.getMethodInstance(cl), object : XC_MethodHook() { override fun beforeHookedMethod(param: MethodHookParam?) { val ctx = param?.args?.get(0) as? Context ?: return val url = param.args?.get(1) as? Uri ?: return + val cleanUrl = removeTrackingUrl(url) val intent = CustomTabsIntent.Builder() .setShowTitle(true) .build() - intent.launchUrl(ctx, url) + intent.launchUrl(ctx, cleanUrl) param.result = null } }) } catch (e: Exception) { Log.e(TAG, "Failed to replace browser", e) } -} +} \ No newline at end of file diff --git a/app/src/main/java/io/github/cloudburst/messengerex/patches/Patches.kt b/app/src/main/java/io/github/cloudburst/messengerex/patches/Patches.kt new file mode 100644 index 0000000..7111cea --- /dev/null +++ b/app/src/main/java/io/github/cloudburst/messengerex/patches/Patches.kt @@ -0,0 +1,3 @@ +package io.github.cloudburst.messengerex.patches + +const val TAG = "MessengerExPatches" \ No newline at end of file