From e5c112a94b878323c8d0b77406ecf5d74c03557c Mon Sep 17 00:00:00 2001 From: inotia00 Date: Tue, 28 Mar 2023 21:42:04 +0900 Subject: [PATCH] refactor(`enable-old-layout`): no longer changes the version shown in app settings --- .../fingerprints/ClientInfoFingerprint.kt | 15 ++++ .../ClientInfoParentFingerprint.kt | 8 +++ .../shared/patch/options/PatchOptions.kt | 47 ++++++++----- .../versionspoof/GeneralVersionSpoofPatch.kt | 69 +++++++++++++++++++ .../fingerprints/OldLayoutFingerprint.kt | 18 ----- .../VersionOverrideFingerprint.kt | 14 ++++ .../misc/oldlayout/patch/OldLayoutPatch.kt | 38 +++++----- .../youtube/settings/host/values/strings.xml | 3 - 8 files changed, 156 insertions(+), 56 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/GeneralVersionSpoofPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/OldLayoutFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/VersionOverrideFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoFingerprint.kt new file mode 100644 index 000000000..d287b958a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoFingerprint.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.shared.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object ClientInfoFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.OR_INT_LIT16 + ) +) diff --git a/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoParentFingerprint.kt new file mode 100644 index 000000000..0f59f4b00 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/fingerprints/ClientInfoParentFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.shared.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object ClientInfoParentFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf("Android Wear") +) diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/options/PatchOptions.kt b/src/main/kotlin/app/revanced/patches/shared/patch/options/PatchOptions.kt index 9d0858224..b11b77a70 100644 --- a/src/main/kotlin/app/revanced/patches/shared/patch/options/PatchOptions.kt +++ b/src/main/kotlin/app/revanced/patches/shared/patch/options/PatchOptions.kt @@ -24,9 +24,9 @@ class PatchOptions : ResourcePatch { companion object : OptionsContainer() { - /* - * Custom Branding Name - */ + /** + * Custom Branding Name + */ internal var YouTubeAppName: String? by option( PatchOption.StringOption( key = "YouTubeAppName", @@ -36,9 +36,9 @@ class PatchOptions : ResourcePatch { ) ) - /* - * Custom Package Name (YouTube) - */ + /** + * Custom Package Name (YouTube) + */ internal var YouTubePackageName: String? by option( PatchOption.StringOption( key = "YouTubePackageName", @@ -48,9 +48,9 @@ class PatchOptions : ResourcePatch { ) ) - /* - * Custom Package Name (YouTube Music) - */ + /** + * Custom Package Name (YouTube Music) + */ internal var MusicPackageName: String? by option( PatchOption.StringOption( key = "MusicPackageName", @@ -60,9 +60,9 @@ class PatchOptions : ResourcePatch { ) ) - /* - * Custom Speed Values - */ + /** + * Custom Speed Values + */ internal var CustomSpeedArrays: String? by option( PatchOption.StringOption( key = "CustomSpeedArrays", @@ -72,9 +72,9 @@ class PatchOptions : ResourcePatch { ) ) - /* - * Overlay Buttons Icon - */ + /** + * Overlay Buttons Icon + */ internal var OverlayButtonsIcon: String? by option( PatchOption.StringOption( key = "OverlayButtonsIcon", @@ -84,9 +84,9 @@ class PatchOptions : ResourcePatch { ) ) - /* - * Theme - */ + /** + * Theme + */ internal var darkThemeBackgroundColor: String? by option( PatchOption.StringOption( key = "darkThemeBackgroundColor", @@ -96,5 +96,16 @@ class PatchOptions : ResourcePatch { ) ) + /** + * Client Spoofing Version + */ + internal var clientSpoofVersion: String? by option( + PatchOption.StringOption( + key = "clientSpoofVersion", + default = "17.28.35", + title = "Old YouTube version to override", + description = "Type the client version to spoof when Old Layout is enabled" + ) + ) } } 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 new file mode 100644 index 000000000..942d961e1 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/patch/versionspoof/GeneralVersionSpoofPatch.kt @@ -0,0 +1,69 @@ +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.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/oldlayout/fingerprints/OldLayoutFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/OldLayoutFingerprint.kt deleted file mode 100644 index bf3a68c91..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/OldLayoutFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.revanced.patches.youtube.misc.oldlayout.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -object OldLayoutFingerprint : MethodFingerprint( - returnType = "L", - access = AccessFlags.PUBLIC or AccessFlags.STATIC, - parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.GOTO, - Opcode.CONST_STRING, - ), - strings = listOf("Unset") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/VersionOverrideFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/VersionOverrideFingerprint.kt new file mode 100644 index 000000000..e857000d4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/fingerprints/VersionOverrideFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.misc.oldlayout.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object VersionOverrideFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.IF_EQZ, + Opcode.CONST_STRING + ), + customFingerprint = { + it.definingClass.endsWith("VersionOverridePatch;") && it.name == "getVersionOverride" + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/patch/OldLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/patch/OldLayoutPatch.kt index e05798222..4a3f98bc2 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/patch/OldLayoutPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/oldlayout/patch/OldLayoutPatch.kt @@ -5,44 +5,48 @@ 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.extensions.addInstructions +import app.revanced.patcher.extensions.replaceInstruction 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.shared.annotation.YouTubeCompatibility -import app.revanced.patches.youtube.misc.oldlayout.fingerprints.OldLayoutFingerprint +import app.revanced.patches.shared.patch.options.PatchOptions +import app.revanced.patches.shared.patch.versionspoof.GeneralVersionSpoofPatch +import app.revanced.patches.youtube.misc.oldlayout.fingerprints.VersionOverrideFingerprint import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch import app.revanced.util.integrations.Constants.MISC_PATH -import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @Patch @Name("enable-old-layout") @Description("Spoof the YouTube client version to use the old layout.") -@DependsOn([SettingsPatch::class]) +@DependsOn( + [ + GeneralVersionSpoofPatch::class, + PatchOptions::class, + SettingsPatch::class + ] +) @YouTubeCompatibility @Version("0.0.1") class OldLayoutPatch : BytecodePatch( listOf( - OldLayoutFingerprint + VersionOverrideFingerprint ) ) { override fun execute(context: BytecodeContext): PatchResult { - OldLayoutFingerprint.result?.let { - val insertIndex = it.scanResult.patternScanResult!!.startIndex + GeneralVersionSpoofPatch.injectSpoof("$MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String;") - with (it.mutableMethod) { - val register = (this.implementation!!.instructions[insertIndex] as OneRegisterInstruction).registerA - addInstructions( - insertIndex + 1, """ - invoke-static {v$register}, $MISC_PATH/VersionOverridePatch;->getVersionOverride(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ - ) - } - } ?: return OldLayoutFingerprint.toErrorResult() + val clientSpoofVersion = PatchOptions.clientSpoofVersion!! + + VersionOverrideFingerprint.result?.let { + val insertIndex = it.scanResult.patternScanResult!!.endIndex + + it.mutableMethod.replaceInstruction(insertIndex, "const-string p0, \"$clientSpoofVersion\"") + + } ?: return VersionOverrideFingerprint.toErrorResult() /* * Add settings diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 8ce874701..0f913a005 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -485,9 +485,6 @@ Is it ready to submit?" Player layout "As this is still an experimental feature, there may be other unknown issues. Are you sure you want to continue though?" - "Tricks the YouTube client version to v17.28.35 to load the old layout - -In the app settings, the YouTube version may be marked as v17.28.35" "Tricks the dpi to change some layouts to phone layouts. If you enable this setting, the following features are available: