From 6ae2b86cb1170f8f801b59efbe738b14adfb11bb Mon Sep 17 00:00:00 2001 From: inotia00 Date: Sun, 29 Jan 2023 11:43:58 +0900 Subject: [PATCH] add `force-vp9-codec` patch --- .../fingerprints/Vp9PrimaryFingerprint.kt | 16 +++ .../fingerprints/Vp9PropsFingerprint.kt | 15 +++ .../fingerprints/Vp9PropsParentFingerprint.kt | 8 ++ .../fingerprints/Vp9SecondaryFingerprint.kt | 17 +++ .../patch/ForceVP9CodecBytecodePatch.kt | 123 ++++++++++++++++++ .../resource/patch/ForceVP9CodecPatch.kt | 49 +++++++ .../patch/LayoutSwitchBytecodePatch.kt | 2 +- .../fingerprints/LayoutSwitchFingerprint.kt | 2 +- .../youtube/settings/host/values/strings.xml | 5 + .../youtube/settings/xml/revanced_prefs.xml | 3 + 10 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PrimaryFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsParentFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9SecondaryFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/patch/ForceVP9CodecBytecodePatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/resource/patch/ForceVP9CodecPatch.kt rename src/main/kotlin/app/revanced/{patches/youtube/extended/layoutswitch/bytecode => shared}/fingerprints/LayoutSwitchFingerprint.kt (91%) diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PrimaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PrimaryFingerprint.kt new file mode 100644 index 000000000..69baa8bc5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PrimaryFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.extended.forcevp9.bytecode.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 Vp9PrimaryFingerprint : MethodFingerprint( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("I"), + opcodes = listOf( + Opcode.RETURN, + Opcode.RETURN + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsFingerprint.kt new file mode 100644 index 000000000..5cfb91c76 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsFingerprint.kt @@ -0,0 +1,15 @@ +package app.revanced.patches.youtube.extended.forcevp9.bytecode.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 Vp9PropsFingerprint : 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/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsParentFingerprint.kt new file mode 100644 index 000000000..84a50b9da --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9PropsParentFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.extended.forcevp9.bytecode.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object Vp9PropsParentFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf("Android Wear") +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9SecondaryFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9SecondaryFingerprint.kt new file mode 100644 index 000000000..917cd2b08 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/fingerprints/Vp9SecondaryFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.extended.forcevp9.bytecode.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 Vp9SecondaryFingerprint : MethodFingerprint( + returnType = "Z", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L", "I"), + opcodes = listOf( + Opcode.RETURN, + Opcode.CONST_4, + Opcode.RETURN + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/patch/ForceVP9CodecBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/patch/ForceVP9CodecBytecodePatch.kt new file mode 100644 index 000000000..dd135bb2f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/bytecode/patch/ForceVP9CodecBytecodePatch.kt @@ -0,0 +1,123 @@ +package app.revanced.patches.youtube.extended.forcevp9.bytecode.patch + +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.instruction +import app.revanced.patcher.extensions.removeInstruction +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult +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.youtube.extended.forcevp9.bytecode.fingerprints.* +import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.extensions.toErrorResult +import app.revanced.shared.fingerprints.LayoutSwitchFingerprint +import app.revanced.shared.util.integrations.Constants.EXTENDED_PATH +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("force-vp9-codec-bytecode-patch") +@YouTubeCompatibility +@Version("0.0.1") +class ForceVP9CodecBytecodePatch : BytecodePatch( + listOf( + LayoutSwitchFingerprint, + Vp9PrimaryFingerprint, + Vp9PropsFingerprint, + Vp9PropsParentFingerprint, + Vp9SecondaryFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + + LayoutSwitchFingerprint.result?.let { parentResult -> + arrayOf( + Vp9PrimaryFingerprint, + Vp9SecondaryFingerprint + ).map { + it.also { it.resolve(context, parentResult.classDef) }.result?.injectOverride() ?: return it.toErrorResult() + } + } ?: return LayoutSwitchFingerprint.toErrorResult() + + Vp9PropsParentFingerprint.result?.let { parentResult -> + Vp9PropsFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.let { + it.hookProps("MANUFACTURER", "getManufacturer") + it.hookProps("BRAND", "getBrand") + it.hookProps("MODEL", "getModel") + } ?: return Vp9PropsFingerprint.toErrorResult() + } ?: return Vp9PropsParentFingerprint.toErrorResult() + + return PatchResultSuccess() + } + + private companion object { + const val INTEGRATIONS_CLASS_DESCRIPTOR = + "$EXTENDED_PATH/CodecOverridePatch;" + + const val INTEGRATIONS_CLASS_METHOD_REFERENCE = + "$INTEGRATIONS_CLASS_DESCRIPTOR->shouldForceVP9(Z)Z" + + fun MethodFingerprintResult.injectOverride() { + with (mutableMethod) { + val startIndex = scanResult.patternScanResult!!.startIndex + val endIndex = scanResult.patternScanResult!!.endIndex + + val startRegister = (instruction(startIndex) as OneRegisterInstruction).registerA + val endRegister = (instruction(endIndex) as OneRegisterInstruction).registerA + + hookOverride(endIndex + 1, endRegister) + removeInstruction(endIndex) + hookOverride(startIndex + 1, startRegister) + removeInstruction(startIndex) + } + } + + fun MutableMethod.hookOverride( + index: Int, + register: Int + ) { + addInstructions( + index, """ + invoke-static {v$register}, $INTEGRATIONS_CLASS_METHOD_REFERENCE + move-result v$register + return v$register + """ + ) + } + + fun MutableMethod.hookProps( + descriptor: String, + fieldName: String + ) { + val insertInstructions = implementation!!.instructions + val targetString = "Landroid/os/Build;->" + + descriptor + + ":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 register = (instruction as OneRegisterInstruction).registerA + + addInstructions( + index + 1, """ + invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->$fieldName(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + break + } + } + } + +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/resource/patch/ForceVP9CodecPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/resource/patch/ForceVP9CodecPatch.kt new file mode 100644 index 000000000..057657d12 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/forcevp9/resource/patch/ForceVP9CodecPatch.kt @@ -0,0 +1,49 @@ +package app.revanced.patches.youtube.extended.forcevp9.resource.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.patch.annotations.DependsOn +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patches.youtube.extended.forcevp9.bytecode.patch.ForceVP9CodecBytecodePatch +import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch +import app.revanced.shared.annotation.YouTubeCompatibility +import app.revanced.shared.util.resources.ResourceHelper + +@Patch +@Name("force-vp9-codec") +@Description("Forces the VP9 codec for videos.") +@DependsOn( + [ + ForceVP9CodecBytecodePatch::class, + SettingsPatch::class + ] +) +@YouTubeCompatibility +@Version("0.0.1") +class ForceVP9CodecPatch : ResourcePatch { + override fun execute(context: ResourceContext): PatchResult { + + /* + add settings + */ + ResourceHelper.addSettings2( + context, + "PREFERENCE_CATEGORY: REVANCED_EXTENDED_SETTINGS", + "PREFERENCE: EXTENDED_SETTINGS", + "SETTINGS: EXPERIMENTAL_FLAGS", + "SETTINGS: ENABLE_VP9_CODEC" + ) + + ResourceHelper.patchSuccess( + context, + "force-vp9-codec" + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt index 33e458092..b59622e4a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/patch/LayoutSwitchBytecodePatch.kt @@ -7,9 +7,9 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patches.youtube.extended.layoutswitch.bytecode.fingerprints.LayoutSwitchFingerprint import app.revanced.shared.annotation.YouTubeCompatibility import app.revanced.shared.extensions.toErrorResult +import app.revanced.shared.fingerprints.LayoutSwitchFingerprint import app.revanced.shared.util.integrations.Constants.EXTENDED_PATH @Name("layout-switch-bytecode-patch") diff --git a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt b/src/main/kotlin/app/revanced/shared/fingerprints/LayoutSwitchFingerprint.kt similarity index 91% rename from src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt rename to src/main/kotlin/app/revanced/shared/fingerprints/LayoutSwitchFingerprint.kt index 0153574bf..76cc364ab 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/extended/layoutswitch/bytecode/fingerprints/LayoutSwitchFingerprint.kt +++ b/src/main/kotlin/app/revanced/shared/fingerprints/LayoutSwitchFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.extended.layoutswitch.bytecode.fingerprints +package app.revanced.shared.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 86f88b9b9..79296e2c3 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -255,6 +255,8 @@ Is it ready to submit?" Wide search bar is disabled Wide search bar is enabled Enable wide search bar + Spoof device information to enable VP9 codec + Enable VP9 codec Experimental Flags Report issues or leave suggestions here ReVanced Extended Issue Center @@ -481,6 +483,9 @@ If you enable this setting, the following features are not available: If you enable this setting, the following features are not available: - Ambient mode - Community Posts" + "Spoofs device information to enable VP9 codec + +Since these setting is quite outdated, it may not be valid" Dislike data is provided by the Return YouTube Dislike API. Tap here to learn more. ReturnYouTubeDislike.com Dislikes shown as number diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 2b82d1251..b50c71080 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -348,6 +348,8 @@ +