Skip to content

Commit b575fc6

Browse files
OctoNezdoSumAtrIX
andauthored
feat(Boost For Reddit): Add Fix /s/ links patch (#3154)
Co-authored-by: oSumAtrIX <[email protected]>
1 parent c979e92 commit b575fc6

File tree

11 files changed

+229
-26
lines changed

11 files changed

+229
-26
lines changed

api/revanced-patches.api

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,18 @@ public final class app/revanced/patches/reddit/ad/general/HideAdsPatch : app/rev
535535
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
536536
}
537537

538+
public abstract class app/revanced/patches/reddit/customclients/BaseFixSLinksPatch : app/revanced/patcher/patch/BytecodePatch {
539+
public fun <init> (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Ljava/util/Set;)V
540+
public synthetic fun <init> (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
541+
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
542+
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
543+
protected abstract fun getIntegrationsClassDescriptor ()Ljava/lang/String;
544+
protected final fun getResolveSLinkMethod ()Ljava/lang/String;
545+
protected final fun getSetAccessTokenMethod ()Ljava/lang/String;
546+
protected abstract fun patchNavigationHandler (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V
547+
protected abstract fun patchSetAccessToken (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V
548+
}
549+
538550
public abstract class app/revanced/patches/reddit/customclients/BaseSpoofClientPatch : app/revanced/patcher/patch/BytecodePatch {
539551
public fun <init> (Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V
540552
public synthetic fun <init> (Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@@ -570,6 +582,14 @@ public final class app/revanced/patches/reddit/customclients/boostforreddit/api/
570582
public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
571583
}
572584

585+
public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch {
586+
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch;
587+
}
588+
589+
public final class app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
590+
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch;
591+
}
592+
573593
public final class app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
574594
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch;
575595
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
@@ -648,10 +668,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/detec
648668
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
649669
}
650670

651-
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patcher/patch/BytecodePatch {
671+
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch {
652672
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch;
653-
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
654-
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
673+
}
674+
675+
public final class app/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
676+
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch;
655677
}
656678

657679
public final class app/revanced/patches/reddit/layout/disablescreenshotpopup/DisableScreenshotPopupPatch : app/revanced/patcher/patch/BytecodePatch {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package app.revanced.patches.reddit.customclients
2+
3+
import app.revanced.patcher.PatchClass
4+
import app.revanced.patcher.data.BytecodeContext
5+
import app.revanced.patcher.fingerprint.MethodFingerprint
6+
import app.revanced.patcher.fingerprint.MethodFingerprintResult
7+
import app.revanced.patcher.patch.BytecodePatch
8+
import app.revanced.util.resultOrThrow
9+
10+
abstract class BaseFixSLinksPatch(
11+
private val handleNavigationFingerprint: MethodFingerprint,
12+
private val setAccessTokenFingerprint: MethodFingerprint,
13+
compatiblePackages: Set<CompatiblePackage>,
14+
dependencies: Set<PatchClass> = emptySet(),
15+
) : BytecodePatch(
16+
name = "Fix /s/ links",
17+
fingerprints = setOf(handleNavigationFingerprint, setAccessTokenFingerprint),
18+
compatiblePackages = compatiblePackages,
19+
dependencies = dependencies,
20+
) {
21+
protected abstract val integrationsClassDescriptor: String
22+
23+
protected val resolveSLinkMethod =
24+
"patchResolveSLink(Ljava/lang/String;)Z"
25+
26+
protected val setAccessTokenMethod =
27+
"patchSetAccessToken(Ljava/lang/String;)V"
28+
29+
override fun execute(context: BytecodeContext) {
30+
handleNavigationFingerprint.resultOrThrow().patchNavigationHandler(context)
31+
setAccessTokenFingerprint.resultOrThrow().patchSetAccessToken(context)
32+
}
33+
34+
/**
35+
* Patch app's navigation handler to resolve /s/ links.
36+
*
37+
* @param context The current [BytecodeContext].
38+
*
39+
*/
40+
protected abstract fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext)
41+
42+
/**
43+
* Patch access token setup in app to resolve /s/ links with an access token
44+
* in order to bypass API bans when making unauthorized requests.
45+
*
46+
* @param context The current [BytecodeContext].
47+
*/
48+
protected abstract fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext)
49+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink
2+
3+
import app.revanced.patcher.data.BytecodeContext
4+
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
5+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
6+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
7+
import app.revanced.patcher.fingerprint.MethodFingerprintResult
8+
import app.revanced.patcher.util.smali.ExternalLabel
9+
import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch
10+
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.GetOAuthAccessTokenFingerprint
11+
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.HandleNavigationFingerprint
12+
import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.IntegrationsPatch
13+
14+
@Suppress("unused")
15+
object FixSLinksPatch : BaseFixSLinksPatch(
16+
handleNavigationFingerprint = HandleNavigationFingerprint,
17+
setAccessTokenFingerprint = GetOAuthAccessTokenFingerprint,
18+
compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit")),
19+
dependencies = setOf(IntegrationsPatch::class),
20+
) {
21+
override val integrationsClassDescriptor = "Lapp/revanced/integrations/boostforreddit/FixSLinksPatch;"
22+
23+
override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) {
24+
mutableMethod.apply {
25+
val urlRegister = "p1"
26+
val tempRegister = "v1"
27+
addInstructionsWithLabels(
28+
0,
29+
"""
30+
invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod
31+
move-result $tempRegister
32+
if-eqz $tempRegister, :continue
33+
return $tempRegister
34+
""",
35+
ExternalLabel("continue", getInstruction(0)),
36+
)
37+
}
38+
}
39+
40+
override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction(
41+
3,
42+
"invoke-static { v0 }, $integrationsClassDescriptor->$setAccessTokenMethod",
43+
)
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints
2+
import app.revanced.patcher.fingerprint.MethodFingerprint
3+
import com.android.tools.smali.dexlib2.AccessFlags
4+
5+
internal object GetOAuthAccessTokenFingerprint : MethodFingerprint(
6+
strings = listOf("access_token"),
7+
accessFlags = AccessFlags.PUBLIC.value,
8+
returnType = "Ljava/lang/String",
9+
customFingerprint = { _, classDef -> classDef.type == "Lnet/dean/jraw/http/oauth/OAuthData;" },
10+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints
2+
import app.revanced.patcher.fingerprint.MethodFingerprint
3+
4+
internal object HandleNavigationFingerprint : MethodFingerprint(
5+
strings = listOf(
6+
"android.intent.action.SEARCH",
7+
"subscription",
8+
"sort",
9+
"period",
10+
"boostforreddit.com/themes",
11+
),
12+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations
2+
3+
import app.revanced.patcher.patch.annotation.Patch
4+
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
5+
import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints.InitFingerprint
6+
7+
@Patch(requiresIntegrations = true)
8+
object IntegrationsPatch : BaseIntegrationsPatch(
9+
setOf(InitFingerprint)
10+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints
2+
3+
import app.revanced.patcher.extensions.or
4+
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
5+
import com.android.tools.smali.dexlib2.AccessFlags
6+
7+
internal object InitFingerprint : IntegrationsFingerprint(
8+
customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/rubenmayayo/reddit/MyApplication;" && methodDef.name == "onCreate" },
9+
insertIndexResolver = { 1 } // Insert after call to super class.
10+
)
Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,49 @@
11
package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink
22

33
import app.revanced.patcher.data.BytecodeContext
4-
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
5-
import app.revanced.patcher.patch.BytecodePatch
6-
import app.revanced.patcher.patch.annotation.CompatiblePackage
7-
import app.revanced.patcher.patch.annotation.Patch
4+
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
5+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
6+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
7+
import app.revanced.patcher.fingerprint.MethodFingerprintResult
8+
import app.revanced.patcher.util.smali.ExternalLabel
9+
import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch
810
import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.LinkHelperOpenLinkFingerprint
9-
import app.revanced.util.exception
11+
import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.SetAuthorizationHeaderFingerprint
12+
import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.IntegrationsPatch
1013

11-
@Patch(
12-
name = "Fix /s/ links",
13-
description = "Fixes the issue where /s/ links do not work.",
14-
compatiblePackages = [
14+
@Suppress("unused")
15+
object FixSLinksPatch : BaseFixSLinksPatch(
16+
handleNavigationFingerprint = LinkHelperOpenLinkFingerprint,
17+
setAccessTokenFingerprint = SetAuthorizationHeaderFingerprint,
18+
compatiblePackages = setOf(
1519
CompatiblePackage("com.laurencedawson.reddit_sync"),
1620
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
17-
CompatiblePackage("com.laurencedawson.reddit_sync.dev")
18-
],
19-
requiresIntegrations = true
20-
)
21-
object FixSLinksPatch : BytecodePatch(
22-
setOf(LinkHelperOpenLinkFingerprint)
21+
CompatiblePackage("com.laurencedawson.reddit_sync.dev"),
22+
),
23+
dependencies = setOf(IntegrationsPatch::class),
2324
) {
24-
override fun execute(context: BytecodeContext) =
25-
LinkHelperOpenLinkFingerprint.result?.mutableMethod?.addInstructions(
26-
1,
27-
"""
28-
invoke-static { p3 }, Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;->resolveSLink(Ljava/lang/String;)Ljava/lang/String;
29-
move-result-object p3
30-
"""
31-
) ?: throw LinkHelperOpenLinkFingerprint.exception
25+
override val integrationsClassDescriptor = "Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;"
26+
27+
override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) {
28+
mutableMethod.apply {
29+
val urlRegister = "p3"
30+
val tempRegister = "v2"
31+
32+
addInstructionsWithLabels(
33+
0,
34+
"""
35+
invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod
36+
move-result $tempRegister
37+
if-eqz $tempRegister, :continue
38+
return $tempRegister
39+
""",
40+
ExternalLabel("continue", getInstruction(0)),
41+
)
42+
}
43+
}
44+
45+
override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction(
46+
0,
47+
"invoke-static { p0 }, $integrationsClassDescriptor->$setAccessTokenMethod",
48+
)
3249
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints
2+
3+
import app.revanced.patcher.fingerprint.MethodFingerprint
4+
5+
internal object SetAuthorizationHeaderFingerprint : MethodFingerprint(
6+
strings = listOf("Authorization", "bearer "),
7+
returnType = "Ljava/util/HashMap;",
8+
customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/laurencedawson/reddit_sync/singleton/a;" },
9+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations
2+
3+
import app.revanced.patcher.patch.annotation.Patch
4+
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
5+
import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.fingerprints.InitFingerprint
6+
7+
@Patch(requiresIntegrations = true)
8+
object IntegrationsPatch : BaseIntegrationsPatch(
9+
setOf(InitFingerprint)
10+
)

0 commit comments

Comments
 (0)