Skip to content

Commit

Permalink
fix(YouTube - Client spoof): Removed unused code (#3030)
Browse files Browse the repository at this point in the history
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
  • Loading branch information
LisoUseInAIKyrios and oSumAtrIX committed Sep 25, 2023
1 parent ae03c60 commit 15e27bf
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import app.revanced.util.resources.ResourceUtils.mergeStrings

@Patch(
dependencies = [
BottomControlsResourcePatch::class,
SettingsPatch::class
SettingsPatch::class,
BottomControlsResourcePatch::class
]
)
object CopyVideoUrlResourcePatch : ResourcePatch() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
override fun execute(context: BytecodeContext) {
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.

VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")
// This patch needs a few adjustments and lots of testing before it can change to the new video id hook.
// There's a few corner cases and some weirdness when loading new videos (specifically with detecting shorts).
VideoIdPatch.legacyInjectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->newVideoLoaded(Ljava/lang/String;)V")

// endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
}

/*
* Set current video id
* Set current video id.
*
* The new video id hook seems to work without issues,
* but it's easier to keep using this hook as it's well tested and has no known problems.
*/
VideoIdPatch.injectCallBackgroundPlay("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
VideoIdPatch.legacyInjectCallBackgroundPlay("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")

/*
* Seekbar drawing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction

@Patch(
description = "Spoofs the signature to prevent playback issues.",
dependencies = [
SpoofSignatureResourcePatch::class,
IntegrationsPatch::class,
SettingsPatch::class,
PlayerTypeHookPatch::class,
VideoInformationPatch::class,
PlayerResponseMethodHookPatch::class,
]
)
object SpoofSignaturePatch : BytecodePatch(
setOf(
ProtobufParameterBuilderFingerprint,
PlayerResponseModelImplFingerprint,
StoryboardThumbnailParentFingerprint,
StoryboardRendererSpecFingerprint,
Expand All @@ -39,29 +39,60 @@ object SpoofSignaturePatch : BytecodePatch(
"Lapp/revanced/integrations/patches/spoof/SpoofSignaturePatch;"

override fun execute(context: BytecodeContext) {
// Hook parameter.
ProtobufParameterBuilderFingerprint.result?.let {
val setParamMethod = context
.toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex, true).getMethod() as MutableMethod

setParamMethod.apply {
val protobufParameterRegister = 3

addInstructions(
0,
"""
invoke-static {p$protobufParameterRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$protobufParameterRegister
"""
SettingsPatch.PreferenceScreen.MISC.addPreferences(
PreferenceScreen(
key = "revanced_spoof_signature_verification",
title = StringResource(
"revanced_spoof_signature_verification_title",
"Spoof app signature"
),
preferences = listOf(
SwitchPreference(
"revanced_spoof_signature_verification_enabled",
StringResource("revanced_spoof_signature_verification_enabled_title", "Spoof app signature"),
StringResource(
"revanced_spoof_signature_verification_enabled_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Enhanced bitrate is not available\\n"
+ "• Videos cannot be downloaded\\n"
+ "• No seekbar thumbnails for paid or age restricted videos"
),
StringResource(
"revanced_spoof_signature_verification_enabled_summary_off",
"App signature not spoofed\\n\\nVideo playback may not work"
),
StringResource(
"revanced_spoof_signature_verification_enabled_user_dialog_message",
"Turning off this setting will cause video playback issues."
)
),
SwitchPreference(
"revanced_spoof_signature_in_feed_enabled",
StringResource("revanced_spoof_signature_in_feed_enabled_title", "Spoof app signature in feed"),
StringResource(
"revanced_spoof_signature_in_feed_enabled_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Feed videos are missing subtitles\\n"
+ "• Automatically played feed videos will show up in your watch history"
),
StringResource(
"revanced_spoof_signature_in_feed_enabled_summary_off",
"App signature not spoofed for feed videos\n\n"
+ "Feed videos will play for less than 1 minute before encountering playback issues"
)
)
)
}
} ?: throw ProtobufParameterBuilderFingerprint.exception
)
)

// When signature spoofing is enabled, the seekbar when tapped does not show
// the video time, chapter names, or the video thumbnail.
// Changing the value returned of this method forces all of these to show up,
// except the thumbnails are blank, which is handled with the patch below.
// Hook the player parameters.
PlayerResponseMethodHookPatch.injectProtoBufferHook("$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;)Ljava/lang/String;")

// Force the seekbar thumbnails to show up.
// This is only required to show the seekbar time and chapters
// if the storyboard spec fetch fails.
StoryboardThumbnailParentFingerprint.result?.classDef?.let { classDef ->
StoryboardThumbnailFingerprint.also {
it.resolve(
Expand Down Expand Up @@ -89,58 +120,58 @@ object SpoofSignaturePatch : BytecodePatch(
"""
)
} ?: throw StoryboardThumbnailFingerprint.exception
}

/**
* Hook StoryBoard renderer url
*/
PlayerResponseModelImplFingerprint.result?.let {
it.mutableMethod.apply {
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
val getStoryBoardRegister = getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA
/**
* Hook StoryBoard renderer url
*/
PlayerResponseModelImplFingerprint.result?.let {
it.mutableMethod.apply {
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
val getStoryBoardRegister = getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA

addInstructions(
getStoryBoardIndex,
"""
addInstructions(
getStoryBoardIndex,
"""
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$getStoryBoardRegister
"""
)
}
} ?: throw PlayerResponseModelImplFingerprint.exception
)
}
} ?: throw PlayerResponseModelImplFingerprint.exception

StoryboardRendererSpecFingerprint.result?.let {
it.mutableMethod.apply {
val storyBoardUrlParams = 0
StoryboardRendererSpecFingerprint.result?.let {
it.mutableMethod.apply {
val storyBoardUrlParams = 0

addInstructionsWithLabels(
0,
"""
addInstructionsWithLabels(
0,
"""
if-nez p$storyBoardUrlParams, :ignore
invoke-static { p$storyBoardUrlParams }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$storyBoardUrlParams
""",
ExternalLabel("ignore", getInstruction(0))
)
}
} ?: throw StoryboardRendererSpecFingerprint.exception
ExternalLabel("ignore", getInstruction(0))
)
}
} ?: throw StoryboardRendererSpecFingerprint.exception

// Hook recommended value
StoryboardRendererInitFingerprint.result?.let {
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
// Hook recommended value
StoryboardRendererInitFingerprint.result?.let {
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex

val originalValueRegister = it.mutableMethod
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
val originalValueRegister = it.mutableMethod
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA

it.mutableMethod.apply {
addInstructions(
moveOriginalRecommendedValueIndex + 1,
"""
it.mutableMethod.apply {
addInstructions(
moveOriginalRecommendedValueIndex + 1,
"""
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
move-result v$originalValueRegister
"""
)
}
} ?: throw StoryboardRendererInitFingerprint.exception
}
)
}
} ?: throw StoryboardRendererInitFingerprint.exception
}
}
}
Original file line number Diff line number Diff line change
@@ -1,68 +0,0 @@
package app.revanced.patches.youtube.misc.fix.playback

import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.PreferenceScreen
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.SettingsPatch

@Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class])
object SpoofSignatureResourcePatch : ResourcePatch() {
internal var scrubbedPreviewThumbnailResourceId: Long = -1

override fun execute(context: ResourceContext) {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
PreferenceScreen(
key = "revanced_spoof_signature_verification",
title = StringResource(
"revanced_spoof_signature_verification_title",
"Spoof app signature"
),
preferences = listOf(
SwitchPreference(
"revanced_spoof_signature_verification_enabled",
StringResource("revanced_spoof_signature_verification_enabled_title", "Spoof app signature"),
StringResource(
"revanced_spoof_signature_verification_enabled_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• No ambient mode\\n"
+ "• Videos cannot be downloaded"
),
StringResource(
"revanced_spoof_signature_verification_enabled_summary_off",
"App signature not spoofed\\n\\nVideo playback may not work"
),
StringResource(
"revanced_spoof_signature_verification_enabled_user_dialog_message",
"Turning off this setting will cause video playback issues."
)
),
SwitchPreference(
"revanced_spoof_signature_in_feed_enabled",
StringResource("revanced_spoof_signature_in_feed_enabled_title", "Spoof app signature in feed"),
StringResource(
"revanced_spoof_signature_in_feed_enabled_summary_on",
"App signature spoofed\\n\\n"
+ "Side effects include:\\n"
+ "• Feed videos are missing subtitles\\n"
+ "• Automatically played feed videos will show up in your watch history"
),
StringResource(
"revanced_spoof_signature_in_feed_enabled_summary_off",
"App signature not spoofed for feed videos\n\n"
+ "Feed videos will play for less than 1 minute before encountering playback issues"
)
)
)
)
)

scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
it.type == "id" && it.name == "thumbnail"
}.id
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ object PlayerControlsBytecodePatch : BytecodePatch(

private var moveToRegisterInstructionIndex: Int = 0
private var viewRegister: Int = 0
private lateinit var inflateFingerprintResult: MethodFingerprintResult

override fun execute(context: BytecodeContext) {
LayoutConstructorFingerprint.result?.let {
Expand All @@ -31,17 +32,13 @@ object PlayerControlsBytecodePatch : BytecodePatch(
} ?: throw LayoutConstructorFingerprint.exception

showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!
}

private var inflateFingerprintResult: MethodFingerprintResult? = null
set(fingerprint) {
field = fingerprint!!.also {
moveToRegisterInstructionIndex = it.scanResult.patternScanResult!!.endIndex
viewRegister =
(it.mutableMethod.implementation!!.instructions[moveToRegisterInstructionIndex] as OneRegisterInstruction).registerA
}
inflateFingerprintResult = BottomControlsInflateFingerprint.result!!.also {
moveToRegisterInstructionIndex = it.scanResult.patternScanResult!!.endIndex
viewRegister =
(it.mutableMethod.implementation!!.instructions[moveToRegisterInstructionIndex] as OneRegisterInstruction).registerA
}
}

/**
* Injects the code to change the visibility of controls.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ object VideoInformationPatch : BytecodePatch(
/*
* Inject call for video id
*/
val videoIdMethodDescriptor = "$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V"
VideoIdPatch.injectCall(videoIdMethodDescriptor)
VideoIdPatch.injectCallBackgroundPlay(videoIdMethodDescriptor)
VideoIdPatch.injectCall("$INTEGRATIONS_CLASS_DESCRIPTOR->setVideoId(Ljava/lang/String;)V")

/*
* Set the video time method
Expand Down
Loading

0 comments on commit 15e27bf

Please sign in to comment.