generated from ReVanced/revanced-patches-template
-
-
Notifications
You must be signed in to change notification settings - Fork 337
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
278 additions
and
382 deletions.
There are no files selected for viewing
147 changes: 147 additions & 0 deletions
147
src/main/kotlin/app/revanced/patches/all/privacy/DisableAnalyticsAndTelemetryPatch.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
package app.revanced.patches.all.privacy | ||
|
||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions | ||
import app.revanced.patcher.patch.BytecodePatch | ||
import app.revanced.patcher.patch.PatchException | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patcher.util.smali.ExternalLabel | ||
import app.revanced.patches.all.privacy.fingerprints.* | ||
import app.revanced.util.resultOrThrow | ||
import java.util.logging.Logger | ||
|
||
@Patch( | ||
name = "Disable analytics and telemetry", | ||
description = "Patches the app to disable analytics and telemetry services.", | ||
use = false, | ||
) | ||
@Suppress("unused") | ||
object DisableAnalyticsAndTelemetryPatch : BytecodePatch( | ||
setOf( | ||
InitializeAsyncStatsigClientFingerprint, | ||
InitAnalyticsFingerprint, | ||
InitAppsFlyerSDKFingerprint, | ||
SetupComsCoreFingerprint, | ||
CallSettingsSpiFingerprint, | ||
DoConfigFetchFingerprint, | ||
SendFingerprint, | ||
InitializeSdkFingerprint, | ||
BuildSegmentFingerprint, | ||
InitSDKFingerprint, | ||
InitAmplitudeFingerprint, | ||
), | ||
) { | ||
private val logger = Logger.getLogger(this::class.java.name) | ||
|
||
private val disableGoogleAnalytics by option("Google Analytics") | ||
private val disableAmplitude by option("Amplitude") | ||
private val disableStatsig by option("Statsig") | ||
private val disableAppsFlyerSDK by option("Apps Flyer SDK") | ||
private val disableAppsFlyerPlugin by option("Apps Flyer plugin") | ||
private val disableComsCore by option("ComsCore") | ||
private val disableCrashlytics by option("Crashlytics") | ||
private val disableFirebaseTransport by option("Firebase Transport") | ||
private val disableMoEngage by option("MoEngage") | ||
private val disableSegment by option("Segment") | ||
|
||
override fun execute(context: BytecodeContext) = mapOf( | ||
disableAmplitude to { | ||
InitAmplitudeFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-object p0", | ||
) | ||
}, | ||
disableStatsig to { | ||
InitializeAsyncStatsigClientFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-void", | ||
) | ||
}, | ||
disableAppsFlyerSDK to { | ||
InitAppsFlyerSDKFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-object p0", | ||
) | ||
}, | ||
disableAppsFlyerPlugin to { | ||
InitSDKFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-void", | ||
) | ||
}, | ||
disableComsCore to { | ||
SetupComsCoreFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-void", | ||
) | ||
}, | ||
// Neutralize the method sending data to the backend. | ||
disableFirebaseTransport to { | ||
SendFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"return-void", | ||
) | ||
}, | ||
// Empties the "context" argument to force an exception. | ||
disableGoogleAnalytics to { | ||
InitAnalyticsFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"const/4 p0, 0x0", | ||
) | ||
}, | ||
// Empties the writeKey parameter to abort initialization | ||
disableSegment to { | ||
BuildSegmentFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
"const-string p2, \"\"", | ||
) | ||
}, | ||
// Neutralize the two methods responsible for requesting Crashlytics' configuration. | ||
// which effectively disables the SDK. | ||
disableCrashlytics to { | ||
CallSettingsSpiFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
""" | ||
const/4 p1, 0x0 | ||
return-object p1 | ||
""", | ||
) | ||
|
||
DoConfigFetchFingerprint.resultOrThrow().mutableMethod.apply { | ||
// Jumps to the end of the method to directly return an empty object. | ||
addInstructionsWithLabels( | ||
0, | ||
""" | ||
goto :return_unit | ||
""", | ||
ExternalLabel("return_unit", getInstruction(getInstructions().lastIndex - 2)), | ||
) | ||
} | ||
}, | ||
disableMoEngage to { | ||
InitializeSdkFingerprint.resultOrThrow().mutableMethod.addInstructions( | ||
0, | ||
""" | ||
const/4 v0, 0x0 | ||
return-object v0 | ||
""", | ||
) | ||
}, | ||
).forEach { (option, patch) -> | ||
val isEnabled by option | ||
if (!isEnabled!!) return@forEach | ||
|
||
val message = try { | ||
patch() | ||
|
||
"Disabled ${option.title}" | ||
} catch (exception: PatchException) { | ||
"${option.title} was not found. Skipping." | ||
} | ||
|
||
logger.info(message) | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
...tlin/app/revanced/patches/all/privacy/DisableAnalyticsAndTelemetryThroughManifestPatch.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package app.revanced.patches.all.privacy | ||
|
||
import app.revanced.patcher.data.ResourceContext | ||
import app.revanced.patcher.patch.PatchException | ||
import app.revanced.patcher.patch.ResourcePatch | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.util.asSequence | ||
import app.revanced.util.getNode | ||
import org.w3c.dom.Document | ||
import org.w3c.dom.Element | ||
import java.util.logging.Logger | ||
|
||
@Patch( | ||
name = "Disable analytics and telemetry through manifest", | ||
description = "Patches the manifest to disable analytics and telemetry services.", | ||
use = false, | ||
) | ||
@Suppress("unused") | ||
object DisableAnalyticsAndTelemetryThroughManifestPatch : ResourcePatch() { | ||
private val logger = Logger.getLogger(this::class.java.name) | ||
|
||
private val disableFirebaseTelemetry by option("Firebase telemetry") | ||
private val disableFacebookSdk by option("Facebook SDK") | ||
private val disableGoogleAnalytics by option("Google Analytics") | ||
|
||
override fun execute(context: ResourceContext) { | ||
context.document["AndroidManifest.xml"].use { document -> | ||
mapOf( | ||
disableFirebaseTelemetry to { | ||
document.addMetadata( | ||
"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", | ||
) | ||
}, | ||
disableFacebookSdk to { | ||
document.addMetadata( | ||
"com.facebook.sdk.AutoLogAppEventsEnabled" to "false", | ||
"com.facebook.sdk.AdvertiserIDCollectionEnabled" to "false", | ||
"com.facebook.sdk.MonitorEnabled" to "false", | ||
"com.facebook.sdk.AutoInitEnabled" to "false", | ||
) | ||
}, | ||
disableGoogleAnalytics to { | ||
document.addMetadata( | ||
"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 { option, patch -> | ||
val isEnabled by option | ||
if (!isEnabled!!) return@forEach | ||
|
||
val message = try { | ||
patch() | ||
|
||
"Disabled ${option.title}" | ||
} catch (exception: PatchException) { | ||
"${option.title} was not found. Skipping." | ||
} | ||
|
||
logger.info(message) | ||
} | ||
} | ||
} | ||
|
||
private const val META_DATA_TAG = "meta-data" | ||
private const val NAME_ATTRIBUTE = "android:name" | ||
private const val VALUE_ATTRIBUTE = "android:value" | ||
|
||
private fun Document.addMetadata(vararg metaDataNodes: Pair<String, String>) = | ||
metaDataNodes.forEach { (nodeName, nodeValue) -> | ||
val applicationNode = getNode("application") as Element | ||
applicationNode.getElementsByTagName(META_DATA_TAG) | ||
.asSequence() | ||
.first { it.attributes.getNamedItem(NAME_ATTRIBUTE).nodeValue == nodeName } | ||
.attributes.getNamedItem(VALUE_ATTRIBUTE).nodeValue = nodeValue | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/kotlin/app/revanced/patches/all/privacy/PatchExtension.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package app.revanced.patches.all.privacy | ||
|
||
import app.revanced.patcher.patch.Patch | ||
import app.revanced.patcher.patch.options.PatchOption | ||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.booleanPatchOption | ||
import kotlin.properties.ReadOnlyProperty | ||
|
||
internal fun Patch<*>.option( | ||
title: String, | ||
) = ReadOnlyProperty<Any?, PatchOption<Boolean?>> { _, property -> | ||
booleanPatchOption(key = property.name, default = true, title = title, required = true) | ||
} |
Oops, something went wrong.