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

View File

@ -8,5 +8,5 @@ import com.android.tools.smali.dexlib2.Opcode
internal object MiniPlayerOverrideNoContextFingerprint : MethodFingerprint(
returnType = "Z",
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.MISC_PATH
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Suppress("unused")
object OpenLinksDirectlyPatch : BaseBytecodePatch(
@ -33,11 +32,8 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
).forEach { fingerprint ->
fingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val insertIndex = implementation!!.instructions
.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "parse"
}
val insertRegister = getInstruction<Instruction35c>(insertIndex).registerC
val insertIndex = getTargetIndexWithMethodReferenceName("parse")
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
replaceInstruction(
insertIndex,

View File

@ -4,26 +4,36 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
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(
returnType = "Ljava/lang/Object",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/Object"),
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.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
Opcode.CHECK_CAST
Opcode.RETURN_OBJECT
),
customFingerprint = { methodDef, classDef ->
methodDef.name == "a"
&& classDef.methods.count() == 3
customFingerprint = custom@{ methodDef, _ ->
if (methodDef.implementation == null)
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.SHORTS_CLASS_DESCRIPTOR
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.getTargetIndexReversed
import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
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.reference.MethodReference
@Suppress("unused")
object ResumingShortsOnStartupPatch : BaseBytecodePatch(
@ -57,27 +59,27 @@ object ResumingShortsOnStartupPatch : BaseBytecodePatch(
UserWasInShortsFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val startIndex = getStringInstructionIndex("Failed to read user_was_in_shorts proto after successful warmup")
val exceptionIndex = getTargetIndexReversed(startIndex, Opcode.RETURN_VOID) - 1
val targetIndex = getTargetIndexReversed(exceptionIndex, Opcode.RETURN_VOID) + 1
if (getInstruction(targetIndex).opcode != Opcode.IGET_OBJECT)
throw PatchException("Failed to find insert index")
val replaceReference = getInstruction<ReferenceInstruction>(targetIndex).reference
val replaceInstruction = getInstruction<TwoRegisterInstruction>(targetIndex)
val listenableInstructionIndex = indexOfFirstInstruction {
opcode == Opcode.INVOKE_INTERFACE &&
getReference<MethodReference>()?.definingClass == "Lcom/google/common/util/concurrent/ListenableFuture;" &&
getReference<MethodReference>()?.name == "isDone"
}
if (listenableInstructionIndex < 0) throw PatchException("Could not find instruction index")
val originalInstructionRegister = getInstruction<FiveRegisterInstruction>(listenableInstructionIndex).registerC
val freeRegister = getInstruction<OneRegisterInstruction>(listenableInstructionIndex + 1).registerA
addInstructionsWithLabels(
targetIndex + 1,
listenableInstructionIndex + 1,
"""
invoke-static {}, $SHORTS_CLASS_DESCRIPTOR->disableResumingStartupShortsPlayer()Z
move-result v${replaceInstruction.registerA}
if-eqz v${replaceInstruction.registerA}, :show
move-result v$freeRegister
if-eqz v$freeRegister, :show
return-void
: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.49.37",
"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.resultOrThrow
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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@ -54,7 +53,7 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
it.mutableMethod.apply {
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
val rollingNumberClassReference =
getInstruction<BuilderInstruction21c>(rollingNumberClassIndex).reference
getInstruction<ReferenceInstruction>(rollingNumberClassIndex).reference
val rollingNumberClass =
context.findClass(rollingNumberClassReference.toString())!!.mutableClass

View File

@ -1,16 +1,12 @@
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
/**
* This fingerprint is compatible with YouTube v18.29.38+
*/
internal object RollingNumberSetterFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CHECK_CAST,
Opcode.IGET,
Opcode.AND_INT_LIT8
),
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
internal object RollingNumberSetterFingerprint : LiteralValueFingerprint(
opcodes = listOf(Opcode.CHECK_CAST),
literalSupplier = { 45427773 }
)

View File

@ -22,5 +22,6 @@ internal object RollingNumberTextViewFingerprint : MethodFingerprint(
),
customFingerprint = custom@{ _, classDef ->
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 upward1902 = false
internal var upward1909 = false
internal var upward1912 = false
override fun execute(context: ResourceContext) {
contexts = context
@ -80,6 +81,7 @@ object SettingsPatch : BaseResourcePatch(
upward1849 = 235000000 <= playServicesVersion
upward1902 = 240204000 < playServicesVersion
upward1909 = 241002000 <= playServicesVersion
upward1912 = 241302000 <= playServicesVersion
break
}