Skip to content

Commit

Permalink
- fix latest messenger update
Browse files Browse the repository at this point in the history
- clean urls before opening
- add analytics kill
  • Loading branch information
C10udburst committed Jul 1, 2024
1 parent f5ab49f commit 0fe1708
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 37 deletions.
15 changes: 10 additions & 5 deletions app/src/main/java/io/github/cloudburst/messengerex/Module.java
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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);
}
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/java/io/github/cloudburst/messengerex/Utils.kt
Original file line number Diff line number Diff line change
@@ -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()
}
Original file line number Diff line number Diff line change
@@ -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}")
}
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.cloudburst.messengerex.patches

const val TAG = "MessengerExPatches"

0 comments on commit 0fe1708

Please sign in to comment.