From e6cce8554116df3c0ea6dbb7440c59c9e73d8334 Mon Sep 17 00:00:00 2001 From: Samo Hribar <34912839+samolego@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:51:33 +0200 Subject: [PATCH] feat(Viber - Hide ads): Support latest app target (#5863) --- patches/api/patches.api | 1 - .../patches/viber/ads/Fingerprints.kt | 10 ++----- .../patches/viber/ads/HideAdsPatch.kt | 30 +++++++++++++++++-- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/patches/api/patches.api b/patches/api/patches.api index 00b58e88e..24ff0e3a8 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1877,4 +1877,3 @@ public final class app/revanced/util/resource/StringResource : app/revanced/util public final class app/revanced/util/resource/StringResource$Companion { public final fun fromNode (Lorg/w3c/dom/Node;)Lapp/revanced/util/resource/StringResource; } - diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt index 11ebe0d11..29b752cf8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt @@ -2,12 +2,6 @@ package app.revanced.patches.viber.ads import app.revanced.patcher.fingerprint -internal val adsFreeFingerprint = fingerprint { - returns("I") - parameters() - custom { method, classDef -> - classDef.type.contains("com/viber/voip/feature/viberplus") && - classDef.superclass?.contains("com/viber/voip/core/feature") == true && // Must extend com.viber.voip.core.feature.? - classDef.methods.count() == 1 - } +internal val findAdStringFingerprint = fingerprint { + strings("viber_plus_debug_ads_free_flag") } diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt index 91bff02c6..0ec31e376 100644 --- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt @@ -1,17 +1,41 @@ package app.revanced.patches.viber.ads +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.fingerprint +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.returnEarly +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.TypeReference @Suppress("unused") val hideAdsPatch = bytecodePatch( name = "Hide Ads", description = "Hides ad banners between chats.", ) { - compatibleWith("com.viber.voip"("25.9.2.0")) + compatibleWith("com.viber.voip"("25.9.2.0", "26.1.2.0")) execute { - // Return 1 (true) indicating ads should be disabled. - adsFreeFingerprint.method.returnEarly(1) + val method = findAdStringFingerprint.method + + // Find the ads free string index + val stringIndex = findAdStringFingerprint.stringMatches!!.first().index + + // Search backwards from the string to find the `new-instance` (TypeReference) instruction + val typeRefIndex = method.indexOfFirstInstructionReversedOrThrow(stringIndex) { this.opcode == Opcode.NEW_INSTANCE } + + // Get the class name from the TypeReference + val targetClass = method.getInstruction(typeRefIndex).reference as TypeReference + + // Patch the ads-free method to always return true + fingerprint { + returns("I") + parameters() + custom { method, classDef -> + classDef == targetClass + } + }.method.returnEarly(1) } }