diff --git a/src/main/kotlin/app/revanced/patches/music/misc/versionspoof/patch/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/versionspoof/patch/SpoofAppVersionPatch.kt index d627eaef7..891923ec6 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/versionspoof/patch/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/versionspoof/patch/SpoofAppVersionPatch.kt @@ -4,33 +4,27 @@ import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.music.utils.settings.resource.patch.MusicSettingsPatch import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility -import app.revanced.patches.shared.patch.versionspoof.GeneralVersionSpoofPatch +import app.revanced.patches.shared.patch.versionspoof.AbstractVersionSpoofPatch import app.revanced.util.enum.CategoryType import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH @Patch @Name("spoof-app-version") @Description("Spoof the YouTube Music client version.") -@DependsOn( - [ - GeneralVersionSpoofPatch::class, - MusicSettingsPatch::class - ] -) +@DependsOn([MusicSettingsPatch::class]) @YouTubeMusicCompatibility @Version("0.0.1") -class SpoofAppVersionPatch : BytecodePatch() { +class SpoofAppVersionPatch : AbstractVersionSpoofPatch( + "$MUSIC_MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" +) { override fun execute(context: BytecodeContext): PatchResult { - GeneralVersionSpoofPatch.injectSpoof("$MUSIC_MISC_PATH/SpoofAppVersionPatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;") - MusicSettingsPatch.addMusicPreference(CategoryType.MISC, "revanced_spoof_app_version", "false") return PatchResultSuccess() diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/AbstractVersionSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/AbstractVersionSpoofPatch.kt new file mode 100644 index 000000000..9672d5a8c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/AbstractVersionSpoofPatch.kt @@ -0,0 +1,60 @@ +package app.revanced.patches.shared.patch.versionspoof + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patches.shared.fingerprints.ClientInfoFingerprint +import app.revanced.patches.shared.fingerprints.ClientInfoParentFingerprint +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference +import org.jf.dexlib2.iface.instruction.OneRegisterInstruction +import org.jf.dexlib2.iface.instruction.ReferenceInstruction + +@Name("abstract-version-spoof") +@Version("0.0.1") +abstract class AbstractVersionSpoofPatch( + private val descriptor: String +) : BytecodePatch( + listOf(ClientInfoParentFingerprint) +) { + override fun execute(context: BytecodeContext): PatchResult { + + ClientInfoParentFingerprint.result?.let { parentResult -> + ClientInfoFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let { + it.apply { + var insertIndex = 0 + val insertInstructions = implementation!!.instructions + val targetString = "Landroid/os/Build\$VERSION;->RELEASE:Ljava/lang/String;" + + for ((index, instruction) in insertInstructions.withIndex()) { + if (instruction.opcode != Opcode.SGET_OBJECT) continue + + val indexString = ((instruction as? ReferenceInstruction)?.reference as? DexBackedFieldReference).toString() + + if (indexString != targetString) continue + + val targetRegister = (instruction as OneRegisterInstruction).registerA + insertIndex = index - 1 + + addInstructions( + insertIndex, """ + invoke-static {v$targetRegister}, $descriptor + move-result-object v$targetRegister + """ + ) + break + } + if (insertIndex <= 0) return ClientInfoFingerprint.toErrorResult() + } + } ?: return ClientInfoFingerprint.toErrorResult() + } ?: return ClientInfoParentFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/GeneralVersionSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/GeneralVersionSpoofPatch.kt deleted file mode 100644 index c3ac231be..000000000 --- a/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/GeneralVersionSpoofPatch.kt +++ /dev/null @@ -1,69 +0,0 @@ -package app.revanced.patches.shared.patch.versionspoof - -import app.revanced.extensions.toErrorResult -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import app.revanced.patches.shared.fingerprints.ClientInfoFingerprint -import app.revanced.patches.shared.fingerprints.ClientInfoParentFingerprint -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction -import org.jf.dexlib2.iface.instruction.ReferenceInstruction -import kotlin.properties.Delegates - -@Name("general-version-spoof") -@Version("0.0.1") -class GeneralVersionSpoofPatch : BytecodePatch( - listOf( - ClientInfoParentFingerprint - ) -) { - override fun execute(context: BytecodeContext): PatchResult { - - ClientInfoParentFingerprint.result?.let { parentResult -> - ClientInfoFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let { - val insertInstructions = it.implementation!!.instructions - val targetString = "Landroid/os/Build\$VERSION;->RELEASE:Ljava/lang/String;" - - for ((index, instruction) in insertInstructions.withIndex()) { - if (instruction.opcode != Opcode.SGET_OBJECT) continue - - val indexString = ((instruction as? ReferenceInstruction)?.reference as? DexBackedFieldReference).toString() - - if (indexString != targetString) continue - - insertMethod = it - insertIndex = index - 1 - targetRegister = (instruction as OneRegisterInstruction).registerA - break - } - if (insertIndex <= 0) return ClientInfoFingerprint.toErrorResult() - } ?: return ClientInfoFingerprint.toErrorResult() - } ?: return ClientInfoParentFingerprint.toErrorResult() - - return PatchResultSuccess() - } - - companion object { - private var insertIndex by Delegates.notNull() - private var targetRegister by Delegates.notNull() - private lateinit var insertMethod: MutableMethod - - - fun injectSpoof(methodDescriptor: String) { - insertMethod.addInstructions( - insertIndex, """ - invoke-static {v$targetRegister}, $methodDescriptor - move-result-object v$targetRegister - """ - ) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/patch/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/patch/SpoofAppVersionPatch.kt index a4e2a8870..12f95ffc3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/patch/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/spoofappversion/patch/SpoofAppVersionPatch.kt @@ -3,38 +3,34 @@ package app.revanced.patches.youtube.misc.spoofappversion.patch import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version -import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.shared.annotation.YouTubeCompatibility -import app.revanced.patches.shared.patch.versionspoof.GeneralVersionSpoofPatch +import app.revanced.patches.shared.patch.versionspoof.AbstractVersionSpoofPatch import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch +import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch.Companion.contexts import app.revanced.util.integrations.Constants.MISC_PATH import app.revanced.util.resources.ResourceUtils.copyXmlNode @Patch @Name("spoof-app-version") @Description("Tricks YouTube into thinking, you are running an older version of the app. One of the side effects also includes restoring the old UI.") -@DependsOn( - [ - GeneralVersionSpoofPatch::class, - SettingsPatch::class - ] -) +@DependsOn([SettingsPatch::class]) @YouTubeCompatibility @Version("0.0.1") -class SpoofAppVersionPatch : ResourcePatch { - override fun execute(context: ResourceContext): PatchResult { - - GeneralVersionSpoofPatch.injectSpoof("$MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;") +class SpoofAppVersionPatch : AbstractVersionSpoofPatch( + "$MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;" +) { + override fun execute(context: BytecodeContext): PatchResult { + super.execute(context) /** * Copy arrays */ - context.copyXmlNode("youtube/spoofappversion/host", "values/arrays.xml", "resources") + contexts.copyXmlNode("youtube/spoofappversion/host", "values/arrays.xml", "resources") /** * Add settings