fix(YouTube Music/Sanitize sharing links): tracking parameters are not removed from the system share panel

This commit is contained in:
inotia00
2024-08-11 17:39:55 +09:00
parent 5ecbe49d1f
commit 4aec1a16b5
8 changed files with 55 additions and 137 deletions

View File

@ -1,15 +0,0 @@
package app.revanced.patches.music.misc.tracking
import app.revanced.patches.music.misc.tracking.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.shared.tracking.BaseSanitizeUrlQueryPatch
import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
object SanitizeUrlQueryBytecodePatch : BaseSanitizeUrlQueryPatch(
"$MISC_PATH/SanitizeUrlQueryPatch;",
listOf(
CopyTextEndpointFingerprint,
ShareLinkFormatterFingerprint
),
null
)

View File

@ -4,6 +4,7 @@ import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.tracking.BaseSanitizeUrlQueryPatch
import app.revanced.util.patch.BaseResourcePatch
@Suppress("unused")
@ -11,7 +12,7 @@ object SanitizeUrlQueryPatch : BaseResourcePatch(
name = "Sanitize sharing links",
description = "Adds an option to remove tracking query parameters from URLs when sharing links.",
dependencies = setOf(
SanitizeUrlQueryBytecodePatch::class,
BaseSanitizeUrlQueryPatch::class,
SettingsPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE

View File

@ -3,39 +3,69 @@ package app.revanced.patches.shared.tracking
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
import app.revanced.patches.shared.tracking.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.shared.tracking.fingerprints.SystemShareLinkFormatterFingerprint
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
abstract class BaseSanitizeUrlQueryPatch(
private val descriptor: String,
private val sharedFingerprints: List<MethodFingerprint>,
private val additionalFingerprints: List<MethodFingerprint>? = null
) : BytecodePatch(
buildSet {
addAll(sharedFingerprints)
additionalFingerprints?.let(::addAll)
}
object BaseSanitizeUrlQueryPatch : BytecodePatch(
setOf(
CopyTextEndpointFingerprint,
ShareLinkFormatterFingerprint,
SystemShareLinkFormatterFingerprint
)
) {
private fun MethodFingerprint.invoke() {
resultOrThrow().let {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$PATCHES_PATH/SanitizeUrlQueryPatch;"
override fun execute(context: BytecodeContext) {
CopyTextEndpointFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val targetIndex = it.scanResult.patternScanResult!!.startIndex
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 2, """
invoke-static {v$targetRegister}, $descriptor->stripQueryParameters(Ljava/lang/String;)Ljava/lang/String;
invoke-static {v$targetRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->stripQueryParameters(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$targetRegister
"""
)
}
}
}
override fun execute(context: BytecodeContext) {
for (fingerprint in sharedFingerprints)
fingerprint.invoke()
arrayOf(
ShareLinkFormatterFingerprint,
SystemShareLinkFormatterFingerprint
).forEach { fingerprint ->
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
for ((index, instruction) in implementation!!.instructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_VIRTUAL)
continue
if ((instruction as ReferenceInstruction).reference.toString() != "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;")
continue
if (getInstruction(index + 1).opcode != Opcode.GOTO)
continue
val invokeInstruction = instruction as FiveRegisterInstruction
replaceInstruction(
index,
"invoke-static {v${invokeInstruction.registerC}, v${invokeInstruction.registerD}, v${invokeInstruction.registerE}}, "
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->stripQueryParameters(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;)V"
)
}
}
}
}
}
}

View File

@ -1,4 +1,4 @@
package app.revanced.patches.music.misc.tracking.fingerprints
package app.revanced.patches.shared.tracking.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
@ -6,16 +6,14 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
/**
* Sharing panel of YouTube Music
* Sharing panel
*/
internal object ShareLinkFormatterFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L", "Ljava/util/Map;"),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.CONST_STRING,
null,
Opcode.INVOKE_VIRTUAL
),
customFingerprint = custom@{ methodDef, _ ->

View File

@ -1,4 +1,4 @@
package app.revanced.patches.youtube.misc.tracking.fingerprints
package app.revanced.patches.shared.tracking.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint

View File

@ -1,58 +0,0 @@
package app.revanced.patches.youtube.misc.tracking
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.shared.tracking.BaseSanitizeUrlQueryPatch
import app.revanced.patches.shared.tracking.fingerprints.CopyTextEndpointFingerprint
import app.revanced.patches.youtube.misc.tracking.fingerprints.ShareLinkFormatterFingerprint
import app.revanced.patches.youtube.misc.tracking.fingerprints.SystemShareLinkFormatterFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
object SanitizeUrlQueryBytecodePatch : BaseSanitizeUrlQueryPatch(
"$MISC_PATH/SanitizeUrlQueryPatch;",
listOf(CopyTextEndpointFingerprint),
listOf(
ShareLinkFormatterFingerprint,
SystemShareLinkFormatterFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$MISC_PATH/SanitizeUrlQueryPatch;"
override fun execute(context: BytecodeContext) {
super.execute(context)
arrayOf(
ShareLinkFormatterFingerprint,
SystemShareLinkFormatterFingerprint
).forEach { fingerprint ->
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
for ((index, instruction) in implementation!!.instructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_VIRTUAL)
continue
if ((instruction as ReferenceInstruction).reference.toString() != "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;")
continue
if (getInstruction(index + 1).opcode != Opcode.GOTO)
continue
val invokeInstruction = instruction as FiveRegisterInstruction
replaceInstruction(
index,
"invoke-static {v${invokeInstruction.registerC}, v${invokeInstruction.registerD}, v${invokeInstruction.registerE}}, "
+ "$INTEGRATIONS_CLASS_DESCRIPTOR->stripQueryParameters(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;)V"
)
}
}
}
}
}
}

View File

@ -1,6 +1,7 @@
package app.revanced.patches.youtube.misc.tracking
import app.revanced.patcher.data.ResourceContext
import app.revanced.patches.shared.tracking.BaseSanitizeUrlQueryPatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.patch.BaseResourcePatch
@ -10,7 +11,7 @@ object SanitizeUrlQueryPatch : BaseResourcePatch(
name = "Sanitize sharing links",
description = "Adds an option to remove tracking query parameters from URLs when sharing links.",
dependencies = setOf(
SanitizeUrlQueryBytecodePatch::class,
BaseSanitizeUrlQueryPatch::class,
SettingsPatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE

View File

@ -1,39 +0,0 @@
package app.revanced.patches.youtube.misc.tracking.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
/**
* Sharing panel of YouTube
*
* This fingerprint is quite complex to be compatible with all versions from YouTube v18.25.40 to the latest version.
* If you drop supporting the old version, please change the fingerprint to be more intuitive.
*/
internal object ShareLinkFormatterFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.CHECK_CAST,
Opcode.GOTO,
Opcode.MOVE_OBJECT,
Opcode.INVOKE_VIRTUAL
),
customFingerprint = custom@{ methodDef, _ ->
if (methodDef.implementation == null)
return@custom false
var count = 0
for (instruction in methodDef.implementation!!.instructions) {
if (instruction.opcode != Opcode.SGET_OBJECT)
continue
val objectInstruction = instruction as ReferenceInstruction
if ((objectInstruction.reference as FieldReference).name != "androidAppEndpoint")
continue
count++
}
count == 2
}
)