From 9efd7904acc6dc70f45c6c0f835c839473d9205f Mon Sep 17 00:00:00 2001 From: johnconner122 <107796137+johnconner122@users.noreply.github.com> Date: Sat, 24 Jun 2023 05:55:46 +0500 Subject: [PATCH] feat(infinityforreddit): add `change-oauth-client-id` patch (#2452) Co-authored-by: oSumAtrIX --- .../AbstractChangeOAuthClientIdPatch.kt | 12 +++-- .../api/patch/ChangeOAuthClientIdPatch.kt | 21 ++++---- .../AbstractClientIdFingerprint.kt | 12 +++++ .../GetHTTPBasicAuthHeaderFingerprint.kt | 6 +++ .../LoginActivityOnCreateFingerprint.kt | 6 +++ .../api/patch/ChangeOAuthClientIdPatch.kt | 43 +++++++++++++++ .../api/patch/ChangeOAuthClientIdPatch.kt | 52 ++++++++++--------- 7 files changed, 112 insertions(+), 40 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt index 27bc8842a..75607e794 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/AbstractChangeOAuthClientIdPatch.kt @@ -1,19 +1,21 @@ package app.revanced.patches.reddit.customclients import android.os.Environment +import app.revanced.extensions.toErrorResult import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.* import java.io.File abstract class AbstractChangeOAuthClientIdPatch( private val redirectUri: String, private val options: ChangeOAuthClientIdOptionsContainer, - private val fingerprint: MethodFingerprint, -) : BytecodePatch(listOf(fingerprint)) { + private val fingerprints: List +) : BytecodePatch(fingerprints) { override fun execute(context: BytecodeContext): PatchResult { if (options.clientId == null) { - // Test if on Android + // Ensure device runs Android. try { Class.forName("android.os.Environment") } catch (e: ClassNotFoundException) { @@ -36,10 +38,10 @@ abstract class AbstractChangeOAuthClientIdPatch( }.let { options.clientId = it.readText().trim() } } - return fingerprint.patch(context) + return fingerprints.map { it.result ?: throw it.toErrorResult() }.patch(context) } - abstract fun MethodFingerprint.patch(context: BytecodeContext): PatchResult + abstract fun List.patch(context: BytecodeContext): PatchResult companion object Options { open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() { diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt index 1f8004d1d..d6c286d6a 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/boostforreddit/api/patch/ChangeOAuthClientIdPatch.kt @@ -1,10 +1,9 @@ package app.revanced.patches.reddit.customclients.boostforreddit.api.patch -import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.* import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.Patch @@ -19,16 +18,18 @@ import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( "http://rubenmayayo.com", Options, - GetClientIdFingerprint + listOf(GetClientIdFingerprint) ) { - override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult { - result?.mutableMethod?.addInstructions( - 0, - """ - const-string v0, "$clientId" - return-object v0 + override fun List.patch(context: BytecodeContext): PatchResult { + forEach { + it.mutableMethod.addInstructions( + 0, """ - ) ?: return toErrorResult() + const-string v0, "$clientId" + return-object v0 + """ + ) + } return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt new file mode 100644 index 000000000..9099dfefa --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/AbstractClientIdFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +abstract class AbstractClientIdFingerprint(classTypeSuffix: String, methodName: String) : MethodFingerprint( + strings = listOf("NOe2iKrPPzwscA"), + customFingerprint = custom@{ methodDef, classDef -> + if (!classDef.type.endsWith(classTypeSuffix)) return@custom false + + methodDef.name == methodName + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt new file mode 100644 index 000000000..3bff5626c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/GetHTTPBasicAuthHeaderFingerprint.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints + +object GetHTTPBasicAuthHeaderFingerprint : AbstractClientIdFingerprint( + "APIUtils;", + "getHTTPBasicAuthHeader" +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt new file mode 100644 index 000000000..740fd318d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/fingerprints/LoginActivityOnCreateFingerprint.kt @@ -0,0 +1,6 @@ +package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints + +object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint( + "LoginActivity;", + "onCreate" +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt new file mode 100644 index 000000000..ac6d76d3b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/patch/ChangeOAuthClientIdPatch.kt @@ -0,0 +1,43 @@ +package app.revanced.patches.reddit.customclients.infinityforreddit.api.patch + +import app.revanced.patcher.annotation.* +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.method.impl.MethodFingerprintResult +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.reddit.customclients.AbstractChangeOAuthClientIdPatch +import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.GetHTTPBasicAuthHeaderFingerprint +import app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints.LoginActivityOnCreateFingerprint +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch +@Name("change-oauth-client-id") +@Description("Changes the OAuth client ID.") +@Compatibility([Package("ml.docilealligator.infinityforreddit")]) +@Version("0.0.1") +class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( + "infinity://localhost", + Options, + listOf(GetHTTPBasicAuthHeaderFingerprint, LoginActivityOnCreateFingerprint) +) { + override fun List.patch(context: BytecodeContext): PatchResult { + forEach { + val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index + it.mutableMethod.apply { + val oAuthClientIdRegister = getInstruction(clientIdIndex).registerA + + replaceInstruction( + clientIdIndex, + "const-string v$oAuthClientIdRegister, \"$clientId\"" + ) + } + } + + return PatchResultSuccess() + } + + companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer() +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt index e7ceb004d..0446445b4 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/api/patch/ChangeOAuthClientIdPatch.kt @@ -27,39 +27,41 @@ import java.util.* class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch( "http://redditsync/auth", Options, - GetAuthorizationStringFingerprint, + listOf(GetAuthorizationStringFingerprint) ) { - override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult { - result?.also { result -> - GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply { - val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8)) - addInstructions( - 0, - """ + override fun List.patch(context: BytecodeContext): PatchResult { + map { it.result ?: return it.toErrorResult() }.forEach { fingerprintResult -> + fingerprintResult.also { result -> + GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply { + val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8)) + addInstructions( + 0, + """ const-string v0, "Basic $auth" return-object v0 """ - ) - } ?: return GetBearerTokenFingerprint.toErrorResult() - }?.let { - val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index + ) + } ?: return GetBearerTokenFingerprint.toErrorResult() + }.let { + val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index - it.mutableMethod.apply { - val authorizationStringInstruction = getInstruction(occurrenceIndex) - val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA - val reference = authorizationStringInstruction.reference as StringReference + it.mutableMethod.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&" - ) + val newAuthorizationUrl = reference.string.replace( + "client_id=.*?&".toRegex(), + "client_id=$clientId&" + ) - replaceInstruction( - occurrenceIndex, - "const-string v$targetRegister, \"$newAuthorizationUrl\"" - ) + replaceInstruction( + occurrenceIndex, + "const-string v$targetRegister, \"$newAuthorizationUrl\"" + ) + } } - } ?: return toErrorResult() + } return PatchResultSuccess() }