From fcce0a6948577afa13b4e8bfc66540e300eb6f3b Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Mon, 12 Jan 2026 17:01:25 +0700 Subject: [PATCH] refactor(syncforreddit): SpoofClientPatch --- .../sync/syncforreddit/api/Fingerprints.kt | 19 ++---- .../syncforreddit/api/SpoofClientPatch.kt | 59 +++++++++++-------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt index c7902b1f4..1d2ff2bad 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/Fingerprints.kt @@ -1,19 +1,12 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.api -import app.revanced.patcher.fingerprint +import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.patch.BytecodePatchContext -internal val getAuthorizationStringFingerprint = fingerprint { - strings("authorize.compact?client_id") -} +internal val BytecodePatchContext.getAuthorizationStringMethod by gettingFirstMutableMethodDeclaratively("authorize.compact?client_id") -internal val getBearerTokenFingerprint = fingerprint { - strings("Basic") -} +internal val BytecodePatchContext.getBearerTokenMethod by gettingFirstMutableMethodDeclaratively("Basic") -internal val getUserAgentFingerprint = fingerprint { - strings("android:com.laurencedawson.reddit_sync") -} +internal val BytecodePatchContext.getUserAgentMethod by gettingFirstMutableMethodDeclaratively("android:com.laurencedawson.reddit_sync") -internal val imgurImageAPIFingerprint = fingerprint { - strings("https://imgur-apiv3.p.rapidapi.com/3/image") -} +internal val BytecodePatchContext.imgurImageAPIMethod by gettingFirstMutableMethodDeclaratively("https://imgur-apiv3.p.rapidapi.com/3/image") diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt index 2b00e2051..469ca5086 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt @@ -3,19 +3,22 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.api import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patches.reddit.customclients.`Spoof client` -import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch +import app.revanced.patches.reddit.customclients.sync.detection.piracy.`Disable piracy detection` import app.revanced.patches.shared.misc.string.replaceStringPatch +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.returnEarly +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.StringReference import java.util.Base64 +@Suppress("unused") val spoofClientPatch = `Spoof client`( redirectUri = "http://redditsync/auth", ) { clientIdOption -> dependsOn( - disablePiracyDetectionPatch, + `Disable piracy detection`, // Redirects from SSL to WWW domain are bugged causing auth problems. // Manually rewrite the URLs to fix this. replaceStringPatch("ssl.reddit.com", "www.reddit.com") @@ -32,28 +35,30 @@ val spoofClientPatch = `Spoof client`( apply { // region Patch client id. - getBearerTokenFingerprint.match(getAuthorizationStringFingerprint.originalClassDef).method.apply { + getBearerTokenMethod.apply { val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8)) returnEarly("Basic $auth") + } - val occurrenceIndex = - getAuthorizationStringFingerprint.stringMatches.first().index - - getAuthorizationStringFingerprint.method.apply { - val authorizationStringInstruction = getInstruction(occurrenceIndex) - val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA - val reference = authorizationStringInstruction.reference as StringReference - - val newAuthorizationUrl = reference.string.replace( - "client_id=.*?&".toRegex(), - "client_id=$clientId&", - ) - - replaceInstruction( - occurrenceIndex, - "const-string v$targetRegister, \"$newAuthorizationUrl\"", - ) + getAuthorizationStringMethod.apply { + val occurrenceIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.CONST_STRING && + getReference()?.string?.contains("client_id=") == true } + + val authorizationStringInstruction = getInstruction(occurrenceIndex) + val targetRegister = authorizationStringInstruction.registerA + val reference = authorizationStringInstruction.getReference()!! + + val newAuthorizationUrl = reference.string.replace( + "client_id=.*?&".toRegex(), + "client_id=$clientId&", + ) + + replaceInstruction( + occurrenceIndex, + "const-string v$targetRegister, \"$newAuthorizationUrl\"", + ) } // endregion @@ -64,15 +69,19 @@ val spoofClientPatch = `Spoof client`( val randomName = (0..100000).random() val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)" - getUserAgentFingerprint.method.returnEarly(userAgent) + getUserAgentMethod.returnEarly(userAgent) // endregion // region Patch Imgur API URL. - imgurImageAPIFingerprint.let { - val apiUrlIndex = it.stringMatches.first().index - it.method.replaceInstruction( + imgurImageAPIMethod.apply { + val apiUrlIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.CONST_STRING && + getReference()?.string == "https://api.imgur.com/3/image" + } + + replaceInstruction( apiUrlIndex, "const-string v1, \"https://api.imgur.com/3/image\"", )