feat(youtube): support version 18.15.40

This commit is contained in:
oSumAtrIX 2023-04-23 06:23:42 +02:00
parent ac9ad79f2f
commit b2916a379a
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
10 changed files with 61 additions and 61 deletions

View File

@ -1,13 +1,10 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
object ShortsTextComponentParentFingerprint : MethodFingerprint( object ShortsTextComponentParentFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
access = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = listOf("L", "L"), parameters = listOf("L", "L"),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,

View File

@ -16,15 +16,16 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
Opcode.MOVE_OBJECT, // available unused register Opcode.MOVE_OBJECT, // available unused register
Opcode.MOVE_OBJECT_FROM16, Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16, Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_FROM16, Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here. Opcode.MOVE_OBJECT, // CharSequence reference, and control flow label. Insert code here.
Opcode.INVOKE_VIRTUAL_RANGE, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL_RANGE, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.GOTO, Opcode.GOTO,
Opcode.CONST_4, Opcode.CONST_4,

View File

@ -26,6 +26,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@ -101,14 +102,15 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
textComponentContextFingerprintResult.mutableMethod.apply { textComponentContextFingerprintResult.mutableMethod.apply {
// Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence // Get the conversion context obfuscated field name, and the registers for the AtomicReference and CharSequence
val conversionContextFieldName = val conversionContextFieldReference =
(instruction(conversionContextIndex) as ReferenceInstruction).reference.toString() (instruction(conversionContextIndex) as ReferenceInstruction).reference
val contextRegister = // any free register // any free register
val contextRegister =
(instruction(atomicReferenceStartIndex) as TwoRegisterInstruction).registerB (instruction(atomicReferenceStartIndex) as TwoRegisterInstruction).registerB
val atomicReferenceRegister = val atomicReferenceRegister =
(instruction(atomicReferenceStartIndex + 4) as BuilderInstruction35c).registerC (instruction(atomicReferenceStartIndex + 5) as FiveRegisterInstruction).registerC
val insertIndex = atomicReferenceStartIndex + 7 val insertIndex = atomicReferenceStartIndex + 8
val moveCharSequenceInstruction = instruction(insertIndex) as TwoRegisterInstruction val moveCharSequenceInstruction = instruction(insertIndex) as TwoRegisterInstruction
val charSequenceRegister = moveCharSequenceInstruction.registerB val charSequenceRegister = moveCharSequenceInstruction.registerB
@ -117,10 +119,10 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
replaceInstruction(insertIndex, "move-object/from16 v$contextRegister, p0") replaceInstruction(insertIndex, "move-object/from16 v$contextRegister, p0")
addInstructions( addInstructions(
insertIndex + 1, """ insertIndex + 1, """
iget-object v$contextRegister, v$contextRegister, $conversionContextFieldName # copy obfuscated context field into free register iget-object v$contextRegister, v$contextRegister, $conversionContextFieldReference # copy obfuscated context field into free register
invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; invoke-static {v$contextRegister, v$atomicReferenceRegister, v$charSequenceRegister}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
move-result-object v$charSequenceRegister move-result-object v$charSequenceRegister
move-object v${moveCharSequenceInstruction.registerA}, v${moveCharSequenceInstruction.registerB} # original instruction at the insertion point move-object v${moveCharSequenceInstruction.registerA}, v${charSequenceRegister} # original instruction at the insertion point
""" """
) )
} }

View File

@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.searchbar.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object CreateSearchSuggestionsFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.CONST_4
),
strings = listOf("ss_rds")
)

View File

@ -1,27 +0,0 @@
package app.revanced.patches.youtube.layout.searchbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object DrawActionBarFingerprint : MethodFingerprint(
"V",
AccessFlags.PRIVATE or AccessFlags.FINAL,
listOf("I", "I"),
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.INVOKE_STATIC,
),
)

View File

@ -17,7 +17,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.searchbar.annotations.WideSearchbarCompatibility import app.revanced.patches.youtube.layout.searchbar.annotations.WideSearchbarCompatibility
import app.revanced.patches.youtube.layout.searchbar.fingerprints.DrawActionBarFingerprint import app.revanced.patches.youtube.layout.searchbar.fingerprints.CreateSearchSuggestionsFingerprint
import app.revanced.patches.youtube.layout.searchbar.fingerprints.SetWordmarkHeaderFingerprint import app.revanced.patches.youtube.layout.searchbar.fingerprints.SetWordmarkHeaderFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@ -30,7 +30,7 @@ import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Version("0.0.1") @Version("0.0.1")
class WideSearchbarPatch : BytecodePatch( class WideSearchbarPatch : BytecodePatch(
listOf( listOf(
SetWordmarkHeaderFingerprint, DrawActionBarFingerprint SetWordmarkHeaderFingerprint, CreateSearchSuggestionsFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
@ -44,12 +44,12 @@ class WideSearchbarPatch : BytecodePatch(
) )
) )
val result = DrawActionBarFingerprint.result ?: return DrawActionBarFingerprint.toErrorResult() val result = CreateSearchSuggestionsFingerprint.result ?: return CreateSearchSuggestionsFingerprint.toErrorResult()
// patch methods // patch methods
mapOf( mapOf(
SetWordmarkHeaderFingerprint to 1, SetWordmarkHeaderFingerprint to 1,
DrawActionBarFingerprint to result.scanResult.patternScanResult!!.endIndex CreateSearchSuggestionsFingerprint to result.scanResult.patternScanResult!!.startIndex
).forEach { (fingerprint, callIndex) -> ).forEach { (fingerprint, callIndex) ->
context.walkMutable(callIndex, fingerprint).injectSearchBarHook() context.walkMutable(callIndex, fingerprint).injectSearchBarHook()
} }
@ -68,7 +68,7 @@ class WideSearchbarPatch : BytecodePatch(
fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) = fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) =
fromFingerprint.result?.let { fromFingerprint.result?.let {
toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod
} ?: throw SetWordmarkHeaderFingerprint.toErrorResult() } ?: throw fromFingerprint.toErrorResult()
/** /**

View File

@ -21,7 +21,9 @@ import app.revanced.patches.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility import app.revanced.patches.youtube.layout.sponsorblock.annotations.SponsorBlockCompatibility
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.* import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.AppendTimeFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.PlayerOverlaysLayoutInitFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.bytecode.fingerprints.RectangleFieldInvalidatorFingerprint
import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch import app.revanced.patches.youtube.layout.sponsorblock.resource.patch.SponsorBlockResourcePatch
import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatFingerprint
import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint import app.revanced.patches.youtube.misc.autorepeat.fingerprints.AutoRepeatParentFingerprint
@ -153,14 +155,22 @@ class SponsorBlockBytecodePatch : BytecodePatch(
/* /*
* Draw segment * Draw segment
*/ */
val drawSegmentInstructionInsertIndex = (seekbarMethodInstructions.size - 1 - 2)
val (canvasInstance, centerY) = (seekbarMethodInstructions[drawSegmentInstructionInsertIndex] as FiveRegisterInstruction).let { // Find the drawCircle call and draw the segment before it
it.registerC to it.registerE for (i in seekbarMethodInstructions.size - 1 downTo 0) {
val invokeInstruction = seekbarMethodInstructions[i] as? ReferenceInstruction ?: continue
if ((invokeInstruction.reference as MethodReference).name != "drawCircle") continue
val (canvasInstance, centerY) = (invokeInstruction as FiveRegisterInstruction).let {
it.registerC to it.registerE
}
seekbarMethod.addInstruction(
i,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
)
break
} }
seekbarMethod.addInstruction(
drawSegmentInstructionInsertIndex,
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
)
/* /*
* Voting & Shield button * Voting & Shield button

View File

@ -9,5 +9,5 @@ object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
access = AccessFlags.PUBLIC or AccessFlags.STATIC, access = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"), parameters = listOf("L"),
strings = listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT") strings = listOf("PLAYBACK_RATE_MENU_BOTTOM_SHEET_FRAGMENT")
) )

View File

@ -9,5 +9,5 @@ object ComponentContextParserFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.NEW_INSTANCE Opcode.NEW_INSTANCE
), ),
strings = listOf("LoggingProperties are not in proto format") strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings")
) )

View File

@ -10,7 +10,6 @@ import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
@ -22,6 +21,7 @@ import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponent
import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.Instruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@Description("Hooks the method which parses the bytes into a ComponentContext to filter components.") @Description("Hooks the method which parses the bytes into a ComponentContext to filter components.")
@ -44,15 +44,15 @@ class LithoFilterPatch : BytecodePatch(
val insertHookIndex = result.scanResult.patternScanResult!!.endIndex val insertHookIndex = result.scanResult.patternScanResult!!.endIndex
val builderMethodDescriptor = instruction(builderMethodIndex).descriptor val builderMethodDescriptor = instruction(builderMethodIndex).descriptor
val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor
// Register is overwritten right after it is used for this patch, therefore free to clobber. // Register is overwritten right after it is used in this patch, therefore free to clobber.
val clobberedRegister = instruction(insertHookIndex).oneRegister val clobberedRegister = instruction(insertHookIndex - 1).twoRegisterA
@Suppress("UnnecessaryVariable") @Suppress("UnnecessaryVariable")
// The register, this patch clobbers, is previously used for the StringBuilder, // The register, this patch clobbers, is previously used for the StringBuilder,
// later on a new StringBuilder is instantiated on it. // later on a new StringBuilder is instantiated on it.
val stringBuilderRegister = clobberedRegister val stringBuilderRegister = clobberedRegister
val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegister val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegisterA
addInstructions( addInstructions(
insertHookIndex, // right after setting the component.pathBuilder field, insertHookIndex, // right after setting the component.pathBuilder field,
@ -69,7 +69,7 @@ class LithoFilterPatch : BytecodePatch(
listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex))) listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex)))
) )
} }
} ?: return PatchResultError("Could not find the method to hook.") } ?: return ComponentContextParserFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }
@ -81,8 +81,12 @@ class LithoFilterPatch : BytecodePatch(
val Instruction.descriptor val Instruction.descriptor
get() = (this as ReferenceInstruction).reference.toString() get() = (this as ReferenceInstruction).reference.toString()
val Instruction.oneRegister val Instruction.oneRegisterA
get() = (this as OneRegisterInstruction).registerA get() = (this as OneRegisterInstruction).registerA
val Instruction.twoRegisterA
get() = (this as TwoRegisterInstruction).registerA
} }
} }