From 862a7ec5b0767c28e79454a44218069d3e9cbac7 Mon Sep 17 00:00:00 2001 From: Sculas Date: Wed, 5 Jul 2023 23:01:27 +0200 Subject: [PATCH] feat(pixiv): add `hide-ads` patch (#2578) Co-authored-by: oSumAtrIX --- .../fingerprints/IsNotPremiumFingerprint.kt | 21 ++++++++++++ .../patches/pixiv/ads/patch/HideAdsPatch.kt | 33 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt new file mode 100644 index 000000000..453ec7fe3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/pixiv/ads/fingerprints/IsNotPremiumFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.pixiv.ads.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags + + +object IsNotPremiumFingerprint : MethodFingerprint( + "V", + AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + listOf("L"), + strings = listOf("pixivAccountManager"), + customFingerprint = custom@{ _, classDef -> + // The "isNotPremium" method is the only method in the class. + if (classDef.virtualMethods.count() != 1) return@custom false + + classDef.virtualMethods.first().let { isNotPremiumMethod -> + isNotPremiumMethod.parameterTypes.size == 0 && isNotPremiumMethod.returnType == "Z" + } + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt new file mode 100644 index 000000000..4b072f321 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/pixiv/ads/patch/HideAdsPatch.kt @@ -0,0 +1,33 @@ +package app.revanced.patches.pixiv.ads.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.* +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.pixiv.ads.fingerprints.IsNotPremiumFingerprint + +@Patch +@Name("hide-ads") +@Description("Hides ads.") +@Compatibility([Package("jp.pxv.android")]) +@Version("0.0.1") +class HideAdsPatch : BytecodePatch(listOf(IsNotPremiumFingerprint)) { + override fun execute(context: BytecodeContext): PatchResult { + // Always return false in the "isNotPremium" method which normally returns !this.accountManager.isPremium. + // However, this is not the method that controls the user's premium status. + // Instead, this method is used to determine whether ads should be shown. + IsNotPremiumFingerprint.result?.mutableClass?.virtualMethods?.first()?.addInstructions( + 0, + """ + const/4 v0, 0x0 + return v0 + """ + ) ?: return IsNotPremiumFingerprint.toErrorResult() + + return PatchResultSuccess() + } +} \ No newline at end of file