From 43f919d9ad3b36b27aea18eb4055da4c4b471d27 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 28 Jan 2026 13:42:56 +0100 Subject: [PATCH] progress --- .../spotify/misc/extension/Fingerprints.kt | 4 +- .../patches/spotify/misc/extension/Hooks.kt | 54 +++++++++++++------ .../spotify/misc/privacy/Fingerprints.kt | 38 ++++++------- .../misc/privacy/SanitizeSharingLinksPatch.kt | 16 +++--- .../spotify/misc/widgets/Fingerprints.kt | 5 +- .../strava/mediaupload/Fingerprints.kt | 30 ++++++----- .../OverwriteMediaUploadParametersPatch.kt | 6 +-- .../DisableLoginRequirementPatch.kt | 12 +---- .../login/disablerequirement/Fingerprints.kt | 19 ++++--- .../tiktok/misc/settings/Fingerprints.kt | 18 ++----- .../patches/tiktok/shared/Fingerprints.kt | 17 ++---- .../revanced/patches/trakt/Fingerprints.kt | 24 +++------ .../revanced/patches/trakt/UnlockProPatch.kt | 11 ++-- .../tudortmund/lockscreen/Fingerprints.kt | 13 ++--- .../annoyances/notifications/Fingerprints.kt | 10 ++-- .../patches/twitch/ad/shared/util/AdPatch.kt | 14 ++--- .../twitch/misc/settings/SettingsPatch.kt | 4 +- .../twitter/misc/links/Fingerprints.kt | 33 +++++------- .../patches/viber/misc/navbar/Fingerprints.kt | 16 +++--- .../misc/navbar/HideNavigationButtons.kt | 19 +++---- .../youtube/ad/general/Fingerprints.kt | 7 +-- .../patches/youtube/ad/video/Fingerprints.kt | 13 ++--- .../DisableChapterSkipDoubleTapPatch.kt | 14 ++--- .../interaction/doubletap/Fingerprints.kt | 16 +++--- .../interaction/downloads/Fingerprints.kt | 6 +-- .../layout/autocaptions/Fingerprints.kt | 19 ++----- .../formfactor/ChangeFormFactorPatch.kt | 16 +++--- .../youtube/layout/formfactor/Fingerprints.kt | 13 +++-- .../fullscreenambientmode/Fingerprints.kt | 11 ++-- .../layout/hide/shorts/Fingerprints.kt | 4 +- .../hide/shorts/HideShortsComponentsPatch.kt | 9 ++-- 31 files changed, 218 insertions(+), 273 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt index 7d18ae7c2..8359bd7b0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Fingerprints.kt @@ -1,8 +1,6 @@ package app.revanced.patches.spotify.misc.extension -import app.revanced.patcher.firstMethodComposite -import app.revanced.patcher.instructions -import app.revanced.patcher.invoke +import app.revanced.patcher.* internal val loadOrbitLibraryMethodMatch = firstMethodComposite { instructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt index efee1d891..2fdd95ecd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/extension/Hooks.kt @@ -1,30 +1,52 @@ package app.revanced.patches.spotify.misc.extension +import app.revanced.patcher.definingClass import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.instructions +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.name +import app.revanced.patcher.parameterTypes +import app.revanced.patcher.returnType +import app.revanced.patches.shared.misc.extension.activityOnCreateExtensionHook import app.revanced.patches.shared.misc.extension.extensionHook -import app.revanced.patches.spotify.shared.mainActivityOnCreateMethod import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference -internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateMethod } +internal val mainActivityOnCreateHook = activityOnCreateExtensionHook( + "Lcom/spotify/music/SpotifyMainActivity;" +) -internal val loadOrbitLibraryHook = extensionHook { - // FIXME: Creating this is a mess and needs refactoring. - extensionHook( - getInsertIndex = { - loadOrbitLibraryMethodMatch.stringMatches.last().index - }, - getContextRegister = { method -> - val contextReferenceIndex = method.indexOfFirstInstruction { - getReference()?.type == "Landroid/content/Context;" +private var contextReferenceIndex = -1 + +internal val loadOrbitLibraryHook = extensionHook( + getInsertIndex = { + // Find the last orbit_library_load string usage + var lastIndex = -1 + instructions.forEachIndexed { index, instruction -> + instruction.toString().let { + if (it.contains("orbit_library_load") || it.contains("orbit-jni-spotify")) { + lastIndex = index + } } - val contextRegister = - method.getInstruction(contextReferenceIndex).registerA + } + lastIndex + }, + getContextRegister = { + contextReferenceIndex = indexOfFirstInstruction { + getReference()?.type == "Landroid/content/Context;" + } + val contextRegister = + getInstruction(contextReferenceIndex).registerA - "v$contextRegister" - }, - fingerprint = loadOrbitLibraryMethodMatch, + "v$contextRegister" + }, +) { + instructions( + "orbit_library_load"(), + "orbit-jni-spotify"() ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/Fingerprints.kt index bd299d0b1..041a01d6e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/Fingerprints.kt @@ -1,34 +1,30 @@ package app.revanced.patches.spotify.misc.privacy -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.shareCopyUrlMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.shareCopyUrlMethod by gettingFirstMutableMethodDeclarativelyOrNull( + "clipboard", + "Spotify Link", +) { + name("invokeSuspend") returnType("Ljava/lang/Object;") parameterTypes("Ljava/lang/Object;") - strings("clipboard", "Spotify Link") - custom { method, _ -> - method.name == "invokeSuspend" - } } -internal val BytecodePatchContext.oldShareCopyUrlMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.oldShareCopyUrlMethod by gettingFirstMutableMethodDeclaratively( + "clipboard", + "createNewSession failed", +) { + name("apply") returnType("Ljava/lang/Object;") parameterTypes("Ljava/lang/Object;") - strings("clipboard", "createNewSession failed") - custom { method, _ -> - method.name == "apply" - } } -internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFirstMutableMethodDeclarativelyOrNull { returnType("Ljava/lang/String;") parameterTypes("L", "Ljava/lang/String;") opcodes( @@ -38,16 +34,12 @@ internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFir Opcode.MOVE_RESULT_OBJECT, Opcode.RETURN_OBJECT, ) - literal { - '\n'.code.toLong() - } + literal { '\n'.code.toLong() } } -internal val BytecodePatchContext.oldFormatAndroidShareSheetUrlMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.oldFormatAndroidShareSheetUrlMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC) returnType("Ljava/lang/String;") parameterTypes("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;") - literal { - '\n'.code.toLong() - } + instructions('\n'.code.toLong()()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatch.kt index b5644a3f8..9ed03b32c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatch.kt @@ -2,13 +2,12 @@ package app.revanced.patches.spotify.misc.privacy import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.methodReference import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch -import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch;" @@ -25,15 +24,15 @@ val `Sanitize sharing links` by creatingBytecodePatch( val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" + "sanitizeSharingLink(Ljava/lang/String;)Ljava/lang/String;" - val copyFingerprint = if (shareCopyUrlMethod.immutableMethodOrNull != null) { + val copyMethod = if (shareCopyUrlMethod != null) { shareCopyUrlMethod } else { oldShareCopyUrlMethod } - copyFingerprint.method.apply { + copyMethod!!.apply { val newPlainTextInvokeIndex = indexOfFirstInstructionOrThrow { - getReference()?.name == "newPlainText" + methodReference?.name == "newPlainText" } val urlRegister = getInstruction(newPlainTextInvokeIndex).registerD @@ -48,9 +47,8 @@ val `Sanitize sharing links` by creatingBytecodePatch( // Android native share sheet is used for all other quick share types (X, WhatsApp, etc). val shareUrlParameter: String - val shareSheetFingerprint = if (formatAndroidShareSheetUrlMethod.immutableMethodOrNull != null) { - val methodAccessFlags = formatAndroidShareSheetUrlMethod.immutableMethod - shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags.accessFlags)) { + val shareSheetMethod = if (formatAndroidShareSheetUrlMethod != null) { + shareUrlParameter = if (AccessFlags.STATIC.isSet(formatAndroidShareSheetUrlMethod!!.accessFlags)) { // In newer implementations the method is static, so p0 is not `this`. "p1" } else { @@ -65,7 +63,7 @@ val `Sanitize sharing links` by creatingBytecodePatch( oldFormatAndroidShareSheetUrlMethod } - shareSheetFingerprint.method.addInstructions( + shareSheetMethod!!.addInstructions( 0, """ invoke-static { $shareUrlParameter }, $extensionMethodDescriptor diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt index f66f9e748..e7c43c966 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt @@ -1,11 +1,10 @@ package app.revanced.patches.spotify.misc.widgets -import app.revanced.patcher.gettingFirstMethodDeclaratively +import app.revanced.patcher.gettingFirstMutableMethodDeclaratively import app.revanced.patcher.opcodes import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.canBindAppWidgetPermissionMethod by gettingFirstMethodDeclaratively { - strings("android.permission.BIND_APPWIDGET") +internal val BytecodePatchContext.canBindAppWidgetPermissionMethod by gettingFirstMutableMethodDeclaratively("android.permission.BIND_APPWIDGET") { opcodes(Opcode.AND_INT_LIT8) } diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/Fingerprints.kt index 1c4453cea..3e63b5b82 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/Fingerprints.kt @@ -1,19 +1,25 @@ package app.revanced.patches.strava.mediaupload -internal val BytecodePatchContext.getCompressionQualityMethod by gettingFirstMethodDeclaratively { - custom { method, _ -> - method.name == "getCompressionQuality" - } +import app.revanced.patcher.definingClass +import app.revanced.patcher.firstMutableMethodDeclaratively +import app.revanced.patcher.name +import app.revanced.patcher.patch.BytecodePatchContext +import com.android.tools.smali.dexlib2.iface.ClassDef + +context(_: BytecodePatchContext) +internal fun ClassDef.getGetCompressionQualityMethod() = firstMutableMethodDeclaratively { + name("getCompressionQuality") + definingClass { endsWith("/MediaUploadParameters;") } } -internal val BytecodePatchContext.getMaxDurationMethod by gettingFirstMethodDeclaratively { - custom { method, _ -> - method.name == "getMaxDuration" - } +context(_: BytecodePatchContext) +internal fun ClassDef.getGetMaxDurationMethod() = firstMutableMethodDeclaratively { + name("getMaxDuration") + definingClass { endsWith("/MediaUploadParameters;") } } -internal val BytecodePatchContext.getMaxSizeMethod by gettingFirstMethodDeclaratively { - custom { method, _ -> - method.name == "getMaxSize" - } +context(_: BytecodePatchContext) +internal fun ClassDef.getGetMaxSizeMethod() = firstMutableMethodDeclaratively { + name("getMaxSize") + definingClass { endsWith("/MediaUploadParameters;") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/OverwriteMediaUploadParametersPatch.kt b/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/OverwriteMediaUploadParametersPatch.kt index 9c018c053..fe612e70a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/OverwriteMediaUploadParametersPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/strava/mediaupload/OverwriteMediaUploadParametersPatch.kt @@ -31,15 +31,15 @@ val `Overwrite media upload parameters` by creatingBytecodePatch( val mediaUploadParametersClass = firstClassDef { type.endsWith("/MediaUploadParameters;") } compressionQuality?.let { compressionQuality -> - getCompressionQualityMethod.match(mediaUploadParametersClass).method.returnEarly(compressionQuality / 100f) + mediaUploadParametersClass.getGetCompressionQualityMethod().returnEarly(compressionQuality / 100f) } maxDuration?.let { maxDuration -> - getMaxDurationMethod.match(mediaUploadParametersClass).method.returnEarly(maxDuration) + mediaUploadParametersClass.getGetMaxDurationMethod().returnEarly(maxDuration) } maxSize?.let { - getMaxSizeMethod.match(mediaUploadParametersClass).method.returnEarly(it) + mediaUploadParametersClass.getGetMaxSizeMethod().returnEarly(it) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/DisableLoginRequirementPatch.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/DisableLoginRequirementPatch.kt index 331ec9896..b492b884b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/DisableLoginRequirementPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/DisableLoginRequirementPatch.kt @@ -1,7 +1,7 @@ package app.revanced.patches.tiktok.misc.login.disablerequirement -import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.creatingBytecodePatch +import app.revanced.util.returnEarly @Suppress("unused", "ObjectPropertyName") val `Disable login requirement` by creatingBytecodePatch { @@ -14,14 +14,6 @@ val `Disable login requirement` by creatingBytecodePatch { listOf( mandatoryLoginServiceMethod, mandatoryLoginService2Method, - ).forEach { fingerprint -> - fingerprint.method.addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """, - ) - } + ).forEach { method -> method.returnEarly() } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt index 01ed94541..58df3b4ca 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/login/disablerequirement/Fingerprints.kt @@ -1,15 +1,14 @@ package app.revanced.patches.tiktok.misc.login.disablerequirement -internal val BytecodePatchContext.mandatoryLoginServiceMethod by gettingFirstMethodDeclaratively { - custom { method, classDef -> - classDef.endsWith("/MandatoryLoginService;") && - method.name == "enableForcedLogin" - } +import app.revanced.patcher.* +import app.revanced.patcher.patch.BytecodePatchContext + +internal val BytecodePatchContext.mandatoryLoginServiceMethod by gettingFirstMutableMethodDeclaratively { + name("enableForcedLogin") + definingClass { endsWith("/MandatoryLoginService;") } } -internal val BytecodePatchContext.mandatoryLoginService2Method by gettingFirstMethodDeclaratively { - custom { method, classDef -> - classDef.endsWith("/MandatoryLoginService;") && - method.name == "shouldShowForcedLogin" - } +internal val BytecodePatchContext.mandatoryLoginService2Method by gettingFirstMutableMethodDeclaratively { + name("shouldShowForcedLogin") + definingClass { endsWith("/MandatoryLoginService;") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt index aa35b7ad6..8202cd524 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/misc/settings/Fingerprints.kt @@ -1,9 +1,6 @@ package app.revanced.patches.tiktok.misc.settings -import app.revanced.patcher.definingClass -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.gettingFirstMutableMethodDeclaratively -import app.revanced.patcher.name +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext internal val BytecodePatchContext.addSettingsEntryMethod by gettingFirstMutableMethodDeclaratively { @@ -20,16 +17,9 @@ internal val BytecodePatchContext.settingsEntryMethod by gettingFirstMethodDecla "pls pass item or extends the EventUnit", ) -internal val BytecodePatchContext.settingsEntryInfoMethod by gettingFirstMethodDeclaratively { - strings( - "ExposeItem(title=", - ", icon=", - ) -} +internal val BytecodePatchContext.settingsEntryInfoMethod by gettingFirstMethod("ExposeItem(title=", ", icon=") internal val BytecodePatchContext.settingsStatusLoadMethod by gettingFirstMethodDeclaratively { - custom { method, classDef -> - classDef.endsWith("Lapp/revanced/extension/tiktok/settings/SettingsStatus;") && - method.name == "load" - } + name("load") + definingClass { endsWith("Lapp/revanced/extension/tiktok/settings/SettingsStatus;") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt index 553eb40a3..ab12affd0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tiktok/shared/Fingerprints.kt @@ -1,15 +1,12 @@ package app.revanced.patches.tiktok.shared -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode internal val BytecodePatchContext.getEnterFromMethod by gettingFirstMethodDeclaratively { + definingClass { endsWith("/BaseListFragmentPanel;") } returnType("Ljava/lang/String;") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameterTypes("Z") @@ -22,14 +19,8 @@ internal val BytecodePatchContext.getEnterFromMethod by gettingFirstMethodDeclar Opcode.MOVE_RESULT_OBJECT, Opcode.RETURN_OBJECT, ) - custom { methodDef, _ -> - methodDef.definingClass.endsWith("/BaseListFragmentPanel;") - } } -internal val BytecodePatchContext.onRenderFirstFrameMethod by gettingFirstMethodDeclaratively { - strings("method_enable_viewpager_preload_duration") - custom { _, classDef -> - classDef.endsWith("/BaseListFragmentPanel;") - } +internal val BytecodePatchContext.onRenderFirstFrameMethod by gettingFirstMutableMethodDeclaratively("method_enable_viewpager_preload_duration") { + definingClass { endsWith("/BaseListFragmentPanel;") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt index e7f614bd9..04e93d1ea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/trakt/Fingerprints.kt @@ -1,28 +1,16 @@ package app.revanced.patches.trakt -import app.revanced.patcher.custom +import app.revanced.patcher.definingClass import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.name import app.revanced.patcher.patch.BytecodePatchContext internal val BytecodePatchContext.isVIPEPMethod by gettingFirstMutableMethodDeclaratively { - custom { method, classDef -> - if (!classDef.endsWith("RemoteUser;")) return@custom false - - method.name == "isVIPEP" - } + name("isVIPEP") + definingClass { endsWith("RemoteUser;") } } internal val BytecodePatchContext.isVIPMethod by gettingFirstMutableMethodDeclaratively { - custom { method, classDef -> - if (!classDef.endsWith("RemoteUser;")) return@custom false - - method.name == "isVIP" - } + name("isVIP") + definingClass { endsWith("RemoteUser;") } } -internal val BytecodePatchContext.remoteUserMethod by gettingFirstMutableMethodDeclaratively { - custom { _, classDef -> - classDef.endsWith("RemoteUser;") - } -} - -// TODO \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/trakt/UnlockProPatch.kt b/patches/src/main/kotlin/app/revanced/patches/trakt/UnlockProPatch.kt index b1a9cf6ca..a85040cbd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/trakt/UnlockProPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/trakt/UnlockProPatch.kt @@ -1,20 +1,17 @@ package app.revanced.patches.trakt import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.creatingBytecodePatch +import com.android.tools.smali.dexlib2.mutable.MutableMethod @Suppress("unused", "ObjectPropertyName") val `Unlock pro` by creatingBytecodePatch { compatibleWith("tv.trakt.trakt"("1.1.1")) apply { - arrayOf(isVIPMethod, isVIPEPMethod).onEach { fingerprint -> - // Resolve both fingerprints on the same class. - fingerprint.match(remoteUserMethod.immutableClassDef) // TODO - }.forEach { fingerprint -> - // Return true for both VIP check methods. - fingerprint.addInstructions( + // Return true for both VIP check methods. + arrayOf(isVIPMethod, isVIPEPMethod).forEach { method: MutableMethod -> + method.addInstructions( 0, """ const/4 v0, 0x1 diff --git a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt index 9963d6cff..82e34c48b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tudortmund/lockscreen/Fingerprints.kt @@ -1,19 +1,14 @@ package app.revanced.patches.tudortmund.lockscreen -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags internal val BytecodePatchContext.brightnessMethod by gettingFirstMethodDeclaratively { + name("run") + definingClass { contains("/ScreenPlugin$") } accessFlags(AccessFlags.PUBLIC) returnType("V") parameterTypes() - custom { method, classDef -> - method.name == "run" && - method.definingClass.contains("/ScreenPlugin\$") && - classDef.fields.any { it.type == "Ljava/lang/Float;" } - } + custom { immutableClassDef.anyField { type == "Ljava/lang/Float;" } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt index 2ad41c028..f84bd279e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/tumblr/annoyances/notifications/Fingerprints.kt @@ -1,9 +1,13 @@ package app.revanced.patches.tumblr.annoyances.notifications +import app.revanced.patcher.gettingFirstMutableMethod +import app.revanced.patcher.patch.BytecodePatchContext + // The BlogNotifyCtaDialog asks you if you want to enable notifications for a blog. // It shows whenever you visit a certain blog for the second time and disables itself // if it was shown a total of 3 times (stored in app storage). // This targets the BlogNotifyCtaDialog.isEnabled() method to let it always return false. -internal val BytecodePatchContext.isBlogNotifyEnabledMethod by gettingFirstMethodDeclaratively { - strings("isEnabled --> ", "blog_notify_enabled") -} +internal val BytecodePatchContext.isBlogNotifyEnabledMethod by gettingFirstMutableMethod( + "isEnabled --> ", + "blog_notify_enabled", +) diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt index 8d7968721..88a4c8228 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/ad/shared/util/AdPatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.twitch.ad.shared.util import app.revanced.patcher.extensions.ExternalLabel import app.revanced.patcher.extensions.addInstructionsWithLabels import app.revanced.patcher.extensions.getInstruction -import app.revanced.patcher.firstClassDefMutableOrNull +import app.revanced.patcher.firstMutableClassDefOrNull import app.revanced.patcher.patch.BytecodePatchBuilder import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.patch.bytecodePatch @@ -30,10 +30,10 @@ fun adPatch( classDefType: String, methodNames: Set, returnMethod: ReturnMethod, - ) = with(firstClassDefMutableOrNull(classDefType)) { - this ?: return false + ): Boolean { + val classDef = firstMutableClassDefOrNull(classDefType) ?: return false - methods.filter { it.name in methodNames }.forEach { + classDef.methods.filter { it.name in methodNames }.forEach { method -> val retInstruction = when (returnMethod.returnType) { 'V' -> "return-void" 'Z' -> @@ -45,17 +45,17 @@ fun adPatch( else -> throw NotImplementedError() } - it.addInstructionsWithLabels( + method.addInstructionsWithLabels( 0, """ ${createConditionInstructions("v0")} $retInstruction """, - ExternalLabel(skipLabelName, it.getInstruction(0)), + ExternalLabel(skipLabelName, method.getInstruction(0)), ) } - true + return true } block(::createConditionInstructions, BytecodePatchContext::blockMethods) diff --git a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt index 6c2c048f3..bfbc111bc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitch/misc/settings/SettingsPatch.kt @@ -145,7 +145,7 @@ val Settings by creatingBytecodePatch( ) // Intercept onclick events for the settings menu - menuGroupsOnClickFingerprint.method.addInstructionsWithLabels( + menuGroupsOnClickMethod.addInstructionsWithLabels( 0, """ invoke-static {p1}, $ACTIVITY_HOOKS_CLASS_DESCRIPTOR->handleSettingMenuOnClick(Ljava/lang/Enum;)Z @@ -157,7 +157,7 @@ val Settings by creatingBytecodePatch( """, ExternalLabel( "no_rv_settings_onclick", - menuGroupsOnClickFingerprint.method.getInstruction(0), + menuGroupsOnClickMethod.getInstruction(0), ), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt index 4881427f8..19a92e376 100644 --- a/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/twitter/misc/links/Fingerprints.kt @@ -1,36 +1,29 @@ package app.revanced.patches.twitter.misc.links -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags -internal val BytecodePatchContext.sanitizeSharingLinksMethod by gettingFirstMethodDeclaratively { - returnType("Ljava/lang/String;") - strings("", "shareParam", "sessionToken") -} +internal val BytecodePatchContext.sanitizeSharingLinksMethod by gettingFirstMutableMethod( + "", + "shareParam", + "sessionToken", +) { returnType == "Ljava/lang/String;" } // Returns a shareable link string based on a tweet ID and a username. -internal val BytecodePatchContext.linkBuilderMethod by gettingFirstMethodDeclaratively { - strings("/%1\$s/status/%2\$d") -} +internal val BytecodePatchContext.linkBuilderMethod by gettingFirstMutableMethod($$"/%1$s/status/%2$d") // TODO remove this once changeLinkSharingDomainResourcePatch is restored // Returns a shareable link for the "Share via..." dialog. -internal val BytecodePatchContext.linkResourceGetterMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.linkResourceGetterMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameterTypes("Landroid/content/res/Resources;") - custom { _, classDef -> - classDef.fields.any { field -> - field.type.startsWith("Lcom/twitter/model/core/") - } + custom { + immutableClassDef.anyField { type.startsWith("Lcom/twitter/model/core/") } } } -internal val BytecodePatchContext.linkSharingDomainHelperMethod by gettingFirstMethodDeclaratively { - custom { method, classDef -> - method.name == "getShareDomain" && classDef.type == EXTENSION_CLASS_DESCRIPTOR - } +internal val BytecodePatchContext.linkSharingDomainHelperMethod by gettingFirstMutableMethodDeclaratively { + name("getShareDomain") + definingClass(EXTENSION_CLASS_DESCRIPTOR) } diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/Fingerprints.kt index 674cc17b1..860b829a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/Fingerprints.kt @@ -1,18 +1,16 @@ package app.revanced.patches.viber.misc.navbar -import app.revanced.patcher.gettingFirstMethodDeclaratively + +import app.revanced.patcher.firstMutableMethodDeclaratively +import app.revanced.patcher.gettingFirstMethod import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType +import com.android.tools.smali.dexlib2.iface.ClassDef -internal val BytecodePatchContext.tabIdClassMethod by gettingFirstMethodDeclaratively { - strings("shouldShowTabId") -} +internal val BytecodePatchContext.tabIdClassMethod by gettingFirstMethod("shouldShowTabId") -context(BytecodePatchContext) -internal val shouldShowTabIdMethodFingerprint get() = fingerprint { +context(_: BytecodePatchContext) +internal fun ClassDef.getShouldShowTabIdMethod() = firstMutableMethodDeclaratively { parameterTypes("I", "I") returnType("Z") - custom { methodDef, classDef -> - classDef == tabIdClassMethod.classDef - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/HideNavigationButtons.kt b/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/HideNavigationButtons.kt index b64e63fb4..4f77967ef 100644 --- a/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/HideNavigationButtons.kt +++ b/patches/src/main/kotlin/app/revanced/patches/viber/misc/navbar/HideNavigationButtons.kt @@ -1,6 +1,7 @@ package app.revanced.patches.viber.misc.navbar import app.revanced.patcher.extensions.addInstructionsWithLabels +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.booleanOption import app.revanced.patcher.patch.creatingBytecodePatch import java.util.logging.Logger @@ -8,7 +9,7 @@ import java.util.logging.Logger @Suppress("unused", "ObjectPropertyName") val `Hide navigation buttons` by creatingBytecodePatch( description = "Permanently hides navigation bar buttons, such as Explore and Marketplace.", - use = false + use = false, ) { compatibleWith("com.viber.voip") @@ -26,7 +27,7 @@ val `Hide navigation buttons` by creatingBytecodePatch( if (allowedItems.size == AllowedNavigationItems.entries.size) { return@apply Logger.getLogger(this::class.java.name).warning( - "No hide navigation buttons options are enabled. No changes applied." + "No hide navigation buttons options are enabled. No changes applied.", ) } @@ -42,7 +43,7 @@ val `Hide navigation buttons` by creatingBytecodePatch( nop """ - shouldShowTabIdMethodFingerprint.method + tabIdClassMethod.immutableClassDef.getShouldShowTabIdMethod() .addInstructionsWithLabels(0, injectionInstructions) } } @@ -54,7 +55,7 @@ val `Hide navigation buttons` by creatingBytecodePatch( private enum class AllowedNavigationItems( val defaultHideOption: Boolean, private val itemName: String, - private vararg val ids: Int + private vararg val ids: Int, ) { CHATS(false, "Chats", 0), CALLS(false, "Calls", 1, 7), @@ -62,16 +63,16 @@ private enum class AllowedNavigationItems( MORE(false, "More", 3), PAY(true, "Pay", 5), CAMERA(true, "Camera", 6), - MARKETPLACE(true, "Marketplace", 8); + MARKETPLACE(true, "Marketplace", 8), + ; val optionName = "Hide $itemName" val description = "Permanently hides the $itemName button." - fun buildAllowInstruction(): String = - ids.joinToString("\n") { id -> - """ + fun buildAllowInstruction(): String = ids.joinToString("\n") { id -> + """ const/4 v0, $id # If tabId == $id ($itemName), don't hide it if-eq p1, v0, :continue """ - } + } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt index ee232b812..7313117c2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/Fingerprints.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.ad.general import app.revanced.patcher.accessFlags +import app.revanced.patcher.custom import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext @@ -16,9 +17,9 @@ internal val BytecodePatchContext.fullScreenEngagementAdContainerMethod by getti accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes() - custom { method, _ -> - method.containsLiteralInstruction(fullScreenEngagementAdContainer) && - indexOfAddListInstruction(method) >= 0 + custom { + containsLiteralInstruction(fullScreenEngagementAdContainer) && + indexOfAddListInstruction(this) >= 0 } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt index 7d0adf6e2..dacd065a9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/Fingerprints.kt @@ -1,8 +1,9 @@ package app.revanced.patches.youtube.ad.video -internal val BytecodePatchContext.loadVideoAdsMethod by gettingFirstMethodDeclaratively { - strings( - "TriggerBundle doesn't have the required metadata specified by the trigger ", - "Ping migration no associated ping bindings for activated trigger: ", - ) -} +import app.revanced.patcher.gettingFirstMethod +import app.revanced.patcher.patch.BytecodePatchContext + +internal val BytecodePatchContext.loadVideoAdsMethod by gettingFirstMethod( + "TriggerBundle doesn't have the required metadata specified by the trigger ", + "Ping migration no associated ping bindings for activated trigger: ", +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt index 3c205f385..258e8b108 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.youtube.interaction.doubletap +import app.revanced.patcher.* import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources @@ -13,7 +14,6 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import java.util.logging.Logger -import kotlin.jvm.java private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/DisableDoubleTapActionsPatch;" @@ -53,7 +53,7 @@ val `Disable double tap actions` by creatingBytecodePatch( SwitchPreference("revanced_disable_chapter_skip_double_tap"), ) - val doubleTapInfoGetSeekSourceFingerprint = fingerprint { + val doubleTapInfoGetSeekSourceMethod = firstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameterTypes("Z") returnType(seekTypeEnumMethod.immutableClassDef.type) @@ -64,13 +64,11 @@ val `Disable double tap actions` by creatingBytecodePatch( Opcode.SGET_OBJECT, Opcode.RETURN_OBJECT, ) - custom { _, classDef -> - classDef.fields.count() == 4 - } + custom { immutableClassDef.fields.count() == 4 } } // Force isChapterSeek flag to false. - doubleTapInfoGetSeekSourceFingerprint.method.addInstructions( + doubleTapInfoGetSeekSourceMethod.addInstructions( 0, """ invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z @@ -78,9 +76,7 @@ val `Disable double tap actions` by creatingBytecodePatch( """, ) - doubleTapInfoCtorMethod.match( - doubleTapInfoGetSeekSourceFingerprint.classDef, - ).method.addInstructions( + doubleTapInfoGetSeekSourceMethod.immutableClassDef.getDoubleTapInfoCtorMethod().addInstructions( 0, """ invoke-static { p3 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/Fingerprints.kt index d1653eeb8..d5079f8a8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/Fingerprints.kt @@ -1,25 +1,27 @@ package app.revanced.patches.youtube.interaction.doubletap import app.revanced.patcher.accessFlags +import app.revanced.patcher.firstMutableMethodDeclaratively import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.iface.ClassDef -internal val BytecodePatchContext.seekTypeEnumMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.seekTypeEnumMethod by gettingFirstMethodDeclaratively( + "SEEK_SOURCE_SEEK_TO_NEXT_CHAPTER", + "SEEK_SOURCE_SEEK_TO_PREVIOUS_CHAPTER", +) { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - strings( - "SEEK_SOURCE_SEEK_TO_NEXT_CHAPTER", - "SEEK_SOURCE_SEEK_TO_PREVIOUS_CHAPTER", - ) } -internal val BytecodePatchContext.doubleTapInfoCtorMethod by gettingFirstMethodDeclaratively { +context(_: BytecodePatchContext) +internal fun ClassDef.getDoubleTapInfoCtorMethod() = firstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameterTypes( "Landroid/view/MotionEvent;", "I", "Z", - "Lj\$/time/Duration;", + "Lj$/time/Duration;", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt index a788c818d..1eac7848a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/Fingerprints.kt @@ -1,11 +1,7 @@ package app.revanced.patches.youtube.interaction.downloads -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.instructions -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags internal val BytecodePatchContext.offlineVideoEndpointMethod by gettingFirstMethodDeclaratively { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt index cad239cc7..2272ed39c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/Fingerprints.kt @@ -1,32 +1,27 @@ package app.revanced.patches.youtube.layout.autocaptions -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.opcodes -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.startVideoInformerMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.startVideoInformerMethod by gettingFirstMethodDeclaratively("pc") { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") opcodes( Opcode.INVOKE_INTERFACE, Opcode.RETURN_VOID, ) - strings("pc") } -internal val BytecodePatchContext.storyboardRendererDecoderRecommendedLevelMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.storyboardRendererDecoderRecommendedLevelMethod by gettingFirstMethodDeclaratively("#-1#") { returnType("V") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameterTypes("L") - strings("#-1#") } -internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDeclaratively("DISABLE_CAPTIONS_OPTION") { + definingClass { endsWith("/SubtitleTrack;") } accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Z") parameterTypes() @@ -38,8 +33,4 @@ internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDecla Opcode.MOVE_RESULT, Opcode.RETURN, ) - strings("DISABLE_CAPTIONS_OPTION") - custom { _, classDef -> - classDef.endsWith("/SubtitleTrack;") - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt index 402cd6d60..2aea8d5c7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt @@ -1,8 +1,8 @@ package app.revanced.patches.youtube.layout.formfactor +import app.revanced.patcher.* import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction -import app.revanced.patcher.instructions import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -46,21 +46,19 @@ val `Change form factor` by creatingBytecodePatch( hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR) - val createPlayerRequestBodyWithModelFingerprint = fingerprint { + val formFactorEnumConstructorClass = formFactorEnumConstructorMethod.definingClass + + val createPlayerRequestBodyWithModelMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("L") parameterTypes() instructions( - fieldAccess(smali = "Landroid/os/Build;->MODEL:Ljava/lang/String;"), - fieldAccess( - definingClass = formFactorEnumConstructorMethod.immutableClassDef.type, - type = "I", - afterAtMost(50), - ), + field { name == "MODEL" && definingClass == "Landroid/os/Build;" }, + field { type == "I" && definingClass == formFactorEnumConstructorClass }, ) } - createPlayerRequestBodyWithModelFingerprint.let { + createPlayerRequestBodyWithModelMatch.let { it.method.apply { val index = it.indices.last() val register = getInstruction(index).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt index b3f32f78e..01113a2a5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/Fingerprints.kt @@ -5,12 +5,11 @@ import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags -internal val BytecodePatchContext.formFactorEnumConstructorMethod by gettingFirstMethodDeclaratively { +internal val BytecodePatchContext.formFactorEnumConstructorMethod by gettingFirstMethodDeclaratively( + "UNKNOWN_FORM_FACTOR", + "SMALL_FORM_FACTOR", + "LARGE_FORM_FACTOR", + "AUTOMOTIVE_FORM_FACTOR", +) { accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) - strings( - "UNKNOWN_FORM_FACTOR", - "SMALL_FORM_FACTOR", - "LARGE_FORM_FACTOR", - "AUTOMOTIVE_FORM_FACTOR", - ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt index b0851ad93..cf6183f22 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/Fingerprints.kt @@ -1,18 +1,13 @@ package app.revanced.patches.youtube.layout.hide.fullscreenambientmode -import app.revanced.patcher.accessFlags -import app.revanced.patcher.gettingFirstMethodDeclaratively -import app.revanced.patcher.parameterTypes +import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.returnType import com.android.tools.smali.dexlib2.AccessFlags internal val BytecodePatchContext.setFullScreenBackgroundColorMethod by gettingFirstMethodDeclaratively { + name("onLayout") + definingClass { endsWith("/YouTubePlayerViewNotForReflection;") } returnType("V") accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) parameterTypes("Z", "I", "I", "I", "I") - custom { method, classDef -> - classDef.type.endsWith("/YouTubePlayerViewNotForReflection;") && - method.name == "onLayout" - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt index abf6e1279..6f1fc1d95 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt @@ -2,10 +2,10 @@ package app.revanced.patches.youtube.layout.hide.shorts import app.revanced.patcher.accessFlags import app.revanced.patcher.after -import app.revanced.patcher.at import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.instructions import app.revanced.patcher.invoke +import app.revanced.patcher.method import app.revanced.patcher.opcodes import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext @@ -21,7 +21,7 @@ internal val BytecodePatchContext.shortsBottomBarContainerMethod by gettingFirst instructions( "r_pfvc"(), ResourceType.ID("bottom_bar_container"), - methodCall(name = "getHeight"), + method("getHeight"), Opcode.MOVE_RESULT(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index 11d6d473b..75a42ebe7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.extensions.wideLiteral import app.revanced.patcher.patch.booleanOption +import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -95,7 +96,8 @@ private val hideShortsComponentsResourcePatch = resourcePatch { SwitchPreference("revanced_hide_shorts_effect_button"), SwitchPreference("revanced_hide_shorts_green_screen_button"), SwitchPreference("revanced_hide_shorts_hashtag_button"), - SwitchPreference("revanced_hide_shorts_live_preview"), SwitchPreference("revanced_hide_shorts_new_posts_button"), + SwitchPreference("revanced_hide_shorts_live_preview"), + SwitchPreference("revanced_hide_shorts_new_posts_button"), SwitchPreference("revanced_hide_shorts_shop_button"), SwitchPreference("revanced_hide_shorts_tagged_products"), SwitchPreference("revanced_hide_shorts_search_suggestions"), @@ -103,7 +105,8 @@ private val hideShortsComponentsResourcePatch = resourcePatch { SwitchPreference("revanced_hide_shorts_stickers"), // Bottom of the screen. - SwitchPreference("revanced_hide_shorts_auto_dubbed_label"), SwitchPreference("revanced_hide_shorts_location_label"), + SwitchPreference("revanced_hide_shorts_auto_dubbed_label"), + SwitchPreference("revanced_hide_shorts_location_label"), SwitchPreference("revanced_hide_shorts_channel_bar"), SwitchPreference("revanced_hide_shorts_info_panel"), SwitchPreference("revanced_hide_shorts_full_video_link_label"), @@ -154,7 +157,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch { private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/ShortsFilter;" @Suppress("unused", "ObjectPropertyName") -val `Hide Shorts componentsby creatingBytecodePatch( +val `Hide Shorts components` by creatingBytecodePatch( description = "Adds options to hide components related to Shorts.", ) { dependsOn(