diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt index 047b0309a..58181c652 100644 --- a/src/main/kotlin/app/revanced/extensions/Extensions.kt +++ b/src/main/kotlin/app/revanced/extensions/Extensions.kt @@ -1,12 +1,23 @@ package app.revanced.extensions import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.MethodFingerprintExtensions.name +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import org.jf.dexlib2.iface.Method import org.jf.dexlib2.util.MethodUtil import org.w3c.dom.Node +// TODO: populate this to all patches +/** + * Convert a [MethodFingerprint] to a [PatchResultError]. + * + * @return A [PatchResultError] for the [MethodFingerprint]. + */ +fun MethodFingerprint.toErrorResult() = PatchResultError("Failed to resolve $name") + /** * Find the [MutableMethod] from a given [Method] in a [MutableClass]. * diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/createbutton/patch/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/createbutton/patch/CreateButtonRemoverPatch.kt index 61cc2174b..a70dc9f2a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/createbutton/patch/CreateButtonRemoverPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/createbutton/patch/CreateButtonRemoverPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.pivotbar.createbutton.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -19,7 +20,6 @@ import app.revanced.patches.youtube.layout.pivotbar.fingerprints.InitializeButto import app.revanced.patches.youtube.layout.pivotbar.resource.patch.ResolvePivotBarFingerprintsPatch import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.injectHook -import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.toErrorResult import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/resource/patch/ResolvePivotBarFingerprintsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/resource/patch/ResolvePivotBarFingerprintsPatch.kt index bf1cc3f62..785d61c53 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/resource/patch/ResolvePivotBarFingerprintsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/resource/patch/ResolvePivotBarFingerprintsPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.pivotbar.resource.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext @@ -13,7 +14,6 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.youtube.layout.pivotbar.annotations.PivotBarCompatibility import app.revanced.patches.youtube.layout.pivotbar.fingerprints.InitializeButtonsFingerprint import app.revanced.patches.youtube.layout.pivotbar.fingerprints.PivotBarConstructorFingerprint -import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.toErrorResult @DependsOn([ResourceMappingPatch::class]) @PivotBarCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/shortsbutton/patch/ShortsButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/shortsbutton/patch/ShortsButtonRemoverPatch.kt index 66ec687c0..b1e9e7d28 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/shortsbutton/patch/ShortsButtonRemoverPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/shortsbutton/patch/ShortsButtonRemoverPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.layout.pivotbar.shortsbutton.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version @@ -19,7 +20,6 @@ import app.revanced.patches.youtube.layout.pivotbar.shortsbutton.fingerprints.Pi import app.revanced.patches.youtube.layout.pivotbar.shortsbutton.fingerprints.PivotBarShortsButtonViewFingerprint import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.injectHook -import app.revanced.patches.youtube.layout.pivotbar.utils.InjectionUtils.toErrorResult import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/utils/InjectionUtils.kt index e8ba2fc3f..8667b10d0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/utils/InjectionUtils.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/pivotbar/utils/InjectionUtils.kt @@ -1,10 +1,7 @@ package app.revanced.patches.youtube.layout.pivotbar.utils -import app.revanced.patcher.extensions.MethodFingerprintExtensions.name import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.instruction -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import app.revanced.patcher.patch.PatchResultError import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import org.jf.dexlib2.Opcode.MOVE_RESULT_OBJECT import org.jf.dexlib2.iface.instruction.OneRegisterInstruction @@ -30,7 +27,4 @@ internal object InjectionUtils { hook.replace("REGISTER_INDEX", register.toString()), ) } - - // TODO: move this to a global extension class and use it in all patches - fun MethodFingerprint.toErrorResult() = PatchResultError("Failed to resolve $name") } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt index b70a46e2a..59da051c6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/annotations/WideSearchbarCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36") + "com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36", "17.45.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckFingerprint.kt new file mode 100644 index 000000000..146bf2388 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckFingerprint.kt @@ -0,0 +1,8 @@ +package app.revanced.patches.youtube.layout.widesearchbar.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint + +object IsInOfflineModeCheckFingerprint : MethodFingerprint( + "L", + strings = listOf("bundle_is_in_offline_mode") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckResultFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckResultFingerprint.kt new file mode 100644 index 000000000..37553c83b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/IsInOfflineModeCheckResultFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.layout.widesearchbar.fingerprints + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.Opcode + +object IsInOfflineModeCheckResultFingerprint : MethodFingerprint( + "L", + parameters = listOf("L", "L", "L", "L", "L"), + opcodes = listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.NEW_INSTANCE, + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT, + ), +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/SetWordmarkHeaderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/SetWordmarkHeaderFingerprint.kt new file mode 100644 index 000000000..84ee99988 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/SetWordmarkHeaderFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.youtube.layout.widesearchbar.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 SetWordmarkHeaderFingerprint : MethodFingerprint( + "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.IGET_BOOLEAN, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.CONST, + Opcode.INVOKE_STATIC, + ), + customFingerprint = { methodDef -> methodDef.parameterTypes.first() == "Landroid/widget/ImageView;" } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneFingerprint.kt deleted file mode 100644 index aafb8d63d..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneFingerprint.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.revanced.patches.youtube.layout.widesearchbar.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 WideSearchbarOneFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), - listOf(Opcode.IF_NEZ, Opcode.SGET_OBJECT, Opcode.IGET_OBJECT, Opcode.INVOKE_STATIC) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneParentFingerprint.kt deleted file mode 100644 index 66e86710c..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarOneParentFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.widesearchbar.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object WideSearchbarOneParentFingerprint : MethodFingerprint( - "V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("L"), - strings = listOf("FEhistory", "FEmy_videos", "FEpurchases") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoFingerprint.kt deleted file mode 100644 index 81aa1d690..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.layout.widesearchbar.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 WideSearchbarTwoFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf( - Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_EQZ, Opcode.NEW_INSTANCE - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoParentFingerprint.kt deleted file mode 100644 index 5ead7d84f..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/fingerprints/WideSearchbarTwoParentFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.layout.widesearchbar.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint -import org.jf.dexlib2.AccessFlags - -object WideSearchbarTwoParentFingerprint : MethodFingerprint( - "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), - strings = listOf("VIDEO_QUALITIES_QUICK_MENU_BOTTOM_SHEET_FRAGMENT") -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/patch/WideSearchbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/patch/WideSearchbarPatch.kt index ed5e83ded..95ae73046 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/patch/WideSearchbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/widesearchbar/patch/WideSearchbarPatch.kt @@ -1,11 +1,13 @@ package app.revanced.patches.youtube.layout.widesearchbar.patch +import app.revanced.extensions.toErrorResult import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchResult @@ -13,15 +15,14 @@ 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.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility -import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneFingerprint -import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarOneParentFingerprint -import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoFingerprint -import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.WideSearchbarTwoParentFingerprint -import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch -import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.layout.widesearchbar.annotations.WideSearchbarCompatibility +import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.IsInOfflineModeCheckFingerprint +import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.IsInOfflineModeCheckResultFingerprint +import app.revanced.patches.youtube.layout.widesearchbar.fingerprints.SetWordmarkHeaderFingerprint +import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch @Patch @DependsOn([IntegrationsPatch::class, SettingsPatch::class]) @@ -31,9 +32,38 @@ import app.revanced.patches.shared.settings.preference.impl.SwitchPreference @Version("0.0.1") class WideSearchbarPatch : BytecodePatch( listOf( - WideSearchbarOneParentFingerprint, WideSearchbarTwoParentFingerprint + SetWordmarkHeaderFingerprint, IsInOfflineModeCheckFingerprint ) ) { + private companion object { + /** + * Walk a fingerprints method at a given index mutably. + * + * @param index The index to walk at. + * @param fromFingerprint The fingerprint to walk the method on. + * @return The [MutableMethod] which was walked on. + */ + fun BytecodeContext.walkMutable(index: Int, fromFingerprint: MethodFingerprint) = + fromFingerprint.result?.let { + toMethodWalker(it.method).nextMethod(index, true).getMethod() as MutableMethod + } ?: throw SetWordmarkHeaderFingerprint.toErrorResult() + + + /** + * Injects instructions required for certain methods. + * + */ + fun MutableMethod.injectSearchBarHook() { + addInstructions( + implementation!!.instructions.size - 1, + """ + invoke-static {}, Lapp/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z + move-result p0 + """ + ) + } + } + override fun execute(context: BytecodeContext): PatchResult { SettingsPatch.PreferenceScreen.LAYOUT.addPreferences( SwitchPreference( @@ -45,76 +75,20 @@ class WideSearchbarPatch : BytecodePatch( ) ) - WideSearchbarOneFingerprint.resolve(context, WideSearchbarOneParentFingerprint.result!!.classDef) - WideSearchbarTwoFingerprint.resolve(context, WideSearchbarTwoParentFingerprint.result!!.classDef) + // resolve fingerprints + IsInOfflineModeCheckFingerprint.result?.let { + if (!IsInOfflineModeCheckResultFingerprint.resolve(context, it.classDef)) + return IsInOfflineModeCheckResultFingerprint.toErrorResult() + } ?: return IsInOfflineModeCheckFingerprint.toErrorResult() - val resultOne = WideSearchbarOneFingerprint.result - - //This should be the method aF in class fbn - val targetMethodOne = - context.toMethodWalker(resultOne!!.method) - .nextMethod(resultOne.scanResult.patternScanResult!!.endIndex, true).getMethod() as MutableMethod - - //Since both methods have the same smali code, inject instructions using a method. - addInstructions(targetMethodOne) - - val resultTwo = WideSearchbarTwoFingerprint.result - - //This should be the method aB in class fbn - val targetMethodTwo = - context.toMethodWalker(resultTwo!!.method) - .nextMethod(resultTwo.scanResult.patternScanResult!!.startIndex, true).getMethod() as MutableMethod - - //Since both methods have the same smali code, inject instructions using a method. - addInstructions(targetMethodTwo) + // patch methods + mapOf( + SetWordmarkHeaderFingerprint to 1, + IsInOfflineModeCheckResultFingerprint to 0 + ).forEach { (fingerprint, callIndex) -> + context.walkMutable(callIndex, fingerprint).injectSearchBarHook() + } return PatchResultSuccess() } - - private fun addInstructions(method: MutableMethod) { - val index = method.implementation!!.instructions.size - 1 - method.addInstructions( - index, """ - invoke-static {}, Lapp/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z - move-result p0 - """ - ) - } - - //targetMethodOne: in class fbn - /* - .method public static aF(Ltxm;)Z - invoke-virtual {p0}, Ltxm;->b()Lahah; - move-result-object p0 - iget-object p0, p0, Lahah;->e:Lakfd; - if-nez p0, :cond_a - sget-object p0, Lakfd;->a:Lakfd; - :cond_a - iget-boolean p0, p0, Lakfd;->V:Z - //added code here: - invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z - move-result p0 - //original code here: - return p0 - .end method - */ - - //targetMethodTwo: in class fbn - /* - .method public static aB(Ltxm;)Z - invoke-virtual {p0}, Ltxm;->b()Lahah; - move-result-object p0 - iget-object p0, p0, Lahah;->e:Lakfd; - if-nez p0, :cond_a - sget-object p0, Lakfd;->a:Lakfd; - :cond_a - iget-boolean p0, p0, Lakfd;->y:Z - //added code here: - invoke-static {}, app/revanced/integrations/patches/NewActionbarPatch;->getNewActionBar()Z - move-result p0 - //original code here: - return p0 - .end method - - */ }