diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt index fdae0ddb..2cb98620 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt @@ -1,102 +1,63 @@ package app.revanced.patches.instagram.patches.ads.timeline -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.MediaFingerprint +import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.IsAdCheckOneFingerprint +import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.IsAdCheckTwoFingerprint import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ShowAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.GenericMediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.MediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.PaidPartnershipAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.ShoppingAdFingerprint +import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( name = "Hide timeline ads", - description = "Removes ads from the timeline.", - compatiblePackages = [CompatiblePackage("com.instagram.android", ["275.0.0.27.98"])] + compatiblePackages = [CompatiblePackage("com.instagram.android")], ) @Suppress("unused") object HideTimelineAdsPatch : BytecodePatch( setOf( ShowAdFingerprint, - MediaFingerprint, - PaidPartnershipAdFingerprint // Unlike the other ads this one is resolved from all classes. - ) + IsAdCheckOneFingerprint, + IsAdCheckTwoFingerprint, + ), ) { override fun execute(context: BytecodeContext) { - // region Resolve required methods to check for ads. + // The exact function of the following methods is unknown. + // They are used to check if a post is an ad. + val isAdCheckOneMethod = IsAdCheckOneFingerprint.result?.method ?: throw IsAdCheckOneFingerprint.exception + val isAdCheckTwoMethod = IsAdCheckTwoFingerprint.result?.method ?: throw IsAdCheckTwoFingerprint.exception - ShowAdFingerprint.result ?: throw ShowAdFingerprint.exception + ShowAdFingerprint.result?.let { + it.mutableMethod.apply { + // The register that holds the post object. + val postRegister = getInstruction(1).registerC - PaidPartnershipAdFingerprint.result ?: throw PaidPartnershipAdFingerprint.exception + // At this index the check for an ad can be performed. + val checkIndex = it.scanResult.patternScanResult!!.endIndex - MediaFingerprint.result?.let { - GenericMediaAdFingerprint.resolve(context, it.classDef) - ShoppingAdFingerprint.resolve(context, it.classDef) - - return@let - } ?: throw MediaFingerprint.exception - - // endregion - - ShowAdFingerprint.result!!.apply { - // region Create instructions. - - val scanStart = scanResult.patternScanResult!!.startIndex - val jumpIndex = scanStart - 1 - - val mediaInstanceRegister = mutableMethod.getInstruction(scanStart).registerC - val freeRegister = mutableMethod.getInstruction(jumpIndex).registerA - - val returnFalseLabel = "an_ad" - - val checkForAdInstructions = - listOf(GenericMediaAdFingerprint, PaidPartnershipAdFingerprint, ShoppingAdFingerprint) - .map(MediaAdFingerprint::toString) - .joinToString("\n") { - """ - invoke-virtual {v$mediaInstanceRegister}, $it - move-result v$freeRegister - if-nez v$freeRegister, :$returnFalseLabel - """.trimIndent() - }.let { "$it\nconst/4 v0, 0x1\nreturn v0" } - - // endregion - - // region Patch. - - val insertIndex = scanStart + 3 - - mutableMethod.addInstructionsWithLabels( - insertIndex, - checkForAdInstructions, - ExternalLabel( - returnFalseLabel, - mutableMethod.getInstruction(mutableMethod.implementation!!.instructions.size - 2 /* return false = ad */) - ) - ) - - // endregion - - // region Jump to checks for ads from previous patch. - - mutableMethod.apply { + // If either check returns true, the post is an ad and is hidden by returning false. addInstructionsWithLabels( - jumpIndex + 1, - "if-nez v$freeRegister, :start_check", - ExternalLabel("start_check", getInstruction(insertIndex)) + checkIndex, + """ + invoke-virtual { v$postRegister }, $isAdCheckOneMethod + move-result v0 + if-nez v0, :hide_ad + + invoke-static { v$postRegister }, $isAdCheckTwoMethod + move-result v0 + if-eqz v0, :not_an_ad + + :hide_ad + const/4 v0, 0x0 # Returning false to hide the ad. + return v0 + """, + ExternalLabel("not_an_ad", getInstruction(checkIndex)), ) - }.removeInstruction(jumpIndex) - - // endregion - } + } + } ?: throw ShowAdFingerprint.exception } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt new file mode 100644 index 00000000..58380feb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.instagram.patches.ads.timeline.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object IsAdCheckOneFingerprint : MethodFingerprint( + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.XOR_INT_LIT8, + Opcode.IF_NE, + Opcode.RETURN, + Opcode.INVOKE_VIRTUAL, + ), +) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt similarity index 51% rename from src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt rename to src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt index 8a2d75b4..aa826abf 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt @@ -1,8 +1,14 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads +package app.revanced.patches.instagram.patches.ads.timeline.fingerprints +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object GenericMediaAdFingerprint : MediaAdFingerprint( +internal object IsAdCheckTwoFingerprint : MethodFingerprint( + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), opcodes = listOf( Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT_OBJECT, @@ -12,7 +18,5 @@ internal object GenericMediaAdFingerprint : MediaAdFingerprint( Opcode.IF_EQZ, Opcode.CONST_4, Opcode.RETURN, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file + ), +) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt deleted file mode 100644 index 9959811d..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -internal object MediaFingerprint : MethodFingerprint( - strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata") -) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt index 53ab5ee9..70eda9ab 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt @@ -10,16 +10,12 @@ internal object ShowAdFingerprint : MethodFingerprint( AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL, listOf("L", "L", "Z", "Z"), opcodes = listOf( + Opcode.SGET_OBJECT, + Opcode.IF_NE, + Opcode.IF_NEZ, Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_NEZ, Opcode.RETURN, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, ), ) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt deleted file mode 100644 index 11f21b3f..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.ClassDef -import com.android.tools.smali.dexlib2.iface.Method - -internal abstract class MediaAdFingerprint( - returnType: String? = "Z", - accessFlags: Int? = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters: Iterable? = listOf(), - opcodes: Iterable?, - customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null -) : MethodFingerprint( - returnType, - accessFlags, - parameters, - opcodes, - customFingerprint = customFingerprint -) { - abstract override fun toString(): String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt deleted file mode 100644 index 2a390022..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -internal object PaidPartnershipAdFingerprint : MediaAdFingerprint( - "V", - null, - listOf("L", "L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IPUT_BOOLEAN, - Opcode.IPUT_BOOLEAN - ), - customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("ClipsEditMetadataController;") - } -) { - override fun toString() = result!!.let { - val adCheckIndex = it.scanResult.patternScanResult!!.startIndex - val adCheckInstruction = it.method.implementation!!.instructions.elementAt(adCheckIndex) - - val adCheckMethod = (adCheckInstruction as ReferenceInstruction).reference as MethodReference - - adCheckMethod.toString() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt deleted file mode 100644 index 9dd1232c..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import com.android.tools.smali.dexlib2.Opcode - -internal object ShoppingAdFingerprint : MediaAdFingerprint( - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.XOR_INT_LIT8, - Opcode.IF_EQZ, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file