From 3f868cd995a278d4c9c3e93d2d5a15f42bb268b8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 21 May 2025 02:45:44 +0900 Subject: [PATCH] feat(kakaotalk): add patch and fingerprint to remove More tab ad --- patches/api/patches.api | 4 ++ .../kakaotalk/ads/RemoveMoreTabAdPatch.kt | 45 ++++++++++++++++++ .../RemoveMoreTabAdFingerprint.kt | 46 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index bbbd42e2d..89fd4ba71 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -252,6 +252,10 @@ public final class app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatchKt { public static final fun getRemoveFocusAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatchKt { + public static final fun getRemoveMoreTabAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatchKt { public static final fun getRemoveOlkChatRoomListAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt new file mode 100644 index 000000000..fd03e92fd --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.adBigUIModelFingerprint +import app.revanced.patches.kakaotalk.ads.fingerprints.addSectionToMoreTabUIFingerprint +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +val removeMoreTabAdPatch = bytecodePatch( + name = "Remove More tab ad", + description = "Removes the ad from the More tab.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + val addSectionToMoreTabUIMethod = addSectionToMoreTabUIFingerprint.method + val addSectionToMoreTabUIInsns = addSectionToMoreTabUIMethod.instructions + + val adBigUIModelClass = adBigUIModelFingerprint.method.definingClass + + val matches = addSectionToMoreTabUIInsns.mapIndexedNotNull { idx, inst -> + if (inst is BuilderInstruction35c + && inst.opcode == Opcode.INVOKE_VIRTUAL + && (inst.getReference()?.name == "add") + ) { + val prev = addSectionToMoreTabUIInsns.getOrNull(idx - 1) as? BuilderInstruction35c + val ref = (prev?.getReference()) + if (ref?.definingClass == adBigUIModelClass) { + Pair(idx - 1, idx) + } else null + } else null + } + + matches + .sortedByDescending { it.second } + .forEach { (loadIdx, invokeIdx) -> + addSectionToMoreTabUIMethod.removeInstruction(invokeIdx) + addSectionToMoreTabUIMethod.removeInstruction(loadIdx) + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt new file mode 100644 index 000000000..0a1eb6012 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val addSectionToMoreTabUIFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;") + returns("Ljava/lang/Object;") + strings( + "call to \'resume\' before \'invoke\' with coroutine", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.KakaoPayUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WalletUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WeatherUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.KakaoNowUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.TalkManualUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.ServiceGroupUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WalletBannerUiModel", + "null cannot be cast to non-null type kotlin.Boolean", + ) + opcodes( + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.CONST_4, + Opcode.IF_EQZ, + ) +} + +internal val adBigUIModelFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() + returns("Ljava/lang/String;") + strings( + "AdBig(uiModel=", + ) + opcodes( + Opcode.NEW_INSTANCE, + Opcode.CONST_STRING, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.CONST_STRING, + ) + custom { method, classDef -> method.name == "toString" } +} \ No newline at end of file