Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Disable analytics and telemetry patches #3448

Draft
wants to merge 21 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.revanced.patches.all.analytics.appsflyer

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.appsflyer.fingerprints.AppsFlyerInitFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable AppsFlyer analytics SDK"
)
@Suppress("unused")
object DisableAppsFlyer : BytecodePatch(
setOf(AppsFlyerInitFingerprint)
) {
override fun execute(context: BytecodeContext) {
AppsFlyerInitFingerprint.resultOrThrow().mutableMethod.addInstructions(
0,
"""
sget-object p0, Lkotlin/Unit;->INSTANCE:Lkotlin/Unit;
return-object p0
"""
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app.revanced.patches.all.analytics.appsflyer.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object AppsFlyerInitFingerprint : MethodFingerprint(
LisoUseInAIKyrios marked this conversation as resolved.
Show resolved Hide resolved
returnType = "Ljava/lang/Object;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.SYNTHETIC,
parameters = listOf("L", "L", "L"),
customFingerprint = { _, classDef ->
classDef.sourceFile == "CatchingAppsFlyerLibWrapper.kt"
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package app.revanced.patches.all.analytics.comscore

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.comscore.fingerprints.ComScoreSetupFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable ComScore analytics SDK"
)
@Suppress("unused")
object DisableComScore : BytecodePatch(
setOf(ComScoreSetupFingerprint)
) {
override fun execute(context: BytecodeContext) {
ComScoreSetupFingerprint.resultOrThrow().mutableMethod.addInstructions(0, "return-void")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.revanced.patches.all.analytics.comscore.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object ComScoreSetupFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
customFingerprint = { methodDef, classDef ->
classDef.type == "Lcom/comscore/util/setup/Setup;" && methodDef.name == "setUp"
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package app.revanced.patches.all.analytics.crashlytics

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.crashlytics.fingerprints.DoConfigFetchFingerprint
import app.revanced.patches.all.analytics.crashlytics.fingerprints.SettingsSpiCallFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable Crashlytics"
)
@Suppress("unused")
object DisableCrashlytics : BytecodePatch(
setOf(SettingsSpiCallFingerprint, DoConfigFetchFingerprint)
) {
override fun execute(context: BytecodeContext) {
// Neutralize the two methods responsible for requesting Crashlytics' configuration
// which effectively disables the SDK

SettingsSpiCallFingerprint.resultOrThrow().mutableMethod.addInstructions(
0,
"""
const/4 p1, 0x0
return-object p1
"""
)

DoConfigFetchFingerprint.resultOrThrow().mutableMethod.addInstructions(
0,
"""
sget-object p1, Lkotlin/Unit;->INSTANCE:Lkotlin/Unit;
return-object p1
"""
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.revanced.patches.all.analytics.crashlytics.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object DoConfigFetchFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, classDef ->
classDef.sourceFile == "RemoteSettingsFetcher.kt" && methodDef.name == "doConfigFetch"
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.revanced.patches.all.analytics.crashlytics.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object SettingsSpiCallFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC.value,
strings = listOf("Settings request failed."),
customFingerprint = { _, classDef ->
classDef.sourceFile == "DefaultSettingsSpiCall.java"
}
)
LisoUseInAIKyrios marked this conversation as resolved.
Outdated
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.revanced.patches.all.analytics.facebook

import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.resource.AndroidManifest

@Patch(
name = "Disable Facebook Analytics",
description = "Disables parts of the Facebook SDK responsible for data gathering."
)
@Suppress("unused")
object DisableFacebookAnalytics : ResourcePatch() {
override fun execute(context: ResourceContext) {
mapOf(
"com.facebook.sdk.AutoLogAppEventsEnabled" to "false",
"com.facebook.sdk.AdvertiserIDCollectionEnabled" to "false",
"com.facebook.sdk.MonitorEnabled" to "false",
// This entry disables completely the SDK, preventing Facebook login from working, may not be desired
//"com.facebook.sdk.AutoInitEnabled" to "false"
// TODO Add a patch option to choose to disable the SDK completely ?
).forEach {
AndroidManifest.addMetadata(context, it.key, it.value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.revanced.patches.all.analytics.firebase

import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.resource.AndroidManifest

@Patch(
name = "Disable Firebase collections",
description = "Disables multiple Firebase data collection mechanisms."
)
@Suppress("unused")
object DisableFirebaseCollections : ResourcePatch() {
override fun execute(context: ResourceContext) {
mapOf(
"firebase_analytics_collection_enabled" to "false",
"firebase_analytics_collection_deactivated" to "true",
"firebase_crashlytics_collection_enabled" to "false",
"firebase_performance_collection_enabled" to "false",
"firebase_performance_collection_deactivated" to "true",
"firebase_data_collection_default_enabled" to "false"
).forEach {
AndroidManifest.addMetadata(context, it.key, it.value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package app.revanced.patches.all.analytics.firebase

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.firebase.fingerprints.SendFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable Firebase transport",
description = "Prevents the sending of Firebase Logging and Firebase Crashlytics logs to Google's servers."
)
@Suppress("unused")
object DisableFirebaseTransport : BytecodePatch(
setOf(SendFingerprint)
) {
override fun execute(context: BytecodeContext) {
// Neutralize the method sending data to the backend
SendFingerprint.resultOrThrow().mutableMethod.addInstructions(0,"return-void")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.revanced.patches.all.analytics.firebase.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object SendFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, classDef ->
classDef.sourceFile == "TransportRuntime.java" && methodDef.name == "send"
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app.revanced.patches.all.analytics.google

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.google.fingerprints.AnalyticsInitFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable Google Analytics"
)
@Suppress("unused")
object DisableGoogleAnalytics : BytecodePatch(
setOf(AnalyticsInitFingerprint)
) {
override fun execute(context: BytecodeContext) {
// Empties the "context" argument to force an exception
AnalyticsInitFingerprint.resultOrThrow().mutableMethod.addInstructions(0,"const/4 p0, 0x0")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package app.revanced.patches.all.analytics.google

import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.resource.AndroidManifest

@Patch(
name = "Disable Google Analytics collections",
description = "Disables multiple Google Analytics data collection mechanisms."
)
@Suppress("unused")
object DisableGoogleAnalyticsCollections : ResourcePatch() {
override fun execute(context: ResourceContext) {
mapOf(
"google_analytics_adid_collection_enabled" to "false",
"google_analytics_default_allow_ad_personalization_signals" to "false",
"google_analytics_automatic_screen_reporting_enabled" to "false",
"google_analytics_default_allow_ad_storage" to "false",
"google_analytics_default_allow_ad_user_data" to "false",
"google_analytics_default_allow_analytics_storage" to "false",
"google_analytics_sgtm_upload_enabled" to "false",
"google_analytics_deferred_deep_link_enabled" to "false"
).forEach {
AndroidManifest.addMetadata(context, it.key, it.value)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package app.revanced.patches.all.analytics.google.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object AnalyticsInitFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/content/Context;"),
strings = listOf("Slow initialization (ms)"),
customFingerprint = { _, classDef ->
classDef.sourceFile?.startsWith("com.google.android.gms:play-services-analytics-impl") == true
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package app.revanced.patches.all.analytics.moengage

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.moengage.fingerprints.MoEngageInitFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable MoEngage analytics SDK"
)
@Suppress("unused")
object DisableMoEngage : BytecodePatch(
setOf(MoEngageInitFingerprint)
) {
override fun execute(context: BytecodeContext) {
MoEngageInitFingerprint.resultOrThrow().mutableMethod.addInstructions(0, "return-void")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.revanced.patches.all.analytics.moengage.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object MoEngageInitFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, classDef ->
classDef.sourceFile == "DefaultMoEngageSdk.kt" && methodDef.name == "init"
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app.revanced.patches.all.analytics.segment

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.analytics.segment.fingerprints.SegmentBuilderFingerprint
import app.revanced.util.resultOrThrow

@Patch(
name = "Disable Segment analytics SDK"
)
@Suppress("unused")
object DisableSegment : BytecodePatch(
setOf(SegmentBuilderFingerprint)
) {
override fun execute(context: BytecodeContext) {
// Empties the writeKey parameter to abort initialization
SegmentBuilderFingerprint.resultOrThrow().mutableMethod.addInstructions(0,"const-string p2, \"\"")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.revanced.patches.all.analytics.segment.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

object SegmentBuilderFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("Landroid/content/Context;", "Ljava/lang/String;"),
strings = listOf("writeKey must not be empty.")
)
Loading
Loading