@@ -5,23 +5,28 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
55import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
66import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
77import app.revanced.patcher.extensions.InstructionExtensions.instructions
8+ import app.revanced.patcher.fingerprint
89import app.revanced.patcher.patch.BytecodePatchBuilder
910import app.revanced.patcher.patch.BytecodePatchContext
1011import app.revanced.patcher.patch.bytecodePatch
12+ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
1113import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
1214import app.revanced.patches.all.misc.resources.addResources
1315import app.revanced.patches.all.misc.resources.addResourcesPatch
1416import app.revanced.util.findFreeRegister
1517import app.revanced.util.findInstructionIndicesReversedOrThrow
1618import app.revanced.util.getReference
19+ import app.revanced.util.indexOfFirstInstruction
1720import app.revanced.util.indexOfFirstInstructionOrThrow
1821import app.revanced.util.insertLiteralOverride
1922import app.revanced.util.returnEarly
2023import com.android.tools.smali.dexlib2.AccessFlags
2124import com.android.tools.smali.dexlib2.Opcode
2225import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
26+ import com.android.tools.smali.dexlib2.iface.Method
2327import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
2428import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
29+ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
2530import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
2631import com.android.tools.smali.dexlib2.iface.reference.FieldReference
2732import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@@ -31,6 +36,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
3136internal const val EXTENSION_CLASS_DESCRIPTOR =
3237 " Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
3338
39+ private lateinit var buildRequestMethod: MutableMethod
40+ private var buildRequestMethodUrlRegister = - 1
41+
3442fun spoofVideoStreamsPatch (
3543 block : BytecodePatchBuilder .() -> Unit = {},
3644 fixMediaFetchHotConfigChanges : BytecodePatchBuilder .() -> Boolean = { false },
@@ -91,18 +99,17 @@ fun spoofVideoStreamsPatch(
9199 // region Get replacement streams at player requests.
92100
93101 buildRequestFingerprint.method.apply {
94- val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
95- opcode == Opcode .INVOKE_VIRTUAL &&
96- getReference<MethodReference >()?.name == " newUrlRequestBuilder"
97- }
98- val urlRegister = getInstruction<FiveRegisterInstruction >(newRequestBuilderIndex).registerD
99- val freeRegister = findFreeRegister(newRequestBuilderIndex, urlRegister)
102+ buildRequestMethod = this
103+
104+ val newRequestBuilderIndex = indexOfNewUrlRequestBuilderInstruction(this )
105+ buildRequestMethodUrlRegister = getInstruction<FiveRegisterInstruction >(newRequestBuilderIndex).registerD
106+ val freeRegister = findFreeRegister(newRequestBuilderIndex, buildRequestMethodUrlRegister)
100107
101108 addInstructions(
102109 newRequestBuilderIndex,
103110 """
104111 move-object v$freeRegister , p1
105- invoke-static { v$urlRegister , v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR ->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
112+ invoke-static { v$buildRequestMethodUrlRegister , v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR ->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
106113 """
107114 )
108115 }
@@ -187,6 +194,21 @@ fun spoofVideoStreamsPatch(
187194
188195 // endregion
189196
197+ // region block getAtt request
198+
199+ buildRequestMethod.apply {
200+ val insertIndex = indexOfNewUrlRequestBuilderInstruction(this )
201+
202+ addInstructions(
203+ insertIndex, """
204+ invoke-static { v$buildRequestMethodUrlRegister }, $EXTENSION_CLASS_DESCRIPTOR ->blockGetAttRequest(Ljava/lang/String;)Ljava/lang/String;
205+ move-result-object v$buildRequestMethodUrlRegister
206+ """
207+ )
208+ }
209+
210+ // endregion
211+
190212 // region Remove /videoplayback request body to fix playback.
191213 // It is assumed, YouTube makes a request with a body tuned for Android.
192214 // Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
@@ -243,6 +265,50 @@ fun spoofVideoStreamsPatch(
243265
244266 // endregion
245267
268+ // region Disable SABR playback.
269+ // If SABR is disabled, it seems 'MediaFetchHotConfig' may no longer need an override (not confirmed).
270+
271+ val (mediaFetchEnumClass, sabrFieldReference) = with (mediaFetchEnumConstructorFingerprint.method) {
272+ val stringIndex = mediaFetchEnumConstructorFingerprint.stringMatches!! .first {
273+ it.string == DISABLED_BY_SABR_STREAMING_URI_STRING
274+ }.index
275+
276+ val mediaFetchEnumClass = definingClass
277+ val sabrFieldIndex = indexOfFirstInstructionOrThrow(stringIndex) {
278+ opcode == Opcode .SPUT_OBJECT &&
279+ getReference<FieldReference >()?.type == mediaFetchEnumClass
280+ }
281+
282+ Pair (
283+ mediaFetchEnumClass,
284+ getInstruction<ReferenceInstruction >(sabrFieldIndex).reference
285+ )
286+ }
287+
288+ fingerprint {
289+ returns(mediaFetchEnumClass)
290+ opcodes(
291+ Opcode .SGET_OBJECT ,
292+ Opcode .RETURN_OBJECT ,
293+ )
294+ custom { method, _ ->
295+ ! method.parameterTypes.isEmpty()
296+ }
297+ }.method.addInstructionsWithLabels(
298+ 0 ,
299+ """
300+ invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR ->disableSABR()Z
301+ move-result v0
302+ if-eqz v0, :ignore
303+ sget-object v0, $sabrFieldReference
304+ return-object v0
305+ :ignore
306+ nop
307+ """
308+ )
309+
310+ // endregion
311+
246312 // region turn off stream config replacement feature flag.
247313
248314 if (fixMediaFetchHotConfigChanges()) {
@@ -271,3 +337,12 @@ fun spoofVideoStreamsPatch(
271337 executeBlock()
272338 }
273339}
340+
341+ internal fun indexOfNewUrlRequestBuilderInstruction (method : Method ) = method.indexOfFirstInstruction {
342+ opcode == Opcode .INVOKE_VIRTUAL && getReference<MethodReference >().toString() ==
343+ " Lorg/chromium/net/CronetEngine;" +
344+ " ->newUrlRequestBuilder(" +
345+ " Ljava/lang/String;Lorg/chromium/net/UrlRequest${' $' } Callback;" +
346+ " Ljava/util/concurrent/Executor;" +
347+ " )Lorg/chromium/net/UrlRequest${' $' } Builder;"
348+ }
0 commit comments