Skip to content

Commit 82a0847

Browse files
oSumAtrIXLisoUseInAIKyrios
andauthored
fix(YouTube - Client spoof): Spoof iOS client model to fix various side effects (#3220)
Co-authored-by: LisoUseInAIKyrios <[email protected]>
1 parent 0d1c455 commit 82a0847

11 files changed

+54
-56
lines changed

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientPatch.kt

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
1919
import app.revanced.patches.youtube.misc.settings.SettingsPatch
2020
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
2121
import app.revanced.util.getReference
22+
import app.revanced.util.indexOfFirstInstruction
2223
import app.revanced.util.resultOrThrow
2324
import com.android.tools.smali.dexlib2.AccessFlags
2425
import com.android.tools.smali.dexlib2.Opcode
@@ -34,7 +35,6 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
3435
name = "Spoof client",
3536
description = "Spoofs the client to allow video playback.",
3637
dependencies = [
37-
SpoofClientResourcePatch::class,
3838
PlayerResponseMethodHookPatch::class,
3939
SettingsPatch::class,
4040
AddResourcesPatch::class,
@@ -74,6 +74,7 @@ object SpoofClientPatch : BytecodePatch(
7474
BuildPlayerRequestURIFingerprint,
7575
SetPlayerRequestClientTypeFingerprint,
7676
CreatePlayerRequestBodyFingerprint,
77+
CreatePlayerRequestBodyWithModelFingerprint,
7778

7879
// Storyboard spoof.
7980
StoryboardRendererSpecFingerprint,
@@ -97,10 +98,9 @@ object SpoofClientPatch : BytecodePatch(
9798
sorting = Sorting.UNSORTED,
9899
preferences = setOf(
99100
SwitchPreference("revanced_spoof_client"),
100-
SwitchPreference("revanced_spoof_client_use_ios"),
101+
SwitchPreference("revanced_spoof_client_use_testsuite"),
101102
),
102103
),
103-
104104
)
105105

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

171+
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.let {
172+
val instructions = it.getInstructions()
173+
174+
val getClientModelIndex = it.indexOfFirstInstruction {
175+
getReference<FieldReference>().toString() == "Landroid/os/Build;->MODEL:Ljava/lang/String;"
176+
}
177+
178+
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
179+
instructions.subList(
180+
getClientModelIndex,
181+
instructions.lastIndex,
182+
).first { instruction ->
183+
instruction.opcode == Opcode.IPUT_OBJECT
184+
}.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientModelField")
185+
}
186+
171187
// endregion
172188

173189
// region Spoof client type for /player requests.
@@ -189,7 +205,7 @@ object SpoofClientPatch : BytecodePatch(
189205
)
190206
}
191207

192-
// Change requestMessage.clientInfo.clientType and requestMessage.clientInfo.clientVersion to the spoofed values.
208+
// Change client info to use the spoofed values.
193209
// Do this in a helper method, to remove the need of picking out multiple free registers from the hooked code.
194210
result.mutableClass.methods.add(
195211
ImmutableMethod(
@@ -216,12 +232,17 @@ object SpoofClientPatch : BytecodePatch(
216232
move-result v1
217233
iput v1, v0, $clientInfoClientTypeField
218234
235+
# Set client model to the spoofed value.
236+
iget-object v1, v0, $clientInfoClientModelField
237+
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientModel(Ljava/lang/String;)Ljava/lang/String;
238+
move-result-object v1
239+
iput-object v1, v0, $clientInfoClientModelField
240+
219241
# Set client version to the spoofed value.
220242
iget-object v1, v0, $clientInfoClientVersionField
221243
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientVersion(Ljava/lang/String;)Ljava/lang/String;
222244
move-result-object v1
223245
iput-object v1, v0, $clientInfoClientVersionField
224-
225246
:disabled
226247
return-void
227248
""",

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofClientResourcePatch.kt

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ object SpoofSignaturePatch : BytecodePatch(
4343
StoryboardRendererDecoderSpecFingerprint,
4444
StoryboardRendererDecoderRecommendedLevelFingerprint,
4545
StoryboardThumbnailParentFingerprint,
46-
ScrubbedPreviewLayoutFingerprint,
46+
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint,
4747
StatsQueryParameterFingerprint,
4848
ParamsMapPutFingerprint,
4949
),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
2+
3+
import app.revanced.patcher.extensions.or
4+
import app.revanced.patcher.fingerprint.MethodFingerprint
5+
import app.revanced.util.getReference
6+
import com.android.tools.smali.dexlib2.AccessFlags
7+
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
8+
9+
internal object CreatePlayerRequestBodyWithModelFingerprint : MethodFingerprint(
10+
returnType = "L",
11+
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
12+
parameters = listOf(),
13+
customFingerprint = { methodDef, _ ->
14+
methodDef.implementation!!.instructions.any {
15+
it.getReference<FieldReference>().toString() == "Landroid/os/Build;->MODEL:Ljava/lang/String;"
16+
}
17+
},
18+
)

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/ParamsMapPutFingerprint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
55
import com.android.tools.smali.dexlib2.AccessFlags
66
import com.android.tools.smali.dexlib2.Opcode
77

8+
@Deprecated("Fingerprint is obsolete and will be deleted soon")
89
internal object ParamsMapPutFingerprint : MethodFingerprint(
910
returnType = "V",
1011
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/PlayerResponseModelImplLiveStreamFingerprint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import app.revanced.util.containsWideLiteralInstructionValue
66
import com.android.tools.smali.dexlib2.AccessFlags
77
import com.android.tools.smali.dexlib2.Opcode
88

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

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/ScrubbedPreviewLayoutFingerprint.kt

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/SpoofSignaturePatchScrubbedPreviewLayoutFingerprint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import app.revanced.util.patch.LiteralValueFingerprint
66
import com.android.tools.smali.dexlib2.AccessFlags
77
import com.android.tools.smali.dexlib2.Opcode
88

9+
@Deprecated("Fingerprint is obsolete and will be deleted soon")
910
internal object SpoofSignaturePatchScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
1011
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
1112
returnType = "V",

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/StatsQueryParameterFingerprint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package app.revanced.patches.youtube.misc.fix.playback.fingerprints
22

33
import app.revanced.patcher.fingerprint.MethodFingerprint
44

5+
@Deprecated("Fingerprint is obsolete and will be deleted soon")
56
internal object StatsQueryParameterFingerprint : MethodFingerprint(
67
strings = listOf("adunit"),
78
)

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/StoryboardThumbnailParentFingerprint.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.android.tools.smali.dexlib2.AccessFlags
1010
* An additional change here might force the thumbnails to be created,
1111
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
1212
*/
13+
@Deprecated("Fingerprint is obsolete and will be deleted soon")
1314
internal object StoryboardThumbnailParentFingerprint : MethodFingerprint(
1415
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
1516
returnType = "Landroid/graphics/Bitmap;",

0 commit comments

Comments
 (0)