diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/TiktokAdsCompatibility.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/TiktokAdsCompatibility.kt new file mode 100644 index 000000000..0a1f92c65 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/ad/annotations/TiktokAdsCompatibility.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.tiktok.ad.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [ + Package("com.ss.android.ugc.trill", arrayOf()), + Package("com.zhiliaoapp.musically", arrayOf()) + ] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class TiktokAdsCompatibility diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt new file mode 100644 index 000000000..d7864768d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/ad/fingerprints/FeedItemListCloneFingerprint.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.tiktok.ad.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility + +@Name("feed-item-clone-fingerprint") +@MatchingMethod( + "Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;", + "clone", +) +@TiktokAdsCompatibility +@Version("0.0.1") +object FeedItemListCloneFingerprint : MethodFingerprint( + null, null, null, null,null, { methodDef -> + methodDef.definingClass.endsWith("/FeedItemList;") && methodDef.name == "clone" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/TiktokAdsPatch.kt b/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/TiktokAdsPatch.kt new file mode 100644 index 000000000..19852f8a4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/tiktok/ad/patch/TiktokAdsPatch.kt @@ -0,0 +1,48 @@ +package app.revanced.patches.tiktok.ad.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.impl.BytecodeData +import app.revanced.patcher.extensions.addInstruction +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultError +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patcher.patch.impl.BytecodePatch +import app.revanced.patches.tiktok.ad.annotations.TiktokAdsCompatibility +import app.revanced.patches.tiktok.ad.fingerprints.FeedItemListCloneFingerprint +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.iface.instruction.ReferenceInstruction +import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction +import org.jf.dexlib2.iface.reference.FieldReference + +@Patch +@Name("tiktok-ads") +@Description("Removes ads from TikTok.") +@TiktokAdsCompatibility +@Version("0.0.1") +class TiktokAdsPatch : BytecodePatch( + listOf(FeedItemListCloneFingerprint) +) { + override fun execute(data: BytecodeData): PatchResult { + val method = FeedItemListCloneFingerprint.result!!.mutableMethod + // iterate all instructions in the clone method + for ((index, instruction) in method.implementation!!.instructions.withIndex()) { + // conditions for the instruction we need + if (instruction.opcode.ordinal != Opcode.IPUT_OBJECT.ordinal) continue + val clonePreloadAdsFieldInstruction = (instruction as? ReferenceInstruction) + if ((clonePreloadAdsFieldInstruction?.reference as? FieldReference)?.name != "preloadAds") continue + + // set null instead of the field "preloadAds" + val overrideRegister = (clonePreloadAdsFieldInstruction as TwoRegisterInstruction).registerA + method.addInstruction( + index, + "const/4 v$overrideRegister, 0x0" + ) + return PatchResultSuccess() + } + + return PatchResultError("Could not find required instruction.") + } +}