Merge pull request 'feat(kakaotalk): update compatibility to version 25.4.3 and add show deleted messages patch' (#4) from kakaotalk-dev into main

Reviewed-on: #4
This commit is contained in:
2025-06-08 02:04:14 +09:00
22 changed files with 227 additions and 18 deletions

View File

@ -276,6 +276,10 @@ public final class app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatchKt {
public static final fun getRemove99ClampPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/kakaotalk/chatlog/ShowDeletedMessagePatchKt {
public static final fun getShowDeletedMessagePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatchKt {
public static final fun getRemove300PlusLimitBaseChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
public static final fun getRemove300PlusLimitOpenChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
@ -309,6 +313,10 @@ public final class app/revanced/patches/kakaotalk/misc/RemoveShopTabPatchKt {
public static final fun getRemoveShopTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/kakaotalk/packagename/ChangePackageNameInSourcePatchKt {
public static final fun getChangePackageNameInSourcePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
public final class app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatchKt {
public static final fun getAllowReplyToFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}

View File

@ -9,7 +9,7 @@ val removeBizBoardPatch = bytecodePatch(
name = "Remove BizBoard ads",
description = "Removes the BizBoard ad by forcing its dimensions to 0x0 and visibility to GONE in onMeasure.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = measuringBizBoardFingerprint.method

View File

@ -8,7 +8,7 @@ val removeFocusAdPatch = bytecodePatch(
name = "Remove focus ad",
description = "Removes the focus ad from the app.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
loadFocusAdFingerprint.method.addInstructions(

View File

@ -14,7 +14,7 @@ val removeMoreTabAdPatch = bytecodePatch(
name = "Remove More tab ad",
description = "Removes the ad from the More tab.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val addSectionToMoreTabUIMethod = addSectionToMoreTabUIFingerprint.method

View File

@ -8,7 +8,7 @@ val removeNativeAdPatch = bytecodePatch(
name = "Remove native ad",
description = "Removes the native ad from the app.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = loadNativeAdFingerprint.method

View File

@ -10,7 +10,7 @@ val removeOlkChatRoomListAdPatch = bytecodePatch(
name = "Remove OpenLink chat room list ad",
description = "Removes the OpenLink chat room list ad.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val findUnit = kotlinUnitInstanceFingerprint.method

View File

@ -14,7 +14,7 @@ val changeModelPatch = bytecodePatch(
"model", "SM-X926N"
)
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
changeModelFingerprint.method.addInstructions(

View File

@ -13,7 +13,7 @@ val remove99ClampPatch = bytecodePatch(
name = "Disable 99 unread limit",
description = "Skip the 99-cap so unread count shows full value"
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = processWatermarkCountFingerprint.method

View File

@ -0,0 +1,64 @@
package app.revanced.patches.kakaotalk.chatlog
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.kakaotalk.chatlog.fingerprints.chatLogGetTextFingerprint
import app.revanced.patches.kakaotalk.chatlog.fingerprints.chatLogSetTextFingerprint
import app.revanced.patches.kakaotalk.chatlog.fingerprints.replaceToFeedFingerprint
import com.android.tools.smali.dexlib2.Opcode
val showDeletedMessagePatch = bytecodePatch(
name = "Show deleted messages",
description = "Allows you to see deleted messages in chat logs.",
) {
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = replaceToFeedFingerprint.method
val insns = method.instructions
val orInsnsIdx = insns
.indexOfFirst { it.opcode == Opcode.OR_INT_LIT16 }
if (orInsnsIdx == -1) error("could not find or built message $orInsnsIdx")
method.addInstructions(
orInsnsIdx + 1,
"""
const/16 p1, 0x1
""".trimIndent()
)
val setTextMethod = chatLogSetTextFingerprint.method.name
val getTextMethod = chatLogGetTextFingerprint.method.name
val chatLogClass = chatLogSetTextFingerprint.method.definingClass
method.replaceInstruction(
orInsnsIdx + 2,
"nop"
)
method.addInstructions(
orInsnsIdx + 3,
"""
invoke-virtual {p0}, $chatLogClass->$getTextMethod()Ljava/lang/String;
move-result-object v2
const-string v1, "[Deleted] "
new-instance v3, Ljava/lang/StringBuilder;
invoke-direct {v3}, Ljava/lang/StringBuilder;-><init>()V
invoke-virtual {v3, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {v3, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-virtual {p0, v1}, $chatLogClass->$setTextMethod(Ljava/lang/String;)V
invoke-virtual {p0}, $chatLogClass->getChatRoomId()J
move-result-wide v2
""".trimIndent()
)
}
}

View File

@ -0,0 +1,52 @@
package app.revanced.patches.kakaotalk.chatlog.fingerprints
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val chatLogFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
returns("Ljava/lang/String;")
parameters()
strings(
"[class:",
"] ChatLog [id=",
)
}
internal val chatLogSetTextFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
returns("V")
parameters("Ljava/lang/String;")
opcodes(
Opcode.CONST_4,
Opcode.CONST_STRING,
Opcode.CONST_STRING,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.CONST_16,
Opcode.IF_LE,
)
custom { method, classDef -> classDef.sourceFile == "ChatLog.kt" }
}
internal val chatLogGetTextFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC)
returns("Ljava/lang/String;")
parameters()
opcodes(
Opcode.IGET_BOOLEAN,
Opcode.CONST_STRING,
Opcode.IF_EQZ,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.GOTO,
Opcode.MOVE_OBJECT,
)
custom { method, classDef -> classDef.sourceFile == "ChatLog.kt" }
}

View File

@ -0,0 +1,20 @@
package app.revanced.patches.kakaotalk.chatlog.fingerprints
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
internal val replaceToFeedFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("V")
strings(
"feedType",
"{}",
"safeBot",
"getString(...)",
"hidden",
"byHost",
"previous_message",
"previous_enc",
"enc : %s, %s",
)
}

View File

@ -14,7 +14,7 @@ val remove300PlusLimitBaseChatRoomPatch = bytecodePatch(
name = "Disable 300+ unread limit (BaseChatRoom)",
description = "Always show the real unread count instead of '300+' in base chatroom list"
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = limit300PlusBaseChatRoomFingerprint.method
@ -40,7 +40,7 @@ val remove300PlusLimitOpenChatRoomPatch = bytecodePatch(
name = "Disable 300+ unread limit (OpenChatRoom)",
description = "Always show the real unread count instead of '300+' in open chatroom list"
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = limit300PlusOpenChatRoomFingerprint.method

View File

@ -9,7 +9,7 @@ val forceEnableEmoticonPlusPatch = bytecodePatch(
name = "Force enable emoticon plus feature",
description = "Force enable emoticon plus feature (Unpurchased emoticon can be sent once per day)",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
isEnableEmoticonPlusFingerprint.method.addInstructions(

View File

@ -10,7 +10,7 @@ val ghostMode = bytecodePatch(
name = "Ghost Mode",
description = "Don't expose your typing status to the other party.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val findUnit = kotlinUnitInstanceFingerprint.method

View File

@ -21,7 +21,7 @@ val bypassMoatCheckPatch = bytecodePatch(
name = "Bypass Moat check",
description = "Bypass Moat check that prevents the app from running.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val patch: (Fingerprint) -> Unit = {

View File

@ -10,7 +10,7 @@ val bypassRequestChecksumPatch = bytecodePatch(
name = "Bypass requestChecksums",
description = "Prevents the execution of checksum verification logic by making it return early."
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val findUnit = kotlinUnitInstanceFingerprint.method

View File

@ -9,7 +9,7 @@ val verifyingSignaturePatch = bytecodePatch(
name = "Disable verifying signature",
description = "Disables the signature verification check that prevents the app from running.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
verifyingSignatureFingerprint.method.addInstructions(

View File

@ -11,7 +11,7 @@ val forceEnableDebugModePatch = bytecodePatch(
name = "Force enable debug mode",
description = "Enables debug mode in the app.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = configConstructorFingerprint.method

View File

@ -15,7 +15,7 @@ val removeShopTabPatch = bytecodePatch(
name = "Remove shop tab",
description = "Removes the shop tab from the bottom navigation bar.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val method = addNavigationTabFingerprint.method

View File

@ -0,0 +1,65 @@
package app.revanced.patches.kakaotalk.packagename
import app.revanced.patcher.extensions.InstructionExtensions.instructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.findMutableMethodOf
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference
val changePackageNameInSourcePatch = bytecodePatch(
name = "Change package name in source",
description = "Changes the package name in the source code of KakaoTalk.",
use = false,
) {
// dependsOn(changePackageNamePatch)
execute {
// val newPackageName = if (packageNameOption.value == packageNameOption.default) {
// "com.kakao.talk.revanced"
// } else {
// packageNameOption.value!!
// }
val newPackageName = "com.kakao.talk.revanced"
val newStringReference = ImmutableStringReference(newPackageName)
classes.forEach { classDef ->
classDef.methods.forEach { method ->
val insns = method.implementation?.instructions ?: return@forEach
for ((i, insn) in insns.withIndex()) {
if (insn is Instruction21c &&
insn.opcode == Opcode.CONST_STRING &&
insn.getReference<StringReference>()!!.string == "com.kakao.talk") {
val mutableMethod = proxy(classDef).mutableClass.findMutableMethodOf(method)
mutableMethod.instructions
.filterIsInstance<BuilderInstruction21c>()
.filter { it.opcode == Opcode.CONST_STRING &&
it.getReference<StringReference>()!!.string == "com.kakao.talk" }
.forEach {
val idx = mutableMethod.instructions.indexOf(it)
println("Replacing package name in method $mutableMethod at index $idx")
mutableMethod.replaceInstruction(
idx,
BuilderInstruction21c(
Opcode.CONST_STRING,
it.registerA,
ImmutableStringReference(newPackageName)
)
)
}
}
}
}
}
}
}

View File

@ -15,7 +15,7 @@ val allowReplyToFeedPatch = app.revanced.patcher.patch.bytecodePatch(
name = "Allow reply to feed",
description = "Allows replying to feed messages",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val patch: (Fingerprint) -> Unit = { fp ->

View File

@ -17,7 +17,7 @@ val versionInfoPatch = bytecodePatch(
name = "Version info patch",
description = "Patches the version info to include '(ReVanced)' in the version string.",
) {
compatibleWith("com.kakao.talk"("25.4.2"))
compatibleWith("com.kakao.talk"("25.4.3"))
execute {
val runPatch: (Fingerprint, Boolean) -> Unit = { fp, inDetail ->