Skip to content

Commit

Permalink
fix(YouTube - Client spoof): Spoof iOS client model to fix various si…
Browse files Browse the repository at this point in the history
…de effects (ReVanced#3220)

Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com>
  • Loading branch information
oSumAtrIX and LisoUseInAIKyrios committed May 23, 2024
1 parent c519fdf commit 9b5f4ce
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
Expand All @@ -34,7 +35,6 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
name = "Spoof client",
description = "Spoofs the client to allow video playback.",
dependencies = [
SpoofClientResourcePatch::class,
PlayerResponseMethodHookPatch::class,
SettingsPatch::class,
AddResourcesPatch::class,
Expand Down Expand Up @@ -74,6 +74,7 @@ object SpoofClientPatch : BytecodePatch(
BuildPlayerRequestURIFingerprint,
SetPlayerRequestClientTypeFingerprint,
CreatePlayerRequestBodyFingerprint,
CreatePlayerRequestBodyWithModelFingerprint,

// Storyboard spoof.
StoryboardRendererSpecFingerprint,
Expand All @@ -97,10 +98,9 @@ object SpoofClientPatch : BytecodePatch(
sorting = Sorting.UNSORTED,
preferences = setOf(
SwitchPreference("revanced_spoof_client"),
SwitchPreference("revanced_spoof_client_use_ios"),
SwitchPreference("revanced_spoof_client_use_testsuite"),
),
),

)

// region Block /initplayback requests to fall back to /get_watch requests.
Expand Down Expand Up @@ -168,6 +168,22 @@ object SpoofClientPatch : BytecodePatch(
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
}

val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
val instructions = it.getInstructions()

val getClientModelIndex = it.indexOfFirstInstruction {
getReference<FieldReference>().toString() == "Landroid/os/Build;->MODEL:Ljava/lang/String;"
}

// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
instructions.subList(
getClientModelIndex,
instructions.lastIndex,
).first { instruction ->
instruction.opcode == Opcode.IPUT_OBJECT
}.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
}

// endregion

// region Spoof client type for /player requests.
Expand All @@ -189,7 +205,7 @@ object SpoofClientPatch : BytecodePatch(
)
}

// Change requestMessage.clientInfo.clientType and requestMessage.clientInfo.clientVersion to the spoofed values.
// Change client info to use the spoofed values.
// Do this in a helper method, to remove the need of picking out multiple free registers from the hooked code.
result.mutableClass.methods.add(
ImmutableMethod(
Expand All @@ -216,12 +232,17 @@ object SpoofClientPatch : BytecodePatch(
move-result v1
iput v1, v0, $clientInfoClientTypeField
# Set client model to the spoofed value.
iget-object v1, v0, $clientInfoClientModelField
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientModel(Ljava/lang/String;)Ljava/lang/String;
move-result-object v1
iput-object v1, v0, $clientInfoClientModelField
# Set client version to the spoofed value.
iget-object v1, v0, $clientInfoClientVersionField
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientVersion(Ljava/lang/String;)Ljava/lang/String;
move-result-object v1
iput-object v1, v0, $clientInfoClientVersionField
:disabled
return-void
""",
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ object SpoofSignaturePatch : BytecodePatch(
StoryboardRendererDecoderSpecFingerprint,
StoryboardRendererDecoderRecommendedLevelFingerprint,
StoryboardThumbnailParentFingerprint,
ScrubbedPreviewLayoutFingerprint,
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint,
StatsQueryParameterFingerprint,
ParamsMapPutFingerprint,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.reference.FieldReference

internal object CreatePlayerRequestBodyWithModelFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
customFingerprint = { methodDef, _ ->
methodDef.implementation!!.instructions.any {
it.getReference<FieldReference>().toString() == "Landroid/os/Build;->MODEL:Ljava/lang/String;"
}
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode

@Deprecated("Fingerprint is obsolete and will be deleted soon")
internal object ParamsMapPutFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode

@Deprecated("Fingerprint is obsolete and will be deleted soon")
internal object PlayerResponseModelImplLiveStreamFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode

@Deprecated("Fingerprint is obsolete and will be deleted soon")
internal object SpoofSignaturePatchScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

@Deprecated("Fingerprint is obsolete and will be deleted soon")
internal object StatsQueryParameterFingerprint : MethodFingerprint(
strings = listOf("adunit"),
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
* An additional change here might force the thumbnails to be created,
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
*/
@Deprecated("Fingerprint is obsolete and will be deleted soon")
internal object StoryboardThumbnailParentFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Landroid/graphics/Bitmap;",
Expand Down
9 changes: 4 additions & 5 deletions src/main/resources/addresources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1092,11 +1092,10 @@
<string name="revanced_spoof_client_summary_on">Client is spoofed</string>
<string name="revanced_spoof_client_summary_off">Client is not spoofed\n\nVideo playback may not work</string>
<string name="revanced_spoof_client_user_dialog_message">Turning off this setting may cause video playback issues.</string>
<!-- It is ideal, but not required, if the text here appears is alphabetically after the text used for 'revanced_client_spoof_title' -->
<string name="revanced_spoof_client_use_ios_title">Spoof client to iOS</string>
<string name="revanced_spoof_client_use_ios_summary">Spoof the client to iOS instead of an Android Testsuite</string>
<string name="revanced_spoof_client_use_ios_summary_on">Client is spoofed to an iOS client\n\nSide effects include:\n• 60 fps video may not be available\n• No HDR video\n• Some videos may not load\n• Higher video qualities may be missing</string>
<string name="revanced_spoof_client_use_ios_summary_off">Client is spoofed to an Android Testsuite client (iOS client is used for live streams)\n\nSide effects include:\n• Subtitles are missing\n• Player gestures may not work\n• Low quality Shorts seekbar thumbnails</string>
<string name="revanced_spoof_client_use_testsuite_title">Spoof client to Android Testsuite</string>
<string name="revanced_spoof_client_use_testsuite_summary">Spoof the client to Android Testsuite</string>
<string name="revanced_spoof_client_use_testsuite_summary_on">Client is spoofed to an Android Testsuite client (iOS client is used for live streams)\n\nSide effects include, but are not limited to:\n• Speed flyout menu is missing\n• Captions are missing\n• Player swipe gestures may not work\n• Low quality Shorts seekbar thumbnails\n• Watch history may not work</string>
<string name="revanced_spoof_client_use_testsuite_summary_off">Client is spoofed to an iOS client\n\nSide effects include:\n• No HDR video\n• Speed flyout menu is missing</string>
<string name="revanced_spoof_client_storyboard_timeout">Spoof client thumbnails not available (API timed out)</string>
<string name="revanced_spoof_client_storyboard_io_exception">Spoof client thumbnails temporarily not available: %s</string>
</patch>
Expand Down

0 comments on commit 9b5f4ce

Please sign in to comment.