Skip to content

Commit

Permalink
feat(Boost For Reddit): Add Fix /s/ links patch (#3154)
Browse files Browse the repository at this point in the history
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
  • Loading branch information
OctoNezd and oSumAtrIX committed Jun 8, 2024
1 parent 2f252aa commit 5fa9fd2
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 26 deletions.
28 changes: 25 additions & 3 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,18 @@ public final class app/revanced/patches/reddit/ad/general/HideAdsPatch : app/rev
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public abstract class app/revanced/patches/reddit/customclients/BaseFixSLinksPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Ljava/util/Set;)V
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
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
protected abstract fun getIntegrationsClassDescriptor ()Ljava/lang/String;
protected final fun getResolveSLinkMethod ()Ljava/lang/String;
protected final fun getSetAccessTokenMethod ()Ljava/lang/String;
protected abstract fun patchNavigationHandler (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V
protected abstract fun patchSetAccessToken (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;Lapp/revanced/patcher/data/BytecodeContext;)V
}

public abstract class app/revanced/patches/reddit/customclients/BaseSpoofClientPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;Ljava/util/Set;)V
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
Expand Down Expand Up @@ -570,6 +582,14 @@ public final class app/revanced/patches/reddit/customclients/boostforreddit/api/
public fun patchUserAgent (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
}

public final class app/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch {
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/fix/slink/FixSLinksPatch;
}

public final class app/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/boostforreddit/misc/integrations/IntegrationsPatch;
}

public final class app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch {
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch;
public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V
Expand Down Expand Up @@ -648,10 +668,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/detec
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patcher/patch/BytecodePatch {
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch : app/revanced/patches/reddit/customclients/BaseFixSLinksPatch {
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public final class app/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch;
}

public final class app/revanced/patches/reddit/layout/disablescreenshotpopup/DisableScreenshotPopupPatch : app/revanced/patcher/patch/BytecodePatch {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package app.revanced.patches.reddit.customclients

import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.util.resultOrThrow

abstract class BaseFixSLinksPatch(
private val handleNavigationFingerprint: MethodFingerprint,
private val setAccessTokenFingerprint: MethodFingerprint,
compatiblePackages: Set<CompatiblePackage>,
dependencies: Set<PatchClass> = emptySet(),
) : BytecodePatch(
name = "Fix /s/ links",
fingerprints = setOf(handleNavigationFingerprint, setAccessTokenFingerprint),
compatiblePackages = compatiblePackages,
dependencies = dependencies,
) {
protected abstract val integrationsClassDescriptor: String

protected val resolveSLinkMethod =
"patchResolveSLink(Ljava/lang/String;)Z"

protected val setAccessTokenMethod =
"patchSetAccessToken(Ljava/lang/String;)V"

override fun execute(context: BytecodeContext) {
handleNavigationFingerprint.resultOrThrow().patchNavigationHandler(context)
setAccessTokenFingerprint.resultOrThrow().patchSetAccessToken(context)
}

/**
* Patch app's navigation handler to resolve /s/ links.
*
* @param context The current [BytecodeContext].
*
*/
protected abstract fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext)

/**
* Patch access token setup in app to resolve /s/ links with an access token
* in order to bypass API bans when making unauthorized requests.
*
* @param context The current [BytecodeContext].
*/
protected abstract fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.GetOAuthAccessTokenFingerprint
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints.HandleNavigationFingerprint
import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.IntegrationsPatch

@Suppress("unused")
object FixSLinksPatch : BaseFixSLinksPatch(
handleNavigationFingerprint = HandleNavigationFingerprint,
setAccessTokenFingerprint = GetOAuthAccessTokenFingerprint,
compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit")),
dependencies = setOf(IntegrationsPatch::class),
) {
override val integrationsClassDescriptor = "Lapp/revanced/integrations/boostforreddit/FixSLinksPatch;"

override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) {
mutableMethod.apply {
val urlRegister = "p1"
val tempRegister = "v1"
addInstructionsWithLabels(
0,
"""
invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod
move-result $tempRegister
if-eqz $tempRegister, :continue
return $tempRegister
""",
ExternalLabel("continue", getInstruction(0)),
)
}
}

override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction(
3,
"invoke-static { v0 }, $integrationsClassDescriptor->$setAccessTokenMethod",
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

internal object GetOAuthAccessTokenFingerprint : MethodFingerprint(
strings = listOf("access_token"),
accessFlags = AccessFlags.PUBLIC.value,
returnType = "Ljava/lang/String",
customFingerprint = { _, classDef -> classDef.type == "Lnet/dean/jraw/http/oauth/OAuthData;" },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint

internal object HandleNavigationFingerprint : MethodFingerprint(
strings = listOf(
"android.intent.action.SEARCH",
"subscription",
"sort",
"period",
"boostforreddit.com/themes",
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations

import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
import app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints.InitFingerprint

@Patch(requiresIntegrations = true)
object IntegrationsPatch : BaseIntegrationsPatch(
setOf(InitFingerprint)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.reddit.customclients.boostforreddit.misc.integrations.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint
import com.android.tools.smali.dexlib2.AccessFlags

internal object InitFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/rubenmayayo/reddit/MyApplication;" && methodDef.name == "onCreate" },
insertIndexResolver = { 1 } // Insert after call to super class.
)
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink

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.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.reddit.customclients.BaseFixSLinksPatch
import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.LinkHelperOpenLinkFingerprint
import app.revanced.util.exception
import app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints.SetAuthorizationHeaderFingerprint
import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.IntegrationsPatch

@Patch(
name = "Fix /s/ links",
description = "Fixes the issue where /s/ links do not work.",
compatiblePackages = [
@Suppress("unused")
object FixSLinksPatch : BaseFixSLinksPatch(
handleNavigationFingerprint = LinkHelperOpenLinkFingerprint,
setAccessTokenFingerprint = SetAuthorizationHeaderFingerprint,
compatiblePackages = setOf(
CompatiblePackage("com.laurencedawson.reddit_sync"),
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
CompatiblePackage("com.laurencedawson.reddit_sync.dev")
],
requiresIntegrations = true
)
object FixSLinksPatch : BytecodePatch(
setOf(LinkHelperOpenLinkFingerprint)
CompatiblePackage("com.laurencedawson.reddit_sync.dev"),
),
dependencies = setOf(IntegrationsPatch::class),
) {
override fun execute(context: BytecodeContext) =
LinkHelperOpenLinkFingerprint.result?.mutableMethod?.addInstructions(
1,
"""
invoke-static { p3 }, Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;->resolveSLink(Ljava/lang/String;)Ljava/lang/String;
move-result-object p3
"""
) ?: throw LinkHelperOpenLinkFingerprint.exception
override val integrationsClassDescriptor = "Lapp/revanced/integrations/syncforreddit/FixSLinksPatch;"

override fun MethodFingerprintResult.patchNavigationHandler(context: BytecodeContext) {
mutableMethod.apply {
val urlRegister = "p3"
val tempRegister = "v2"

addInstructionsWithLabels(
0,
"""
invoke-static { $urlRegister }, $integrationsClassDescriptor->$resolveSLinkMethod
move-result $tempRegister
if-eqz $tempRegister, :continue
return $tempRegister
""",
ExternalLabel("continue", getInstruction(0)),
)
}
}

override fun MethodFingerprintResult.patchSetAccessToken(context: BytecodeContext) = mutableMethod.addInstruction(
0,
"invoke-static { p0 }, $integrationsClassDescriptor->$setAccessTokenMethod",
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package app.revanced.patches.reddit.customclients.syncforreddit.fix.slink.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

internal object SetAuthorizationHeaderFingerprint : MethodFingerprint(
strings = listOf("Authorization", "bearer "),
returnType = "Ljava/util/HashMap;",
customFingerprint = { methodDef, _ -> methodDef.definingClass == "Lcom/laurencedawson/reddit_sync/singleton/a;" },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations

import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
import app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.fingerprints.InitFingerprint

@Patch(requiresIntegrations = true)
object IntegrationsPatch : BaseIntegrationsPatch(
setOf(InitFingerprint)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.reddit.customclients.syncforreddit.misc.integrations.fingerprints

import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint

internal object InitFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef, classDef ->
methodDef.name == "onCreate" && classDef.type == "Lcom/laurencedawson/reddit_sync/RedditApplication;"
},
insertIndexResolver = { 1 }, // Insert after call to super class.
)

0 comments on commit 5fa9fd2

Please sign in to comment.