Skip to content

Commit

Permalink
feat(Instagram - Hide timeline ads): Make compatible with latest vers…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
oSumAtrIX committed Mar 12, 2024
1 parent dff4a3f commit a212f29
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 169 deletions.
Original file line number Diff line number Diff line change
@@ -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.

ShowAdFingerprint.result ?: throw ShowAdFingerprint.exception

PaidPartnershipAdFingerprint.result ?: throw PaidPartnershipAdFingerprint.exception

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
// 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

val mediaInstanceRegister = mutableMethod.getInstruction<FiveRegisterInstruction>(scanStart).registerC
val freeRegister = mutableMethod.getInstruction<OneRegisterInstruction>(jumpIndex).registerA
ShowAdFingerprint.result?.let {
it.mutableMethod.apply {
// The register that holds the post object.
val postRegister = getInstruction<FiveRegisterInstruction>(1).registerC

val returnFalseLabel = "an_ad"
// At this index the check for an ad can be performed.
val checkIndex = it.scanResult.patternScanResult!!.endIndex

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
}
}
}
Original file line number Diff line number Diff line change
@@ -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,
),
)
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,7 +18,5 @@ internal object GenericMediaAdFingerprint : MediaAdFingerprint(
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
)
) {
override fun toString() = result!!.method.toString()
}
),
)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
)

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit a212f29

Please sign in to comment.