refactor: Simplify AbstractSpoofClientPatch class

This commit is contained in:
oSumAtrIX 2023-12-02 17:39:53 +01:00
parent 840b29e989
commit c003f40a65
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
10 changed files with 91 additions and 126 deletions

View File

@ -1,6 +1,7 @@
package app.revanced.patches.reddit.customclients
import app.revanced.extensions.exception
import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.MethodFingerprintResult
@ -9,14 +10,22 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
abstract class AbstractSpoofClientPatch(
redirectUri: String,
private val clientIdFingerprints: List<MethodFingerprint>,
private val userAgentFingerprints: List<MethodFingerprint>? = null,
private val miscellaneousFingerprints: List<MethodFingerprint>? = null
) : BytecodePatch(buildSet {
addAll(clientIdFingerprints)
userAgentFingerprints?.let(::addAll)
miscellaneousFingerprints?.let(::addAll)
}) {
private val miscellaneousFingerprints: Set<MethodFingerprint> = emptySet(),
private val clientIdFingerprints: Set<MethodFingerprint> = emptySet(),
private val userAgentFingerprints: Set<MethodFingerprint> = emptySet(),
compatiblePackages: Set<CompatiblePackage>,
dependencies: Set<PatchClass> = emptySet(),
) : BytecodePatch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID.",
fingerprints = buildSet {
addAll(clientIdFingerprints)
userAgentFingerprints.let(::addAll)
miscellaneousFingerprints.let(::addAll)
},
compatiblePackages = compatiblePackages,
dependencies = dependencies
) {
var clientId by stringPatchOption(
"client-id",
null,
@ -30,9 +39,9 @@ abstract class AbstractSpoofClientPatch(
)
override fun execute(context: BytecodeContext) {
fun List<MethodFingerprint>?.executePatch(
patch: List<MethodFingerprintResult>.(BytecodeContext) -> Unit
) = this?.map { it.result ?: throw it.exception }?.patch(context)
fun Set<MethodFingerprint>.executePatch(
patch: Set<MethodFingerprintResult>.(BytecodeContext) -> Unit
) = this.map { it.result ?: throw it.exception }.toSet().patch(context)
clientIdFingerprints.executePatch { patchClientId(context) }
userAgentFingerprints.executePatch { patchUserAgent(context) }
@ -46,7 +55,7 @@ abstract class AbstractSpoofClientPatch(
* @param context The current [BytecodeContext].
*
*/
abstract fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext)
open fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {}
/**
* Patch the user agent.
@ -54,8 +63,7 @@ abstract class AbstractSpoofClientPatch(
*
* @param context The current [BytecodeContext].
*/
// Not every client needs to patch the user agent.
open fun List<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {}
open fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {}
/**
* Patch miscellaneous things such as protection measures.
@ -63,6 +71,5 @@ abstract class AbstractSpoofClientPatch(
*
* @param context The current [BytecodeContext].
*/
// Not every client needs to patch miscellaneous things.
open fun List<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) {}
open fun Set<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) {}
}

View File

@ -4,27 +4,22 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.GetAuthorizationUrlFingerprint
import app.revanced.patches.reddit.customclients.baconreader.api.fingerprints.RequestTokenFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [
CompatiblePackage("com.onelouder.baconreader"),
CompatiblePackage("com.onelouder.baconreader.premium")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"http://baconreader.com/auth", listOf(GetAuthorizationUrlFingerprint, RequestTokenFingerprint)
redirectUri = "http://baconreader.com/auth",
clientIdFingerprints = setOf(GetAuthorizationUrlFingerprint, RequestTokenFingerprint),
compatiblePackages = setOf(
CompatiblePackage("com.onelouder.baconreader"),
CompatiblePackage("com.onelouder.baconreader.premium")
)
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
fun MethodFingerprintResult.patch(replacementString: String) {
val clientIdIndex = scanResult.stringsScanResult!!.matches.first().index

View File

@ -3,25 +3,20 @@ package app.revanced.patches.reddit.customclients.boostforreddit.api
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.Constants.OAUTH_USER_AGENT
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.LoginActivityOnCreateFingerprint
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [CompatiblePackage("com.rubenmayayo.reddit")]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"http://rubenmayayo.com",
clientIdFingerprints = listOf(GetClientIdFingerprint),
userAgentFingerprints = listOf(LoginActivityOnCreateFingerprint)
redirectUri = "http://rubenmayayo.com",
clientIdFingerprints = setOf(GetClientIdFingerprint),
userAgentFingerprints = setOf(LoginActivityOnCreateFingerprint),
compatiblePackages = setOf(CompatiblePackage("com.rubenmayayo.reddit"))
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
first().mutableMethod.addInstructions(
0,
"""
@ -31,7 +26,7 @@ object SpoofClientPatch : AbstractSpoofClientPatch(
)
}
override fun List<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
first().let { result ->
result.mutableMethod.apply {
val insertIndex = result.scanResult.patternScanResult!!.endIndex

View File

@ -3,8 +3,6 @@ package app.revanced.patches.reddit.customclients.infinityforreddit.api
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
@ -13,19 +11,13 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [
CompatiblePackage("ml.docilealligator.infinityforreddit")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"infinity://localhost",
clientIdFingerprints = listOf(APIUtilsFingerprint),
redirectUri = "infinity://localhost",
clientIdFingerprints = setOf(APIUtilsFingerprint),
compatiblePackages = setOf(CompatiblePackage("ml.docilealligator.infinityforreddit"))
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
first().mutableClass.methods.apply {
val getClientIdMethod = single { it.name == "getId" }.also(::remove)

View File

@ -11,10 +11,10 @@ import app.revanced.util.Utils.returnEarly
@Patch(
name = "Unlock subscription",
description = "Unlocks the subscription feature but requires a custom client ID.",
dependencies = [SpoofClientPatch::class],
compatiblePackages = [
CompatiblePackage("ml.docilealligator.infinityforreddit")
]
],
dependencies = [SpoofClientPatch::class]
)
@Suppress("unused")
object UnlockSubscriptionPatch : BytecodePatch(

View File

@ -3,28 +3,23 @@ package app.revanced.patches.reddit.customclients.joeyforreddit.api
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.joeyforreddit.api.fingerprints.GetClientIdFingerprint
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.DisablePiracyDetectionPatch
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
dependencies = [DisablePiracyDetectionPatch::class],
compatiblePackages = [
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
redirectUri = "https://127.0.0.1:65023/authorize_callback",
clientIdFingerprints = setOf(GetClientIdFingerprint),
compatiblePackages = setOf(
CompatiblePackage("o.o.joey"),
CompatiblePackage("o.o.joey.pro"),
CompatiblePackage("o.o.joey.dev")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"https://127.0.0.1:65023/authorize_callback", listOf(GetClientIdFingerprint)
),
dependencies = setOf(DisablePiracyDetectionPatch::class)
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
first().mutableMethod.addInstructions(
0,
"""

View File

@ -6,29 +6,24 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.fingerprint.MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult.StringMatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BasicAuthorizationFingerprint
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.BuildAuthorizationStringFingerprint
import app.revanced.patches.reddit.customclients.redditisfun.api.fingerprints.GetUserAgentFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [
CompatiblePackage("com.andrewshu.android.reddit"),
CompatiblePackage("com.andrewshu.android.redditdonation")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"redditisfun://auth",
listOf(BuildAuthorizationStringFingerprint, BasicAuthorizationFingerprint),
listOf(GetUserAgentFingerprint)
redirectUri = "redditisfun://auth",
clientIdFingerprints = setOf(BuildAuthorizationStringFingerprint, BasicAuthorizationFingerprint),
userAgentFingerprints = setOf(GetUserAgentFingerprint),
compatiblePackages = setOf(
CompatiblePackage("com.andrewshu.android.reddit"),
CompatiblePackage("com.andrewshu.android.redditdonation")
)
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
/**
* Replaces a one register instruction with a const-string instruction
* at the index returned by [getReplacementIndex].
@ -54,7 +49,7 @@ object SpoofClientPatch : AbstractSpoofClientPatch(
last().replaceWith("$clientId:") { last().index + 7 }
}
override fun List<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
// Use a random user agent.
val randomName = (0..100000).random()
val userAgent = "android:app.revanced.$randomName:v1.0.0 (by /u/revanced)"

View File

@ -5,8 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.relayforreddit.api.fingerprints.*
import com.android.tools.smali.dexlib2.Opcode
@ -14,29 +12,26 @@ import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [
CompatiblePackage("free.reddit.news"),
CompatiblePackage("reddit.news")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"dbrady://relay",
listOf(
redirectUri = "dbrady://relay",
miscellaneousFingerprints = setOf(
SetRemoteConfigFingerprint,
RedditCheckDisableAPIFingerprint
),
clientIdFingerprints = setOf(
LoginActivityClientIdFingerprint,
GetLoggedInBearerTokenFingerprint,
GetLoggedOutBearerTokenFingerprint,
GetRefreshTokenFingerprint
),
miscellaneousFingerprints = listOf(
SetRemoteConfigFingerprint,
RedditCheckDisableAPIFingerprint
compatiblePackages = setOf(
CompatiblePackage("free.reddit.news"),
CompatiblePackage("reddit.news")
)
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
forEach {
val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.apply {
@ -50,7 +45,7 @@ object SpoofClientPatch : AbstractSpoofClientPatch(
}
}
override fun List<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) {
// Do not load remote config which disables OAuth login remotely.
first().mutableMethod.addInstructions(0, "return-void")

View File

@ -3,21 +3,17 @@ package app.revanced.patches.reddit.customclients.slide.api
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints.GetClientIdFingerprint
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
compatiblePackages = [CompatiblePackage("me.ccrama.redditslide")]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"http://www.ccrama.me", listOf(GetClientIdFingerprint)
redirectUri = "http://www.ccrama.me",
clientIdFingerprints = setOf(GetClientIdFingerprint),
compatiblePackages = setOf(CompatiblePackage("me.ccrama.redditslide"))
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
first().mutableMethod.addInstructions(
0,
"""

View File

@ -6,8 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprintResult
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.reddit.customclients.AbstractSpoofClientPatch
import app.revanced.patches.reddit.customclients.Constants.OAUTH_USER_AGENT
import app.revanced.patches.reddit.customclients.syncforreddit.api.fingerprints.GetAuthorizationStringFingerprint
@ -20,24 +18,21 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import java.util.*
@Patch(
name = "Spoof client",
description = "Restores functionality of the app by using custom client ID's.",
dependencies = [DisablePiracyDetectionPatch::class],
compatiblePackages = [
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
redirectUri = "http://redditsync/auth",
miscellaneousFingerprints = setOf(ImgurImageAPIFingerprint),
clientIdFingerprints = setOf(GetAuthorizationStringFingerprint),
userAgentFingerprints = setOf(LoadBrowserURLFingerprint),
compatiblePackages = setOf(
CompatiblePackage("com.laurencedawson.reddit_sync"),
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
CompatiblePackage("com.laurencedawson.reddit_sync.dev")
]
)
@Suppress("unused")
object SpoofClientPatch : AbstractSpoofClientPatch(
"http://redditsync/auth",
clientIdFingerprints = listOf(GetAuthorizationStringFingerprint),
userAgentFingerprints = listOf(LoadBrowserURLFingerprint),
miscellaneousFingerprints = listOf(ImgurImageAPIFingerprint)
),
dependencies = setOf(DisablePiracyDetectionPatch::class)
) {
override fun List<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchClientId(context: BytecodeContext) {
forEach { fingerprintResult ->
fingerprintResult.also { result ->
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
@ -73,7 +68,7 @@ object SpoofClientPatch : AbstractSpoofClientPatch(
}
// Use the non-commercial Imgur API endpoint.
override fun List<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) = first().let {
override fun Set<MethodFingerprintResult>.patchMiscellaneous(context: BytecodeContext) = first().let {
val apiUrlIndex = it.scanResult.stringsScanResult!!.matches.first().index
it.mutableMethod.replaceInstruction(
@ -82,7 +77,7 @@ object SpoofClientPatch : AbstractSpoofClientPatch(
)
}
override fun List<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
override fun Set<MethodFingerprintResult>.patchUserAgent(context: BytecodeContext) {
first().let { result ->
val insertIndex = result.scanResult.patternScanResult!!.startIndex