From 266888c0043ae79bee988ae675d9dca41245bce0 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:28:32 +0900 Subject: [PATCH] fix(YouTube/Return YouTube Dislike): prevent `RollingNumber` from being applied in YouTube v18.40.34+ --- .../general/ReturnYouTubeDislikePatch.kt | 23 +++++++++++++++++++ .../SpoofAppVersionPatchFingerprint.kt | 20 ++++++++++++++++ .../youtube/utils/settings/SettingsPatch.kt | 4 +++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/SpoofAppVersionPatchFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt index df4afaa3d..531bc8c75 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/ReturnYouTubeDislikePatch.kt @@ -3,6 +3,7 @@ package app.revanced.patches.youtube.utils.returnyoutubedislike.general import app.revanced.extensions.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction @@ -10,11 +11,14 @@ import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.misc.spoofappversion.SpoofAppVersionPatch import app.revanced.patches.youtube.utils.litho.LithoFilterPatch import app.revanced.patches.youtube.utils.playerresponse.PlayerResponsePatch import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.DislikeFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.LikeFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.RemoveLikeFingerprint +import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.SpoofAppVersionPatchFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentAtomicReferenceFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentAtomicReferenceLegacyFingerprint import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentConstructorFingerprint @@ -41,6 +45,7 @@ import com.android.tools.smali.dexlib2.iface.reference.Reference ReturnYouTubeDislikeOldLayoutPatch::class, ReturnYouTubeDislikeShortsPatch::class, SettingsPatch::class, + SpoofAppVersionPatch::class, VideoIdPatch::class ], compatiblePackages = [ @@ -72,6 +77,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch( DislikeFingerprint, LikeFingerprint, RemoveLikeFingerprint, + SpoofAppVersionPatchFingerprint, TextComponentConstructorFingerprint ) ) { @@ -189,6 +195,23 @@ object ReturnYouTubeDislikePatch : BytecodePatch( } } ?: throw TextComponentConstructorFingerprint.exception + if (SettingsPatch.upward1840) { + SpoofAppVersionPatchFingerprint.result?.let { + it.mutableMethod.apply { + addInstructionsWithLabels( + 0, """ + sget-object v0, Lapp/revanced/integrations/settings/SettingsEnum;->INITIALIZED:Lapp/revanced/integrations/settings/SettingsEnum; + invoke-virtual {v0}, Lapp/revanced/integrations/settings/SettingsEnum;->getBoolean()Z + move-result v0 + if-nez v0, :initialized + const-string v0, "18.39.41" + return-object v0 + """, ExternalLabel("initialized", getInstruction(0)) + ) + } + } ?: throw SpoofAppVersionPatchFingerprint.exception + } + if (SettingsPatch.upward1834) { LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR) PlayerResponsePatch.injectCall("$FILTER_CLASS_DESCRIPTOR->newPlayerResponseVideoId(Ljava/lang/String;Z)V") diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/SpoofAppVersionPatchFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/SpoofAppVersionPatchFingerprint.kt new file mode 100644 index 000000000..9ecb86a4e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/general/fingerprints/SpoofAppVersionPatchFingerprint.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +/** + * In YouTube v18.40.34+, |segmented_like_dislike_button.eml| is no longer used by some accounts (a/b tests). + * https://github.com/ReVanced/revanced-patches/issues/2904 + * + * I suspect this is due to a new type of SpannableString called 'RollingNumber' in YouTube's internal code. + * No in-depth reverse engineering has been done on this yet. + * + * After installing the app for the first time, the app version is spoofed to v18.39.41 for about 500ms before the restart dialog is shown. + * By doing this we can bypass these a/b tests being applied. + */ +object SpoofAppVersionPatchFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lapp/revanced/integrations/patches/misc/SpoofAppVersionPatch;" + && methodDef.name == "getVersionOverride" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt index 84af23254..42078bb6e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt @@ -90,9 +90,10 @@ object SettingsPatch : AbstractSettingsResourcePatch( val playServicesVersion = node.textContent.toInt() + is1836 = playServicesVersion in 233700000..233801999 upward1828 = 232900000 <= playServicesVersion upward1834 = 233502000 <= playServicesVersion - is1836 = playServicesVersion in 233700000..233801999 + upward1840 = 234102000 <= playServicesVersion break } @@ -202,6 +203,7 @@ object SettingsPatch : AbstractSettingsResourcePatch( internal var is1836: Boolean = false internal var upward1828: Boolean = false internal var upward1834: Boolean = false + internal var upward1840: Boolean = false internal fun addPreference(settingArray: Array) { contexts.addPreference(settingArray)