diff --git a/src/main/kotlin/app/revanced/shared/Index.kt b/src/main/kotlin/app/revanced/Index.kt similarity index 89% rename from src/main/kotlin/app/revanced/shared/Index.kt rename to src/main/kotlin/app/revanced/Index.kt index bdb08a6a0..c3bed6708 100644 --- a/src/main/kotlin/app/revanced/shared/Index.kt +++ b/src/main/kotlin/app/revanced/Index.kt @@ -1,4 +1,4 @@ -package app.revanced.shared +package app.revanced import app.revanced.patcher.patch.Patch import app.revanced.patches.ad.VideoAdsPatch @@ -7,7 +7,7 @@ import app.revanced.patches.layout.* import app.revanced.patches.misc.IntegrationsPatch /** - * Index contains all the patches and signatures. + * Index contains all the patches. */ @Suppress("Unused") object Index { diff --git a/src/main/kotlin/app/revanced/patches/ad/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/ad/VideoAdsPatch.kt index b10fdd372..497f4422f 100644 --- a/src/main/kotlin/app/revanced/patches/ad/VideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/ad/VideoAdsPatch.kt @@ -18,7 +18,7 @@ class VideoAdsPatch : Patch( metadata = PatchMetadata( shortName = "video-ads", name = "YouTube Video Ads Patch", - description = "Patch to remove ads in the YouTube video player", + description = "Patch to remove ads in the YouTube video player.", compatiblePackages = compatiblePackages, version = "0.0.1" ), @@ -62,11 +62,7 @@ class VideoAdsPatch : Patch( ) ) { override fun execute(patcherData: PatcherData): PatchResult { - val constructorSignature = signatures.first() - var result = signatures.first().result - result ?: return PatchResultError( - "Could not resolve required signature ${constructorSignature.methodSignatureMetadata.name}" - ) + var result = signatures.first().result!! val responsibleMethodSignature = MethodSignature( methodSignatureMetadata = MethodSignatureMetadata( diff --git a/src/main/kotlin/app/revanced/patches/interaction/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/interaction/EnableSeekbarTappingPatch.kt index 90d3a6925..f33987b0a 100644 --- a/src/main/kotlin/app/revanced/patches/interaction/EnableSeekbarTappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/interaction/EnableSeekbarTappingPatch.kt @@ -1,31 +1,135 @@ package app.revanced.patches.interaction -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData +import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.PatchMetadata import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.signature.MethodMetadata +import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstructions +import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode import org.jf.dexlib2.builder.instruction.BuilderInstruction21t import org.jf.dexlib2.iface.Method import org.jf.dexlib2.iface.instruction.formats.Instruction11n +private val compatiblePackages = arrayOf("com.google.android.youtube") + class EnableSeekbarTappingPatch : Patch( - PatchMetadata( - "enable-seekbar-tapping", - "TODO", - "TODO" + metadata = PatchMetadata( + "seekbar-tapping", + "Enable seekbar tapping patch", + "Enable tapping on the seekbar of the YouTube player.", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "enable-seekbar-tapping-parent-signature", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for a parent method, which is needed to find the actual method required to be patched.", + version = "0.0.1" + ), + returnType = "L", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + methodParameters = listOf(), + opcodes = listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_4, + Opcode.NEW_ARRAY, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_WIDE, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_4, + Opcode.APUT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_WIDE, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_4, + Opcode.APUT_OBJECT, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.RETURN_OBJECT + ) + ), + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "enable-seekbar-tapping-signature", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for the method required to be patched.", + version = "0.0.1" + ), + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + methodParameters = listOf("L"), + opcodes = listOf( + Opcode.CMPG_DOUBLE, + Opcode.IF_GTZ, + Opcode.GOTO, + Opcode.INT_TO_FLOAT, + Opcode.INT_TO_FLOAT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.RETURN, + Opcode.IGET_OBJECT, + Opcode.IF_EQZ, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_WIDE, + Opcode.INT_TO_FLOAT, + Opcode.IGET, + Opcode.IGET_OBJECT, + Opcode.IGET, + Opcode.DIV_INT_2ADDR, + Opcode.ADD_INT, + Opcode.SUB_INT_2ADDR, + Opcode.INT_TO_FLOAT, + Opcode.CMPG_FLOAT, + Opcode.IF_GTZ, + Opcode.INT_TO_FLOAT, + Opcode.CMPG_FLOAT, + Opcode.IF_GTZ, + Opcode.CONST_4, + Opcode.INVOKE_INTERFACE, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_VIRTUAL + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { - var map = cache.methodMap["tap-seekbar-parent-method"] + override fun execute(patcherData: PatcherData): PatchResult { + var result = signatures.first().result!! val tapSeekMethods = mutableMapOf() // find the methods which tap the seekbar - for (it in map.definingClassProxy.immutableClass.methods) { + for (it in result.definingClassProxy.immutableClass.methods) { if (it.implementation == null) continue val instructions = it.implementation!!.instructions @@ -45,16 +149,16 @@ class EnableSeekbarTappingPatch : Patch( } // replace map because we dont need the upper one anymore - map = cache.methodMap["enable-seekbar-tapping"] + result = signatures.last().result!! - val implementation = map.method.implementation!! + val implementation = result.method.implementation!! // if tap-seeking is enabled, do not invoke the two methods below val pMethod = tapSeekMethods["P"]!! val oMethod = tapSeekMethods["O"]!! implementation.addInstructions( - map.scanData.endIndex, + result.scanData.endIndex, """ invoke-virtual { v12, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V invoke-virtual { v12, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V @@ -62,13 +166,13 @@ class EnableSeekbarTappingPatch : Patch( ) // if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label - val elseLabel = implementation.newLabelForIndex(map.scanData.endIndex) + val elseLabel = implementation.newLabelForIndex(result.scanData.endIndex) implementation.addInstruction( - map.scanData.endIndex, + result.scanData.endIndex, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) ) implementation.addInstructions( - map.scanData.endIndex, + result.scanData.endIndex, """ invoke-static { }, Lfi/razerman/youtube/preferences/BooleanPreferences;->isTapSeekingEnabled()Z move-result v0 diff --git a/src/main/kotlin/app/revanced/patches/layout/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/layout/CreateButtonRemoverPatch.kt index 20b233695..836f3e178 100644 --- a/src/main/kotlin/app/revanced/patches/layout/CreateButtonRemoverPatch.kt +++ b/src/main/kotlin/app/revanced/patches/layout/CreateButtonRemoverPatch.kt @@ -1,25 +1,85 @@ package app.revanced.patches.layout -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData +import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.PatchMetadata import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.signature.MethodMetadata +import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstruction +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +private val compatiblePackages = arrayOf("com.google.android.youtube") class CreateButtonRemoverPatch : Patch( - PatchMetadata( - "create-button-remover", - "TODO", - "TODO" + metadata = PatchMetadata( + "create-button", + "Create button patch", + "Disable the create button.", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "create-button-method", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for the method required to be patched.", + version = "0.0.1" + ), + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + methodParameters = listOf("Z"), + opcodes = listOf( + Opcode.IGET, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.CONST, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.INVOKE_DIRECT_RANGE, + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.MOVE_OBJECT + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { - val map = cache.methodMap["create-button-patch"] + override fun execute(patcherData: PatcherData): PatchResult { + val result = signatures.first().result!! // Hide the button view via proxy by passing it to the hideCreateButton method - map.method.implementation!!.addInstruction( - map.scanData.endIndex, + result.method.implementation!!.addInstruction( + result.scanData.endIndex, "invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->hideCreateButton(Landroid/view/View;)V".asInstruction() ) diff --git a/src/main/kotlin/app/revanced/patches/layout/HideReelsPatch.kt b/src/main/kotlin/app/revanced/patches/layout/HideReelsPatch.kt index f92b22bd2..f86ef2a2e 100644 --- a/src/main/kotlin/app/revanced/patches/layout/HideReelsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/layout/HideReelsPatch.kt @@ -1,27 +1,106 @@ package app.revanced.patches.layout -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData +import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.patch.Patch import app.revanced.patcher.patch.PatchMetadata import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.signature.MethodMetadata +import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstruction +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +private val compatiblePackages = arrayOf("com.google.android.youtube") class HideReelsPatch : Patch( - PatchMetadata( + metadata = PatchMetadata( "hide-reels", - "TODO", - "TODO" + "Hide reels patch", + "Hide reels on the page.", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "hide-reels-signature", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for the method required to be patched.", + version = "0.0.1" + ), + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + methodParameters = listOf( + "L", + "L", + "L", + "L", + "L", + "L", + "L", + "L", + "L", + "L", + "L", + "[B", + "[B", + "[B", + "[B", + "[B", + "[B" + ), + opcodes = listOf( + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.INVOKE_DIRECT, + Opcode.MOVE_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT_FROM16, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT_FROM16, + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.MOVE_OBJECT_FROM16, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST, + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IPUT_OBJECT + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { - val map = cache.methodMap["hide-reel-patch"] - val implementation = map.method.implementation!! + override fun execute(patcherData: PatcherData): PatchResult { + val result = signatures.first().result!! + val implementation = result.method.implementation!! // HideReel will hide the reel view before it is being used, // so we pass the view to the HideReel method implementation.addInstruction( - map.scanData.endIndex - 1, + result.scanData.endIndex - 1, "invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->HideReel(Landroid/view/View;)V".asInstruction() ) diff --git a/src/main/kotlin/app/revanced/patches/layout/HideSuggestionsPatch.kt b/src/main/kotlin/app/revanced/patches/layout/HideSuggestionsPatch.kt index a6abd5db1..edf348ebd 100644 --- a/src/main/kotlin/app/revanced/patches/layout/HideSuggestionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/layout/HideSuggestionsPatch.kt @@ -1,13 +1,15 @@ package app.revanced.patches.layout -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.* import app.revanced.patcher.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patcher.signature.MethodMetadata import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstructions -import app.revanced.patches.SHARED_METADATA import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode import org.jf.dexlib2.builder.instruction.BuilderInstruction22c @@ -17,20 +19,72 @@ import org.jf.dexlib2.iface.instruction.formats.Instruction35c import org.jf.dexlib2.immutable.ImmutableMethod import org.jf.dexlib2.immutable.ImmutableMethodImplementation +private val compatiblePackages = arrayOf("com.google.android.youtube") + class HideSuggestionsPatch : Patch( - PatchMetadata( + metadata = PatchMetadata( "hide-suggestions", - "TODO", - "TODO" + "Hide suggestions patch", + "Hide suggested videos.", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "hide-suggestions-parent-method", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for a parent method, which is needed to find the actual method required to be patched.", + version = "0.0.1" + ), + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + methodParameters = listOf("L", "Z"), + opcodes = listOf( + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET, + Opcode.AND_INT_LIT16, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.CONST, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.CHECK_CAST, + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.GOTO, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, + Opcode.IF_EQ + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { - val map = cache.methodMap["hide-suggestions-patch"].findParentMethod( + override fun execute(patcherData: PatcherData): PatchResult { + val result = signatures.first().result!!.findParentMethod( MethodSignature( - "hide-suggestions-method", - SHARED_METADATA, - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, + methodSignatureMetadata = MethodSignatureMetadata( + name = "hide-suggestions-method", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for the method, which is required to be patched.", + version = "0.0.1" + ), + returnType = "V", + accessFlags = AccessFlags.FINAL or AccessFlags.PUBLIC, listOf("Z"), listOf( Opcode.IPUT_BOOLEAN, @@ -40,11 +94,11 @@ class HideSuggestionsPatch : Patch( Opcode.RETURN_VOID ) ) - ) ?: return PatchResultError("Parent method hide-suggestions-method has not been found") + ) ?: return PatchResultError("Method old-quality-patch-method has not been found") // deep clone the method in order to add a new register // TODO: replace by a mutable method implementation with settable register count when available - val originalMethod = map.immutableMethod + val originalMethod = result.immutableMethod val originalImplementation = originalMethod.implementation!! val clonedMethod = ImmutableMethod( originalMethod.returnType, @@ -96,7 +150,7 @@ class HideSuggestionsPatch : Patch( } // resolve the class proxy - val clazz = map.definingClassProxy.resolve() + val clazz = result.definingClassProxy.resolve() // remove the old method & add the clone with our additional register clazz.methods.remove(originalMethod) diff --git a/src/main/kotlin/app/revanced/patches/layout/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/layout/MinimizedPlaybackPatch.kt index 38bd78721..39731d890 100644 --- a/src/main/kotlin/app/revanced/patches/layout/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/layout/MinimizedPlaybackPatch.kt @@ -1,33 +1,80 @@ package app.revanced.patches.layout -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData +import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.patch.Patch -import app.revanced.patcher.patch.PatchMetadata -import app.revanced.patcher.patch.PatchResult -import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.* +import app.revanced.patcher.signature.MethodMetadata +import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstructions +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +private val compatiblePackages = arrayOf("com.google.android.youtube") class MinimizedPlaybackPatch : Patch( - PatchMetadata( + metadata = PatchMetadata( "minimized-playback", - "TODO", - "TODO" + "Minimized Playback Patch", + "Enable minimized and background playback.", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "minimized-playback-manager", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature for the method required to be patched.", + version = "0.0.1" + ), + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + methodParameters = listOf("L"), + opcodes = listOf( + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET, + Opcode.AND_INT_LIT16, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.CONST, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.CHECK_CAST, + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.GOTO, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, + Opcode.IF_EQ + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { + override fun execute(patcherData: PatcherData): PatchResult { // Instead of removing all instructions like Vanced, // we return the method at the beginning instead - cache.methodMap["minimized-playback-manager"] - .method - .implementation!! - .addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 + signatures.first().result!!.method.implementation!!.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 """.trimIndent().asInstructions() - ) + ) return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/layout/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/layout/OldQualityLayoutPatch.kt index 77b6185c7..3d494beb2 100644 --- a/src/main/kotlin/app/revanced/patches/layout/OldQualityLayoutPatch.kt +++ b/src/main/kotlin/app/revanced/patches/layout/OldQualityLayoutPatch.kt @@ -1,30 +1,91 @@ package app.revanced.patches.layout -import app.revanced.patcher.cache.Cache +import app.revanced.patcher.PatcherData import app.revanced.patcher.extensions.AccessFlagExtensions.Companion.or import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.* +import app.revanced.patcher.signature.MethodMetadata import app.revanced.patcher.signature.MethodSignature +import app.revanced.patcher.signature.MethodSignatureMetadata +import app.revanced.patcher.signature.PatternScanMethod import app.revanced.patcher.smali.asInstructions -import app.revanced.patches.SHARED_METADATA import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode import org.jf.dexlib2.builder.instruction.BuilderInstruction21t +private val compatiblePackages = arrayOf("com.google.android.youtube") + class OldQualityLayoutPatch : Patch( - PatchMetadata( + metadata = PatchMetadata( "old-quality-layout", - "TODO", - "TODO" + "Old Quality Layout Patch", + "Enable the original quality flyout menu", + compatiblePackages, + "1.0.0" + ), + signatures = listOf( + MethodSignature( + methodSignatureMetadata = MethodSignatureMetadata( + name = "old-quality-parent-method-signature", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature to find a parent method required by the Old Quality Layout patch.", + version = "0.0.1" + ), + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + methodParameters = listOf("L", "L", "L", "L", "L", "L", "L"), + opcodes = listOf( + Opcode.IPUT_OBJECT, + Opcode.CONST, + Opcode.CONST, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET_BOOLEAN, + Opcode.CONST_4, + Opcode.CONST_4, + Opcode.CONST, + ) + ) ) ) { - override fun execute(cache: Cache): PatchResult { - val map = cache.methodMap["old-quality-patch"].findParentMethod( + override fun execute(patcherData: PatcherData): PatchResult { + var result = signatures.first().result!! + + result = result.findParentMethod( MethodSignature( - "old-quality-patch-method", - SHARED_METADATA, - "L", - AccessFlags.FINAL or AccessFlags.PUBLIC, + methodSignatureMetadata = MethodSignatureMetadata( + name = "old-quality-method-signature", + methodMetadata = MethodMetadata(null, null), // unknown + patternScanMethod = PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. + compatiblePackages = compatiblePackages, + description = "Signature to find the method required by the Old Quality Layout patch", + version = "0.0.1" + ), + returnType = "L", + accessFlags = AccessFlags.FINAL or AccessFlags.PUBLIC, emptyList(), listOf( Opcode.IGET, @@ -36,9 +97,9 @@ class OldQualityLayoutPatch : Patch( Opcode.RETURN_OBJECT ) ) - ) ?: return PatchResultError("Parent method old-quality-patch-method has not been found") + ) ?: return PatchResultError("Method old-quality-patch-method has not been found") - val implementation = map.method.implementation!! + val implementation = result.method.implementation!! // if useOldStyleQualitySettings == true, jump over all instructions and return the field at the end val jmpInstruction = diff --git a/src/main/kotlin/app/revanced/patches/misc/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/misc/IntegrationsPatch.kt index 3b0c2e3ff..8b60412aa 100644 --- a/src/main/kotlin/app/revanced/patches/misc/IntegrationsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/misc/IntegrationsPatch.kt @@ -20,8 +20,8 @@ private val compatiblePackages = arrayOf("com.google.android.youtube") class IntegrationsPatch : Patch( metadata = PatchMetadata( "integrations", - "Inject integrations", - "Applies mandatory patches to implement the ReVanced integrations into the application", + "Inject integrations Patch", + "Applies mandatory patches to implement the ReVanced integrations into the application.", compatiblePackages, "1.0.0" ), @@ -76,11 +76,7 @@ class IntegrationsPatch : Patch( ) ) { override fun execute(patcherData: PatcherData): PatchResult { - val signature = signatures.first() - val result = signatures.first().result - result ?: return PatchResultError( - "Could not resolve required signature ${signature.methodSignatureMetadata.name}" - ) + val result = signatures.first().result!! val implementation = result.method.implementation!! val count = implementation.registerCount - 1