feat(infinityforreddit): add change-oauth-client-id
patch (#2452)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
8a6c5c3a31
commit
9efd7904ac
|
@ -1,19 +1,21 @@
|
||||||
package app.revanced.patches.reddit.customclients
|
package app.revanced.patches.reddit.customclients
|
||||||
|
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import app.revanced.extensions.toErrorResult
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||||
import app.revanced.patcher.patch.*
|
import app.revanced.patcher.patch.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractChangeOAuthClientIdPatch(
|
abstract class AbstractChangeOAuthClientIdPatch(
|
||||||
private val redirectUri: String,
|
private val redirectUri: String,
|
||||||
private val options: ChangeOAuthClientIdOptionsContainer,
|
private val options: ChangeOAuthClientIdOptionsContainer,
|
||||||
private val fingerprint: MethodFingerprint,
|
private val fingerprints: List<MethodFingerprint>
|
||||||
) : BytecodePatch(listOf(fingerprint)) {
|
) : BytecodePatch(fingerprints) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
if (options.clientId == null) {
|
if (options.clientId == null) {
|
||||||
// Test if on Android
|
// Ensure device runs Android.
|
||||||
try {
|
try {
|
||||||
Class.forName("android.os.Environment")
|
Class.forName("android.os.Environment")
|
||||||
} catch (e: ClassNotFoundException) {
|
} catch (e: ClassNotFoundException) {
|
||||||
|
@ -36,10 +38,10 @@ abstract class AbstractChangeOAuthClientIdPatch(
|
||||||
}.let { options.clientId = it.readText().trim() }
|
}.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<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult
|
||||||
|
|
||||||
companion object Options {
|
companion object Options {
|
||||||
open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() {
|
open class ChangeOAuthClientIdOptionsContainer : OptionsContainer() {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package app.revanced.patches.reddit.customclients.boostforreddit.api.patch
|
package app.revanced.patches.reddit.customclients.boostforreddit.api.patch
|
||||||
|
|
||||||
import app.revanced.extensions.toErrorResult
|
|
||||||
import app.revanced.patcher.annotation.*
|
import app.revanced.patcher.annotation.*
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
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.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
@ -19,16 +18,18 @@ import app.revanced.patches.reddit.customclients.boostforreddit.api.fingerprints
|
||||||
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
|
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
|
||||||
"http://rubenmayayo.com",
|
"http://rubenmayayo.com",
|
||||||
Options,
|
Options,
|
||||||
GetClientIdFingerprint
|
listOf(GetClientIdFingerprint)
|
||||||
) {
|
) {
|
||||||
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
|
override fun List<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
|
||||||
result?.mutableMethod?.addInstructions(
|
forEach {
|
||||||
0,
|
it.mutableMethod.addInstructions(
|
||||||
"""
|
0,
|
||||||
const-string v0, "$clientId"
|
|
||||||
return-object v0
|
|
||||||
"""
|
"""
|
||||||
) ?: return toErrorResult()
|
const-string v0, "$clientId"
|
||||||
|
return-object v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
)
|
|
@ -0,0 +1,6 @@
|
||||||
|
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
|
||||||
|
|
||||||
|
object GetHTTPBasicAuthHeaderFingerprint : AbstractClientIdFingerprint(
|
||||||
|
"APIUtils;",
|
||||||
|
"getHTTPBasicAuthHeader"
|
||||||
|
)
|
|
@ -0,0 +1,6 @@
|
||||||
|
package app.revanced.patches.reddit.customclients.infinityforreddit.api.fingerprints
|
||||||
|
|
||||||
|
object LoginActivityOnCreateFingerprint : AbstractClientIdFingerprint(
|
||||||
|
"LoginActivity;",
|
||||||
|
"onCreate"
|
||||||
|
)
|
|
@ -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<MethodFingerprintResult>.patch(context: BytecodeContext): PatchResult {
|
||||||
|
forEach {
|
||||||
|
val clientIdIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
||||||
|
it.mutableMethod.apply {
|
||||||
|
val oAuthClientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||||
|
|
||||||
|
replaceInstruction(
|
||||||
|
clientIdIndex,
|
||||||
|
"const-string v$oAuthClientIdRegister, \"$clientId\""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object Options : AbstractChangeOAuthClientIdPatch.Options.ChangeOAuthClientIdOptionsContainer()
|
||||||
|
}
|
|
@ -27,39 +27,41 @@ import java.util.*
|
||||||
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
|
class ChangeOAuthClientIdPatch : AbstractChangeOAuthClientIdPatch(
|
||||||
"http://redditsync/auth",
|
"http://redditsync/auth",
|
||||||
Options,
|
Options,
|
||||||
GetAuthorizationStringFingerprint,
|
listOf(GetAuthorizationStringFingerprint)
|
||||||
) {
|
) {
|
||||||
override fun MethodFingerprint.patch(context: BytecodeContext): PatchResult {
|
override fun List<MethodFingerprint>.patch(context: BytecodeContext): PatchResult {
|
||||||
result?.also { result ->
|
map { it.result ?: return it.toErrorResult() }.forEach { fingerprintResult ->
|
||||||
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
|
fingerprintResult.also { result ->
|
||||||
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
|
GetBearerTokenFingerprint.also { it.resolve(context, result.classDef) }.result?.mutableMethod?.apply {
|
||||||
addInstructions(
|
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
|
||||||
0,
|
addInstructions(
|
||||||
"""
|
0,
|
||||||
|
"""
|
||||||
const-string v0, "Basic $auth"
|
const-string v0, "Basic $auth"
|
||||||
return-object v0
|
return-object v0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
} ?: return GetBearerTokenFingerprint.toErrorResult()
|
} ?: return GetBearerTokenFingerprint.toErrorResult()
|
||||||
}?.let {
|
}.let {
|
||||||
val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
val occurrenceIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
||||||
|
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
|
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
|
||||||
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
|
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
|
||||||
val reference = authorizationStringInstruction.reference as StringReference
|
val reference = authorizationStringInstruction.reference as StringReference
|
||||||
|
|
||||||
val newAuthorizationUrl = reference.string.replace(
|
val newAuthorizationUrl = reference.string.replace(
|
||||||
"client_id=.*?&".toRegex(),
|
"client_id=.*?&".toRegex(),
|
||||||
"client_id=$clientId&"
|
"client_id=$clientId&"
|
||||||
)
|
)
|
||||||
|
|
||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
occurrenceIndex,
|
occurrenceIndex,
|
||||||
"const-string v$targetRegister, \"$newAuthorizationUrl\""
|
"const-string v$targetRegister, \"$newAuthorizationUrl\""
|
||||||
)
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} ?: return toErrorResult()
|
}
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue