feat(youtube): support version 18.08.37
This commit is contained in:
+7
-2
@@ -6,6 +6,7 @@ import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.instruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchResult
|
||||
import app.revanced.patcher.patch.PatchResultSuccess
|
||||
@@ -20,6 +21,7 @@ import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutC
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import org.jf.dexlib2.iface.instruction.Instruction
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
import org.jf.dexlib2.iface.reference.MethodReference
|
||||
@@ -66,12 +68,15 @@ class HideAutoplayButtonPatch : BytecodePatch(
|
||||
|
||||
val jumpInstruction = layoutGenMethodInstructions[insertIndex + branchIndex] as Instruction
|
||||
|
||||
// can be clobbered because this register is overwritten after the injected code
|
||||
val clobberRegister = (instruction(insertIndex) as OneRegisterInstruction).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/patches/HideAutoplayButtonPatch;->isButtonShown()Z
|
||||
move-result v11
|
||||
if-eqz v11, :hidden
|
||||
move-result v$clobberRegister
|
||||
if-eqz v$clobberRegister, :hidden
|
||||
""", listOf(ExternalLabel("hidden", jumpInstruction))
|
||||
)
|
||||
} ?: return LayoutConstructorFingerprint.toErrorResult()
|
||||
|
||||
+3
-2
@@ -6,14 +6,15 @@ import app.revanced.patcher.annotation.Package
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf(
|
||||
"17.49.37",
|
||||
"17.49.37",
|
||||
"18.03.36",
|
||||
"18.03.42",
|
||||
"18.04.35",
|
||||
"18.04.41",
|
||||
"18.05.32",
|
||||
"18.05.35",
|
||||
"18.05.40"
|
||||
"18.05.40",
|
||||
"18.08.37"
|
||||
)
|
||||
)]
|
||||
)
|
||||
|
||||
-3
@@ -7,12 +7,9 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
|
||||
object CrowdfundingBoxFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_4,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.CONST,
|
||||
),
|
||||
customFingerprint = { methodDef ->
|
||||
methodDef.implementation?.instructions?.any { instruction ->
|
||||
|
||||
+14
-11
@@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
@@ -15,7 +16,7 @@ import app.revanced.patches.youtube.layout.hide.crowdfundingbox.annotations.Crow
|
||||
import app.revanced.patches.youtube.layout.hide.crowdfundingbox.bytecode.fingerprints.CrowdfundingBoxFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.crowdfundingbox.resource.patch.CrowdfundingBoxResourcePatch
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@DependsOn([IntegrationsPatch::class, CrowdfundingBoxResourcePatch::class])
|
||||
@@ -29,18 +30,20 @@ class CrowdfundingBoxPatch : BytecodePatch(
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
val crowdfundingBoxResult = CrowdfundingBoxFingerprint.result!!
|
||||
val crowdfundingBoxMethod = crowdfundingBoxResult.mutableMethod
|
||||
CrowdfundingBoxFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val objectRegister = (instruction(insertIndex) as TwoRegisterInstruction).registerA
|
||||
|
||||
val moveResultObjectIndex =
|
||||
crowdfundingBoxResult.scanResult.patternScanResult!!.endIndex - 2
|
||||
|
||||
crowdfundingBoxMethod.addInstruction(
|
||||
moveResultObjectIndex + 1, """
|
||||
invoke-static {v${(crowdfundingBoxMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V
|
||||
"""
|
||||
)
|
||||
addInstruction(insertIndex, "invoke-static {v$objectRegister}, $INTEGRATIONS_METHOD_DESCRIPTOR")
|
||||
}
|
||||
} ?: return CrowdfundingBoxFingerprint.toErrorResult()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-14
@@ -3,19 +3,6 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike.annotations
|
||||
import app.revanced.patcher.annotation.Compatibility
|
||||
import app.revanced.patcher.annotation.Package
|
||||
|
||||
@Compatibility(
|
||||
[Package(
|
||||
"com.google.android.youtube", arrayOf(
|
||||
"17.49.37",
|
||||
"18.03.36",
|
||||
"18.03.42",
|
||||
"18.04.35",
|
||||
"18.04.41",
|
||||
"18.05.32",
|
||||
"18.05.35",
|
||||
"18.05.40"
|
||||
)
|
||||
)]
|
||||
)
|
||||
@Compatibility([Package("com.google.android.youtube", arrayOf("18.08.37"))])
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
internal annotation class ReturnYouTubeDislikeCompatibility
|
||||
-3
@@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object DislikeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/dislike")
|
||||
)
|
||||
-3
@@ -1,14 +1,11 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
|
||||
@FuzzyPatternScanMethod(2)
|
||||
object LikeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/like")
|
||||
)
|
||||
-3
@@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object RemoveLikeFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf("like/removelike")
|
||||
)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
object TextComponentConstructorFingerprint : MethodFingerprint(
|
||||
access = AccessFlags.CONSTRUCTOR or AccessFlags.PRIVATE,
|
||||
strings = listOf("TextComponent")
|
||||
)
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
object TextComponentFingerprint : MethodFingerprint(
|
||||
strings = listOf("com.google.android.apps.youtube.music")
|
||||
)
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
|
||||
object TextComponentSpecParentFingerprint : MethodFingerprint(
|
||||
strings = listOf("TextComponentSpec: No converter for extension: ")
|
||||
)
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object TextReferenceFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC_RANGE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.INVOKE_VIRTUAL
|
||||
)
|
||||
)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
object TextReferenceParamFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.MOVE_OBJECT_FROM16 // the first occurrence of this instruction uses the register for the text object
|
||||
)
|
||||
)
|
||||
+35
-20
@@ -25,7 +25,9 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.patch.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.video.videoid.patch.VideoIdPatch
|
||||
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.TwoRegisterInstruction
|
||||
|
||||
@Patch
|
||||
@DependsOn(
|
||||
@@ -42,7 +44,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@Version("0.0.1")
|
||||
class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
listOf(
|
||||
TextComponentSpecParentFingerprint,
|
||||
TextComponentConstructorFingerprint,
|
||||
ShortsTextComponentParentFingerprint,
|
||||
LikeFingerprint,
|
||||
DislikeFingerprint,
|
||||
@@ -78,27 +80,37 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
// region Hook components
|
||||
|
||||
TextComponentFingerprint.also { it.resolve(context, TextComponentSpecParentFingerprint.result!!.classDef) }
|
||||
.result?.let {
|
||||
with(it.mutableMethod) {
|
||||
val createComponentMethod = this
|
||||
TextReferenceFingerprint.also {
|
||||
it.resolve(
|
||||
context,
|
||||
TextComponentConstructorFingerprint.result!!.classDef
|
||||
)
|
||||
}.result?.let { result ->
|
||||
val moveTextRefParamInstructionIndex = TextReferenceParamFingerprint.also {
|
||||
if (!TextReferenceParamFingerprint.resolve(context, result.method, result.classDef))
|
||||
return TextReferenceParamFingerprint.toErrorResult()
|
||||
}.result!!.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
val conversionContextParam = 5
|
||||
val textRefParam = createComponentMethod.parameters.size - 2
|
||||
// Insert index must be 0, otherwise UI does not updated correctly in some situations
|
||||
// such as switching from full screen or when using previous/next overlay buttons.
|
||||
val insertIndex = 0
|
||||
result.mutableMethod.apply {
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
createComponentMethod.addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-object/from16 v7, p$conversionContextParam
|
||||
move-object/from16 v8, p$textRefParam
|
||||
invoke-static {v7, v8}, $INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: return TextComponentFingerprint.toErrorResult()
|
||||
val atomicReferenceInstruction = (instruction(insertIndex - 1) as FiveRegisterInstruction)
|
||||
val conversionContextParam = atomicReferenceInstruction.registerC
|
||||
val textRefParam = (instruction(moveTextRefParamInstructionIndex) as TwoRegisterInstruction).registerA
|
||||
|
||||
// Overwritten after injected code, which is why it can be used.
|
||||
val clobberRegister = atomicReferenceInstruction.registerD
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
# required instruction, otherwise register might be out of range
|
||||
move-object/from16 v$clobberRegister, v$textRefParam
|
||||
invoke-static {v$clobberRegister, v$conversionContextParam}, $ON_COMPONENT_CREATED_DESCRIPTOR
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: return TextReferenceFingerprint.toErrorResult()
|
||||
|
||||
ShortsTextComponentParentFingerprint.result?.let {
|
||||
context
|
||||
@@ -138,6 +150,9 @@ class ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
const val INTEGRATIONS_PATCH_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/patches/ReturnYouTubeDislikePatch;"
|
||||
|
||||
const val ON_COMPONENT_CREATED_DESCRIPTOR =
|
||||
"$INTEGRATIONS_PATCH_CLASS_DESCRIPTOR->onComponentCreated(Ljava/lang/Object;Ljava/util/concurrent/atomic/AtomicReference;)V"
|
||||
|
||||
private fun MethodFingerprint.toPatch(voteKind: Vote) = VotePatch(this, voteKind)
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -30,10 +30,6 @@ class SpoofAppVersionPatch : BytecodePatch(
|
||||
SpoofAppVersionFingerprint
|
||||
)
|
||||
) {
|
||||
companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofAppVersionPatch"
|
||||
}
|
||||
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
|
||||
SwitchPreference(
|
||||
@@ -61,4 +57,8 @@ class SpoofAppVersionPatch : BytecodePatch(
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/patches/SpoofAppVersionPatch"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ import org.jf.dexlib2.AccessFlags
|
||||
import org.jf.dexlib2.Opcode
|
||||
|
||||
|
||||
@FuzzyPatternScanMethod(2) // TODO: Find a good threshold value
|
||||
@FuzzyPatternScanMethod(2)
|
||||
object MiniPlayerDimensionsCalculatorFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||
import org.jf.dexlib2.AccessFlags
|
||||
|
||||
|
||||
object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
access = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("L"),
|
||||
strings = listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT")
|
||||
)
|
||||
+23
-15
@@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.youtube.layout.tabletminiplayer.patch
|
||||
|
||||
import app.revanced.extensions.toErrorResult
|
||||
import app.revanced.patcher.annotation.Description
|
||||
import app.revanced.patcher.annotation.Name
|
||||
import app.revanced.patcher.annotation.Version
|
||||
@@ -16,10 +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.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
||||
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
|
||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@@ -33,7 +31,8 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
class TabletMiniPlayerPatch : BytecodePatch(
|
||||
listOf(
|
||||
MiniPlayerDimensionsCalculatorFingerprint,
|
||||
MiniPlayerResponseModelSizeCheckFingerprint
|
||||
MiniPlayerResponseModelSizeCheckFingerprint,
|
||||
MiniPlayerOverrideParentFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext): PatchResult {
|
||||
@@ -47,33 +46,42 @@ class TabletMiniPlayerPatch : BytecodePatch(
|
||||
)
|
||||
)
|
||||
|
||||
// first resolve the fingerprints via the parent fingerprint
|
||||
// First resolve the fingerprints via the parent fingerprint.
|
||||
val miniPlayerClass = MiniPlayerDimensionsCalculatorFingerprint.result!!.classDef
|
||||
|
||||
/*
|
||||
* no context parameter method
|
||||
* No context parameter method.
|
||||
*/
|
||||
MiniPlayerOverrideNoContextFingerprint.resolve(context, miniPlayerClass)
|
||||
val (method, _, parameterRegister) = MiniPlayerOverrideNoContextFingerprint.addProxyCall()
|
||||
// - 1 means to insert before the return instruction
|
||||
|
||||
// Insert right before the return instruction.
|
||||
val secondInsertIndex = method.implementation!!.instructions.size - 1
|
||||
method.insertOverride(secondInsertIndex, parameterRegister /** same register used to return **/)
|
||||
method.insertOverride(
|
||||
secondInsertIndex, parameterRegister
|
||||
/** same register used to return **/
|
||||
)
|
||||
|
||||
/*
|
||||
* method with context parameter
|
||||
* Method with context parameter.
|
||||
*/
|
||||
MiniPlayerOverrideFingerprint.resolve(context, miniPlayerClass)
|
||||
val (_, _, _) = MiniPlayerOverrideFingerprint.addProxyCall()
|
||||
MiniPlayerOverrideParentFingerprint.result?.let {
|
||||
if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef))
|
||||
return MiniPlayerOverrideFingerprint.toErrorResult()
|
||||
|
||||
MiniPlayerOverrideFingerprint.addProxyCall()
|
||||
|
||||
} ?: return MiniPlayerOverrideParentFingerprint.toErrorResult()
|
||||
|
||||
/*
|
||||
* size check return value override
|
||||
* Size check return value override.
|
||||
*/
|
||||
val (_, _, _) = MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall()
|
||||
MiniPlayerResponseModelSizeCheckFingerprint.addProxyCall()
|
||||
|
||||
return PatchResultSuccess()
|
||||
}
|
||||
|
||||
// helper methods
|
||||
// Helper methods.
|
||||
private companion object {
|
||||
fun MethodFingerprint.addProxyCall(): Triple<MutableMethod, Int, Int> {
|
||||
val (method, scanIndex, parameterRegister) = this.unwrap()
|
||||
|
||||
Reference in New Issue
Block a user