Skip to content

Commit 0077028

Browse files
feat(Twitter): Add Change link sharing domain patch (#3753)
Co-authored-by: oSumAtrIX <[email protected]>
1 parent 596c2b0 commit 0077028

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

api/revanced-patches.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,12 @@ public final class app/revanced/patches/twitter/misc/hook/patch/recommendation/H
14901490
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/hook/patch/recommendation/HideRecommendedUsersPatch;
14911491
}
14921492

1493+
public final class app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch : app/revanced/patcher/patch/BytecodePatch {
1494+
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch;
1495+
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
1496+
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
1497+
}
1498+
14931499
public final class app/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatch : app/revanced/patcher/patch/BytecodePatch {
14941500
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatch;
14951501
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package app.revanced.patches.twitter.misc.links
2+
3+
import app.revanced.patcher.data.BytecodeContext
4+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
5+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
6+
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
7+
import app.revanced.patcher.patch.BytecodePatch
8+
import app.revanced.patcher.patch.annotation.CompatiblePackage
9+
import app.revanced.patcher.patch.annotation.Patch
10+
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
11+
import app.revanced.patches.twitter.misc.links.fingerprints.LinkBuilderFingerprint
12+
import app.revanced.patches.twitter.misc.links.fingerprints.LinkResourceGetterFingerprint
13+
import app.revanced.patches.twitter.misc.links.fingerprints.LinkSharingDomainFingerprint
14+
import app.revanced.util.exception
15+
import app.revanced.util.getReference
16+
import app.revanced.util.indexOfFirstInstructionOrThrow
17+
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
18+
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
19+
import com.android.tools.smali.dexlib2.iface.reference.StringReference
20+
21+
@Patch(
22+
name = "Change link sharing domain",
23+
description = "Replaces the domain name of Twitter links when sharing them.",
24+
compatiblePackages = [CompatiblePackage("com.twitter.android")],
25+
)
26+
@Suppress("unused")
27+
object ChangeLinkSharingDomainPatch : BytecodePatch(
28+
setOf(
29+
LinkBuilderFingerprint,
30+
LinkResourceGetterFingerprint,
31+
LinkSharingDomainFingerprint,
32+
),
33+
) {
34+
private var domainName by stringPatchOption(
35+
key = "domainName",
36+
default = "fxtwitter.com",
37+
title = "Domain name",
38+
description = "The domain name to use when sharing links.",
39+
required = true,
40+
)
41+
42+
// This method is used to build the link that is shared when the "Share via..." button is pressed.
43+
private const val FORMAT_METHOD_RESOURCE_REFERENCE =
44+
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
45+
"formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;"
46+
47+
// This method is used to build the link that is shared when the "Copy link" button is pressed.
48+
private const val FORMAT_METHOD_REFERENCE =
49+
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
50+
"formatLink(JLjava/lang/String;)Ljava/lang/String;"
51+
52+
override fun execute(context: BytecodeContext) {
53+
LinkSharingDomainFingerprint.result?.let {
54+
val replacementIndex = it.scanResult.stringsScanResult!!.matches.first().index
55+
val domainRegister = it.mutableMethod.getInstruction<OneRegisterInstruction>(replacementIndex).registerA
56+
it.mutableMethod.replaceInstruction(
57+
replacementIndex,
58+
"const-string v$domainRegister, \"https://$domainName\"",
59+
)
60+
} ?: throw LinkSharingDomainFingerprint.exception
61+
62+
// Replace the domain name when copying a link with "Copy link" button.
63+
LinkBuilderFingerprint.result?.let {
64+
it.mutableMethod.apply {
65+
addInstructions(
66+
0,
67+
"""
68+
invoke-static { p0, p1, p2 }, $FORMAT_METHOD_REFERENCE
69+
move-result-object p0
70+
return-object p0
71+
""",
72+
)
73+
}
74+
} ?: throw LinkBuilderFingerprint.exception
75+
76+
// Used in the Share via... dialog.
77+
LinkResourceGetterFingerprint.result?.mutableMethod?.apply {
78+
val constWithParameterName = indexOfFirstInstructionOrThrow {
79+
getReference<StringReference>()?.string?.contains("id.toString()") == true
80+
}
81+
82+
// Format the link with the new domain name register (2 instructions above the const-string).
83+
val formatLinkCallIndex = constWithParameterName - 2
84+
val formatLinkCall = getInstruction<Instruction35c>(formatLinkCallIndex)
85+
86+
// Replace the original method call with the new method call.
87+
replaceInstruction(
88+
formatLinkCallIndex,
89+
"invoke-static { v${formatLinkCall.registerE} }, $FORMAT_METHOD_RESOURCE_REFERENCE",
90+
)
91+
} ?: throw LinkResourceGetterFingerprint.exception
92+
}
93+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package app.revanced.patches.twitter.misc.links.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
5+
// Returns a shareable link string based on a tweet ID and a username.
6+
internal object LinkBuilderFingerprint : MethodFingerprint(
7+
strings = listOf("/%1\$s/status/%2\$d"),
8+
)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package app.revanced.patches.twitter.misc.links.fingerprints
2+
3+
import app.revanced.patcher.extensions.or
4+
import app.revanced.patcher.fingerprint.MethodFingerprint
5+
import com.android.tools.smali.dexlib2.AccessFlags
6+
7+
// Gets Resource string for share link view available by pressing "Share via" button.
8+
internal object LinkResourceGetterFingerprint : MethodFingerprint(
9+
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
10+
parameters = listOf("Landroid/content/res/Resources;"),
11+
strings = listOf("res.getString(R.string.t…lUsername, id.toString())"),
12+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package app.revanced.patches.twitter.misc.links.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
5+
internal object LinkSharingDomainFingerprint : MethodFingerprint(
6+
strings = listOf("https://fxtwitter.com"),
7+
)

0 commit comments

Comments
 (0)