From e12e484e3796c5c9c8505b677838cdf8432f2e79 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Wed, 18 May 2022 23:58:54 +0200 Subject: [PATCH 1/5] fix: breaking changes by `revanced-patcher` dependency Signed-off-by: oSumAtrIX --- build.gradle.kts | 1 + .../app/revanced/extensions/Extensions.kt | 2 +- src/main/kotlin/app/revanced/patches/Index.kt | 44 - .../patches/music/audio/CodecsUnlockPatch.kt | 157 -- .../music/audio/EnableAudioOnlyPatch.kt | 133 -- .../annotations/CodecsUnlockCompatibility.kt | 14 + .../audio/codecs/patch/CodecsUnlockPatch.kt | 44 + .../signatures/AllCodecsReferenceSignature.kt | 62 + .../codecs/signatures/CodecsLockSignature.kt | 47 + .../ExclusiveAudioCompatibility.kt | 14 + .../patch/ExclusiveAudioPatch.kt | 70 + .../signatures/ExclusiveAudioSignature.kt | 60 + .../music/layout/RemoveTasteBuilderPatch.kt | 94 - .../music/layout/RemoveUpgradeTabPatch.kt | 151 -- .../RemoveTasteBuilderCompatibility.kt | 14 + .../patch/RemoveTasteBuilderPatch.kt | 46 + .../TasteBuilderConstructorSignature.kt | 43 + .../RemoveUpgradeButtonCompatibility.kt | 14 + .../patch/RemoveUpgradeButtonPatch.kt | 76 + .../PivotBarConstructorSignature.kt | 71 + .../music/premium/BackgroundPlayPatch.kt | 92 - .../BackgroundPlayCompatibility.kt | 14 + .../patch/BackgroundPlayPatch.kt | 37 + .../BackgroundPlaybackDisableSignature.kt | 52 + .../patches/youtube/ad/HomeAdsPatch.kt | 1706 ---------------- .../patches/youtube/ad/HomePromoPatch.kt | 188 -- .../patches/youtube/ad/VideoAdsPatch.kt | 112 -- .../annotation/PromotionsCompatibility.kt | 14 + .../youtube/ad/home/patch/HomeAdsPatch.kt | 1710 +++++++++++++++++ .../youtube/ad/home/patch/PromotionsPatch.kt | 65 + .../PromotedDiscoveryActionParentSignature.kt | 58 + .../PromotedDiscoveryAppParentSignature.kt | 61 + .../annotations/VideoAdsCompatibility.kt | 14 + .../youtube/ad/video/patch/VideoAdsPatch.kt | 51 + .../ShowVideoAdsConstructorSignature.kt | 40 + .../interaction/EnableSeekbarTappingPatch.kt | 186 -- .../annotation/SeekbarTappingCompatibility.kt | 14 + .../patch/EnableSeekbarTappingPatch.kt | 94 + .../SeekbarTappingParentSignature.kt | 51 + .../signatures/SeekbarTappingSignature.kt | 41 + .../layout/CreateButtonRemoverPatch.kt | 102 - .../patches/youtube/layout/HideReelsPatch.kt | 115 -- .../youtube/layout/MinimizedPlaybackPatch.kt | 89 - .../youtube/layout/OldQualityLayoutPatch.kt | 127 -- .../layout/ShortsButtonRemoverPatch.kt | 135 -- .../annotations/CreateButtonCompatibility.kt | 13 + .../patch/CreateButtonRemoverPatch.kt | 46 + .../signatures/CreateButtonSignature.kt | 57 + .../MinimizedPlaybackCompatibility.kt | 13 + .../patch/MinimizedPlaybackPatch.kt | 39 + .../MinimizedPlaybackManagerSignature.kt | 51 + .../OldQualityLayoutCompatibility.kt | 13 + .../patch/OldQualityLayoutPatch.kt | 66 + .../signatures/OldQualityParentSignature.kt | 50 + .../annotations/HideReelsCompatibility.kt | 13 + .../layout/reels/patch/HideReelsPatch.kt | 38 + .../reels/signatures/HideReelsSignature.kt | 58 + .../annotations/ShortsButtonCompatibility.kt | 13 + .../button/patch/ShortsButtonRemoverPatch.kt | 53 + .../PivotBarButtonTabenumSignature.kt | 45 + .../PivotBarButtonsViewSignature.kt | 49 + .../patches/youtube/misc/IntegrationsPatch.kt | 125 -- .../annotations/IntegrationsCompatibility.kt | 13 + .../integrations/patch/IntegrationsPatch.kt | 65 + .../integrations/signatures/InitSignature.kt | 57 + .../FixLocaleConfigErrorCompatibility.kt | 13 + .../patch}/FixLocaleConfigErrorPatch.kt | 32 +- .../app/revanced/patches/SignatureChecker.kt | 39 +- 68 files changed, 3692 insertions(+), 3594 deletions(-) delete mode 100644 src/main/kotlin/app/revanced/patches/Index.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/audio/CodecsUnlockPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/audio/EnableAudioOnlyPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/AllCodecsReferenceSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/CodecsLockSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/signatures/ExclusiveAudioSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/layout/RemoveTasteBuilderPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/layout/RemoveUpgradeTabPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/signatures/TasteBuilderConstructorSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/signatures/PivotBarConstructorSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/music/premium/BackgroundPlayPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/signatures/BackgroundPlaybackDisableSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/HomeAdsPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/HomePromoPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/VideoAdsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/PromotionsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/EnableSeekbarTappingPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/CreateButtonRemoverPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/HideReelsPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/MinimizedPlaybackPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/OldQualityLayoutPatch.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/ShortsButtonRemoverPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/signatures/OldQualityParentSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/reels/annotations/HideReelsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/IntegrationsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt rename src/main/kotlin/app/revanced/patches/youtube/misc/{ => manifest/patch}/FixLocaleConfigErrorPatch.kt (56%) diff --git a/build.gradle.kts b/build.gradle.kts index 4fbc0499..c26f10b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,7 @@ dependencies { testImplementation(kotlin("test")) implementation("app.revanced:revanced-patcher:1.+") + implementation(kotlin("reflect")) } java { diff --git a/src/main/kotlin/app/revanced/extensions/Extensions.kt b/src/main/kotlin/app/revanced/extensions/Extensions.kt index 16242c94..8162d7af 100644 --- a/src/main/kotlin/app/revanced/extensions/Extensions.kt +++ b/src/main/kotlin/app/revanced/extensions/Extensions.kt @@ -1,6 +1,6 @@ package app.revanced.extensions -import app.revanced.patcher.smali.toInstruction +import app.revanced.patcher.util.smali.toInstruction import org.jf.dexlib2.builder.MutableMethodImplementation internal fun MutableMethodImplementation.injectHideCall( diff --git a/src/main/kotlin/app/revanced/patches/Index.kt b/src/main/kotlin/app/revanced/patches/Index.kt deleted file mode 100644 index 8c45945d..00000000 --- a/src/main/kotlin/app/revanced/patches/Index.kt +++ /dev/null @@ -1,44 +0,0 @@ -package app.revanced.patches - -import app.revanced.patcher.data.base.Data -import app.revanced.patcher.patch.base.Patch -import app.revanced.patches.music.audio.CodecsUnlockPatch -import app.revanced.patches.music.audio.EnableAudioOnlyPatch -import app.revanced.patches.music.layout.RemoveTasteBuilderPatch -import app.revanced.patches.music.layout.RemoveUpgradeTabPatch -import app.revanced.patches.music.premium.BackgroundPlayPatch -import app.revanced.patches.youtube.ad.HomePromoPatch -import app.revanced.patches.youtube.ad.VideoAdsPatch -import app.revanced.patches.youtube.interaction.EnableSeekbarTappingPatch -import app.revanced.patches.youtube.layout.* -import app.revanced.patches.youtube.misc.FixLocaleConfigErrorPatch -import app.revanced.patches.youtube.misc.IntegrationsPatch - -/** - * Index contains all the patches. - */ -@Suppress("Unused") -object Index { - /** - * Array of patches. - * New patches should be added to the array. - */ - val patches: List<() -> Patch> = listOf( - ::IntegrationsPatch, - ::FixLocaleConfigErrorPatch, - //::HomeAdsPatch, - ::VideoAdsPatch, - ::HomePromoPatch, - ::MinimizedPlaybackPatch, - ::CreateButtonRemoverPatch, - ::ShortsButtonRemoverPatch, - ::HideReelsPatch, - ::OldQualityLayoutPatch, - ::EnableSeekbarTappingPatch, - ::EnableAudioOnlyPatch, - ::RemoveUpgradeTabPatch, - ::RemoveTasteBuilderPatch, - ::BackgroundPlayPatch, - ::CodecsUnlockPatch - ) -} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/CodecsUnlockPatch.kt deleted file mode 100644 index 03c2264f..00000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/CodecsUnlockPatch.kt +++ /dev/null @@ -1,157 +0,0 @@ -package app.revanced.patches.music.audio - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.data.implementation.toMethodWalker -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstruction -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val packageMetadata = listOf( - PackageMetadata( - "com.google.android.apps.youtube.music", - listOf("5.03.50") - ) -) - -private val patchMetadata = PatchMetadata( - "codecs-unlock", - "Audio codecs unlock patch", - "Enables more audio codecs. Usually results in better audio quality but may depend on song and device.", - packageMetadata, - "0.0.1" -) - -class CodecsUnlockPatch : BytecodePatch( - patchMetadata, - listOf( - MethodSignature( - MethodSignatureMetadata( - "codec-lock-method", - MethodMetadata( - "Labwj;", - "a", - ), - PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value. - packageMetadata, - "Required signature for ${patchMetadata.name}. Discovered in version 5.03.50.", - "0.0.1" - ), - "L", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L", "L", "L", "L"), - listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.SGET, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_DIRECT, - Opcode.RETURN_OBJECT - ) - ), - MethodSignature( - MethodSignatureMetadata( - "all-codecs-reference-method", - MethodMetadata( - "Laari;", - "b", - ), - PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value. - packageMetadata, - "Required signature for ${patchMetadata.name}. Discovered in version 5.03.50.", - "0.0.1" - ), - "J", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L"), - listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_NEZ, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.MOVE_EXCEPTION, - Opcode.INVOKE_SUPER, - Opcode.MOVE_RESULT_WIDE, - Opcode.RETURN_WIDE - ), - listOf("itag") - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - var result = signatures.first().result!! - - val implementation = result.method.implementation!! - - val instructionIndex = result.scanData.startIndex - - result = signatures.last().result!! - val codecMethod = data - .toMethodWalker(result.immutableMethod) - .walk(result.scanData.startIndex) - .getMethod() - - implementation.replaceInstruction( - instructionIndex, - "invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction() - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/EnableAudioOnlyPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/EnableAudioOnlyPatch.kt deleted file mode 100644 index e1186acb..00000000 --- a/src/main/kotlin/app/revanced/patches/music/audio/EnableAudioOnlyPatch.kt +++ /dev/null @@ -1,133 +0,0 @@ -package app.revanced.patches.music.audio - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.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.toInstruction -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.apps.youtube.music", - listOf("5.03.50") - ) -) - -class EnableAudioOnlyPatch : BytecodePatch( - PatchMetadata( - "audio-only-playback-patch", - "Audio Only Mode Patch", - "Add the option to play music without video.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "audio-only-method-signature", - MethodMetadata("Lgmd;", "c"), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L", "Z"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQ, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.NOP, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_EQZ, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.RETURN_VOID - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result = signatures.first().result!!.findParentMethod( - MethodSignature( - MethodSignatureMetadata( - "audio-only-enabler-method", - MethodMetadata("Lgmd;", "d"), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "Z", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf(), - listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.GOTO, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.RETURN - ) - ) - ) ?: return PatchResultError("Required method for ${metadata.shortName} not found.") - - val implementation = result.method.implementation!! - implementation.replaceInstruction( - implementation.instructions.count() - 1, - "const/4 v0, 0x1".toInstruction() - ) - implementation.addInstruction( - "return v0".toInstruction() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt new file mode 100644 index 00000000..e1404585 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/annotations/CodecsUnlockCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.audio.codecs.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", arrayOf("5.03.50") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class CodecsUnlockCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt new file mode 100644 index 00000000..4f178a6e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt @@ -0,0 +1,44 @@ +package app.revanced.patches.music.audio.codecs.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.data.implementation.toMethodWalker +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility +import app.revanced.patches.music.audio.codecs.signatures.AllCodecsReferenceSignature +import app.revanced.patches.music.audio.codecs.signatures.CodecsLockSignature + +@Patch +@Name("codecs-unlock") +@Description("Enables more audio codecs. Usually results in better audio quality but may depend on song and device.") +@CodecsUnlockCompatibility +@Version("0.0.1") +class CodecsUnlockPatch : BytecodePatch( + listOf( + CodecsLockSignature, AllCodecsReferenceSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + var result = signatures.first().result!! + + val implementation = result.method.implementation!! + + val instructionIndex = result.scanData.startIndex + + result = signatures.last().result!! + val codecMethod = data.toMethodWalker(result.immutableMethod).walk(result.scanData.startIndex).getMethod() + + implementation.replaceInstruction( + instructionIndex, + "invoke-static {}, ${codecMethod.definingClass}->${codecMethod.name}()Ljava/util/Set;".toInstruction() + ) + + return PatchResultSuccess() + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/AllCodecsReferenceSignature.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/AllCodecsReferenceSignature.kt new file mode 100644 index 00000000..2ff563ad --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/AllCodecsReferenceSignature.kt @@ -0,0 +1,62 @@ +package app.revanced.patches.music.audio.codecs.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("all-codecs-reference-signature") +@MatchingMethod( + "Laari;", + "b", +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@CodecsUnlockCompatibility +@Version("0.0.1") +object AllCodecsReferenceSignature : MethodSignature( + "J", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.IPUT_BOOLEAN, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.GOTO, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.IPUT_BOOLEAN, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.GOTO, + Opcode.MOVE_EXCEPTION, + Opcode.INVOKE_SUPER, + Opcode.MOVE_RESULT_WIDE, + Opcode.RETURN_WIDE + ), listOf("itag") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/CodecsLockSignature.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/CodecsLockSignature.kt new file mode 100644 index 00000000..ff3f56de --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/signatures/CodecsLockSignature.kt @@ -0,0 +1,47 @@ +package app.revanced.patches.music.audio.codecs.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.audio.codecs.annotations.CodecsUnlockCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("codec-lock-signature") +@MatchingMethod( + "Labwj;", + "a", +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@CodecsUnlockCompatibility +@Version("0.0.1") +object CodecsLockSignature : MethodSignature( + "L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L", "L"), listOf( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.SGET, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.INVOKE_INTERFACE, + Opcode.INVOKE_DIRECT, + Opcode.RETURN_OBJECT + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt new file mode 100644 index 00000000..6b9b022e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/annotations/ExclusiveAudioCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.audio.exclusiveaudio.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", arrayOf("5.03.50") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class ExclusiveAudioCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt new file mode 100644 index 00000000..e1e67f52 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/patch/ExclusiveAudioPatch.kt @@ -0,0 +1,70 @@ +package app.revanced.patches.music.audio.exclusiveaudio.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.DirectPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility +import app.revanced.patches.music.audio.exclusiveaudio.signatures.ExclusiveAudioSignature +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Patch +@Name("exclusive-audio-playback") +@Description("Add the option to play music without video.") +@ExclusiveAudioCompatibility +@Version("0.0.1") +class ExclusiveAudioPatch : BytecodePatch( + listOf( + ExclusiveAudioSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!!.findParentMethod(@Name("audio-only-enabler-method") @MatchingMethod( + "Lgmd;", + "d" + ) @DirectPatternScanMethod @ExclusiveAudioCompatibility @Version( + "0.0.1" + ) object : MethodSignature( + "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.GOTO, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.RETURN + ) + ) {}) ?: return PatchResultError("Required parent method could not be found.") + + val implementation = result.method.implementation!! + implementation.replaceInstruction( + implementation.instructions.count() - 1, "const/4 v0, 0x1".toInstruction() + ) + implementation.addInstruction( + "return v0".toInstruction() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/signatures/ExclusiveAudioSignature.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/signatures/ExclusiveAudioSignature.kt new file mode 100644 index 00000000..4e384c0a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/signatures/ExclusiveAudioSignature.kt @@ -0,0 +1,60 @@ +package app.revanced.patches.music.audio.exclusiveaudio.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("exclusive-audio-signature") +@MatchingMethod( + "Lgmd;", "c" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@ExclusiveAudioCompatibility +@Version("0.0.1") +object ExclusiveAudioSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + listOf("L", "Z"), + listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQ, + Opcode.CONST_4, + Opcode.GOTO, + Opcode.NOP, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IF_EQZ, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IF_EQZ, + Opcode.IF_EQZ, + Opcode.INVOKE_INTERFACE, + Opcode.INVOKE_INTERFACE, + Opcode.GOTO, + Opcode.RETURN_VOID + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/RemoveTasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/RemoveTasteBuilderPatch.kt deleted file mode 100644 index 904c16e5..00000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/RemoveTasteBuilderPatch.kt +++ /dev/null @@ -1,94 +0,0 @@ -package app.revanced.patches.music.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.formats.Instruction22c - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.apps.youtube.music", - listOf("5.03.50") - ) -) - -class RemoveTasteBuilderPatch : BytecodePatch( - PatchMetadata( - "tasteBuilder-remover", - "Remove TasteBuilder Patch", - "Removes the \"Tell us which artists you like\" card from the Home screen. The same functionality can be triggered from the settings anyway.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "taste-builder-constructor", - MethodMetadata("Lkyu;", ""), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Required signature for this patch.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "L", "L", "L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_VIRTUAL, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - 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, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result = signatures.first().result!! - val implementation = result.method.implementation!! - - val insertIndex = result.scanData.endIndex - 8 - - val register = (implementation.instructions[insertIndex] as Instruction22c).registerA - - val instructionList = - """ - const/16 v1, 0x8 - invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V - """.trimIndent().toInstructions().toMutableList() - - implementation.addInstructions( - insertIndex, - instructionList - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/RemoveUpgradeTabPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/RemoveUpgradeTabPatch.kt deleted file mode 100644 index b55c2800..00000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/RemoveUpgradeTabPatch.kt +++ /dev/null @@ -1,151 +0,0 @@ -package app.revanced.patches.music.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction22t -import org.jf.dexlib2.iface.instruction.formats.Instruction22c -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.apps.youtube.music", - listOf("5.03.50") - ) -) - -class RemoveUpgradeTabPatch : BytecodePatch( - PatchMetadata( - "upgrade-tab-remover", - "Remove Upgrade Tab Patch", - "Remove the upgrade tab from t he pivot bar in YouTube music.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "pivot-bar-constructor", - MethodMetadata("Lhfu;", ""), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Required signature for this patch.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "Z"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_INTERFACE, - Opcode.GOTO, - Opcode.NOP, - Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result = signatures.first().result!! - val implementation = result.method.implementation!! - - val pivotBarElementFieldRef = - (implementation.instructions[result.scanData.endIndex - 1] as Instruction22c).reference - - val register = (implementation.instructions.first() as Instruction35c).registerC - // first compile all the needed instructions - val instructionList = - """ - invoke-interface { v0 }, Ljava/util/List;->size()I - move-result v1 - const/4 v2, 0x3 - invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; - iput-object v0, v$register, $pivotBarElementFieldRef - """.trimIndent().toInstructions().toMutableList() - - - // replace the instruction to retain the label at given index - implementation.replaceInstruction( - result.scanData.endIndex - 1, - instructionList[0] // invoke-interface - ) - // do not forget to remove this instruction since we added it already - instructionList.removeFirst() - - val exitInstruction = instructionList.last() // iput-object - implementation.addInstruction( - result.scanData.endIndex, - exitInstruction - ) - // do not forget to remove this instruction since we added it already - instructionList.removeLast() - - // add the necessary if statement to remove the upgrade tab button in case it exists - instructionList.add( - 2, // if-le - BuilderInstruction22t( - Opcode.IF_LE, - 1, 2, - implementation.newLabelForIndex(result.scanData.endIndex) - ) - ) - - implementation.addInstructions( - result.scanData.endIndex, - instructionList - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt new file mode 100644 index 00000000..fb2c0e38 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/annotations/RemoveTasteBuilderCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.layout.tastebuilder.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", arrayOf("5.03.50") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class RemoveTasteBuilderCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt new file mode 100644 index 00000000..81dac406 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.music.layout.tastebuilder.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.music.layout.tastebuilder.annotations.RemoveTasteBuilderCompatibility +import app.revanced.patches.music.layout.tastebuilder.signatures.TasteBuilderConstructorSignature +import org.jf.dexlib2.iface.instruction.formats.Instruction22c + +@Patch +@Name("tasteBuilder-remover") +@Description("Removes the \"Tell us which artists you like\" card from the Home screen. The same functionality can be triggered from the settings anyway.") +@RemoveTasteBuilderCompatibility +@Version("0.0.1") +class RemoveTasteBuilderPatch : BytecodePatch( + listOf( + TasteBuilderConstructorSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!! + val implementation = result.method.implementation!! + + val insertIndex = result.scanData.endIndex - 8 + + val register = (implementation.instructions[insertIndex] as Instruction22c).registerA + + val instructionList = """ + const/16 v1, 0x8 + invoke-virtual {v${register}, v1}, Landroid/view/View;->setVisibility(I)V + """.trimIndent().toInstructions().toMutableList() + + implementation.addInstructions( + insertIndex, instructionList + ) + + return PatchResultSuccess() + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/signatures/TasteBuilderConstructorSignature.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/signatures/TasteBuilderConstructorSignature.kt new file mode 100644 index 00000000..f00284b0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/signatures/TasteBuilderConstructorSignature.kt @@ -0,0 +1,43 @@ +package app.revanced.patches.music.layout.tastebuilder.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.layout.tastebuilder.annotations.RemoveTasteBuilderCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("taste-builder-constructor") +@MatchingMethod( + "Lkyu;", "" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@RemoveTasteBuilderCompatibility +@Version("0.0.1") +object TasteBuilderConstructorSignature : MethodSignature( + "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L"), listOf( + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_VIRTUAL, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + 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, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt new file mode 100644 index 00000000..9125b39b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/annotations/RemoveUpgradeButtonCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.layout.upgradebutton.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", arrayOf("5.03.50") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class RemoveUpgradeButtonCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt new file mode 100644 index 00000000..9a2813d6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt @@ -0,0 +1,76 @@ +package app.revanced.patches.music.layout.upgradebutton.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.music.layout.upgradebutton.annotations.RemoveUpgradeButtonCompatibility +import app.revanced.patches.music.layout.upgradebutton.signatures.PivotBarConstructorSignature +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.builder.instruction.BuilderInstruction22t +import org.jf.dexlib2.iface.instruction.formats.Instruction22c +import org.jf.dexlib2.iface.instruction.formats.Instruction35c + + +@Patch +@Name("upgrade-button-remover") +@Description("Remove the upgrade tab from t he pivot bar in YouTube music.") +@RemoveUpgradeButtonCompatibility +@Version("0.0.1") +class RemoveUpgradeButtonPatch : BytecodePatch( + listOf( + PivotBarConstructorSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!! + val implementation = result.method.implementation!! + + val pivotBarElementFieldRef = + (implementation.instructions[result.scanData.endIndex - 1] as Instruction22c).reference + + val register = (implementation.instructions.first() as Instruction35c).registerC + // first compile all the needed instructions + val instructionList = """ + invoke-interface { v0 }, Ljava/util/List;->size()I + move-result v1 + const/4 v2, 0x3 + invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; + iput-object v0, v$register, $pivotBarElementFieldRef + """.trimIndent().toInstructions().toMutableList() + + + // replace the instruction to retain the label at given index + implementation.replaceInstruction( + result.scanData.endIndex - 1, instructionList[0] // invoke-interface + ) + // do not forget to remove this instruction since we added it already + instructionList.removeFirst() + + val exitInstruction = instructionList.last() // iput-object + implementation.addInstruction( + result.scanData.endIndex, exitInstruction + ) + // do not forget to remove this instruction since we added it already + instructionList.removeLast() + + // add the necessary if statement to remove the upgrade tab button in case it exists + instructionList.add( + 2, // if-le + BuilderInstruction22t( + Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(result.scanData.endIndex) + ) + ) + + implementation.addInstructions( + result.scanData.endIndex, instructionList + ) + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/signatures/PivotBarConstructorSignature.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/signatures/PivotBarConstructorSignature.kt new file mode 100644 index 00000000..238340d5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/signatures/PivotBarConstructorSignature.kt @@ -0,0 +1,71 @@ +package app.revanced.patches.music.layout.upgradebutton.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.layout.upgradebutton.annotations.RemoveUpgradeButtonCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("pivot-bar-constructor") +@MatchingMethod( + "Lhfu;", "" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@RemoveUpgradeButtonCompatibility +@Version("0.0.1") +object PivotBarConstructorSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + listOf("L", "Z"), + listOf( + Opcode.INVOKE_DIRECT, + Opcode.CONST_4, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_BOOLEAN, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.GOTO, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IGET, + Opcode.CONST, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.CHECK_CAST, + Opcode.GOTO, + Opcode.SGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IGET, + Opcode.CONST, + Opcode.IF_NE, + Opcode.IGET_OBJECT, + Opcode.CHECK_CAST, + Opcode.INVOKE_INTERFACE, + Opcode.GOTO, + Opcode.NOP, + Opcode.IPUT_OBJECT, + Opcode.RETURN_VOID + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/premium/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/premium/BackgroundPlayPatch.kt deleted file mode 100644 index f84aec6f..00000000 --- a/src/main/kotlin/app/revanced/patches/music/premium/BackgroundPlayPatch.kt +++ /dev/null @@ -1,92 +0,0 @@ -package app.revanced.patches.music.premium - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.apps.youtube.music", - listOf("5.03.50") - ) -) - -class BackgroundPlayPatch : BytecodePatch( - PatchMetadata( - "background-play", - "Enable Background Playback Patch", - "Enable playing music in the background.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "background-playback-disabler-method", - MethodMetadata("Lafgf;", "e"), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "Z", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L"), - 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_EQZ, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.RETURN, - Opcode.RETURN - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - signatures.first().result!!.method.implementation!!.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """.trimIndent().toInstructions() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt new file mode 100644 index 00000000..26af8716 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/annotations/BackgroundPlayCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.music.premium.backgroundplay.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.apps.youtube.music", arrayOf("5.03.50") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class BackgroundPlayCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt new file mode 100644 index 00000000..84fe9a09 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/patch/BackgroundPlayPatch.kt @@ -0,0 +1,37 @@ +package app.revanced.patches.music.premium.backgroundplay.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.music.premium.backgroundplay.annotations.BackgroundPlayCompatibility +import app.revanced.patches.music.premium.backgroundplay.signatures.BackgroundPlaybackDisableSignature + +@Patch +@Name("background-play") +@Description("Enable playing music in the background.") +@BackgroundPlayCompatibility +@Version("0.0.1") +class BackgroundPlayPatch : BytecodePatch( + listOf( + BackgroundPlaybackDisableSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + signatures.first().result!!.method.implementation!!.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """.trimIndent().toInstructions() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/signatures/BackgroundPlaybackDisableSignature.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/signatures/BackgroundPlaybackDisableSignature.kt new file mode 100644 index 00000000..98ed8850 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/signatures/BackgroundPlaybackDisableSignature.kt @@ -0,0 +1,52 @@ +package app.revanced.patches.music.premium.backgroundplay.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.music.premium.backgroundplay.annotations.BackgroundPlayCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("background-playback-disabler-signature") +@MatchingMethod( + "Lafgf;", "e" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@BackgroundPlayCompatibility +@Version("0.0.1") +object BackgroundPlaybackDisableSignature : MethodSignature( + "Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), 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_EQZ, + Opcode.CONST_4, + Opcode.RETURN, + Opcode.RETURN, + Opcode.RETURN + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/HomeAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/HomeAdsPatch.kt deleted file mode 100644 index fda073ee..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/HomeAdsPatch.kt +++ /dev/null @@ -1,1706 +0,0 @@ -package app.revanced.patches.youtube.ad - -import app.revanced.extensions.injectHideCall -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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 org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.formats.Instruction11x - - -private val packageMetadata = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.03.38") - ), -) - -private val patchMetadata = PatchMetadata( - "home-ads", - "Home Ads Patch", - "Patch to remove ads in YouTube", - packageMetadata, - "0.0.1" -) - -private val signatureDescription = "Required signature for ${patchMetadata.name}. Discovered in version 17.03.38." - -class HomeAdsPatch : BytecodePatch( - patchMetadata, - listOf( - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-1", - MethodMetadata( - "Ljke;", - "k", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "Z", - AccessFlags.PRIVATE or AccessFlags.FINAL, - listOf("L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.GOTO, - Opcode.IGET_OBJECT, - Opcode.IF_EQ, - Opcode.CONST, - Opcode.GOTO, - Opcode.CONST, - Opcode.INVOKE_DIRECT, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_DIRECT, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.IGET_OBJECT, - Opcode.GOTO, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_EQ, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-2", - MethodMetadata( - "Ljsi;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "I" - ), - listOf( - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IPUT_BOOLEAN, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-3", - MethodMetadata( - "Ljrh;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.MOVE_OBJECT_FROM16 - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-4", - MethodMetadata( - "Ljrk;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "I"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-5", - MethodMetadata( - "Ljrn;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "I"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-6", - MethodMetadata( - "Ljrq;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-7", - MethodMetadata( - "Ljrr;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "I", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-8", - MethodMetadata( - "Ljrt;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-9", - MethodMetadata( - "Ljru;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-10", - MethodMetadata( - "Ljrv;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-11", - MethodMetadata( - "Ljpm;", - "lX", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, - listOf("L", "L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-12", - MethodMetadata( - "Ljpr;", - "b", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PRIVATE or AccessFlags.FINAL, - listOf(), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-13", - MethodMetadata( - "Ljqk;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-14", - MethodMetadata( - "Ljqa;", - "b", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PRIVATE or AccessFlags.FINAL, - listOf(), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-15", - MethodMetadata( - "Ljra;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "I"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.CONST_4, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-16", - MethodMetadata( - "Ljrd;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.CONST_16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) - ), - MethodSignature( - MethodSignatureMetadata( - "home-ads-method-17", - MethodMetadata( - "Ljre;", - "", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - packageMetadata, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B" - ), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.IF_NEZ, - Opcode.MOVE_OBJECT_FROM16, - Opcode.GOTO, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_4, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.CONST_16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.CONST_4, - Opcode.CONST_16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT_RANGE, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.NEW_INSTANCE, - Opcode.CONST_16, - Opcode.INVOKE_DIRECT, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.MOVE_OBJECT_FROM16, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_OBJECT_FROM16, - Opcode.IF_EQZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - for (i in 0 until signatures.count()) { - val signature = signatures.elementAt(i) - val result = signature.result!! - val implementation = result.method.implementation!! - val index = result.scanData.startIndex - val instructions = implementation.instructions - - val register = (instructions[index + (if (i < 2) -1 else 1)] as Instruction11x).registerA - implementation.injectHideCall(index + 2, register) - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/HomePromoPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/HomePromoPatch.kt deleted file mode 100644 index f92d1673..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/HomePromoPatch.kt +++ /dev/null @@ -1,188 +0,0 @@ -package app.revanced.patches.youtube.ad - -import app.revanced.extensions.injectHideCall -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.data.implementation.toMethodWalker -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess -import app.revanced.patcher.proxy.mutableTypes.MutableMethod -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 org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.formats.Instruction11x - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.03.38", "17.14.35", "17.17.34") - ) -) - -private val patchMetadata = PatchMetadata( - "home-promo-ads", - "Home Promo Ads Patch", - "Patch to remove promoted ads in YouTube", - compatiblePackages, - "0.0.1" -) - -private val signatureDescription = "Required signature for ${patchMetadata.name}. Discovered in version 17.03.38." - -class HomePromoPatch : BytecodePatch( - patchMetadata, - listOf( - MethodSignature( - MethodSignatureMetadata( - "promoted-discovery-app-parent-method", - MethodMetadata( - "Ljre;", - "lP", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, - listOf("L", "L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.IGET_BOOLEAN, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.NEW_ARRAY, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_GE, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.APUT_OBJECT, - Opcode.ADD_INT_LIT8, - Opcode.GOTO - ) - ), - MethodSignature( - MethodSignatureMetadata( - "promoted-discovery-action-parent-method", - MethodMetadata( - "Ljqv;", - "lP", - ), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, - listOf("L", "L"), - listOf( - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.MOVE_OBJECT_FROM16, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_BOOLEAN, - Opcode.CONST_4, - Opcode.XOR_INT_2ADDR, - Opcode.IGET_BOOLEAN, - Opcode.INVOKE_DIRECT, - Opcode.IGET_BOOLEAN, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST_4, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - for (signature in signatures) { - val result = signature.result!! - - val methodMetadata = MethodMetadata(signature.metadata.methodMetadata!!.definingClass, "d") - val requiredMethod = result.findParentMethod( - MethodSignature( - MethodSignatureMetadata( - "promoted-discovery-action-method", - methodMetadata, - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - signatureDescription, - "0.0.1" - ), - "V", - AccessFlags.PRIVATE or AccessFlags.FINAL, - listOf("Z", "Z"), - null - ) - ) - ?: return PatchResultError("Required parent method ${methodMetadata.name} could not be found in ${methodMetadata.definingClass}") - - val toBePatchedInvokeOffset = - requiredMethod.immutableMethod.implementation!!.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_DIRECT } - val toBePatchedMethod = data - .toMethodWalker(requiredMethod.immutableMethod) - .walk(toBePatchedInvokeOffset, true) - .getMethod() as MutableMethod - - val implementation = toBePatchedMethod.implementation!! - val invokeVirtualOffset = implementation.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_VIRTUAL } - - val moveResultInstruction = implementation.instructions[invokeVirtualOffset + 1] - if (moveResultInstruction.opcode != Opcode.MOVE_RESULT_OBJECT) - return PatchResultError("The toBePatchedInvokeOffset offset was wrong in ${metadata.name}") - - val register = (moveResultInstruction as Instruction11x).registerA - implementation.injectHideCall(invokeVirtualOffset + 2, register) - } - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/VideoAdsPatch.kt deleted file mode 100644 index 0f8396bb..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/VideoAdsPatch.kt +++ /dev/null @@ -1,112 +0,0 @@ -package app.revanced.patches.youtube.ad - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val packageMetadata = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.14.35", "17.17.34") - ) -) - -private val patchMetadata = PatchMetadata( - "video-ads", - "YouTube Video Ads Patch", - "Patch to remove ads in the YouTube video player.", - packageMetadata, - "0.0.1" -) - -class VideoAdsPatch : BytecodePatch( - patchMetadata, - listOf( - MethodSignature( - MethodSignatureMetadata( - "show-video-ads-constructor", - MethodMetadata( - "Laadb", - "", - ), - PatternScanMethod.Fuzzy(2),// FIXME: Test this threshold and find the best value. - packageMetadata, - "Required signature for ${patchMetadata.name}. Discovered in version 17.14.35.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "L", "L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - null, // either CONST_4 or CONST_16 - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.IPUT_BOOLEAN, - Opcode.RETURN_VOID - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - var result = signatures.first().result!! - - val responsibleMethodSignature = MethodSignature( - MethodSignatureMetadata( - "show-video-ads-method", - MethodMetadata( - "zai", - null // unknown - ), - PatternScanMethod.Direct(), - packageMetadata, - "Signature to find the method, which is responsible for showing the video ads. Discovered in version 17.14.35", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("Z"), - null - ) - - result = result.findParentMethod( - responsibleMethodSignature - ) ?: return PatchResultError( - "Could not find parent method with signature ${responsibleMethodSignature.metadata.name}" - ) - - // Override the parameter by calling shouldShowAds and setting the parameter to the result - result.method.implementation!!.addInstructions( - 0, - """ - invoke-static { }, Lfi/vanced/libraries/youtube/whitelisting/Whitelist;->shouldShowAds()Z - move-result v1 - """.trimIndent().toInstructions() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt new file mode 100644 index 00000000..367d4bc6 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.ad.home.annotation + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class PromotionsCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt new file mode 100644 index 00000000..6b22b16e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt @@ -0,0 +1,1710 @@ +/** +package app.revanced.patches.youtube.ad + +import app.revanced.extensions.injectHideCall +import app.revanced.patcher.annotations.Compatibility +import app.revanced.patcher.annotations.Package +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.metadata.PackageMetadata +import app.revanced.patcher.patch.implementation.metadata.PatchMetadata +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.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 org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.formats.Instruction11x + + +private val packageMetadata = listOf( +PackageMetadata( +"com.google.android.youtube", +listOf("17.03.38") +), +) + +private val patchMetadata = PatchMetadata( +"home-ads", +"Home Ads Patch", +"Patch to remove ads in YouTube", +packageMetadata, +"0.0.1" +) + +private val signatureDescription = "Required signature for ${patchMetadata.name}. Discovered in version 17.03.38." + +class HomeAdsPatch : BytecodePatch( +patchMetadata, +listOf( +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-1", +MethodMetadata( +"Ljke;", +"k", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"Z", +AccessFlags.PRIVATE or AccessFlags.FINAL, +listOf("L"), +listOf( +Opcode.INVOKE_DIRECT, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.GOTO, +Opcode.IGET_OBJECT, +Opcode.IF_EQ, +Opcode.CONST, +Opcode.GOTO, +Opcode.CONST, +Opcode.INVOKE_DIRECT, +Opcode.MOVE_RESULT_OBJECT, +Opcode.INVOKE_DIRECT, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.INVOKE_STATIC, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.INVOKE_STATIC, +Opcode.IGET_OBJECT, +Opcode.GOTO, +Opcode.IGET_OBJECT, +Opcode.INVOKE_STATIC, +Opcode.MOVE_RESULT, +Opcode.IF_EQZ, +Opcode.IGET_OBJECT, +Opcode.IF_EQ, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-2", +MethodMetadata( +"Ljsi;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"I" +), +listOf( +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CONST, +Opcode.CONST_4, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT, +Opcode.IPUT_BOOLEAN, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-3", +MethodMetadata( +"Ljrh;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_16, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.CONST_4, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.MOVE_OBJECT_FROM16 +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-4", +MethodMetadata( +"Ljrk;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf("L", "I"), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-5", +MethodMetadata( +"Ljrn;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf("L", "I"), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-6", +MethodMetadata( +"Ljrq;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-7", +MethodMetadata( +"Ljrr;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"I", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-8", +MethodMetadata( +"Ljrt;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-9", +MethodMetadata( +"Ljru;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-10", +MethodMetadata( +"Ljrv;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_16, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-11", +MethodMetadata( +"Ljpm;", +"lX", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, +listOf("L", "L"), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.INVOKE_STATIC, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-12", +MethodMetadata( +"Ljpr;", +"b", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PRIVATE or AccessFlags.FINAL, +listOf(), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.CONST_4, +Opcode.INVOKE_VIRTUAL, +Opcode.CONST_4, +Opcode.INVOKE_VIRTUAL, +Opcode.RETURN_VOID +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-13", +MethodMetadata( +"Ljqk;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST_4, +Opcode.INVOKE_STATIC, +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-14", +MethodMetadata( +"Ljqa;", +"b", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PRIVATE or AccessFlags.FINAL, +listOf(), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.RETURN_VOID +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-15", +MethodMetadata( +"Ljra;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, +listOf("L", "I"), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.CONST_16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.IGET_OBJECT, +Opcode.CONST_4, +Opcode.CONST_4, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.NEW_INSTANCE, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.CONST_4, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.RETURN_VOID +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-16", +MethodMetadata( +"Ljrd;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.CONST_4, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.CONST_16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST_4, +Opcode.CONST_4, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.NEW_INSTANCE, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.RETURN_VOID +) +), +MethodSignature( +MethodSignatureMetadata( +"home-ads-method-17", +MethodMetadata( +"Ljre;", +"", +), +PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. +packageMetadata, +signatureDescription, +"0.0.1" +), +"V", +AccessFlags.PROTECTED or AccessFlags.CONSTRUCTOR, +listOf( +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"L", +"[B", +"[B", +"[B", +"[B" +), +listOf( +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.CHECK_CAST, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.IF_NEZ, +Opcode.MOVE_OBJECT_FROM16, +Opcode.GOTO, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_4, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.CONST_16, +Opcode.INVOKE_DIRECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.CONST_16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST_4, +Opcode.CONST_4, +Opcode.CONST_4, +Opcode.CONST_16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT_RANGE, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.CONST, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_RESULT_OBJECT, +Opcode.CHECK_CAST, +Opcode.NEW_INSTANCE, +Opcode.CONST_16, +Opcode.INVOKE_DIRECT, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.NEW_INSTANCE, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_DIRECT, +Opcode.IPUT_OBJECT, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.SGET_OBJECT, +Opcode.MOVE_OBJECT_FROM16, +Opcode.INVOKE_VIRTUAL, +Opcode.MOVE_OBJECT_FROM16, +Opcode.IF_EQZ, +Opcode.SGET_OBJECT, +Opcode.INVOKE_VIRTUAL, +Opcode.RETURN_VOID +) +) +) +) { +override fun execute(data: BytecodeData): PatchResult { +for (i in 0 until signatures.count()) { +val signature = signatures.elementAt(i) +val result = signature.result!! +val implementation = result.method.implementation!! +val index = result.scanData.startIndex +val instructions = implementation.instructions + +val register = (instructions[index + (if (i < 2) -1 else 1)] as Instruction11x).registerA +implementation.injectHideCall(index + 2, register) +} + +return PatchResultSuccess() +} +} + **/ \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/PromotionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/PromotionsPatch.kt new file mode 100644 index 00000000..c8d397c5 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/PromotionsPatch.kt @@ -0,0 +1,65 @@ +package app.revanced.patches.youtube.ad.home.patch + +import app.revanced.extensions.injectHideCall +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.data.implementation.toMethodWalker +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.DirectPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.youtube.ad.home.annotation.PromotionsCompatibility +import app.revanced.patches.youtube.ad.home.signatures.PromotedDiscoveryActionParentSignature +import app.revanced.patches.youtube.ad.home.signatures.PromotedDiscoveryAppParentSignature +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.formats.Instruction11x + +@Patch +@Name("home-promo-ads") +@Description("Patch to remove promoted ads in YouTube.") +@PromotionsCompatibility +@Version("0.0.1") +class PromotionsPatch : BytecodePatch( + listOf( + PromotedDiscoveryAppParentSignature, PromotedDiscoveryActionParentSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + for (signature in signatures) { + val result = signature.result!! + + val requiredMethod = + result.findParentMethod(@Name("promotion-ads-signature") @MatchingMethod(name = "d") @DirectPatternScanMethod @PromotionsCompatibility @Version( + "0.0.1" + ) object : MethodSignature( + "V", AccessFlags.PRIVATE or AccessFlags.FINAL, listOf("Z", "Z"), null + ) {}) ?: return PatchResultError("Required parent method could not be found.") + + val toBePatchedInvokeOffset = + requiredMethod.immutableMethod.implementation!!.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_DIRECT } + val toBePatchedMethod = + data.toMethodWalker(requiredMethod.immutableMethod).walk(toBePatchedInvokeOffset, true) + .getMethod() as MutableMethod + + val implementation = toBePatchedMethod.implementation!! + val invokeVirtualOffset = implementation.instructions.indexOfFirst { it.opcode == Opcode.INVOKE_VIRTUAL } + + val moveResultInstruction = implementation.instructions[invokeVirtualOffset + 1] + if (moveResultInstruction.opcode != Opcode.MOVE_RESULT_OBJECT) return PatchResultError("The toBePatchedInvokeOffset offset was wrong in ${(this::class.annotations.find { it is Name } as Name).name}") + + val register = (moveResultInstruction as Instruction11x).registerA + implementation.injectHideCall(invokeVirtualOffset + 2, register) + } + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt new file mode 100644 index 00000000..c3c8d73e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt @@ -0,0 +1,58 @@ +package app.revanced.patches.youtube.ad.home.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("promoted-discovery-app-parent-signature") +@MatchingMethod( + "Ljre;", "lP" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@SeekbarTappingCompatibility +@Version("0.0.1") +object PromotedDiscoveryActionParentSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, + listOf("L", "L"), + listOf( + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.MOVE_OBJECT_FROM16, + Opcode.CHECK_CAST, + Opcode.INVOKE_VIRTUAL_RANGE, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.IGET_BOOLEAN, + Opcode.CONST_4, + Opcode.XOR_INT_2ADDR, + Opcode.IGET_BOOLEAN, + Opcode.INVOKE_DIRECT, + Opcode.IGET_BOOLEAN, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.CONST_4, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt new file mode 100644 index 00000000..7c3ad070 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt @@ -0,0 +1,61 @@ +package app.revanced.patches.youtube.ad.home.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("promoted-discovery-action-parent-signature") +@MatchingMethod( + "Ljqv;", + "lP" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@SeekbarTappingCompatibility +@Version("0.0.1") + +object PromotedDiscoveryAppParentSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.BRIDGE or AccessFlags.SYNTHETIC, + listOf("L", "L"), + listOf( + Opcode.INVOKE_DIRECT, + Opcode.IGET_BOOLEAN, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.NEW_ARRAY, + Opcode.IPUT_OBJECT, + Opcode.CONST_4, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IF_GE, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.APUT_OBJECT, + Opcode.ADD_INT_LIT8, + Opcode.GOTO + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt new file mode 100644 index 00000000..1e6a92ac --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.ad.video.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class VideoAdsCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt new file mode 100644 index 00000000..ef1f5272 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/patch/VideoAdsPatch.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.youtube.ad.video.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.DirectPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility +import app.revanced.patches.youtube.ad.video.signatures.ShowVideoAdsConstructorSignature +import org.jf.dexlib2.AccessFlags + +@Patch +@Name("video-ads") +@Description("Patch to remove ads in the YouTube video player.") +@VideoAdsCompatibility +@Version("0.0.1") +class VideoAdsPatch : BytecodePatch( + listOf( + ShowVideoAdsConstructorSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = + signatures.first().result!!.findParentMethod(@Name("show-video-ads-method-signature") @MatchingMethod( + definingClass = "zai" + ) @DirectPatternScanMethod @VideoAdsCompatibility @Version("0.0.1") object : MethodSignature( + "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), null + ) {}) ?: return PatchResultError("Required parent method could not be found.") + + + // Override the parameter by calling shouldShowAds and setting the parameter to the result + result.method.implementation!!.addInstructions( + 0, """ + invoke-static { }, Lfi/vanced/libraries/youtube/whitelisting/Whitelist;->shouldShowAds()Z + move-result v1 + """.trimIndent().toInstructions() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt new file mode 100644 index 00000000..ca0ae345 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt @@ -0,0 +1,40 @@ +package app.revanced.patches.youtube.ad.video.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("show-video-ads-constructor-signature") +@MatchingMethod( + "Laadb", + "", +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@SeekbarTappingCompatibility +@Version("0.0.1") +object ShowVideoAdsConstructorSignature : MethodSignature( + "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf( + Opcode.INVOKE_DIRECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + null, // either CONST_4 or CONST_16 + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.CONST_4, + Opcode.IPUT_BOOLEAN, + Opcode.RETURN_VOID + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/EnableSeekbarTappingPatch.kt deleted file mode 100644 index 65ecd121..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/EnableSeekbarTappingPatch.kt +++ /dev/null @@ -1,186 +0,0 @@ -package app.revanced.patches.youtube.interaction - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -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 -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.17.34") - ) -) - -class EnableSeekbarTappingPatch : BytecodePatch( - PatchMetadata( - "seekbar-tapping", - "Enable seekbar tapping patch", - "Enable tapping on the seekbar of the YouTube player.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "enable-seekbar-tapping-parent-signature", - MethodMetadata("Lzhj;", "J"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for a parent method, which is needed to find the actual method required to be patched.", - "0.0.1" - ), - "L", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf(), - 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( - "enable-seekbar-tapping-signature", - MethodMetadata("Lfao;", "onTouchEvent"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "Z", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_WIDE, - 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(data: BytecodeData): PatchResult { - var result = signatures.first().result!! - - val tapSeekMethods = mutableMapOf() - - // find the methods which tap the seekbar - for (it in result.definingClassProxy.immutableClass.methods) { - if (it.implementation == null) continue - - val instructions = it.implementation!!.instructions - // here we make sure we actually find the method because it has more then 7 instructions - if (instructions.count() < 7) continue - - // we know that the 7th instruction has the opcode CONST_4 - val instruction = instructions.elementAt(6) - if (instruction.opcode != Opcode.CONST_4) continue - - // the literal for this instruction has to be either 1 or 2 - val literal = (instruction as Instruction11n).narrowLiteral - - // method founds - if (literal == 1) tapSeekMethods["P"] = it - if (literal == 2) tapSeekMethods["O"] = it - } - - // replace map because we dont need the upper one anymore - result = signatures.last().result!! - - 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"]!! - - // get the required register - val instruction = implementation.instructions[result.scanData.endIndex] - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) - return PatchResultError("Could not find the correct register") - val register = (instruction as Instruction35c).registerC - - // the instructions are written in reverse order. - implementation.addInstructions( - result.scanData.endIndex + 1, - """ - invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V - invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V - """.trimIndent().toInstructions() - ) - - // if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label - val elseLabel = implementation.newLabelForIndex(result.scanData.endIndex + 1) - implementation.addInstruction( - result.scanData.endIndex + 1, - BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) - ) - implementation.addInstructions( - result.scanData.endIndex + 1, - """ - invoke-static { }, Lfi/razerman/youtube/preferences/BooleanPreferences;->isTapSeekingEnabled()Z - move-result v0 - """.trimIndent().toInstructions() - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt new file mode 100644 index 00000000..8287b907 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.interaction.seekbar.annotation + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class SeekbarTappingCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt new file mode 100644 index 00000000..3670d72c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt @@ -0,0 +1,94 @@ +package app.revanced.patches.youtube.interaction.seekbar.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import app.revanced.patches.youtube.interaction.seekbar.signatures.SeekbarTappingParentSignature +import app.revanced.patches.youtube.interaction.seekbar.signatures.SeekbarTappingSignature +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 +import org.jf.dexlib2.iface.instruction.formats.Instruction35c + + +@Patch +@Name("seekbar-tapping") +@Description("Enable tapping on the seekbar of the YouTube player.") +@SeekbarTappingCompatibility +@Version("0.0.1") +class EnableSeekbarTappingPatch : BytecodePatch( + listOf( + SeekbarTappingParentSignature, SeekbarTappingSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + var result = signatures.first().result!! + + val tapSeekMethods = mutableMapOf() + + // find the methods which tap the seekbar + for (it in result.definingClassProxy.immutableClass.methods) { + if (it.implementation == null) continue + + val instructions = it.implementation!!.instructions + // here we make sure we actually find the method because it has more then 7 instructions + if (instructions.count() < 7) continue + + // we know that the 7th instruction has the opcode CONST_4 + val instruction = instructions.elementAt(6) + if (instruction.opcode != Opcode.CONST_4) continue + + // the literal for this instruction has to be either 1 or 2 + val literal = (instruction as Instruction11n).narrowLiteral + + // method founds + if (literal == 1) tapSeekMethods["P"] = it + if (literal == 2) tapSeekMethods["O"] = it + } + + // replace map because we dont need the upper one anymore + result = signatures.last().result!! + + 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"]!! + + // get the required register + val instruction = implementation.instructions[result.scanData.endIndex] + if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return PatchResultError("Could not find the correct register") + val register = (instruction as Instruction35c).registerC + + // the instructions are written in reverse order. + implementation.addInstructions( + result.scanData.endIndex + 1, """ + invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V + invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V + """.trimIndent().toInstructions() + ) + + // if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label + val elseLabel = implementation.newLabelForIndex(result.scanData.endIndex + 1) + implementation.addInstruction( + result.scanData.endIndex + 1, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) + ) + implementation.addInstructions( + result.scanData.endIndex + 1, """ + invoke-static { }, Lfi/razerman/youtube/preferences/BooleanPreferences;->isTapSeekingEnabled()Z + move-result v0 + """.trimIndent().toInstructions() + ) + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt new file mode 100644 index 00000000..554b4146 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.youtube.interaction.seekbar.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("enable-seekbar-tapping-parent") +@MatchingMethod("Lzhj;", "J") +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@SeekbarTappingCompatibility +@Version("0.0.1") +object SeekbarTappingParentSignature : MethodSignature( + "L", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), 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 + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt new file mode 100644 index 00000000..7b471c07 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.youtube.interaction.seekbar.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("enable-seekbar-tapping-signature") +@MatchingMethod("Lfao;", "onTouchEvent") +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@SeekbarTappingCompatibility +@Version("0.0.1") +object SeekbarTappingSignature : MethodSignature( + "Z", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_WIDE, + 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 + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/CreateButtonRemoverPatch.kt deleted file mode 100644 index 7293dd65..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/CreateButtonRemoverPatch.kt +++ /dev/null @@ -1,102 +0,0 @@ -package app.revanced.patches.youtube.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.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.toInstruction -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.formats.Instruction35c - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.14.35", "17.17.34") - ) -) - -class CreateButtonRemoverPatch : BytecodePatch( - PatchMetadata( - "create-button", - "Create button patch", - "Disable the create button.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "create-button-method", - MethodMetadata("Lkne", "z"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("Z"), - 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, - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result = signatures.first().result!! - - // Get the required register which holds the view object we need to pass to the method hideCreateButton - val implementation = result.method.implementation!! - val instruction = implementation.instructions[result.scanData.endIndex + 1] - if (instruction.opcode != Opcode.INVOKE_STATIC) - return PatchResultError("Could not find the correct register") - val register = (instruction as Instruction35c).registerC - - // Hide the button view via proxy by passing it to the hideCreateButton method - implementation.addInstruction( - result.scanData.endIndex + 1, - "invoke-static { v$register }, Lfi/razerman/youtube/XAdRemover;->hideCreateButton(Landroid/view/View;)V".toInstruction() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/HideReelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/HideReelsPatch.kt deleted file mode 100644 index 47ce377b..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/HideReelsPatch.kt +++ /dev/null @@ -1,115 +0,0 @@ -package app.revanced.patches.youtube.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstruction -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.17.34") - ) -) - -class HideReelsPatch : BytecodePatch( - PatchMetadata( - "hide-reels", - "Hide reels patch", - "Hide reels on the page.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "hide-reels-signature", - MethodMetadata("Ljvy", ""), // unknown - PatternScanMethod.Fuzzy(3), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf( - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "L", - "[B", - "[B", - "[B", - "[B", - "[B", - "[B" - ), - 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(data: BytecodeData): 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( - result.scanData.endIndex, - "invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->HideReel(Landroid/view/View;)V".toInstruction() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/MinimizedPlaybackPatch.kt deleted file mode 100644 index 91551d52..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/MinimizedPlaybackPatch.kt +++ /dev/null @@ -1,89 +0,0 @@ -package app.revanced.patches.youtube.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.14.35", "17.17.34") - ) -) - -class MinimizedPlaybackPatch : BytecodePatch( - PatchMetadata( - "minimized-playback", - "Minimized Playback Patch", - "Enable minimized and background playback.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "minimized-playback-manager", - MethodMetadata("Lype", "j"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the method required to be patched.", - "0.0.1" - ), - "Z", - AccessFlags.PUBLIC or AccessFlags.STATIC, - listOf("L"), - 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_EQZ - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - // Instead of removing all instructions like Vanced, - // we return the method at the beginning instead - signatures.first().result!!.method.implementation!!.addInstructions( - 0, - """ - const/4 v0, 0x1 - return v0 - """.trimIndent().toInstructions() - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/OldQualityLayoutPatch.kt deleted file mode 100644 index 80114a36..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/OldQualityLayoutPatch.kt +++ /dev/null @@ -1,127 +0,0 @@ -package app.revanced.patches.youtube.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultError -import app.revanced.patcher.patch.implementation.misc.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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.builder.instruction.BuilderInstruction21t - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.17.34") - ) -) - -class OldQualityLayoutPatch : BytecodePatch( - PatchMetadata( - "old-quality-layout", - "Old Quality Layout Patch", - "Enable the original quality flyout menu", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "old-quality-parent-method-signature", - MethodMetadata("Libh", ""), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature to find a parent method required by the Old Quality Layout patch.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - listOf("L", "L", "L", "L", "L", "L", "L"), - listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_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_4, - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - var result = signatures.first().result!! - - result = result.findParentMethod( - MethodSignature( - MethodSignatureMetadata( - "old-quality-method-signature", - MethodMetadata("Libh", null), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature to find the method required by the Old Quality Layout patch", - "0.0.1" - ), - "L", - AccessFlags.FINAL or AccessFlags.PRIVATE, - listOf("Z"), - listOf( - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.GOTO, - Opcode.IGET_OBJECT, - ) - ) - ) ?: return PatchResultError("Method old-quality-patch-method has not been found") - - val implementation = result.method.implementation!! - - // if useOldStyleQualitySettings == true, jump over all instructions - val jmpInstruction = - BuilderInstruction21t( - Opcode.IF_NEZ, - 0, - implementation.instructions[result.scanData.endIndex].location.labels.first() - ) - implementation.addInstruction(5, jmpInstruction) - implementation.addInstructions( - 0, - """ - invoke-static { }, Lfi/razerman/youtube/XGlobals;->useOldStyleQualitySettings()Z - move-result v0 - """.trimIndent().toInstructions() - ) - - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/ShortsButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/ShortsButtonRemoverPatch.kt deleted file mode 100644 index 7a393ef1..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/ShortsButtonRemoverPatch.kt +++ /dev/null @@ -1,135 +0,0 @@ -package app.revanced.patches.youtube.layout - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.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.toInstruction -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.iface.instruction.formats.Instruction11x - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.14.35", "17.17.34") - ) -) - -class ShortsButtonRemoverPatch : BytecodePatch( - PatchMetadata( - "shorts-button", - "Shorts button patch", - "Hide the shorts button.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "pivotbar-buttons-method-tabenum", - MethodMetadata("Lkne", "z"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the pivotbar method that creates all button views.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("Z"), - listOf( - Opcode.CHECK_CAST, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.INVOKE_STATIC, // SomeEnum.fromValue(tabOrdinal) - Opcode.MOVE_RESULT_OBJECT - ) - ), - MethodSignature( - MethodSignatureMetadata( - "pivotbar-buttons-method-view", - MethodMetadata("Lkne", "z"), // unknown - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Signature for the pivotbar method that creates all button views.", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC or AccessFlags.FINAL, - listOf("Z"), - listOf( - Opcode.NEW_INSTANCE, // new StateListDrawable() - Opcode.INVOKE_DIRECT, - Opcode.NEW_ARRAY, - Opcode.CONST, - Opcode.CONST_16, - Opcode.APUT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.MOVE, - Opcode.MOVE_OBJECT, - Opcode.INVOKE_VIRTUAL_RANGE, // pivotBar.getView(drawable, tabName, z, i, map, akebVar, optional) - Opcode.MOVE_RESULT_OBJECT, - ) - ), - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result1 = signatures.first().result!! - val implementation1 = result1.method.implementation!! - val moveEnumInstruction = implementation1.instructions[result1.scanData.endIndex] - val enumRegister = (moveEnumInstruction as Instruction11x).registerA - - val result2 = signatures.last().result!! - val implementation2 = result2.method.implementation!! - val moveViewInstruction = implementation2.instructions[result2.scanData.endIndex] - val viewRegister = (moveViewInstruction as Instruction11x).registerA - - // Save the tab enum in XGlobals to avoid smali/register workarounds - implementation1.addInstruction( - result1.scanData.endIndex + 1, - "sput-object v$enumRegister, Lfi/razerman/youtube/XGlobals;->lastPivotTab:Ljava/lang/Enum;".toInstruction() - ) - - // Hide the button view via proxy by passing it to the hideShortsButton method - // It only hides it if the last tab name is "TAB_SHORTS" - implementation2.addInstruction( - result2.scanData.endIndex + 2, - "invoke-static { v$viewRegister }, Lfi/razerman/youtube/XAdRemover;->hideShortsButton(Landroid/view/View;)V".toInstruction() - ) - - return PatchResultSuccess() - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt new file mode 100644 index 00000000..c00fa9ae --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.createbutton.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class CreateButtonCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt new file mode 100644 index 00000000..288d0481 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.youtube.layout.createbutton.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.youtube.layout.createbutton.signatures.CreateButtonSignature +import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.formats.Instruction35c + +@Patch +@Name("disable-create-button") +@Description("Disable the create button.") +@MinimizedPlaybackCompatibility +@Version("0.0.1") +class CreateButtonRemoverPatch : BytecodePatch( + listOf( + CreateButtonSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!! + + // Get the required register which holds the view object we need to pass to the method hideCreateButton + val implementation = result.method.implementation!! + val instruction = implementation.instructions[result.scanData.endIndex + 1] + if (instruction.opcode != Opcode.INVOKE_STATIC) + return PatchResultError("Could not find the correct register") + val register = (instruction as Instruction35c).registerC + + // Hide the button view via proxy by passing it to the hideCreateButton method + implementation.addInstruction( + result.scanData.endIndex + 1, + "invoke-static { v$register }, Lfi/razerman/youtube/XAdRemover;->hideCreateButton(Landroid/view/View;)V".toInstruction() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt new file mode 100644 index 00000000..022a9a32 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt @@ -0,0 +1,57 @@ +package app.revanced.patches.youtube.layout.createbutton.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("create-button-signature") +@MatchingMethod( + "Lkne", "z" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@AmoledCompatibility +@Version("0.0.1") +object CreateButtonSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + listOf("Z"), + 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, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt new file mode 100644 index 00000000..07fbe86d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.minimizedplayback.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class MinimizedPlaybackCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt new file mode 100644 index 00000000..8cd9c79b --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/patch/MinimizedPlaybackPatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.youtube.layout.minimizedplayback.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility +import app.revanced.patches.youtube.layout.minimizedplayback.signatures.MinimizedPlaybackManagerSignature + + +@Patch +@Name("minimized-playback") +@Description("Enable minimized and background playback.") +@MinimizedPlaybackCompatibility +@Version("0.0.1") + +class MinimizedPlaybackPatch : BytecodePatch( + listOf( + MinimizedPlaybackManagerSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + // Instead of removing all instructions like Vanced, + // we return the method at the beginning instead + signatures.first().result!!.method.implementation!!.addInstructions( + 0, """ + const/4 v0, 0x1 + return v0 + """.trimIndent().toInstructions() + ) + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt new file mode 100644 index 00000000..93473776 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt @@ -0,0 +1,51 @@ +package app.revanced.patches.youtube.layout.minimizedplayback.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("minimized-playback-manager-signature") +@MatchingMethod( + "Lype", "j" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@MinimizedPlaybackCompatibility +@Version("0.0.1") +object MinimizedPlaybackManagerSignature : MethodSignature( + "Z", + AccessFlags.PUBLIC or AccessFlags.STATIC, + listOf("L"), + 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_EQZ + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt new file mode 100644 index 00000000..8992bf9e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.oldqualitylayout.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class OldQualityLayoutCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt new file mode 100644 index 00000000..927dd43c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt @@ -0,0 +1,66 @@ +package app.revanced.patches.youtube.layout.oldqualitylayout.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultError +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility +import app.revanced.patches.youtube.layout.oldqualitylayout.signatures.OldQualityParentSignature +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.builder.instruction.BuilderInstruction21t + +@Patch +@Name("old-quality-layout") +@Description("Enable the original quality flyout menu.") +@OldQualityLayoutCompatibility +@Version("0.0.1") +class OldQualityLayoutPatch : BytecodePatch( + listOf( + OldQualityParentSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!!.findParentMethod(@Name("old-quality-signature") @MatchingMethod( + definingClass = "Libh" + ) @FuzzyPatternScanMethod(2) @OldQualityLayoutCompatibility @Version("0.0.1") object : MethodSignature( + "L", AccessFlags.FINAL or AccessFlags.PRIVATE, listOf("Z"), listOf( + Opcode.CONST_4, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + Opcode.GOTO, + Opcode.IGET_OBJECT, + ) + ) {}) ?: return PatchResultError("Required parent method could not be found.") + + val implementation = result.method.implementation!! + + // if useOldStyleQualitySettings == true, jump over all instructions + val jmpInstruction = BuilderInstruction21t( + Opcode.IF_NEZ, 0, implementation.instructions[result.scanData.endIndex].location.labels.first() + ) + implementation.addInstruction(5, jmpInstruction) + implementation.addInstructions( + 0, """ + invoke-static { }, Lfi/razerman/youtube/XGlobals;->useOldStyleQualitySettings()Z + move-result v0 + """.trimIndent().toInstructions() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/signatures/OldQualityParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/signatures/OldQualityParentSignature.kt new file mode 100644 index 00000000..c9dd15a2 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/signatures/OldQualityParentSignature.kt @@ -0,0 +1,50 @@ +package app.revanced.patches.youtube.layout.oldqualitylayout.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("old-quality-parent-method-signature") +@MatchingMethod( + "Libh", "" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@OldQualityLayoutCompatibility +@Version("0.0.1") +object OldQualityParentSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + listOf("L", "L", "L", "L", "L", "L", "L"), + listOf( + Opcode.INVOKE_DIRECT, + Opcode.IPUT_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_4, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/annotations/HideReelsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/annotations/HideReelsCompatibility.kt new file mode 100644 index 00000000..2144d954 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/annotations/HideReelsCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.reels.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class HideReelsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt new file mode 100644 index 00000000..8b5e14f7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt @@ -0,0 +1,38 @@ +package app.revanced.patches.youtube.layout.reels.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility +import app.revanced.patches.youtube.layout.reels.signatures.HideReelsSignature + +@Patch +@Name("hide-reels") +@Description("Hide reels on the page.") +@HideReelsCompatibility +@Version("0.0.1") +class HideReelsPatch : BytecodePatch( + listOf( + HideReelsSignature + ) +) { + override fun execute(data: BytecodeData): 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( + result.scanData.endIndex, + "invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->HideReel(Landroid/view/View;)V".toInstruction() + ) + + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt new file mode 100644 index 00000000..44baac54 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt @@ -0,0 +1,58 @@ +package app.revanced.patches.youtube.layout.reels.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("hide-reels-signature") +@MatchingMethod( + "Ljvy", "" +) +@FuzzyPatternScanMethod(3) // FIXME: Test this threshold and find the best value. +@HideReelsCompatibility +@Version("0.0.1") +object HideReelsSignature : MethodSignature( + "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf( + "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "[B", "[B", "[B", "[B", "[B", "[B" + ), 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 + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt new file mode 100644 index 00000000..d55ca490 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.shorts.button.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class ShortsButtonCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt new file mode 100644 index 00000000..63571bef --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt @@ -0,0 +1,53 @@ +package app.revanced.patches.youtube.layout.shorts.button.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility +import app.revanced.patches.youtube.layout.shorts.button.signatures.PivotBarButtonTabenumSignature +import app.revanced.patches.youtube.layout.shorts.button.signatures.PivotBarButtonsViewSignature +import org.jf.dexlib2.iface.instruction.formats.Instruction11x + +@Patch +@Name("shorts-button") +@Description("Hide the shorts button.") +@ShortsButtonCompatibility +@Version("0.0.1") +class ShortsButtonRemoverPatch : BytecodePatch( + listOf( + PivotBarButtonTabenumSignature, PivotBarButtonsViewSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result1 = signatures.first().result!! + val implementation1 = result1.method.implementation!! + val moveEnumInstruction = implementation1.instructions[result1.scanData.endIndex] + val enumRegister = (moveEnumInstruction as Instruction11x).registerA + + val result2 = signatures.last().result!! + val implementation2 = result2.method.implementation!! + val moveViewInstruction = implementation2.instructions[result2.scanData.endIndex] + val viewRegister = (moveViewInstruction as Instruction11x).registerA + + // Save the tab enum in XGlobals to avoid smali/register workarounds + implementation1.addInstruction( + result1.scanData.endIndex + 1, + "sput-object v$enumRegister, Lfi/razerman/youtube/XGlobals;->lastPivotTab:Ljava/lang/Enum;".toInstruction() + ) + + // Hide the button view via proxy by passing it to the hideShortsButton method + // It only hides it if the last tab name is "TAB_SHORTS" + implementation2.addInstruction( + result2.scanData.endIndex + 2, + "invoke-static { v$viewRegister }, Lfi/razerman/youtube/XAdRemover;->hideShortsButton(Landroid/view/View;)V".toInstruction() + ) + + return PatchResultSuccess() + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt new file mode 100644 index 00000000..ea37ba63 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.youtube.layout.shorts.button.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("pivotbar-buttons-tabenum-signature") +@MatchingMethod( + "Lkne", "z" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@ShortsButtonCompatibility +@Version("0.0.1") +object PivotBarButtonTabenumSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + listOf("Z"), + listOf( + Opcode.CHECK_CAST, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IGET_OBJECT, + Opcode.CHECK_CAST, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.INVOKE_STATIC, // SomeEnum.fromValue(tabOrdinal) + Opcode.MOVE_RESULT_OBJECT + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt new file mode 100644 index 00000000..b3140fe7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt @@ -0,0 +1,49 @@ +package app.revanced.patches.youtube.layout.shorts.button.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("pivotbar-buttons-view-signature") +@MatchingMethod( + "Lkne", "z" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@ShortsButtonCompatibility +@Version("0.0.1") +object PivotBarButtonsViewSignature : MethodSignature( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + listOf("Z"), + listOf( + Opcode.NEW_INSTANCE, // new StateListDrawable() + Opcode.INVOKE_DIRECT, + Opcode.NEW_ARRAY, + Opcode.CONST, + Opcode.CONST_16, + Opcode.APUT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.MOVE, + Opcode.MOVE_OBJECT, + Opcode.INVOKE_VIRTUAL_RANGE, // pivotBar.getView(drawable, tabName, z, i, map, akebVar, optional) + Opcode.MOVE_RESULT_OBJECT, + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/IntegrationsPatch.kt deleted file mode 100644 index 33b7ea25..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/IntegrationsPatch.kt +++ /dev/null @@ -1,125 +0,0 @@ -package app.revanced.patches.youtube.misc - -import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.extensions.addInstructions -import app.revanced.patcher.extensions.or -import app.revanced.patcher.patch.implementation.BytecodePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata -import app.revanced.patcher.patch.implementation.misc.PatchResult -import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess -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.toInstructions -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode -import org.jf.dexlib2.immutable.ImmutableMethod -import org.jf.dexlib2.immutable.ImmutableMethodImplementation - -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.03.38", "17.14.35", "17.17.34") - ) -) - -class IntegrationsPatch : BytecodePatch( - PatchMetadata( - "integrations", - "Inject Integrations Patch", - "Applies mandatory patches to implement the ReVanced integrations into the application.", - compatiblePackages, - "0.0.1" - ), - listOf( - MethodSignature( - MethodSignatureMetadata( - "integrations-patch", - MethodMetadata("Lacnx", "onCreate"), - PatternScanMethod.Fuzzy(2), // FIXME: Test this threshold and find the best value. - compatiblePackages, - "Inject the integrations into the application with the method of this signature", - "0.0.1" - ), - "V", - AccessFlags.PUBLIC.value, - listOf(), - listOf( - Opcode.SGET_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.CONST_STRING, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST_4, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.SPUT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_SUPER, - Opcode.INVOKE_VIRTUAL - ) - ) - ) -) { - override fun execute(data: BytecodeData): PatchResult { - val result = signatures.first().result!! - - val implementation = result.method.implementation!! - val count = implementation.registerCount - 1 - - implementation.addInstructions( - result.scanData.endIndex + 1, - """ - invoke-static {v$count}, Lpl/jakubweg/StringRef;->setContext(Landroid/content/Context;)V - sput-object v$count, Lapp/revanced/integrations/Globals;->context:Landroid/content/Context; - """.trimIndent().toInstructions() - ) - - val classDef = result.definingClassProxy.resolve() - classDef.methods.add( - ImmutableMethod( - classDef.type, - "getAppContext", - null, - "Landroid/content/Context;", - AccessFlags.PUBLIC or AccessFlags.STATIC, - null, - null, - ImmutableMethodImplementation( - 1, - """ - invoke-static { }, Lapp/revanced/integrations/Globals;->getAppContext()Landroid/content/Context; - move-result-object v0 - return-object v0 - """.trimIndent().toInstructions(), - null, - null - ) - ).toMutable() - ) - return PatchResultSuccess() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt new file mode 100644 index 00000000..318ea09d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.misc.integrations.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class IntegrationsCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt new file mode 100644 index 00000000..538da04d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt @@ -0,0 +1,65 @@ +package app.revanced.patches.youtube.misc.integrations.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.BytecodeData +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.extensions.or +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.BytecodePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.patcher.util.smali.toInstructions +import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility +import app.revanced.patches.youtube.misc.integrations.signatures.InitSignature +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.immutable.ImmutableMethod +import org.jf.dexlib2.immutable.ImmutableMethodImplementation + +@Patch +@Name("integrations") +@Description("Applies mandatory patches to implement the ReVanced integrations into the application.") +@IntegrationsCompatibility +@Version("0.0.1") +class IntegrationsPatch : BytecodePatch( + listOf( + InitSignature + ) +) { + override fun execute(data: BytecodeData): PatchResult { + val result = signatures.first().result!! + + val implementation = result.method.implementation!! + val count = implementation.registerCount - 1 + + implementation.addInstructions( + result.scanData.endIndex + 1, """ + invoke-static {v$count}, Lpl/jakubweg/StringRef;->setContext(Landroid/content/Context;)V + sput-object v$count, Lapp/revanced/integrations/Globals;->context:Landroid/content/Context; + """.trimIndent().toInstructions() + ) + + val classDef = result.definingClassProxy.resolve() + classDef.methods.add( + ImmutableMethod( + classDef.type, + "getAppContext", + null, + "Landroid/content/Context;", + AccessFlags.PUBLIC or AccessFlags.STATIC, + null, + null, + ImmutableMethodImplementation( + 1, """ + invoke-static { }, Lapp/revanced/integrations/Globals;->getAppContext()Landroid/content/Context; + move-result-object v0 + return-object v0 + """.trimIndent().toInstructions(), null, null + ) + ).toMutable() + ) + return PatchResultSuccess() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt new file mode 100644 index 00000000..390fd033 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt @@ -0,0 +1,57 @@ +package app.revanced.patches.youtube.misc.integrations.signatures + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.signature.implementation.method.MethodSignature +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +@Name("init-signature") +@MatchingMethod( + "Lacnx", "onCreate" +) +@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. +@IntegrationsCompatibility +@Version("0.0.1") +object InitSignature : MethodSignature( + "V", + AccessFlags.PUBLIC.value, + listOf(), + listOf( + Opcode.SGET_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.CONST_STRING, + Opcode.IF_NEZ, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.IGET_OBJECT, + Opcode.MOVE_OBJECT, + Opcode.CHECK_CAST, + Opcode.MOVE_OBJECT, + Opcode.CHECK_CAST, + Opcode.CONST_4, + Opcode.CONST_STRING, + Opcode.INVOKE_INTERFACE_RANGE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SPUT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_SUPER, + Opcode.INVOKE_VIRTUAL + ) +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt new file mode 100644 index 00000000..a04be984 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.misc.manifest.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class FixLocaleConfigErrorCompatibility \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/FixLocaleConfigErrorPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt similarity index 56% rename from src/main/kotlin/app/revanced/patches/youtube/misc/FixLocaleConfigErrorPatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt index aefc1807..df1233d9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/FixLocaleConfigErrorPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/patch/FixLocaleConfigErrorPatch.kt @@ -1,28 +1,22 @@ -package app.revanced.patches.youtube.misc +package app.revanced.patches.youtube.misc.manifest.patch +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.implementation.ResourceData +import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.implementation.ResourcePatch -import app.revanced.patcher.patch.implementation.metadata.PackageMetadata -import app.revanced.patcher.patch.implementation.metadata.PatchMetadata import app.revanced.patcher.patch.implementation.misc.PatchResult import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patches.youtube.misc.manifest.annotations.FixLocaleConfigErrorCompatibility import org.w3c.dom.Element -private val compatiblePackages = listOf( - PackageMetadata( - "com.google.android.youtube", - listOf("17.14.35", "17.17.34") - ) -) -class FixLocaleConfigErrorPatch : ResourcePatch( - PatchMetadata( - "locale-config-fix", - "Manifest attribute fix patch", - "Fix an error when building the resources by patching the manifest file.", - compatiblePackages, - "0.0.1" - ), -) { +@Patch +@Name("locale-config-fix") +@Description("Fix an error when building the resources by patching the manifest file.") +@FixLocaleConfigErrorCompatibility +@Version("0.0.1") +class FixLocaleConfigErrorPatch : ResourcePatch() { override fun execute(data: ResourceData): PatchResult { // create an xml editor instance val editor = data.getXmlEditor("AndroidManifest.xml") @@ -35,7 +29,7 @@ class FixLocaleConfigErrorPatch : ResourcePatch( // by replacing the attributes name val attribute = "android:localeConfig" - applicationNode.setAttribute("localeConfig", applicationNode.getAttribute(attribute)) + applicationNode.setAttribute("localeConfig", applicationNode.getAttribute(attribute)) applicationNode.removeAttribute("android:localeConfig") // close & save the modified file diff --git a/src/test/kotlin/app/revanced/patches/SignatureChecker.kt b/src/test/kotlin/app/revanced/patches/SignatureChecker.kt index 43bf21de..ffa80f2c 100644 --- a/src/test/kotlin/app/revanced/patches/SignatureChecker.kt +++ b/src/test/kotlin/app/revanced/patches/SignatureChecker.kt @@ -1,17 +1,18 @@ package app.revanced.patches import app.revanced.patcher.Patcher -import app.revanced.patcher.signature.MethodMetadata -import app.revanced.patcher.signature.MethodSignature -import app.revanced.patcher.signature.PatternScanMethod +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod +import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod +import app.revanced.patcher.signature.implementation.method.annotation.PatternScanMethod import org.jf.dexlib2.iface.Method import org.junit.Test import java.io.File internal class SignatureChecker { @Test - fun checkSignatures() { - return + fun checkMethodSignatures() { + // FIXME: instead of having this as a test, it should be turned into a task which can be ran manually val file = File("stock.apk") if (!file.exists()) { @@ -19,24 +20,26 @@ internal class SignatureChecker { } val patcher = Patcher(file, "signatureCheckerCache", false) patcher.addPatches(Index.patches.map { it() }) - val unresolved = mutableListOf() + val unresolved = mutableListOf() for (signature in patcher.resolveSignatures()) { + val signatureAnnotations = signature::class.annotations + + val nameAnnotation = signatureAnnotations.find { it is Name } as Name if (!signature.resolved) { - unresolved.add(signature) + unresolved.add(nameAnnotation.name) continue } - val patternScanMethod = signature.metadata.patternScanMethod - if (patternScanMethod is PatternScanMethod.Fuzzy) { - val warnings = patternScanMethod.warnings!! + val patternScanMethod = + signatureAnnotations.find { it::class.annotations.any { method -> method is PatternScanMethod } } + if (patternScanMethod is FuzzyPatternScanMethod) { + val warnings = signature.result!!.scanData.warnings!! val method = signature.result!!.method - val methodFromMetadata = - if (signature.metadata.methodMetadata != null) signature.metadata.methodMetadata!! else MethodMetadata( - null, - null - ) - println("Signature: ${signature.metadata.name}.\nMethod: ${methodFromMetadata.definingClass}->${methodFromMetadata.name} (Signature matches: ${method.definingClass}->${method.toStr()})\nWarnings: ${warnings.count()}") + val methodFromMetadata = + signatureAnnotations.find { it is MatchingMethod } as MatchingMethod? ?: MatchingMethod() + + println("Signature: ${nameAnnotation}.\nMethod: ${methodFromMetadata.definingClass}->${methodFromMetadata.name} (Signature matches: ${method.definingClass}->${method.toStr()})\nWarnings: ${warnings.count()}") for (warning in warnings) { println("${warning.instructionIndex} / ${warning.patternIndex}: ${warning.wrongOpcode} (expected: ${warning.correctOpcode})") } @@ -46,8 +49,8 @@ internal class SignatureChecker { } if (unresolved.isNotEmpty()) { val base = Exception("${unresolved.size} signatures were not resolved.") - for (signature in unresolved) { - base.addSuppressed(Exception("Signature ${signature.metadata.name} was not resolved!")) + for (name in unresolved) { + base.addSuppressed(Exception("Signature $name was not resolved!")) } throw base } From a173f6e5a7e65943657e2072e8a72a4a680e5277 Mon Sep 17 00:00:00 2001 From: epicsampler <102923070+epicsampler@users.noreply.github.com> Date: Sun, 22 May 2022 14:17:32 +0000 Subject: [PATCH 2/5] fix: `create-button-signature` --- .../layout/createbutton/signatures/CreateButtonSignature.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt index 022a9a32..45e3c429 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt @@ -6,7 +6,7 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.signature.implementation.method.MethodSignature import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod -import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility +import app.revanced.patches.youtube.layout.createbutton.annotations.CreateButtonCompatibility import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @@ -15,7 +15,7 @@ import org.jf.dexlib2.Opcode "Lkne", "z" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -@AmoledCompatibility +@CreateButtonCompatibility @Version("0.0.1") object CreateButtonSignature : MethodSignature( "V", From d61bac4f8243d0ef72ca91c7c1d5facd858d515e Mon Sep 17 00:00:00 2001 From: epicsampler <102923070+epicsampler@users.noreply.github.com> Date: Sun, 22 May 2022 14:31:17 +0000 Subject: [PATCH 3/5] feat: add `amoled` patch --- .../amoled/annotations/AmoledCompatibility.kt | 13 ++++++ .../layout/amoled/patch/AmoledPatch.kt | 45 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt new file mode 100644 index 00000000..4465aecf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.layout.amoled.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class AmoledCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt new file mode 100644 index 00000000..1ecf1a54 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.youtube.layout.amoled.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.implementation.ResourceData +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.implementation.ResourcePatch +import app.revanced.patcher.patch.implementation.misc.PatchResult +import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess +import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility +import org.w3c.dom.Element +import java.io.File + +@Patch +@Name("amoled") +@Description("Enables black theme (amoled mode)") +@AmoledCompatibility +@Version("0.0.1") +class AmoledPatch : ResourcePatch() { + override fun execute(data: ResourceData): PatchResult { + data.getXmlEditor("res${File.separator}values${File.separator}colors.xml").use { editor -> + val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element + + for (i in 0..resourcesNode.childNodes.length) { + val node = resourcesNode.childNodes.item(i) as Element + + node.nodeValue = when (node.getAttribute("name")) { + "yt_black1", + "yt_black1_opacity95", + "yt_black2", + "yt_black3", + "yt_black4", + "yt_status_bar_background_dark" + -> "@android:color/black" + "yt_selected_nav_label_dark" + -> "#ffdf0000" + else -> continue + } + } + } + + return PatchResultSuccess() + } +} From c4c86b65fd8b2463c1d86ad2e46ec9f08e60d47c Mon Sep 17 00:00:00 2001 From: epicsampler <102923070+epicsampler@users.noreply.github.com> Date: Sun, 22 May 2022 14:34:36 +0000 Subject: [PATCH 4/5] fix: loop in `amoled` patch --- .../revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt index 1ecf1a54..e9d950ea 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt @@ -22,7 +22,7 @@ class AmoledPatch : ResourcePatch() { data.getXmlEditor("res${File.separator}values${File.separator}colors.xml").use { editor -> val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element - for (i in 0..resourcesNode.childNodes.length) { + for (i in 0 until resourcesNode.childNodes.length) { val node = resourcesNode.childNodes.item(i) as Element node.nodeValue = when (node.getAttribute("name")) { From bad25dec1d73137f8b7a1bf4daaceb2279b4d48c Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sun, 22 May 2022 17:11:34 +0200 Subject: [PATCH 5/5] feat: update patches to latest version Signed-off-by: oSumAtrIX --- .../audio/codecs/patch/CodecsUnlockPatch.kt | 4 +- .../patch/RemoveTasteBuilderPatch.kt | 2 +- .../patch/RemoveUpgradeButtonPatch.kt | 10 +-- .../annotation/PromotionsCompatibility.kt | 2 +- .../youtube/ad/home/patch/HomeAdsPatch.kt | 2 +- .../PromotedDiscoveryActionParentSignature.kt | 6 +- .../PromotedDiscoveryAppParentSignature.kt | 8 +-- .../annotations/VideoAdsCompatibility.kt | 2 +- .../ShowVideoAdsConstructorSignature.kt | 6 +- .../annotation/SeekbarTappingCompatibility.kt | 2 +- .../patch/EnableSeekbarTappingPatch.kt | 10 +-- .../SeekbarTappingParentSignature.kt | 2 +- .../signatures/SeekbarTappingSignature.kt | 2 +- .../amoled/annotations/AmoledCompatibility.kt | 2 +- .../layout/amoled/patch/AmoledPatch.kt | 19 +++--- .../annotations/CreateButtonCompatibility.kt | 2 +- .../patch/CreateButtonRemoverPatch.kt | 8 +-- .../signatures/CreateButtonSignature.kt | 2 +- .../MinimizedPlaybackCompatibility.kt | 2 +- .../MinimizedPlaybackManagerSignature.kt | 2 +- .../OldQualityLayoutCompatibility.kt | 2 +- .../patch/OldQualityLayoutPatch.kt | 2 +- .../layout/reels/patch/HideReelsPatch.kt | 5 +- .../reels/signatures/HideReelsSignature.kt | 40 +----------- .../annotations/ShortsButtonCompatibility.kt | 2 +- .../button/patch/ShortsButtonRemoverPatch.kt | 8 +-- .../PivotBarButtonTabenumSignature.kt | 2 +- .../PivotBarButtonsViewSignature.kt | 2 +- .../annotations/IntegrationsCompatibility.kt | 2 +- .../integrations/patch/IntegrationsPatch.kt | 2 +- .../integrations/signatures/InitSignature.kt | 45 +------------- .../FixLocaleConfigErrorCompatibility.kt | 2 +- .../app/revanced/patches/SignatureChecker.kt | 62 ------------------- 33 files changed, 64 insertions(+), 207 deletions(-) delete mode 100644 src/test/kotlin/app/revanced/patches/SignatureChecker.kt diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt index 4f178a6e..a30729d1 100644 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt @@ -29,10 +29,10 @@ class CodecsUnlockPatch : BytecodePatch( val implementation = result.method.implementation!! - val instructionIndex = result.scanData.startIndex + val instructionIndex = result.scanResult.startIndex result = signatures.last().result!! - val codecMethod = data.toMethodWalker(result.immutableMethod).walk(result.scanData.startIndex).getMethod() + val codecMethod = data.toMethodWalker(result.immutableMethod).walk(result.scanResult.startIndex).getMethod() implementation.replaceInstruction( instructionIndex, diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt index 81dac406..b1be2a17 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/tastebuilder/patch/RemoveTasteBuilderPatch.kt @@ -28,7 +28,7 @@ class RemoveTasteBuilderPatch : BytecodePatch( val result = signatures.first().result!! val implementation = result.method.implementation!! - val insertIndex = result.scanData.endIndex - 8 + val insertIndex = result.scanResult.endIndex - 8 val register = (implementation.instructions[insertIndex] as Instruction22c).registerA diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt index 9a2813d6..98119f9b 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/patch/RemoveUpgradeButtonPatch.kt @@ -33,7 +33,7 @@ class RemoveUpgradeButtonPatch : BytecodePatch( val implementation = result.method.implementation!! val pivotBarElementFieldRef = - (implementation.instructions[result.scanData.endIndex - 1] as Instruction22c).reference + (implementation.instructions[result.scanResult.endIndex - 1] as Instruction22c).reference val register = (implementation.instructions.first() as Instruction35c).registerC // first compile all the needed instructions @@ -48,14 +48,14 @@ class RemoveUpgradeButtonPatch : BytecodePatch( // replace the instruction to retain the label at given index implementation.replaceInstruction( - result.scanData.endIndex - 1, instructionList[0] // invoke-interface + result.scanResult.endIndex - 1, instructionList[0] // invoke-interface ) // do not forget to remove this instruction since we added it already instructionList.removeFirst() val exitInstruction = instructionList.last() // iput-object implementation.addInstruction( - result.scanData.endIndex, exitInstruction + result.scanResult.endIndex, exitInstruction ) // do not forget to remove this instruction since we added it already instructionList.removeLast() @@ -64,12 +64,12 @@ class RemoveUpgradeButtonPatch : BytecodePatch( instructionList.add( 2, // if-le BuilderInstruction22t( - Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(result.scanData.endIndex) + Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(result.scanResult.endIndex) ) ) implementation.addInstructions( - result.scanData.endIndex, instructionList + result.scanResult.endIndex, instructionList ) return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt index 367d4bc6..ca6021f3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/annotation/PromotionsCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt index 6b22b16e..bd4d5a15 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/patch/HomeAdsPatch.kt @@ -1697,7 +1697,7 @@ for (i in 0 until signatures.count()) { val signature = signatures.elementAt(i) val result = signature.result!! val implementation = result.method.implementation!! -val index = result.scanData.startIndex +val index = result.scanResult.startIndex val instructions = implementation.instructions val register = (instructions[index + (if (i < 2) -1 else 1)] as Instruction11x).registerA diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt index c3c8d73e..87647362 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryActionParentSignature.kt @@ -6,16 +6,16 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.signature.implementation.method.MethodSignature import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod -import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import app.revanced.patches.youtube.ad.home.annotation.PromotionsCompatibility import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @Name("promoted-discovery-app-parent-signature") @MatchingMethod( - "Ljre;", "lP" + "Ljqb;", "lG" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -@SeekbarTappingCompatibility +@PromotionsCompatibility @Version("0.0.1") object PromotedDiscoveryActionParentSignature : MethodSignature( "V", diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt index 7c3ad070..9d4b9a08 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/home/signatures/PromotedDiscoveryAppParentSignature.kt @@ -6,17 +6,17 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.signature.implementation.method.MethodSignature import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod -import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import app.revanced.patches.youtube.ad.home.annotation.PromotionsCompatibility import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @Name("promoted-discovery-action-parent-signature") @MatchingMethod( - "Ljqv;", - "lP" + "Ljqj;", + "lG" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -@SeekbarTappingCompatibility +@PromotionsCompatibility @Version("0.0.1") object PromotedDiscoveryAppParentSignature : MethodSignature( diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt index 1e6a92ac..1ac74ca1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/annotations/VideoAdsCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt index ca0ae345..912bc6bb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/signatures/ShowVideoAdsConstructorSignature.kt @@ -6,17 +6,17 @@ import app.revanced.patcher.extensions.or import app.revanced.patcher.signature.implementation.method.MethodSignature import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod -import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility +import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @Name("show-video-ads-constructor-signature") @MatchingMethod( - "Laadb", + "Laair", "", ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -@SeekbarTappingCompatibility +@VideoAdsCompatibility @Version("0.0.1") object ShowVideoAdsConstructorSignature : MethodSignature( "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf( diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt index 8287b907..e159dbcf 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/annotation/SeekbarTappingCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.17.34") + "com.google.android.youtube", arrayOf("17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt index 3670d72c..37d1f4ef 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/patch/EnableSeekbarTappingPatch.kt @@ -66,25 +66,25 @@ class EnableSeekbarTappingPatch : BytecodePatch( val oMethod = tapSeekMethods["O"]!! // get the required register - val instruction = implementation.instructions[result.scanData.endIndex] + val instruction = implementation.instructions[result.scanResult.endIndex] if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return PatchResultError("Could not find the correct register") val register = (instruction as Instruction35c).registerC // the instructions are written in reverse order. implementation.addInstructions( - result.scanData.endIndex + 1, """ + result.scanResult.endIndex + 1, """ invoke-virtual { v$register, v2 }, ${oMethod.definingClass}->${oMethod.name}(I)V invoke-virtual { v$register, v2 }, ${pMethod.definingClass}->${pMethod.name}(I)V """.trimIndent().toInstructions() ) // if tap-seeking is disabled, do not invoke the two methods above by jumping to the else label - val elseLabel = implementation.newLabelForIndex(result.scanData.endIndex + 1) + val elseLabel = implementation.newLabelForIndex(result.scanResult.endIndex + 1) implementation.addInstruction( - result.scanData.endIndex + 1, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) + result.scanResult.endIndex + 1, BuilderInstruction21t(Opcode.IF_EQZ, 0, elseLabel) ) implementation.addInstructions( - result.scanData.endIndex + 1, """ + result.scanResult.endIndex + 1, """ invoke-static { }, Lfi/razerman/youtube/preferences/BooleanPreferences;->isTapSeekingEnabled()Z move-result v0 """.trimIndent().toInstructions() diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt index 554b4146..c35be408 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingParentSignature.kt @@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @Name("enable-seekbar-tapping-parent") -@MatchingMethod("Lzhj;", "J") +@MatchingMethod("Lzmx;", "I") @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @SeekbarTappingCompatibility @Version("0.0.1") diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt index 7b471c07..f649b267 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/signatures/SeekbarTappingSignature.kt @@ -11,7 +11,7 @@ import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.Opcode @Name("enable-seekbar-tapping-signature") -@MatchingMethod("Lfao;", "onTouchEvent") +@MatchingMethod("Lfbl;", "onTouchEvent") @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @SeekbarTappingCompatibility @Version("0.0.1") diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt index 4465aecf..8e8d96ff 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/annotations/AmoledCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt index e9d950ea..99538a54 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/amoled/patch/AmoledPatch.kt @@ -14,7 +14,7 @@ import java.io.File @Patch @Name("amoled") -@Description("Enables black theme (amoled mode)") +@Description("Enables pure black theme.") @AmoledCompatibility @Version("0.0.1") class AmoledPatch : ResourcePatch() { @@ -23,18 +23,13 @@ class AmoledPatch : ResourcePatch() { val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element for (i in 0 until resourcesNode.childNodes.length) { - val node = resourcesNode.childNodes.item(i) as Element + val node = resourcesNode.childNodes.item(i) + if (node !is Element) continue - node.nodeValue = when (node.getAttribute("name")) { - "yt_black1", - "yt_black1_opacity95", - "yt_black2", - "yt_black3", - "yt_black4", - "yt_status_bar_background_dark" - -> "@android:color/black" - "yt_selected_nav_label_dark" - -> "#ffdf0000" + val element = resourcesNode.childNodes.item(i) as Element + element.textContent = when (element.getAttribute("name")) { + "yt_black1", "yt_black1_opacity95", "yt_black2", "yt_black3", "yt_black4", "yt_status_bar_background_dark" -> "@android:color/black" + "yt_selected_nav_label_dark" -> "#ffdf0000" else -> continue } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt index c00fa9ae..9c57fe47 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/annotations/CreateButtonCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt index 288d0481..42b75c40 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/patch/CreateButtonRemoverPatch.kt @@ -10,15 +10,15 @@ import app.revanced.patcher.patch.implementation.misc.PatchResult import app.revanced.patcher.patch.implementation.misc.PatchResultError import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess import app.revanced.patcher.util.smali.toInstruction +import app.revanced.patches.youtube.layout.createbutton.annotations.CreateButtonCompatibility import app.revanced.patches.youtube.layout.createbutton.signatures.CreateButtonSignature -import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.instruction.formats.Instruction35c @Patch @Name("disable-create-button") @Description("Disable the create button.") -@MinimizedPlaybackCompatibility +@CreateButtonCompatibility @Version("0.0.1") class CreateButtonRemoverPatch : BytecodePatch( listOf( @@ -30,14 +30,14 @@ class CreateButtonRemoverPatch : BytecodePatch( // Get the required register which holds the view object we need to pass to the method hideCreateButton val implementation = result.method.implementation!! - val instruction = implementation.instructions[result.scanData.endIndex + 1] + val instruction = implementation.instructions[result.scanResult.endIndex + 1] if (instruction.opcode != Opcode.INVOKE_STATIC) return PatchResultError("Could not find the correct register") val register = (instruction as Instruction35c).registerC // Hide the button view via proxy by passing it to the hideCreateButton method implementation.addInstruction( - result.scanData.endIndex + 1, + result.scanResult.endIndex + 1, "invoke-static { v$register }, Lfi/razerman/youtube/XAdRemover;->hideCreateButton(Landroid/view/View;)V".toInstruction() ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt index 45e3c429..6f1a91e5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/createbutton/signatures/CreateButtonSignature.kt @@ -12,7 +12,7 @@ import org.jf.dexlib2.Opcode @Name("create-button-signature") @MatchingMethod( - "Lkne", "z" + "Lknw", "z" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @CreateButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt index 07fbe86d..574c90c8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/annotations/MinimizedPlaybackCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt index 93473776..097d0dc8 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/minimizedplayback/signatures/MinimizedPlaybackManagerSignature.kt @@ -12,7 +12,7 @@ import org.jf.dexlib2.Opcode @Name("minimized-playback-manager-signature") @MatchingMethod( - "Lype", "j" + "Lyuf", "n" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @MinimizedPlaybackCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt index 8992bf9e..3a883458 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/annotations/OldQualityLayoutCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.17.34") + "com.google.android.youtube", arrayOf("17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt index 927dd43c..88b397cc 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/oldqualitylayout/patch/OldQualityLayoutPatch.kt @@ -51,7 +51,7 @@ class OldQualityLayoutPatch : BytecodePatch( // if useOldStyleQualitySettings == true, jump over all instructions val jmpInstruction = BuilderInstruction21t( - Opcode.IF_NEZ, 0, implementation.instructions[result.scanData.endIndex].location.labels.first() + Opcode.IF_NEZ, 0, implementation.instructions[result.scanResult.endIndex].location.labels.first() ) implementation.addInstruction(5, jmpInstruction) implementation.addInstructions( diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt index 8b5e14f7..7f0fb2c3 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/patch/HideReelsPatch.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.implementation.BytecodeData -import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.implementation.BytecodePatch import app.revanced.patcher.patch.implementation.misc.PatchResult import app.revanced.patcher.patch.implementation.misc.PatchResultSuccess @@ -12,7 +11,7 @@ import app.revanced.patcher.util.smali.toInstruction import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility import app.revanced.patches.youtube.layout.reels.signatures.HideReelsSignature -@Patch +//@Patch TODO: converted to litho @Name("hide-reels") @Description("Hide reels on the page.") @HideReelsCompatibility @@ -29,7 +28,7 @@ class HideReelsPatch : BytecodePatch( // HideReel will hide the reel view before it is being used, // so we pass the view to the HideReel method implementation.addInstruction( - result.scanData.endIndex, + result.scanResult.endIndex, "invoke-static { v2 }, Lfi/razerman/youtube/XAdRemover;->HideReel(Landroid/view/View;)V".toInstruction() ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt index 44baac54..61353b27 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/reels/signatures/HideReelsSignature.kt @@ -8,7 +8,6 @@ import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatt import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod import app.revanced.patches.youtube.layout.reels.annotations.HideReelsCompatibility import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode @Name("hide-reels-signature") @MatchingMethod( @@ -18,41 +17,6 @@ import org.jf.dexlib2.Opcode @HideReelsCompatibility @Version("0.0.1") object HideReelsSignature : MethodSignature( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf( - "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "[B", "[B", "[B", "[B", "[B", "[B" - ), 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 - ) + null, AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L", "L"), null, + listOf("multiReelDismissalCallback", "reelItemRenderers", "reelDismissalInfo") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt index d55ca490..f8bf1c64 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/annotations/ShortsButtonCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt index 63571bef..60a24861 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/patch/ShortsButtonRemoverPatch.kt @@ -27,24 +27,24 @@ class ShortsButtonRemoverPatch : BytecodePatch( override fun execute(data: BytecodeData): PatchResult { val result1 = signatures.first().result!! val implementation1 = result1.method.implementation!! - val moveEnumInstruction = implementation1.instructions[result1.scanData.endIndex] + val moveEnumInstruction = implementation1.instructions[result1.scanResult.endIndex] val enumRegister = (moveEnumInstruction as Instruction11x).registerA val result2 = signatures.last().result!! val implementation2 = result2.method.implementation!! - val moveViewInstruction = implementation2.instructions[result2.scanData.endIndex] + val moveViewInstruction = implementation2.instructions[result2.scanResult.endIndex] val viewRegister = (moveViewInstruction as Instruction11x).registerA // Save the tab enum in XGlobals to avoid smali/register workarounds implementation1.addInstruction( - result1.scanData.endIndex + 1, + result1.scanResult.endIndex + 1, "sput-object v$enumRegister, Lfi/razerman/youtube/XGlobals;->lastPivotTab:Ljava/lang/Enum;".toInstruction() ) // Hide the button view via proxy by passing it to the hideShortsButton method // It only hides it if the last tab name is "TAB_SHORTS" implementation2.addInstruction( - result2.scanData.endIndex + 2, + result2.scanResult.endIndex + 2, "invoke-static { v$viewRegister }, Lfi/razerman/youtube/XAdRemover;->hideShortsButton(Landroid/view/View;)V".toInstruction() ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt index ea37ba63..6e88d2b4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonTabenumSignature.kt @@ -12,7 +12,7 @@ import org.jf.dexlib2.Opcode @Name("pivotbar-buttons-tabenum-signature") @MatchingMethod( - "Lkne", "z" + "Lknw", "z" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @ShortsButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt index b3140fe7..cfde6a33 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/shorts/button/signatures/PivotBarButtonsViewSignature.kt @@ -12,7 +12,7 @@ import org.jf.dexlib2.Opcode @Name("pivotbar-buttons-view-signature") @MatchingMethod( - "Lkne", "z" + "Lknw", "z" ) @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @ShortsButtonCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt index 318ea09d..e8e11139 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/annotations/IntegrationsCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt index 538da04d..25bfe66e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/patch/IntegrationsPatch.kt @@ -35,7 +35,7 @@ class IntegrationsPatch : BytecodePatch( val count = implementation.registerCount - 1 implementation.addInstructions( - result.scanData.endIndex + 1, """ + result.scanResult.endIndex + 1, """ invoke-static {v$count}, Lpl/jakubweg/StringRef;->setContext(Landroid/content/Context;)V sput-object v$count, Lapp/revanced/integrations/Globals;->context:Landroid/content/Context; """.trimIndent().toInstructions() diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt index 390fd033..450b7570 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/integrations/signatures/InitSignature.kt @@ -3,55 +3,16 @@ package app.revanced.patches.youtube.misc.integrations.signatures import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Version import app.revanced.patcher.signature.implementation.method.MethodSignature -import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility -import org.jf.dexlib2.AccessFlags -import org.jf.dexlib2.Opcode @Name("init-signature") @MatchingMethod( - "Lacnx", "onCreate" + "Lacuu", "onCreate" ) -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @IntegrationsCompatibility @Version("0.0.1") object InitSignature : MethodSignature( - "V", - AccessFlags.PUBLIC.value, - listOf(), - listOf( - Opcode.SGET_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.CONST_STRING, - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.MOVE_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST_4, - Opcode.CONST_STRING, - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.SPUT_OBJECT, - Opcode.SGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_SUPER, - Opcode.INVOKE_VIRTUAL - ) + null, null, null, null, + listOf("Application creation") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt index a04be984..61da5c01 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/manifest/annotations/FixLocaleConfigErrorCompatibility.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package @Compatibility( [Package( - "com.google.android.youtube", arrayOf("17.14.35", "17.17.34") + "com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36") )] ) @Target(AnnotationTarget.CLASS) diff --git a/src/test/kotlin/app/revanced/patches/SignatureChecker.kt b/src/test/kotlin/app/revanced/patches/SignatureChecker.kt deleted file mode 100644 index ffa80f2c..00000000 --- a/src/test/kotlin/app/revanced/patches/SignatureChecker.kt +++ /dev/null @@ -1,62 +0,0 @@ -package app.revanced.patches - -import app.revanced.patcher.Patcher -import app.revanced.patcher.annotation.Name -import app.revanced.patcher.signature.implementation.method.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.signature.implementation.method.annotation.MatchingMethod -import app.revanced.patcher.signature.implementation.method.annotation.PatternScanMethod -import org.jf.dexlib2.iface.Method -import org.junit.Test -import java.io.File - -internal class SignatureChecker { - @Test - fun checkMethodSignatures() { - - // FIXME: instead of having this as a test, it should be turned into a task which can be ran manually - val file = File("stock.apk") - if (!file.exists()) { - throw IllegalStateException("Missing $file! To run this test, please place stock.apk here: ${file.absolutePath}") - } - val patcher = Patcher(file, "signatureCheckerCache", false) - patcher.addPatches(Index.patches.map { it() }) - val unresolved = mutableListOf() - for (signature in patcher.resolveSignatures()) { - val signatureAnnotations = signature::class.annotations - - val nameAnnotation = signatureAnnotations.find { it is Name } as Name - if (!signature.resolved) { - unresolved.add(nameAnnotation.name) - continue - } - - val patternScanMethod = - signatureAnnotations.find { it::class.annotations.any { method -> method is PatternScanMethod } } - if (patternScanMethod is FuzzyPatternScanMethod) { - val warnings = signature.result!!.scanData.warnings!! - val method = signature.result!!.method - - val methodFromMetadata = - signatureAnnotations.find { it is MatchingMethod } as MatchingMethod? ?: MatchingMethod() - - println("Signature: ${nameAnnotation}.\nMethod: ${methodFromMetadata.definingClass}->${methodFromMetadata.name} (Signature matches: ${method.definingClass}->${method.toStr()})\nWarnings: ${warnings.count()}") - for (warning in warnings) { - println("${warning.instructionIndex} / ${warning.patternIndex}: ${warning.wrongOpcode} (expected: ${warning.correctOpcode})") - } - - println("=".repeat(20)) - } - } - if (unresolved.isNotEmpty()) { - val base = Exception("${unresolved.size} signatures were not resolved.") - for (name in unresolved) { - base.addSuppressed(Exception("Signature $name was not resolved!")) - } - throw base - } - } - - private fun Method.toStr(): String { - return "${this.name}(${this.parameterTypes.joinToString("")})${this.returnType}" - } -} \ No newline at end of file