refactor(relayforreddit): SpoofClientPatch

This commit is contained in:
Pun Butrach 2026-01-12 16:29:36 +07:00
parent 8dfcbd09cc
commit decd7cb23c
2 changed files with 45 additions and 35 deletions

View file

@ -1,27 +1,32 @@
package app.revanced.patches.reddit.customclients.relayforreddit.api package app.revanced.patches.reddit.customclients.relayforreddit.api
import app.revanced.patcher.fingerprint import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.instructions
import app.revanced.patcher.invoke
import app.revanced.patcher.parameterTypes
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
internal fun baseClientIdFingerprint(string: String) = fingerprint { internal val BytecodePatchContext.getLoggedInBearerTokenMethod by gettingFirstMutableMethodDeclaratively(
strings("dj-xCIZQYiLbEg", string) "dj-xCIZQYiLbEg", "authorization_code"
)
internal val BytecodePatchContext.getLoggedOutBearerTokenMethod by gettingFirstMutableMethodDeclaratively(
"dj-xCIZQYiLbEg", "https://oauth.reddit.com/grants/installed_client"
)
internal val BytecodePatchContext.getRefreshTokenMethod by gettingFirstMutableMethodDeclaratively(
"dj-xCIZQYiLbEg", "refresh_token"
)
internal val BytecodePatchContext.loginActivityClientIdMethod by gettingFirstMutableMethodDeclaratively(
"dj-xCIZQYiLbEg", "&duration=permanent"
)
internal val BytecodePatchContext.redditCheckDisableAPIMethod by gettingFirstMutableMethodDeclaratively("Reddit Disabled") {
instructions(Opcode.IF_EQZ())
} }
internal val getLoggedInBearerTokenFingerprint = baseClientIdFingerprint("authorization_code") internal val BytecodePatchContext.setRemoteConfigMethod by gettingFirstMutableMethodDeclaratively("reddit_oauth_url") {
parameterTypes("Lcom/google/firebase/remoteconfig/FirebaseRemoteConfig;")
internal val getLoggedOutBearerTokenFingerprint = baseClientIdFingerprint("https://oauth.reddit.com/grants/installed_client")
internal val getRefreshTokenFingerprint = baseClientIdFingerprint("refresh_token")
internal val loginActivityClientIdFingerprint = baseClientIdFingerprint("&duration=permanent")
internal val redditCheckDisableAPIFingerprint = fingerprint {
opcodes(Opcode.IF_EQZ)
strings("Reddit Disabled")
} }
internal val setRemoteConfigFingerprint = fingerprint {
parameters("Lcom/google/firebase/remoteconfig/FirebaseRemoteConfig;")
strings("reddit_oauth_url")
}

View file

@ -4,33 +4,39 @@ import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.extensions.getInstruction
import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patches.reddit.customclients.spoofClientPatch import app.revanced.patches.reddit.customclients.spoofClientPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") { @Suppress("unused")
val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") { clientIdOption ->
compatibleWith( compatibleWith(
"free.reddit.news", "free.reddit.news",
"reddit.news", "reddit.news",
) )
val clientId by it val clientId by clientIdOption
apply { apply {
// region Patch client id. // region Patch client id.
setOf( listOf(
loginActivityClientIdFingerprint, loginActivityClientIdMethod,
getLoggedInBearerTokenFingerprint, getLoggedInBearerTokenMethod,
getLoggedOutBearerTokenFingerprint, getLoggedOutBearerTokenMethod,
getRefreshTokenFingerprint, getRefreshTokenMethod,
).forEach { fingerprint -> ).forEach { method ->
val clientIdIndex = fingerprint.stringMatches.first().index method.apply {
fingerprint.method.apply { val clientIdIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == "dj-xCIZQYiLbEg"
}
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
fingerprint.method.replaceInstruction( replaceInstruction(
clientIdIndex, clientIdIndex,
"const-string v$clientIdRegister, \"$clientId\"", "const-string v$clientIdRegister, \"$clientId\"",
) )
@ -42,12 +48,11 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") {
// region Patch miscellaneous. // region Patch miscellaneous.
// Do not load remote config which disables OAuth login remotely. // Do not load remote config which disables OAuth login remotely.
setRemoteConfigFingerprint.method.addInstructions(0, "return-void") setRemoteConfigMethod.addInstructions(0, "return-void")
// Prevent OAuth login being disabled remotely. // Prevent OAuth login being disabled remotely.
val checkIsOAuthRequestIndex = redditCheckDisableAPIFingerprint.instructionMatches.first().index redditCheckDisableAPIMethod.apply {
val checkIsOAuthRequestIndex = indexOfFirstInstructionOrThrow(Opcode.IF_EQZ)
redditCheckDisableAPIFingerprint.method.apply {
val returnNextChain = getInstruction<BuilderInstruction21t>(checkIsOAuthRequestIndex).target val returnNextChain = getInstruction<BuilderInstruction21t>(checkIsOAuthRequestIndex).target
replaceInstruction(checkIsOAuthRequestIndex, BuilderInstruction10t(Opcode.GOTO, returnNextChain)) replaceInstruction(checkIsOAuthRequestIndex, BuilderInstruction10t(Opcode.GOTO, returnNextChain))
} }