feat(youtube): add support version v18.30.37

This commit is contained in:
inotia00 2023-08-05 07:07:40 +09:00
parent 00a36941f3
commit d8a10fecf5
15 changed files with 241 additions and 69 deletions

View File

@ -34,7 +34,8 @@ Example:
"18.24.37",
"18.25.40",
"18.27.36",
"18.29.38"
"18.29.38",
"18.30.37"
]
}
]

View File

@ -3,14 +3,9 @@ package app.revanced.patches.shared.fingerprints.litho
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object EmptyComponentBuilderFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT
),
strings = listOf("Failed to convert Element to Flatbuffers: %s")
strings = listOf("Error while converting %s")
)

View File

@ -0,0 +1,17 @@
package app.revanced.patches.shared.fingerprints.litho
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object PbToFbFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("[B"),
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT
),
strings = listOf("PbToFb failed: ")
)

View File

@ -0,0 +1,16 @@
package app.revanced.patches.shared.fingerprints.litho
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object PbToFbLegacyFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT
),
strings = listOf("Failed to convert Element to Flatbuffers: %s")
)

View File

@ -9,6 +9,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
@ -16,6 +17,8 @@ import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.fingerprints.litho.ByteBufferHookFingerprint
import app.revanced.patches.shared.fingerprints.litho.EmptyComponentBuilderFingerprint
import app.revanced.patches.shared.fingerprints.litho.IdentifierFingerprint
import app.revanced.patches.shared.fingerprints.litho.PbToFbFingerprint
import app.revanced.patches.shared.fingerprints.litho.PbToFbLegacyFingerprint
import app.revanced.util.bytecode.getStringIndex
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -31,45 +34,53 @@ class ComponentParserPatch : BytecodePatch(
listOf(
ByteBufferHookFingerprint,
EmptyComponentBuilderFingerprint,
IdentifierFingerprint
IdentifierFingerprint,
PbToFbFingerprint,
PbToFbLegacyFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
EmptyComponentBuilderFingerprint.result?.let {
it.mutableMethod.apply {
val byteBufferClassIndex = it.scanResult.patternScanResult!!.startIndex
byteBufferClassLabel =
getInstruction<ReferenceInstruction>(byteBufferClassIndex).reference.toString()
val targetStringIndex = getStringIndex("Error while converting %s")
val targetIndex = getStringIndex("Failed to convert Element to Flatbuffers: %s") + 2
val builderMethodDescriptor =
getInstruction<ReferenceInstruction>(targetIndex).reference
val emptyComponentFieldDescriptor =
getInstruction<ReferenceInstruction>(targetIndex + 2).reference
for (index in targetStringIndex until implementation!!.instructions.size - 1) {
if (getInstruction(index).opcode != Opcode.INVOKE_STATIC_RANGE) continue
emptyComponentLabel = """
move-object/from16 v0, p1
invoke-static {v0}, $builderMethodDescriptor
move-result-object v0
iget-object v0, v0, $emptyComponentFieldDescriptor
return-object v0
"""
val builderMethodDescriptor =
getInstruction<ReferenceInstruction>(index).reference
val emptyComponentFieldDescriptor =
getInstruction<ReferenceInstruction>(index + 2).reference
it.mutableClass.staticFields.add(
ImmutableField(
definingClass,
"buffer",
"Ljava/nio/ByteBuffer;",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
emptyComponentLabel = """
move-object/from16 v0, p1
invoke-static {v0}, $builderMethodDescriptor
move-result-object v0
iget-object v0, v0, $emptyComponentFieldDescriptor
return-object v0
"""
break
}
if (emptyComponentLabel.isEmpty())
throw PatchResultError("could not find Empty Component Label in method")
}
} ?: return EmptyComponentBuilderFingerprint.toErrorResult()
val pbToFbResult = PbToFbFingerprint.result
?: PbToFbLegacyFingerprint.result
?: throw PbToFbLegacyFingerprint.toErrorResult()
pbToFbResult.let {
it.mutableMethod.apply {
val byteBufferClassIndex = it.scanResult.patternScanResult!!.startIndex
byteBufferClassLabel =
getInstruction<ReferenceInstruction>(byteBufferClassIndex).reference.toString()
}
}
ByteBufferHookFingerprint.result?.let {
(context
.toMethodWalker(it.method)
@ -108,9 +119,28 @@ class ComponentParserPatch : BytecodePatch(
identifierRegister =
getInstruction<OneRegisterInstruction>(identifierIndex).registerA
objectRegister = getInstruction<BuilderInstruction35c>(objectIndex).registerC
freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA
val register = getInstruction<OneRegisterInstruction>(freeIndex).registerA
freeRegister =
if (register == stringBuilderRegister || register == identifierRegister || register == objectRegister)
15
else
register
insertIndex = stringBuilderIndex + 1
it.mutableClass.staticFields.add(
ImmutableField(
definingClass,
"buffer",
"Ljava/nio/ByteBuffer;",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
annotations,
null
).toMutable()
)
}
} ?: return IdentifierFingerprint.toErrorResult()
@ -124,7 +154,8 @@ class ComponentParserPatch : BytecodePatch(
var insertIndex by Delegates.notNull<Int>()
var freeRegister by Delegates.notNull<Int>()
var freeRegister = 15
var identifierRegister by Delegates.notNull<Int>()
var objectRegister by Delegates.notNull<Int>()
var stringBuilderRegister by Delegates.notNull<Int>()
@ -135,7 +166,7 @@ class ComponentParserPatch : BytecodePatch(
insertMethod.apply {
addInstructionsWithLabels(
insertIndex,
"""
"""
sget-object v$freeRegister, $definingClass->buffer:Ljava/nio/ByteBuffer;
invoke-static {v$stringBuilderRegister, v$identifierRegister, v$objectRegister, v$freeRegister}, $descriptor(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/Object;Ljava/nio/ByteBuffer;)Z
move-result v$freeRegister
@ -152,7 +183,7 @@ class ComponentParserPatch : BytecodePatch(
insertMethod.apply {
addInstructionsWithLabels(
insertIndex,
"""
"""
invoke-static {v$stringBuilderRegister, v$identifierRegister}, $descriptor(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
move-result v$freeRegister
if-eqz v$freeRegister, :unfiltered
@ -169,7 +200,7 @@ class ComponentParserPatch : BytecodePatch(
insertMethod.apply {
addInstructionsWithLabels(
insertIndex,
"""
"""
move-object/from16 v$freeRegister, p3
iget-object v$freeRegister, v$freeRegister, ${parameters[2]}->b:Ljava/lang/Object;
if-eqz v$freeRegister, :unfiltered

View File

@ -0,0 +1,18 @@
package app.revanced.patches.youtube.general.mixplaylists.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ElementParserFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.INVOKE_VIRTUAL_RANGE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ
),
strings = listOf("Failed to parse Element")
)

View File

@ -13,8 +13,10 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.general.mixplaylists.fingerprints.BottomPanelOverlayTextFingerprint
import app.revanced.patches.youtube.general.mixplaylists.fingerprints.ElementParserFingerprint
import app.revanced.patches.youtube.general.mixplaylists.fingerprints.EmptyFlatBufferFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
@ -32,6 +34,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
class MixPlaylistsPatch : BytecodePatch(
listOf(
BottomPanelOverlayTextFingerprint,
ElementParserFingerprint,
EmptyFlatBufferFingerprint
)
) {
@ -57,6 +60,14 @@ class MixPlaylistsPatch : BytecodePatch(
* Separated from bytebuffer patch
* Target method is only used for Hide MixPlaylists patch
*/
ElementParserFingerprint.result
?: EmptyFlatBufferFingerprint.result
?: throw EmptyFlatBufferFingerprint.toErrorResult()
/**
* ~YouTube v18.29.38
*/
EmptyFlatBufferFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = implementation!!.instructions.indexOfFirst { instruction ->
@ -65,22 +76,34 @@ class MixPlaylistsPatch : BytecodePatch(
val jumpIndex = getStringIndex("Failed to convert Element to Flatbuffers: %s") + 2
val freeIndex = it.scanResult.patternScanResult!!.startIndex - 1
val freeRegister = getInstruction<TwoRegisterInstruction>(freeIndex).registerA
addInstructionsWithLabels(
insertIndex, """
invoke-static {v$freeRegister}, $GENERAL->hideMixPlaylists([B)Z
move-result v$freeRegister
if-nez v$freeRegister, :not_an_ad
""", ExternalLabel("not_an_ad", getInstruction(jumpIndex))
)
addInstruction(
0,
"move-object/from16 v$freeRegister, p3"
)
inject(freeIndex, insertIndex, jumpIndex)
}
} ?: return EmptyFlatBufferFingerprint.toErrorResult()
}
/**
* YouTube v18.30.xx~
*/
ElementParserFingerprint.result?.let {
it.mutableMethod.apply {
val methodInstructions = implementation!!.instructions
val insertIndex = methodInstructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.INVOKE_INTERFACE
}
val freeIndex = it.scanResult.patternScanResult!!.startIndex - 1
for (index in methodInstructions.size - 1 downTo 0) {
if (getInstruction(index).opcode != Opcode.INVOKE_INTERFACE_RANGE) continue
val jumpIndex = index + 1
inject(freeIndex, insertIndex, jumpIndex)
break
}
}
}
/**
* Add settings
@ -96,4 +119,26 @@ class MixPlaylistsPatch : BytecodePatch(
return PatchResultSuccess()
}
private companion object {
fun MutableMethod.inject(
freeIndex: Int,
insertIndex: Int,
jumpIndex: Int
) {
val freeRegister = getInstruction<TwoRegisterInstruction>(freeIndex).registerA
addInstructionsWithLabels(
insertIndex, """
invoke-static {v$freeRegister}, $GENERAL->hideMixPlaylists([B)Z
move-result v$freeRegister
if-nez v$freeRegister, :not_an_ad
""", ExternalLabel("not_an_ad", getInstruction(jumpIndex))
)
addInstruction(
0,
"move-object/from16 v$freeRegister, p3"
)
}
}
}

View File

@ -3,15 +3,9 @@ package app.revanced.patches.youtube.misc.externalbrowser.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ExternalBrowserSecondaryFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(
Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.CONST_STRING
),
strings = listOf("android.support.customtabs.action.CustomTabsService")
)

View File

@ -17,6 +17,7 @@ import app.revanced.patches.youtube.misc.externalbrowser.fingerprints.ExternalBr
import app.revanced.patches.youtube.misc.externalbrowser.fingerprints.ExternalBrowserTertiaryFingerprint
import app.revanced.patches.youtube.utils.annotations.YouTubeCompatibility
import app.revanced.patches.youtube.utils.settings.resource.patch.SettingsPatch
import app.revanced.util.bytecode.getStringIndex
import app.revanced.util.integrations.Constants.MISC_PATH
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -42,11 +43,11 @@ class ExternalBrowserPatch : BytecodePatch(
).forEach { fingerprint ->
fingerprint.result?.let {
it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex
val register = getInstruction<OneRegisterInstruction>(endIndex).registerA
val targetIndex = getStringIndex("android.support.customtabs.action.CustomTabsService")
val register = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
endIndex + 1, """
targetIndex + 1, """
invoke-static {v$register}, $MISC_PATH/ExternalBrowserPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$register
"""

View File

@ -79,7 +79,10 @@ class HideFilmstripOverlayPatch : BytecodePatch(
if (SettingsPatch.upward1828) {
for (index in insertIndex .. initialIndex) {
if (getInstruction(index).opcode != Opcode.CONST_16 && getInstruction(index).opcode != Opcode.CONST) continue
if (getInstruction(index).opcode != Opcode.CONST_16 &&
getInstruction(index).opcode != Opcode.CONST_4 &&
getInstruction(index).opcode != Opcode.CONST)
continue
val register = getInstruction<OneRegisterInstruction>(index).registerA
val value = getInstruction<WideLiteralInstruction>(index).wideLiteral.toInt()
@ -89,6 +92,10 @@ class HideFilmstripOverlayPatch : BytecodePatch(
Opcode.CONST_16 -> """
const/16 v$register, $value
""".trimIndent()
Opcode.CONST_4 -> """
const/4 v$register, $value
""".trimIndent()
Opcode.CONST -> """
const v$register, $value

View File

@ -41,6 +41,9 @@ class ShortsSubscriptionsButtonPatch : BytecodePatch(
}
} ?: return ShortsSubscriptionsFingerprint.toErrorResult()
/**
* Deprecated in YouTube v18.31.xx+
*/
ShortsSubscriptionsTabletParentFingerprint.result?.let { parentResult ->
parentResult.mutableMethod.apply {
val targetIndex = getWideLiteralIndex(ReelPlayerFooter) - 1

View File

@ -13,7 +13,8 @@ import app.revanced.patcher.annotation.Package
"18.24.37",
"18.25.40",
"18.27.36",
"18.29.38"
"18.29.38",
"18.30.37"
)
)]
)

View File

@ -12,6 +12,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.MOVE_OBJECT,
Opcode.CHECK_CAST,
Opcode.MOVE_OBJECT
)

View File

@ -0,0 +1,18 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object TextComponentAtomicReferenceLegacyFingerprint : MethodFingerprint(
returnType = "L",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.MOVE_OBJECT
)
)

View File

@ -8,6 +8,7 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
@ -20,6 +21,7 @@ import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerpri
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.LikeFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.RemoveLikeFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentAtomicReferenceFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentAtomicReferenceLegacyFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentConstructorFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentContextFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentTmpFingerprint
@ -101,12 +103,34 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
} ?: return TextComponentTmpFingerprint.toErrorResult()
val textComponentAtomicReferenceResult =
TextComponentAtomicReferenceFingerprint.also {
it.resolve(context, parentResult.classDef)
}.result
?:TextComponentAtomicReferenceLegacyFingerprint.also {
it.resolve(context, parentResult.classDef)
}.result
?: return TextComponentAtomicReferenceLegacyFingerprint.toErrorResult()
TextComponentAtomicReferenceFingerprint.also {
it.resolve(
context,
parentResult.classDef
)
it.resolve(context, parentResult.classDef)
}.result?.let {
it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex
val originalRegisterA = getInstruction<TwoRegisterInstruction>(startIndex + 2).registerA
replaceInstruction(
startIndex + 2,
"move-object v$originalRegisterA, v$tmpRegister"
)
replaceInstruction(
startIndex + 1,
"move-result-object v$tmpRegister"
)
}
}
textComponentAtomicReferenceResult.let {
it.mutableMethod.apply {
val atomicReferenceStartIndex = it.scanResult.patternScanResult!!.startIndex
val insertIndex = it.scanResult.patternScanResult!!.endIndex
@ -130,7 +154,7 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
)
removeInstruction(insertIndex)
}
} ?: return TextComponentAtomicReferenceFingerprint.toErrorResult()
}
} ?: return TextComponentConstructorFingerprint.toErrorResult()