feat(YouTube): add support version 19.03.36 ~ 19.16.39

This commit is contained in:
inotia00
2024-04-28 05:09:50 +09:00
parent deedf0d483
commit 9a4d9a9154
11 changed files with 114 additions and 65 deletions

View File

@ -8,6 +8,7 @@ import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPl
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.ModernMiniPlayerConfigFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
@ -33,35 +34,45 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
fingerprints = setOf( fingerprints = setOf(
MiniPlayerDimensionsCalculatorFingerprint, MiniPlayerDimensionsCalculatorFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint, MiniPlayerResponseModelSizeCheckFingerprint,
MiniPlayerOverrideFingerprint MiniPlayerOverrideFingerprint,
ModernMiniPlayerConfigFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
MiniPlayerDimensionsCalculatorFingerprint.resultOrThrow().let { parentResult -> MiniPlayerOverrideNoContextFingerprint.resolve(
MiniPlayerOverrideNoContextFingerprint.resolve(context, parentResult.classDef) context,
MiniPlayerOverrideNoContextFingerprint.resultOrThrow().let { MiniPlayerDimensionsCalculatorFingerprint.resultOrThrow().classDef
)
MiniPlayerOverrideNoContextFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
hook(getTargetIndex(Opcode.RETURN))
hook(getTargetIndexReversed(Opcode.RETURN))
}
}
if (SettingsPatch.upward1912) {
ModernMiniPlayerConfigFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
hook(getTargetIndex(Opcode.RETURN)) hook(it.scanResult.patternScanResult!!.endIndex)
hook(getTargetIndexReversed(Opcode.RETURN))
} }
} }
} } else {
MiniPlayerOverrideFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2)
MiniPlayerOverrideFingerprint.resultOrThrow().let { walkerMethod.apply {
it.mutableMethod.apply { hook(getTargetIndex(Opcode.RETURN))
val walkerMethod = getWalkerMethod(context, getStringInstructionIndex("appName") + 2) hook(getTargetIndexReversed(Opcode.RETURN))
}
walkerMethod.apply {
hook(getTargetIndex(Opcode.RETURN))
hook(getTargetIndexReversed(Opcode.RETURN))
} }
} }
}
MiniPlayerResponseModelSizeCheckFingerprint.resultOrThrow().let { MiniPlayerResponseModelSizeCheckFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
hook(it.scanResult.patternScanResult!!.endIndex) hook(it.scanResult.patternScanResult!!.endIndex)
}
} }
} }

View File

@ -8,5 +8,5 @@ import com.android.tools.smali.dexlib2.Opcode
internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint( internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
returnType = "Z", returnType = "Z",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
opcodes = listOf(Opcode.RETURN), // anchor to insert the instruction opcodes = listOf(Opcode.IGET_BOOLEAN), // anchor to insert the instruction
) )

View File

@ -0,0 +1,18 @@
package app.revanced.patches.youtube.general.tabletminiplayer.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object ModernMiniPlayerConfigFingerprint : MethodReferenceNameFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/content/Context;", "L", "L", "L", "L", "L", "L"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
),
reference = { "getClass" }
)

View File

@ -8,11 +8,10 @@ import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLink
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object OpenLinksDirectlyPatch : BaseBytecodePatch( object OpenLinksDirectlyPatch : BaseBytecodePatch(
@ -33,11 +32,8 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
).forEach { fingerprint -> ).forEach { fingerprint ->
fingerprint.resultOrThrow().let { fingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = implementation!!.instructions val insertIndex = getTargetIndexWithMethodReferenceName("parse")
.indexOfFirst { instruction -> val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "parse"
}
val insertRegister = getInstruction<Instruction35c>(insertIndex).registerC
replaceInstruction( replaceInstruction(
insertIndex, insertIndex,

View File

@ -4,26 +4,36 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint( object OpenLinksDirectlyFingerprintPrimary : MethodFingerprint(
returnType = "Ljava/lang/Object", returnType = "Ljava/lang/Object",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/Object"), parameters = listOf("Ljava/lang/Object"),
opcodes = listOf( opcodes = listOf(
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT, Opcode.RETURN_OBJECT
Opcode.CHECK_CAST
), ),
customFingerprint = { methodDef, classDef -> customFingerprint = custom@{ methodDef, _ ->
methodDef.name == "a" if (methodDef.implementation == null)
&& classDef.methods.count() == 3 return@custom false
if (methodDef.name != "a")
return@custom false
var count = 0
for (instruction in methodDef.implementation!!.instructions) {
if (instruction.opcode != Opcode.SGET_OBJECT)
continue
val objectInstruction = instruction as ReferenceInstruction
if ((objectInstruction.reference as FieldReference).name != "webviewEndpoint")
continue
count++
}
count == 1
} }
) )

View File

@ -11,15 +11,17 @@ import app.revanced.patches.youtube.shorts.startupshortsreset.fingerprints.UserW
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.getReference
import app.revanced.util.getTargetIndex import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexReversed
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object ResumingShortsOnStartupPatch : BaseBytecodePatch( object ResumingShortsOnStartupPatch : BaseBytecodePatch(
@ -57,27 +59,27 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
UserWasInShortsFingerprint.resultOrThrow().let { UserWasInShortsFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = getStringInstructionIndex("Failed to read user_was_in_shorts proto after successful warmup") val listenableInstructionIndex = indexOfFirstInstruction {
val exceptionIndex = getTargetIndexReversed(startIndex, Opcode.RETURN_VOID) - 1 opcode == Opcode.INVOKE_INTERFACE &&
val targetIndex = getTargetIndexReversed(exceptionIndex, Opcode.RETURN_VOID) + 1 getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
if (getInstruction(targetIndex).opcode != Opcode.IGET_OBJECT) getReference<MethodReference>()?.name == "isDone"
throw PatchException("Failed to find insert index") }
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
val replaceReference = getInstruction<ReferenceInstruction>(targetIndex).reference val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
val replaceInstruction = getInstruction<TwoRegisterInstruction>(targetIndex) val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
addInstructionsWithLabels( addInstructionsWithLabels(
targetIndex + 1, listenableInstructionIndex + 1,
""" """
invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
move-result v${replaceInstruction.registerA} move-result v$freeRegister
if-eqz v${replaceInstruction.registerA}, :show if-eqz v$freeRegister, :show
return-void return-void
:show :show
iget-object v${replaceInstruction.registerA}, v${replaceInstruction.registerB}, $replaceReference invoke-interface {v$originalInstructionRegister}, Lcom/google/common/util/concurrent/ListenableFuture;->isDone()Z
""" """
) )
removeInstruction(targetIndex) removeInstruction(listenableInstructionIndex)
} }
} }

View File

@ -55,7 +55,21 @@ object Constants {
"18.48.39", "18.48.39",
"18.49.37", "18.49.37",
"19.01.34", "19.01.34",
"19.02.39" "19.02.39",
"19.03.36",
"19.04.38",
"19.05.36",
"19.06.39",
"19.07.40",
"19.08.36",
"19.09.37",
"19.10.39",
"19.11.43",
"19.12.41",
"19.13.37",
"19.14.43",
"19.15.36",
"19.16.39"
) )
) )
) )

View File

@ -21,7 +21,6 @@ import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexWithMethodReferenceName import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@ -54,7 +53,7 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
it.mutableMethod.apply { it.mutableMethod.apply {
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
val rollingNumberClassReference = val rollingNumberClassReference =
getInstruction<BuilderInstruction21c>(rollingNumberClassIndex).reference getInstruction<ReferenceInstruction>(rollingNumberClassIndex).reference
val rollingNumberClass = val rollingNumberClass =
context.findClass(rollingNumberClassReference.toString())!!.mutableClass context.findClass(rollingNumberClassReference.toString())!!.mutableClass

View File

@ -1,16 +1,12 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
/** /**
* This fingerprint is compatible with YouTube v18.29.38+ * This fingerprint is compatible with YouTube v18.29.38+
*/ */
internal object RollingNumberSetterFingerprint : MethodFingerprint( internal object RollingNumberSetterFingerprint : LiteralValueFingerprint(
opcodes = listOf( opcodes = listOf(Opcode.CHECK_CAST),
Opcode.CHECK_CAST, literalSupplier = { 45427773 }
Opcode.IGET,
Opcode.AND_INT_LIT8
),
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
) )

View File

@ -22,5 +22,6 @@ internal object RollingNumberTextViewFingerprint : MethodFingerprint(
), ),
customFingerprint = custom@{ _, classDef -> customFingerprint = custom@{ _, classDef ->
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
|| classDef.superclass == "Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
} }
) )

View File

@ -46,6 +46,7 @@ object SettingsPatch : BaseResourcePatch(
internal var upward1849 = false internal var upward1849 = false
internal var upward1902 = false internal var upward1902 = false
internal var upward1909 = false internal var upward1909 = false
internal var upward1912 = false
override fun execute(context: ResourceContext) { override fun execute(context: ResourceContext) {
contexts = context contexts = context
@ -80,6 +81,7 @@ object SettingsPatch : BaseResourcePatch(
upward1849 = 235000000 <= playServicesVersion upward1849 = 235000000 <= playServicesVersion
upward1902 = 240204000 < playServicesVersion upward1902 = 240204000 < playServicesVersion
upward1909 = 241002000 <= playServicesVersion upward1909 = 241002000 <= playServicesVersion
upward1912 = 241302000 <= playServicesVersion
break break
} }