From 0693212ba568b58ad9fcddebe30ca5f7604eec7d Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 3 May 2025 19:25:46 +0900 Subject: [PATCH 01/36] feat(kakaotalk): Add patches for changing device model and disabling signature verification --- .../kakaotalk/changemodel/ChangeModelPatch.kt | 29 +++++++++++++++++++ .../fingerprints/ChangeModelFingerprint.kt | 12 ++++++++ .../signature/VerifyingSignaturePatch.kt | 24 +++++++++++++++ .../VerifyingSignatureFingerprint.kt | 12 ++++++++ 4 files changed, 77 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/fingerprints/ChangeModelFingerprint.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt new file mode 100644 index 000000000..87bdfd1d7 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt @@ -0,0 +1,29 @@ +package app.revanced.patches.kakaotalk.changemodel + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.Package +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.stringOption +import app.revanced.patches.kakaotalk.changemodel.fingerprints.changeModelFingerprint + +@Suppress("unused") +val changeModelPatch = bytecodePatch( + name = "Change model", + description = "Changes the device model to supporting subdevice features", +) { + val changeModelOption = stringOption( + "model", "SM-X926N" + ) + + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + changeModelFingerprint.method.addInstructions( + 0, + """ + const-string v0, "${changeModelOption.value}" + return-object v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/fingerprints/ChangeModelFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/fingerprints/ChangeModelFingerprint.kt new file mode 100644 index 000000000..8d59e0fad --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/fingerprints/ChangeModelFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.kakaotalk.changemodel.fingerprints + +import app.revanced.patcher.fingerprint + +@Suppress("unused") +internal val changeModelFingerprint = fingerprint { + strings("MODEL", "\\s", "-", "US", "toUpperCase(...)") + custom { + _, classDef -> + classDef.methods.indexOf(classDef.methods.last()) > 2 + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt new file mode 100644 index 000000000..fb200a087 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.kakaotalk.signature + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.Package +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.memegenerator.detection.signature.verifySignatureFingerprint + +@Suppress("unused") +val verifyingSignaturePatch = bytecodePatch( + name = "Disable verifying signature", + description = "Disables the signature verification check that prevents the app from running.", +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + verifySignatureFingerprint.method.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt new file mode 100644 index 000000000..d5bfb8aa5 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.kakaotalk.signature.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +@Suppress("unused") +internal val verifyingSignatureFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + returns("Z") + parameters() + strings("getPackageName(...)") +} \ No newline at end of file From 88abc37b493626bb57c4c5986533b7a2300cd37b Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 3 May 2025 19:52:43 +0900 Subject: [PATCH 02/36] feat(kakaotalk): Add patches for changing device model and verifying signature --- patches/api/patches.api | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/patches/api/patches.api b/patches/api/patches.api index 7d32bec85..c600fb698 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -244,6 +244,14 @@ public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt { public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/changemodel/ChangeModelPatchKt { + public static final fun getChangeModelPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + +public final class app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatchKt { + public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/lightroom/misc/login/DisableMandatoryLoginPatchKt { public static final fun getDisableMandatoryLoginPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } From b80ec7758f8dca5f3a77ab2aec719b38c99903ae Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 3 May 2025 20:04:30 +0900 Subject: [PATCH 03/36] feat(kakaotalk): Update import for verifying signature fingerprint --- .../patches/kakaotalk/signature/VerifyingSignaturePatch.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt index fb200a087..926b0767b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.signature import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.memegenerator.detection.signature.verifySignatureFingerprint +import app.revanced.patches.kakaotalk.signature.fingerprints.verifyingSignatureFingerprint @Suppress("unused") val verifyingSignaturePatch = bytecodePatch( @@ -13,7 +13,7 @@ val verifyingSignaturePatch = bytecodePatch( compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) execute { - verifySignatureFingerprint.method.addInstructions( + verifyingSignatureFingerprint.method.addInstructions( 0, """ const/4 v0, 0x1 From ccfc313ff7f63e587fb0449072b0a08c6aaea6e8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 00:10:46 +0900 Subject: [PATCH 04/36] feat(kakaotalk): Add patches to remove 300+ unread limit in chatrooms --- patches/api/patches.api | 5 ++ .../chatroom/Remove300PlusLimitPatch.kt | 59 +++++++++++++++++++ .../Remove300PlusLimitFingerprint.kt | 20 +++++++ 3 files changed, 84 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index c600fb698..90a874dc8 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -248,6 +248,11 @@ public final class app/revanced/patches/kakaotalk/changemodel/ChangeModelPatchKt public static final fun getChangeModelPatch ()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; +} + public final class app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatchKt { public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt new file mode 100644 index 000000000..47d5f3c34 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt @@ -0,0 +1,59 @@ +package app.revanced.patches.kakaotalk.chatroom + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.Package +import app.revanced.patches.kakaotalk.chatroom.fingerprints.remove300PlusLimitBaseChatRoomFingerprint +import app.revanced.patches.kakaotalk.chatroom.fingerprints.remove300PlusLimitOpenChatRoomFingerprint +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t + +@Suppress("unused") +val remove300PlusLimitBaseChatRoomPatch = bytecodePatch( + name = "Disable 300+ unread limit (BaseChatRoom)", + description = "Always show the real unread count instead of '300+' in base chatroom list" +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + val method = remove300PlusLimitBaseChatRoomFingerprint.method + + val branches = method.instructions + .filterIsInstance() + .filter { it.opcode == Opcode.IF_LT } + .toList() + + branches.forEach { iflt -> + val idx = method.instructions.indexOf(iflt) + val gotoInsn = BuilderInstruction10t( + Opcode.GOTO, + iflt.target + ) + method.replaceInstruction(idx, gotoInsn) + } + } +} + +@Suppress("unused") +val remove300PlusLimitOpenChatRoomPatch = bytecodePatch( + name = "Disable 300+ unread limit (OpenChatRoom)", + description = "Always show the real unread count instead of '300+' in open chatroom list" +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + val method = remove300PlusLimitOpenChatRoomFingerprint.method + + method.instructions + .filterIsInstance() + .filter { it.opcode == Opcode.IF_LT } + .toList() + .forEach { iflt -> + val idx = method.instructions.indexOf(iflt) + val gotoInsn = BuilderInstruction10t(Opcode.GOTO, iflt.target) + method.replaceInstruction(idx, gotoInsn) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt new file mode 100644 index 000000000..f81510d3f --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.kakaotalk.chatroom.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +@Suppress("unused") +internal val remove300PlusLimitBaseChatRoomFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters("Lcom/kakao/talk/widget/ViewBindable;") + strings("300+") +} + +@Suppress("unused") +internal val remove300PlusLimitOpenChatRoomFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters() + strings("300+") +} \ No newline at end of file From b0d693e431aaf73cd2e939f6ff7e3bc381ba4914 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 00:52:51 +0900 Subject: [PATCH 05/36] feat(kakaotalk): Add version info patch to include '(ReVanced)' in the version string --- patches/api/patches.api | 4 ++ .../kakaotalk/versioninfo/VersionInfoPatch.kt | 41 +++++++++++++++++++ .../fingerprints/VersionInfoFingerprint.kt | 18 ++++++++ 3 files changed, 63 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 90a874dc8..871da0fd5 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -257,6 +257,10 @@ public final class app/revanced/patches/kakaotalk/signature/VerifyingSignaturePa public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatchKt { + public static final fun getVersionInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/lightroom/misc/login/DisableMandatoryLoginPatchKt { public static final fun getDisableMandatoryLoginPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt new file mode 100644 index 000000000..435c88c78 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -0,0 +1,41 @@ +package app.revanced.patches.kakaotalk.versioninfo + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.Package +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.versioninfo.fingerprints.versionInfoFingerprint +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c +import com.android.tools.smali.dexlib2.iface.reference.StringReference +import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference + +@Suppress("unused") +val versionInfoPatch = bytecodePatch( + name = "Version info patch", + description = "Patches the version info to include '(ReVanced)' in the version string.", +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + val inst = versionInfoFingerprint.method.instructions + .filterIsInstance() + .first { + it.opcode == Opcode.CONST_STRING + } + + val versionString = (inst.reference as StringReference).string + + versionInfoFingerprint.method + .replaceInstruction( + inst.location.index, + BuilderInstruction21c( + Opcode.CONST_STRING, + inst.registerA, + ImmutableStringReference( + "$versionString (ReVanced)" + ) + ) + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt new file mode 100644 index 000000000..713f6494d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.kakaotalk.versioninfo.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val versionInfoFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + returns("V") + opcodes( + Opcode.INVOKE_DIRECT, + Opcode.CONST_STRING, + Opcode.IPUT_OBJECT, + Opcode.IPUT_BOOLEAN, + Opcode.IPUT_OBJECT, + Opcode.RETURN_VOID, + ) +} \ No newline at end of file From ea208b37cb1b877fd2be28b29c4c580468ca1103 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 01:06:18 +0900 Subject: [PATCH 06/36] feat(kakaotalk): Add support for version info preview fingerprint patch --- .../kakaotalk/versioninfo/VersionInfoPatch.kt | 37 +++++++++++-------- .../fingerprints/VersionInfoFingerprint.kt | 19 ++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index 435c88c78..b2839f6fb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -1,10 +1,12 @@ package app.revanced.patches.kakaotalk.versioninfo +import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.versioninfo.fingerprints.versionInfoFingerprint +import app.revanced.patches.kakaotalk.versioninfo.fingerprints.versionInfoPreviewFingerprint import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.reference.StringReference @@ -18,24 +20,29 @@ val versionInfoPatch = bytecodePatch( compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) execute { - val inst = versionInfoFingerprint.method.instructions - .filterIsInstance() - .first { - it.opcode == Opcode.CONST_STRING - } + val runPatch: (Fingerprint) -> Unit = { + val versionInfo = it.method.instructions + .filterIsInstance() + .first { + it.opcode == Opcode.CONST_STRING + } - val versionString = (inst.reference as StringReference).string + val versionString = (versionInfo.reference as StringReference).string - versionInfoFingerprint.method - .replaceInstruction( - inst.location.index, - BuilderInstruction21c( - Opcode.CONST_STRING, - inst.registerA, - ImmutableStringReference( - "$versionString (ReVanced)" + it.method + .replaceInstruction( + versionInfo.location.index, + BuilderInstruction21c( + Opcode.CONST_STRING, + versionInfo.registerA, + ImmutableStringReference( + "$versionString (ReVanced)" + ) ) ) - ) + } + + runPatch(versionInfoFingerprint) + runPatch(versionInfoPreviewFingerprint) } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt index 713f6494d..1d47477a5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/fingerprints/VersionInfoFingerprint.kt @@ -15,4 +15,23 @@ internal val versionInfoFingerprint = fingerprint { Opcode.IPUT_OBJECT, Opcode.RETURN_VOID, ) +} + +internal val versionInfoPreviewFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() + returns("Ljava/lang/String;") + opcodes( + Opcode.CONST_STRING, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.NEW_INSTANCE, + Opcode.CONST_4, + Opcode.CONST_4, + Opcode.INVOKE_DIRECT, + Opcode.SGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + ) } \ No newline at end of file From e9545a11c46869990fc0531370ddb38c662972c9 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 01:07:05 +0900 Subject: [PATCH 07/36] feat(kakaotalk): Refactor version info patch to improve readability of instruction filtering --- .../patches/kakaotalk/versioninfo/VersionInfoPatch.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index b2839f6fb..22d1f46df 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -23,8 +23,8 @@ val versionInfoPatch = bytecodePatch( val runPatch: (Fingerprint) -> Unit = { val versionInfo = it.method.instructions .filterIsInstance() - .first { - it.opcode == Opcode.CONST_STRING + .first { inst -> + inst.opcode == Opcode.CONST_STRING } val versionString = (versionInfo.reference as StringReference).string From 82e530a510304ee1c01d0709b3ee809733363a6a Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 01:25:10 +0900 Subject: [PATCH 08/36] feat(kakaotalk): Add patch to remove 99 unread limit in chat logs --- patches/api/patches.api | 4 +++ .../kakaotalk/chatlog/Remove99ClampPatch.kt | 31 +++++++++++++++++++ .../fingerprints/Remove99ClampFingerprint.kt | 11 +++++++ 3 files changed, 46 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 871da0fd5..5d785ffd1 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -248,6 +248,10 @@ public final class app/revanced/patches/kakaotalk/changemodel/ChangeModelPatchKt public static final fun getChangeModelPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +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/chatroom/Remove300PlusLimitPatchKt { public static final fun getRemove300PlusLimitBaseChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getRemove300PlusLimitOpenChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch; diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt new file mode 100644 index 000000000..49ddde073 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.kakaotalk.chatlog + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.Package +import app.revanced.patches.kakaotalk.chatlog.fingerprints.remove99ClampFingerprint +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t + +@Suppress("unused") +val remove99ClampPatch = bytecodePatch( + name = "Disable 99 unread limit", + description = "Skip the 99-cap so unread count shows full value" +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + val method = remove99ClampFingerprint.method + + method.instructions + .filterIsInstance() + .filter { it.opcode == Opcode.IF_LE } + .forEach { ifle -> + val idx = method.instructions.indexOf(ifle) + val goto = BuilderInstruction10t(Opcode.GOTO, ifle.target) + method.replaceInstruction(idx, goto) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt new file mode 100644 index 000000000..26708c068 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt @@ -0,0 +1,11 @@ +package app.revanced.patches.kakaotalk.chatlog.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal val remove99ClampFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Ljava/lang/Object;") + parameters() + strings("notiRead", "openlinkSettingShowUnreadCount") +} \ No newline at end of file From 647756008ea35a64c0928d104b19eeb00ed90a5c Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 03:14:33 +0900 Subject: [PATCH 09/36] feat(kakaotalk): Add patch to remove shop tab from the bottom navigation bar --- patches/api/patches.api | 4 ++ .../kakaotalk/misc/RemoveShopTabPatch.kt | 45 +++++++++++++++++++ .../fingerprints/RemoveShopTabFingerprint.kt | 35 +++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 5d785ffd1..c22dfd05d 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -257,6 +257,10 @@ public final class app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPat public static final fun getRemove300PlusLimitOpenChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +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/signature/VerifyingSignaturePatchKt { public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt new file mode 100644 index 000000000..34f168edd --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.kakaotalk.misc + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.Package +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.misc.fingerprints.removeShopTabFingerprint +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.builder.instruction.BuilderInstruction35c +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +val removeShopTabPatch = bytecodePatch( + name = "Remove shop tab", + description = "Removes the shop tab from the bottom navigation bar.", +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + val method = removeShopTabFingerprint.method + val insns = method.instructions + + val matches = insns.mapIndexedNotNull { idx, inst -> + if (inst is BuilderInstruction35c + && inst.opcode == Opcode.INVOKE_VIRTUAL + && (inst.getReference()?.name == "add") + ) { + val prev = insns.getOrNull(idx - 1) as? BuilderInstruction21c + val fldName = (prev?.reference as? FieldReference)?.name + if (fldName == "SHOPPING_TAB" || fldName == "CALL_TAB") { + Pair(idx - 1, idx) + } else null + } else null + } + + matches + .sortedByDescending { it.second } + .forEach { (loadIdx, invokeIdx) -> + method.removeInstruction(invokeIdx) + method.removeInstruction(loadIdx) + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt new file mode 100644 index 000000000..6418a054d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.kakaotalk.misc.fingerprints + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.fingerprint +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.StringReference + +internal val removeShopTabFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters() + strings("webtoon") +// custom { method, classDef -> +// !method.toMutable().instructions.any { +// it.opcode == Opcode.CONST_STRING && !it.getReference()!!.string.contains("webtoon") +// } +// } + opcodes( + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.SGET_OBJECT, + Opcode.GOTO, + ) +} \ No newline at end of file From 49521fb70259d3033c821974bb961b187f757f4e Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 16:45:15 +0900 Subject: [PATCH 10/36] feat(kakaotalk): Add patch to force enable emoticon plus feature --- patches/api/patches.api | 4 ++++ .../emoticon/ForceEnableEmoticonPlusPatch.kt | 24 +++++++++++++++++++ .../ForceEnableEmoticonPlusFingerprint.kt | 22 +++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index c22dfd05d..1c967bb33 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -257,6 +257,10 @@ public final class app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPat public static final fun getRemove300PlusLimitOpenChatRoomPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatchKt { + public static final fun getForceEnableEmoticonPlusPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/misc/RemoveShopTabPatchKt { public static final fun getRemoveShopTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt new file mode 100644 index 000000000..29268a064 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.kakaotalk.emoticon + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.Package +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.emoticon.fingerprints.forceEnableEmoticonPlusFingerprint + +@Suppress("unused") +val forceEnableEmoticonPlusPatch = bytecodePatch( + name = "Force enable emoticon plus feature", + description = "Force enable emoticon plus feature (Unpurchased emoticon can be sent once per day)", +) { + compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + + execute { + forceEnableEmoticonPlusFingerprint.method.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt new file mode 100644 index 000000000..ab6fc8365 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.kakaotalk.emoticon.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val forceEnableEmoticonPlusFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) + returns("Z") + parameters() + strings("emoticonPlusMe") + opcodes( + Opcode.SGET_OBJECT, + Opcode.IF_EQZ, + Opcode.IGET_BOOLEAN, + Opcode.RETURN, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_4, + Opcode.THROW, + ) +} \ No newline at end of file From f1a87a28f26d2466bb4303a08c33b0ae3e06dcd8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 17:21:51 +0900 Subject: [PATCH 11/36] feat(kakaotalk): Remove unused custom filtering logic from shop tab removal patch --- .../kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt index 6418a054d..8b92bb317 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt @@ -13,11 +13,6 @@ internal val removeShopTabFingerprint = fingerprint { returns("V") parameters() strings("webtoon") -// custom { method, classDef -> -// !method.toMutable().instructions.any { -// it.opcode == Opcode.CONST_STRING && !it.getReference()!!.string.contains("webtoon") -// } -// } opcodes( Opcode.IGET_OBJECT, Opcode.INVOKE_VIRTUAL, From 5b55077ccc613a2c8a710d8c62a91485a264a85d Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sun, 4 May 2025 17:22:49 +0900 Subject: [PATCH 12/36] feat(kakaotalk): Clean up RemoveShopTabFingerprint by removing unused imports --- .../kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt index 8b92bb317..1fa6bb112 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt @@ -1,12 +1,8 @@ package app.revanced.patches.kakaotalk.misc.fingerprints -import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.fingerprint -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.util.getReference import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.reference.StringReference internal val removeShopTabFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) From cb23e62f486e747dceba37fc36f23e4b7b189fc4 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 13:48:37 +0900 Subject: [PATCH 13/36] feat(kakaotalk): Update compatible version for multiple patches to 25.4.0 --- .../patches/kakaotalk/changemodel/ChangeModelPatch.kt | 2 +- .../revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt | 2 +- .../patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt | 4 ++-- .../kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt | 2 +- .../app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt | 2 +- .../patches/kakaotalk/signature/VerifyingSignaturePatch.kt | 2 +- .../patches/kakaotalk/versioninfo/VersionInfoPatch.kt | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt index 87bdfd1d7..23faf46d0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt @@ -15,7 +15,7 @@ val changeModelPatch = bytecodePatch( "model", "SM-X926N" ) - compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { changeModelFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt index 49ddde073..27202e801 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt @@ -14,7 +14,7 @@ val remove99ClampPatch = bytecodePatch( name = "Disable 99 unread limit", description = "Skip the 99-cap so unread count shows full value" ) { - compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { val method = remove99ClampFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt index 47d5f3c34..cf6f38d26 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt @@ -15,7 +15,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(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { val method = remove300PlusLimitBaseChatRoomFingerprint.method @@ -41,7 +41,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(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { val method = remove300PlusLimitOpenChatRoomFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt index 29268a064..088c434a0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt @@ -10,7 +10,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(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { forceEnableEmoticonPlusFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt index 34f168edd..afefd00a8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt @@ -16,7 +16,7 @@ val removeShopTabPatch = bytecodePatch( name = "Remove shop tab", description = "Removes the shop tab from the bottom navigation bar.", ) { - compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { val method = removeShopTabFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt index 926b0767b..3e643c665 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt @@ -10,7 +10,7 @@ val verifyingSignaturePatch = bytecodePatch( name = "Disable verifying signature", description = "Disables the signature verification check that prevents the app from running.", ) { - compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { verifyingSignatureFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index 22d1f46df..e5d3a13ba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -17,7 +17,7 @@ val versionInfoPatch = bytecodePatch( name = "Version info patch", description = "Patches the version info to include '(ReVanced)' in the version string.", ) { - compatibleWith(Package("com.kakao.talk", setOf("25.3.5"))) + compatibleWith("com.kakao.talk"("25.4.0")) execute { val runPatch: (Fingerprint) -> Unit = { From 8ade9e88023566c34e7799ab90b19e8f78590333 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 13:48:43 +0900 Subject: [PATCH 14/36] feat(kakaotalk): Add Ghost Mode patch to hide typing status --- patches/api/patches.api | 4 +++ .../patches/kakaotalk/ghost/GhostModePatch.kt | 25 +++++++++++++++ .../fingerprints/GhostModeFingerprint.kt | 32 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 1c967bb33..d65cc263a 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -261,6 +261,10 @@ public final class app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPl public static final fun getForceEnableEmoticonPlusPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ghost/GhostModePatchKt { + public static final fun getGhostMode ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/misc/RemoveShopTabPatchKt { public static final fun getRemoveShopTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt new file mode 100644 index 000000000..4edad69f2 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.kakaotalk.ghost + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ghost.fingerprints.ghostModeFingerprint + +@Suppress("unused") +val ghostMode = bytecodePatch( + name = "Ghost Mode", + description = "Don't expose your typing status to the other party.", +) { + compatibleWith("com.kakao.talk"("25.4.0")) + + execute { + val method = ghostModeFingerprint.method + + method.addInstructions( + 0, + """ + sget-object v0, Lnk0/C;->a:Lnk0/C; + return-object v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt new file mode 100644 index 000000000..98fe2fe34 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt @@ -0,0 +1,32 @@ +package app.revanced.patches.kakaotalk.ghost.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val ghostModeFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Ljava/lang/Object;") + parameters("Ljava/lang/Object;") + strings( + "method", + "chatId", + "type", + "linkId" + ) + opcodes( + Opcode.SGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.IGET_WIDE, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_WIDE, + Opcode.CONST_WIDE_16, + Opcode.CMP_LONG, + Opcode.IF_GEZ, + Opcode.GOTO + ) +} \ No newline at end of file From b9838f80fdd7cd938ae57d59a781e6f9963abc34 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 17:47:36 +0900 Subject: [PATCH 15/36] feat(kakaotalk): Add KotlinUnitInstanceFingerprint for ghost mode patch --- .../KotlinUnitInstanceFingerprint.kt | 19 +++++++++++++++++++ .../patches/kakaotalk/ghost/GhostModePatch.kt | 8 +++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/common/fingerprints/KotlinUnitInstanceFingerprint.kt diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/common/fingerprints/KotlinUnitInstanceFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/common/fingerprints/KotlinUnitInstanceFingerprint.kt new file mode 100644 index 000000000..f1c381942 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/common/fingerprints/KotlinUnitInstanceFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.kakaotalk.common.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val kotlinUnitInstanceFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() + returns("Ljava/lang/String;") + strings("kotlin.Unit") + opcodes( + Opcode.CONST_STRING, + Opcode.RETURN_OBJECT + ) + custom { method, classDef -> + method.name == "toString" + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt index 4edad69f2..a8ee5793a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -2,6 +2,7 @@ package app.revanced.patches.kakaotalk.ghost import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint import app.revanced.patches.kakaotalk.ghost.fingerprints.ghostModeFingerprint @Suppress("unused") @@ -12,12 +13,17 @@ val ghostMode = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.0")) execute { + val findUnit = kotlinUnitInstanceFingerprint.method + val unitClass = findUnit.definingClass + val method = ghostModeFingerprint.method + // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. + // If it changes, we need to fix it method.addInstructions( 0, """ - sget-object v0, Lnk0/C;->a:Lnk0/C; + sget-object v0, $unitClass->a:$unitClass; return-object v0 """.trimIndent() ) From afdf66dab4d587e8abf2a4534ad877d50662dd20 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 17:49:00 +0900 Subject: [PATCH 16/36] feat(kakaotalk): Rename signature package to integrity for clarity --- .../{signature => integrity}/VerifyingSignaturePatch.kt | 5 ++--- .../fingerprints/VerifyingSignatureFingerprint.kt | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) rename patches/src/main/kotlin/app/revanced/patches/kakaotalk/{signature => integrity}/VerifyingSignaturePatch.kt (80%) rename patches/src/main/kotlin/app/revanced/patches/kakaotalk/{signature => integrity}/fingerprints/VerifyingSignatureFingerprint.kt (82%) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt similarity index 80% rename from patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt rename to patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt index 3e643c665..60987d8c5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt @@ -1,9 +1,8 @@ -package app.revanced.patches.kakaotalk.signature +package app.revanced.patches.kakaotalk.integrity import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.signature.fingerprints.verifyingSignatureFingerprint +import app.revanced.patches.kakaotalk.integrity.fingerprints.verifyingSignatureFingerprint @Suppress("unused") val verifyingSignaturePatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/VerifyingSignatureFingerprint.kt similarity index 82% rename from patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt rename to patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/VerifyingSignatureFingerprint.kt index d5bfb8aa5..bac314ebf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/signature/fingerprints/VerifyingSignatureFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/VerifyingSignatureFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.kakaotalk.signature.fingerprints +package app.revanced.patches.kakaotalk.integrity.fingerprints import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags From b1c9b5e47cde3aa296a4b4bfc52032937c3a80d8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 17:59:50 +0900 Subject: [PATCH 17/36] feat(kakaotalk): Fix syntax in GhostModePatch for instruction clarity --- .../app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt index a8ee5793a..1ddbcc816 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -23,7 +23,7 @@ val ghostMode = bytecodePatch( method.addInstructions( 0, """ - sget-object v0, $unitClass->a:$unitClass; + sget-object v0, $unitClass->a:$unitClass return-object v0 """.trimIndent() ) From e5c7a88550a6f9c4e566fc5a11f877e77b0731c6 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 14 May 2025 17:59:57 +0900 Subject: [PATCH 18/36] feat(kakaotalk): Add bypass request checksums patch to prevent checksum verification --- patches/api/patches.api | 10 ++++-- .../BypassRequestChecksumsFingerprint.kt | 31 ++++++++++++++++ .../BypassRequestChecksumsFingerprint.kt | 36 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index d65cc263a..b34739e7c 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -265,14 +265,18 @@ public final class app/revanced/patches/kakaotalk/ghost/GhostModePatchKt { public static final fun getGhostMode ()Lapp/revanced/patcher/patch/BytecodePatch; } -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/integrity/BypassRequestChecksumsFingerprintKt { + public static final fun getBypassRequestChecksumPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/kakaotalk/signature/VerifyingSignaturePatchKt { +public final class app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatchKt { public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +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/versioninfo/VersionInfoPatchKt { public static final fun getVersionInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt new file mode 100644 index 000000000..a44300f59 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.kakaotalk.integrity + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint +import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassRequestChecksumsFingerprint + +@Suppress("unused") +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.0")) + + execute { + val findUnit = kotlinUnitInstanceFingerprint.method + val unitClass = findUnit.definingClass + + val method = bypassRequestChecksumsFingerprint.method + + // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. + // If it changes, we need to fix it + method.addInstructions( + 0, + """ + sget-object v0, $unitClass->a:$unitClass + return-object v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt new file mode 100644 index 000000000..6e9190a52 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt @@ -0,0 +1,36 @@ +package app.revanced.patches.kakaotalk.integrity.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val bypassRequestChecksumsFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Ljava/lang/Object;") + strings( + "context" + ) + opcodes( + Opcode.INSTANCE_OF, + Opcode.IF_EQZ, + Opcode.MOVE_OBJECT, + Opcode.CHECK_CAST, + Opcode.IGET, + Opcode.CONST_HIGH16, + Opcode.AND_INT, + Opcode.IF_EQZ, + Opcode.SUB_INT_2ADDR, + Opcode.IPUT, + Opcode.GOTO, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IF_NE, + Opcode.INVOKE_STATIC, + Opcode.GOTO, + ) +} \ No newline at end of file From 92b54e85a89be01ad8cfc24b94b1c017e39fe602 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 17 May 2025 18:48:32 +0900 Subject: [PATCH 19/36] feat(kakaotalk): Update compatibility to version 25.4.1 for multiple patches --- .../patches/kakaotalk/changemodel/ChangeModelPatch.kt | 3 +-- .../revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt | 3 +-- .../patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt | 5 ++--- .../kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt | 3 +-- .../app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt | 2 +- .../kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt | 2 +- .../patches/kakaotalk/integrity/VerifyingSignaturePatch.kt | 2 +- .../revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt | 3 +-- .../patches/kakaotalk/versioninfo/VersionInfoPatch.kt | 3 +-- 9 files changed, 10 insertions(+), 16 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt index 23faf46d0..c82fbdeed 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt @@ -1,7 +1,6 @@ package app.revanced.patches.kakaotalk.changemodel import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.stringOption import app.revanced.patches.kakaotalk.changemodel.fingerprints.changeModelFingerprint @@ -15,7 +14,7 @@ val changeModelPatch = bytecodePatch( "model", "SM-X926N" ) - compatibleWith("com.kakao.talk"("25.4.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { changeModelFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt index 27202e801..cf8a7886b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt @@ -3,7 +3,6 @@ package app.revanced.patches.kakaotalk.chatlog import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.Package import app.revanced.patches.kakaotalk.chatlog.fingerprints.remove99ClampFingerprint import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t @@ -14,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val method = remove99ClampFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt index cf6f38d26..a745a65b3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt @@ -3,7 +3,6 @@ package app.revanced.patches.kakaotalk.chatroom import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.patch.Package import app.revanced.patches.kakaotalk.chatroom.fingerprints.remove300PlusLimitBaseChatRoomFingerprint import app.revanced.patches.kakaotalk.chatroom.fingerprints.remove300PlusLimitOpenChatRoomFingerprint import com.android.tools.smali.dexlib2.Opcode @@ -15,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val method = remove300PlusLimitBaseChatRoomFingerprint.method @@ -41,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val method = remove300PlusLimitOpenChatRoomFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt index 088c434a0..ce08b23b0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt @@ -1,7 +1,6 @@ package app.revanced.patches.kakaotalk.emoticon import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.emoticon.fingerprints.forceEnableEmoticonPlusFingerprint @@ -10,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { forceEnableEmoticonPlusFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt index 1ddbcc816..e52316264 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val findUnit = kotlinUnitInstanceFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt index a44300f59..99323a7ba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt @@ -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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val findUnit = kotlinUnitInstanceFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt index 60987d8c5..88817c842 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt @@ -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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { verifyingSignatureFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt index afefd00a8..a63450b6b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt @@ -2,7 +2,6 @@ package app.revanced.patches.kakaotalk.misc import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.misc.fingerprints.removeShopTabFingerprint import app.revanced.util.getReference @@ -16,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val method = removeShopTabFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index e5d3a13ba..6d3a500a7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -3,7 +3,6 @@ package app.revanced.patches.kakaotalk.versioninfo import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.patch.Package import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.versioninfo.fingerprints.versionInfoFingerprint import app.revanced.patches.kakaotalk.versioninfo.fingerprints.versionInfoPreviewFingerprint @@ -17,7 +16,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.0")) + compatibleWith("com.kakao.talk"("25.4.1")) execute { val runPatch: (Fingerprint) -> Unit = { From b2f27a66c3ccf560d8989424bb5134c7b93ca2fc Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 17 May 2025 22:10:42 +0900 Subject: [PATCH 20/36] feat(kakaotalk): Add additional opcodes to GhostModeFingerprint for enhanced functionality For support 25.4.1 --- .../kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt index 98fe2fe34..f2ae38496 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt @@ -17,6 +17,12 @@ internal val ghostModeFingerprint = fingerprint { opcodes( Opcode.SGET_OBJECT, Opcode.INVOKE_STATIC, + Opcode.SGET_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT_OBJECT, Opcode.NEW_INSTANCE, From 610ebf37111cab17b501d33b68ebb4bfcc4de170 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 17 May 2025 22:10:47 +0900 Subject: [PATCH 21/36] feat(kakaotalk): Add additional opcodes to GhostModeFingerprint for enhanced functionality For support 25.4.1 --- patches/api/patches.api | 4 ++ .../kakaotalk/ads/RemoveBizBoardPatch.kt | 39 +++++++++++++++++++ .../fingerprints/RemoveBizBoardFingerprint.kt | 27 +++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index b34739e7c..6829e9814 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -244,6 +244,10 @@ public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt { public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatchKt { + public static final fun getRemoveBizBoardPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/changemodel/ChangeModelPatchKt { public static final fun getChangeModelPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt new file mode 100644 index 000000000..36807b610 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.removeBizBoardFingerprint + +@Suppress("unused") +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.1")) + + execute { + val method = removeBizBoardFingerprint.method + + method.addInstructions( + 0, + """ + const/4 v0, 0x0 + const/4 v1, 0x0 + invoke-virtual {p0, v0, v1}, Landroid/widget/FrameLayout;->setMeasuredDimension(II)V + + invoke-virtual {p0}, Landroid/widget/FrameLayout;->getVisibility()I + move-result v0 + + const/16 v1, 0x8 + + if-eq v0, v1, :skip_set_visibility + + invoke-virtual {p0, v1}, Landroid/widget/FrameLayout;->setVisibility(I)V + + :skip_set_visibility + + return-void + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt new file mode 100644 index 000000000..10e0e1786 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt @@ -0,0 +1,27 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val removeBizBoardFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC) + returns("V") + parameters("I", "I") + opcodes( + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.INT_TO_FLOAT, + Opcode.CONST, + Opcode.MUL_FLOAT_2ADDR, + Opcode.FLOAT_TO_INT, + Opcode.IGET, + Opcode.IF_LE, + Opcode.MOVE, + Opcode.CONST_HIGH16, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.INVOKE_SUPER, + Opcode.RETURN_VOID + ) +} \ No newline at end of file From ae527462e37da4bb3fefe4755f7e4d0ae2f4ef9a Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Sat, 17 May 2025 22:19:59 +0900 Subject: [PATCH 22/36] fix(kakaotalk): fix RemoveBizBoardPatch I simply deleted the bizboard, but there is an issue with having 2 divider, especially on the friends tab. But it's deleted, so let's move on for now --- .../patches/kakaotalk/ads/RemoveBizBoardPatch.kt | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt index 36807b610..597067464 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt @@ -18,19 +18,10 @@ val removeBizBoardPatch = bytecodePatch( 0, """ const/4 v0, 0x0 - const/4 v1, 0x0 - invoke-virtual {p0, v0, v1}, Landroid/widget/FrameLayout;->setMeasuredDimension(II)V + invoke-virtual {p0, v0, v0}, Landroid/view/View;->setMeasuredDimension(II)V - invoke-virtual {p0}, Landroid/widget/FrameLayout;->getVisibility()I - move-result v0 - - const/16 v1, 0x8 - - if-eq v0, v1, :skip_set_visibility - - invoke-virtual {p0, v1}, Landroid/widget/FrameLayout;->setVisibility(I)V - - :skip_set_visibility + const/16 v0, 0x8 + invoke-virtual {p0, v0}, Landroid/view/View;->setVisibility(I)V return-void """.trimIndent() From 2ee3f69c4fcf662c76df7c74fd3cd97219fade4a Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Mon, 19 May 2025 02:11:00 +0900 Subject: [PATCH 23/36] feat(kakaotalk): update compatibility to version 25.4.2 fix some fingerprint at BypassRequestChecksumsFingerprint.kt --- .../app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt | 2 +- .../patches/kakaotalk/changemodel/ChangeModelPatch.kt | 2 +- .../revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt | 2 +- .../patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt | 4 ++-- .../kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt | 2 +- .../app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt | 2 +- .../kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt | 2 +- .../patches/kakaotalk/integrity/VerifyingSignaturePatch.kt | 2 +- .../fingerprints/BypassRequestChecksumsFingerprint.kt | 2 +- .../app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt | 2 +- .../patches/kakaotalk/versioninfo/VersionInfoPatch.kt | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt index 597067464..2695d6749 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val method = removeBizBoardFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt index c82fbdeed..75a285eba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/changemodel/ChangeModelPatch.kt @@ -14,7 +14,7 @@ val changeModelPatch = bytecodePatch( "model", "SM-X926N" ) - compatibleWith("com.kakao.talk"("25.4.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { changeModelFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt index cf8a7886b..1e9fdebc5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val method = remove99ClampFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt index a745a65b3..c0a92d43b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val method = remove300PlusLimitBaseChatRoomFingerprint.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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val method = remove300PlusLimitOpenChatRoomFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt index ce08b23b0..5c4c10ebf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { forceEnableEmoticonPlusFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt index e52316264..4ea5f1deb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val findUnit = kotlinUnitInstanceFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt index 99323a7ba..b59a1b8b7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val findUnit = kotlinUnitInstanceFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt index 88817c842..21527ddba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { verifyingSignatureFingerprint.method.addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt index 6e9190a52..ac9820864 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt @@ -11,6 +11,7 @@ internal val bypassRequestChecksumsFingerprint = fingerprint { "context" ) opcodes( + Opcode.CONST_4, Opcode.INSTANCE_OF, Opcode.IF_EQZ, Opcode.MOVE_OBJECT, @@ -27,7 +28,6 @@ internal val bypassRequestChecksumsFingerprint = fingerprint { Opcode.IGET_OBJECT, Opcode.SGET_OBJECT, Opcode.IGET, - Opcode.CONST_4, Opcode.IF_EQZ, Opcode.IF_NE, Opcode.INVOKE_STATIC, diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt index a63450b6b..7c50ab34c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt @@ -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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val method = removeShopTabFingerprint.method diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index 6d3a500a7..eb08dae8f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -16,7 +16,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.1")) + compatibleWith("com.kakao.talk"("25.4.2")) execute { val runPatch: (Fingerprint) -> Unit = { From 50b735da19e75b7090e0319c6b6b0e5a3f173b12 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Mon, 19 May 2025 19:24:30 +0900 Subject: [PATCH 24/36] refactor(kakaotalk): rename BypassRequestChecksumsFingerprint to BypassRequestChecksumsPatch for clarity --- patches/api/patches.api | 2 +- ...stChecksumsFingerprint.kt => BypassRequestChecksumsPatch.kt} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/{BypassRequestChecksumsFingerprint.kt => BypassRequestChecksumsPatch.kt} (100%) diff --git a/patches/api/patches.api b/patches/api/patches.api index 6829e9814..ce378469b 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -269,7 +269,7 @@ public final class app/revanced/patches/kakaotalk/ghost/GhostModePatchKt { public static final fun getGhostMode ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprintKt { +public final class app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatchKt { public static final fun getBypassRequestChecksumPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt similarity index 100% rename from patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsFingerprint.kt rename to patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt From 60a02aa90a46a6b1a0f8dfb434643dc7b84549c2 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Mon, 19 May 2025 20:23:04 +0900 Subject: [PATCH 25/36] feat(kakaotalk): add bypass moat check patch and associated fingerprints It's up, but it's not working, need to check further --- patches/api/patches.api | 4 + .../integrity/BypassMoatCheckPatch.kt | 80 +++++++++++++++++++ .../BypassMoatCheckFingerprint.kt | 65 +++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index ce378469b..8771e8071 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -269,6 +269,10 @@ public final class app/revanced/patches/kakaotalk/ghost/GhostModePatchKt { public static final fun getGhostMode ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatchKt { + public static final fun getBypassMoatCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatchKt { public static final fun getBypassRequestChecksumPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt new file mode 100644 index 000000000..c5e35e46d --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt @@ -0,0 +1,80 @@ +package app.revanced.patches.kakaotalk.integrity + +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassMoatCheckFingerprintOne +import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassMoatCheckFingerprintTwo +import app.revanced.patches.kakaotalk.integrity.fingerprints.postprocessMoatCheckFailedFingerprint +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.builder.instruction.BuilderInstruction35c +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.immutable.reference.ImmutableFieldReference + +@Suppress("unused") +val bypassMoatCheckPatch = bytecodePatch( + name = "Bypass Moat check", + description = "Bypass Moat check that prevents the app from running.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + val patch: (Fingerprint) -> Unit = { + val method = it.method + val insns = method.instructions + + insns + .filterIsInstance() + .filter { inst -> + inst.opcode == Opcode.SGET_OBJECT && + inst.reference == ImmutableFieldReference( + "Ljava/lang/Boolean;", "FALSE", "Ljava/lang/Boolean;" + ) + } + .forEach { inst -> + println("Replacing ${inst.reference} with TRUE") + val idx = insns.indexOf(inst) + method.replaceInstruction( + idx, + BuilderInstruction21c( + Opcode.SGET_OBJECT, + inst.registerA, + ImmutableFieldReference( + "Ljava/lang/Boolean;", "TRUE", "Ljava/lang/Boolean;" + ) + ) + ) + } + + val postprocessMoatCheckFailedMethod = postprocessMoatCheckFailedFingerprint.method + + val toRemove = mutableListOf() + insns.forEachIndexed { i, inst -> + if (inst is BuilderInstruction35c && + inst.opcode == Opcode.INVOKE_VIRTUAL && + (inst.getReference()?.name == postprocessMoatCheckFailedMethod.name) && + inst.getReference()?.definingClass == + "Lcom/kakaopay/shared/security/moat/PaySecurityWorker;" + ) { + for (j in 0..3) { + insns.getOrNull(i + j)?.let { toRemove += it } + } + } + } + toRemove + .distinct() + .sortedByDescending { insns.indexOf(it) } + .forEach { inst -> + method.removeInstruction(insns.indexOf(inst)) + } + } + + patch(bypassMoatCheckFingerprintOne) + patch(bypassMoatCheckFingerprintTwo) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt new file mode 100644 index 000000000..7692cd653 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt @@ -0,0 +1,65 @@ +package app.revanced.patches.kakaotalk.integrity.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val bypassMoatCheckFingerprintOne = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;", "Ljava/lang/Object;", "Ljava/lang/Object;") + returns("Ljava/lang/Object;") + strings("detectResult", "", "") + opcodes( + Opcode.CHECK_CAST, + Opcode.CHECK_CAST, + Opcode.CHECK_CAST, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.SGET_OBJECT, + Opcode.SGET_OBJECT, + Opcode.CONST_4, + Opcode.IF_NE, + Opcode.CHECK_CAST, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + ) +} + +internal val bypassMoatCheckFingerprintTwo = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;", "Ljava/lang/Object;", "Ljava/lang/Object;") + returns("Ljava/lang/Object;") + strings("detectResult", "", "") + opcodes( + Opcode.CHECK_CAST, + Opcode.CHECK_CAST, + Opcode.CHECK_CAST, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CHECK_CAST, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.SGET_OBJECT, + Opcode.IF_EQZ, + ) +} + +internal val postprocessMoatCheckFailedFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Lcom/kakaopay/kpsd/moat/sdk/MoatFlag;", "Ljava/lang/String;", "[Ljava/lang/String;") + strings("msg_title", "msg_body", "OUTPUT_KEY_FAILURE_TITLE", "OUTPUT_KEY_FAILURE_REASON", "ADS_BLOCK은 result message를 사용해야 합니다.", "let(...)", "OUTPUT_KEY_FAILURE_TYPE", "OUTPUT_KEY_PACKAGE_NAMES") +} \ No newline at end of file From 9b9679a3aa0f19e7b4c7aff7b129074001b43596 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Mon, 19 May 2025 20:48:27 +0900 Subject: [PATCH 26/36] refactor(kakaotalk): remove debug print statement from BypassMoatCheckPatch --- .../revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt index c5e35e46d..bc5b107bc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt @@ -37,7 +37,6 @@ val bypassMoatCheckPatch = bytecodePatch( ) } .forEach { inst -> - println("Replacing ${inst.reference} with TRUE") val idx = insns.indexOf(inst) method.replaceInstruction( idx, From 57f3a92189a5b7a7fa9cd4ac596300b480af8fd3 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Mon, 19 May 2025 20:49:23 +0900 Subject: [PATCH 27/36] feat(kakaotalk): add patch and fingerprint to remove OpenLink chat room list ad --- patches/api/patches.api | 4 +++ .../ads/RemoveOlkChatRoomListAdPatch.kt | 31 +++++++++++++++++++ .../RemoveOlkChatRoomListAdFingerprint.kt | 25 +++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 8771e8071..bf1e3e72e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -248,6 +248,10 @@ public final class app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatchKt { public static final fun getRemoveBizBoardPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatchKt { + public static final fun getRemoveOlkChatRoomListAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/changemodel/ChangeModelPatchKt { public static final fun getChangeModelPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt new file mode 100644 index 000000000..fa2df6351 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.removeOlkChatRoomListAdFingerprint +import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint + +@Suppress("unused") +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")) + + execute { + val findUnit = kotlinUnitInstanceFingerprint.method + val unitClass = findUnit.definingClass + + val method = removeOlkChatRoomListAdFingerprint.method + + // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. + // If it changes, we need to fix it + method.addInstructions( + 0, + """ + sget-object v0, $unitClass->a:$unitClass + return-object v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt new file mode 100644 index 000000000..f424d383f --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt @@ -0,0 +1,25 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val removeOlkChatRoomListAdFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;") + returns("Ljava/lang/Object;") + strings("list", "key_ad_info", "") + opcodes( + Opcode.MOVE_OBJECT_FROM16, + Opcode.SGET_OBJECT, + Opcode.INVOKE_STATIC_RANGE, + Opcode.SGET_BOOLEAN, + Opcode.IGET_OBJECT, + Opcode.IGET, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.CONST_STRING, + Opcode.IGET_OBJECT, + Opcode.IF_EQZ, + ) +} \ No newline at end of file From 9dd4a5e1bc5d15ea8645d21abbfdcb97487c120e Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Tue, 20 May 2025 23:17:01 +0900 Subject: [PATCH 28/36] feat(kakaotalk): add patch and fingerprint to remove focus ad --- patches/api/patches.api | 4 ++++ .../kakaotalk/ads/RemoveFocusAdPatch.kt | 22 +++++++++++++++++++ .../fingerprints/RemoveFocusAdFingerprint.kt | 22 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index bf1e3e72e..bbbd42e2d 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -248,6 +248,10 @@ public final class app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatchKt { public static final fun getRemoveBizBoardPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatchKt { + public static final fun getRemoveFocusAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatchKt { public static final fun getRemoveOlkChatRoomListAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt new file mode 100644 index 000000000..79f77cf07 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.removeFocusAdFingerprint + +val removeFocusAdPatch = bytecodePatch( + name = "Remove focus ad", + description = "Removes the focus ad from the app.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + removeFocusAdFingerprint.method.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt new file mode 100644 index 000000000..c1840d920 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val removeFocusAdFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC) + parameters("Lcom/kakao/adfit/ads/focus/FocusAdLoader\$OnAdLoadListener;") + returns("Z") + strings("listener", " owner is destroyed.", " loading is already started.", "Request Focus AD", " loading is started.", "Focus ad is cached. [id = ") + opcodes( + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.CONST_4, + Opcode.IF_NE, + ) +} \ No newline at end of file From dd45ddde80d894cde85763a2cfe1fa6cd56838b6 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Tue, 20 May 2025 23:22:31 +0900 Subject: [PATCH 29/36] feat(kakaotalk): enhance version info patch to include build timestamp --- .../kakaotalk/versioninfo/VersionInfoPatch.kt | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt index eb08dae8f..5cfc80f4d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatch.kt @@ -10,6 +10,7 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.immutable.reference.ImmutableStringReference +import java.time.format.DateTimeFormatter @Suppress("unused") val versionInfoPatch = bytecodePatch( @@ -19,8 +20,8 @@ val versionInfoPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val runPatch: (Fingerprint) -> Unit = { - val versionInfo = it.method.instructions + val runPatch: (Fingerprint, Boolean) -> Unit = { fp, inDetail -> + val versionInfo = fp.method.instructions .filterIsInstance() .first { inst -> inst.opcode == Opcode.CONST_STRING @@ -28,20 +29,29 @@ val versionInfoPatch = bytecodePatch( val versionString = (versionInfo.reference as StringReference).string - it.method + fp.method .replaceInstruction( versionInfo.location.index, BuilderInstruction21c( Opcode.CONST_STRING, versionInfo.registerA, ImmutableStringReference( - "$versionString (ReVanced)" + if (inDetail) { + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + "$versionString (ReVanced)\nBuild at: ${ + formatter.format( + java.time.LocalDateTime.now() + ) + }" + } else { + "$versionString (ReVanced)" + } ) ) ) } - runPatch(versionInfoFingerprint) - runPatch(versionInfoPreviewFingerprint) + runPatch(versionInfoFingerprint, true) + runPatch(versionInfoPreviewFingerprint, false) } } \ No newline at end of file From 3f868cd995a278d4c9c3e93d2d5a15f42bb268b8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 21 May 2025 02:45:44 +0900 Subject: [PATCH 30/36] feat(kakaotalk): add patch and fingerprint to remove More tab ad --- patches/api/patches.api | 4 ++ .../kakaotalk/ads/RemoveMoreTabAdPatch.kt | 45 ++++++++++++++++++ .../RemoveMoreTabAdFingerprint.kt | 46 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index bbbd42e2d..89fd4ba71 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -252,6 +252,10 @@ public final class app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatchKt { public static final fun getRemoveFocusAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatchKt { + public static final fun getRemoveMoreTabAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatchKt { public static final fun getRemoveOlkChatRoomListAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt new file mode 100644 index 000000000..fd03e92fd --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.adBigUIModelFingerprint +import app.revanced.patches.kakaotalk.ads.fingerprints.addSectionToMoreTabUIFingerprint +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +val removeMoreTabAdPatch = bytecodePatch( + name = "Remove More tab ad", + description = "Removes the ad from the More tab.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + val addSectionToMoreTabUIMethod = addSectionToMoreTabUIFingerprint.method + val addSectionToMoreTabUIInsns = addSectionToMoreTabUIMethod.instructions + + val adBigUIModelClass = adBigUIModelFingerprint.method.definingClass + + val matches = addSectionToMoreTabUIInsns.mapIndexedNotNull { idx, inst -> + if (inst is BuilderInstruction35c + && inst.opcode == Opcode.INVOKE_VIRTUAL + && (inst.getReference()?.name == "add") + ) { + val prev = addSectionToMoreTabUIInsns.getOrNull(idx - 1) as? BuilderInstruction35c + val ref = (prev?.getReference()) + if (ref?.definingClass == adBigUIModelClass) { + Pair(idx - 1, idx) + } else null + } else null + } + + matches + .sortedByDescending { it.second } + .forEach { (loadIdx, invokeIdx) -> + addSectionToMoreTabUIMethod.removeInstruction(invokeIdx) + addSectionToMoreTabUIMethod.removeInstruction(loadIdx) + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt new file mode 100644 index 000000000..0a1eb6012 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveMoreTabAdFingerprint.kt @@ -0,0 +1,46 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val addSectionToMoreTabUIFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Ljava/lang/Object;") + returns("Ljava/lang/Object;") + strings( + "call to \'resume\' before \'invoke\' with coroutine", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.KakaoPayUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WalletUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WeatherUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.KakaoNowUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.TalkManualUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.ServiceGroupUiModel", + "null cannot be cast to non-null type com.kakao.talk.moretab.ui.model.WalletBannerUiModel", + "null cannot be cast to non-null type kotlin.Boolean", + ) + opcodes( + Opcode.SGET_OBJECT, + Opcode.IGET, + Opcode.CONST_4, + Opcode.IF_EQZ, + ) +} + +internal val adBigUIModelFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters() + returns("Ljava/lang/String;") + strings( + "AdBig(uiModel=", + ) + opcodes( + Opcode.NEW_INSTANCE, + Opcode.CONST_STRING, + Opcode.INVOKE_DIRECT, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.CONST_STRING, + ) + custom { method, classDef -> method.name == "toString" } +} \ No newline at end of file From 76dcd4c479848bb6520cd99e7c13b33d0ec87eb8 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 21 May 2025 02:55:35 +0900 Subject: [PATCH 31/36] feat(kakaotalk): rename fingerprint variables for clarity and consistency Going forward, fingerprints will follow the filename of the corresponding patch, but will name the variables that are finely fingerprinted after the functionality of the method for the intended target. This is to promote reusability, and hopefully increase maintainability in the future. --- .../revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt | 4 ++-- .../revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt | 4 ++-- .../patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt | 4 ++-- .../ads/fingerprints/RemoveBizBoardFingerprint.kt | 2 +- .../ads/fingerprints/RemoveFocusAdFingerprint.kt | 2 +- .../fingerprints/RemoveOlkChatRoomListAdFingerprint.kt | 2 +- .../patches/kakaotalk/chatlog/Remove99ClampPatch.kt | 4 ++-- .../chatlog/fingerprints/Remove99ClampFingerprint.kt | 2 +- .../patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt | 8 ++++---- .../fingerprints/Remove300PlusLimitFingerprint.kt | 4 ++-- .../kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt | 4 ++-- .../fingerprints/ForceEnableEmoticonPlusFingerprint.kt | 2 +- .../revanced/patches/kakaotalk/ghost/GhostModePatch.kt | 4 ++-- .../kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt | 2 +- .../patches/kakaotalk/integrity/BypassMoatCheckPatch.kt | 8 ++++---- .../kakaotalk/integrity/BypassRequestChecksumsPatch.kt | 4 ++-- .../integrity/fingerprints/BypassMoatCheckFingerprint.kt | 4 ++-- .../fingerprints/BypassRequestChecksumsFingerprint.kt | 2 +- .../revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt | 4 ++-- .../misc/fingerprints/RemoveShopTabFingerprint.kt | 2 +- 20 files changed, 36 insertions(+), 36 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt index 2695d6749..4274d9a41 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveBizBoardPatch.kt @@ -2,7 +2,7 @@ package app.revanced.patches.kakaotalk.ads import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.ads.fingerprints.removeBizBoardFingerprint +import app.revanced.patches.kakaotalk.ads.fingerprints.measuringBizBoardFingerprint @Suppress("unused") val removeBizBoardPatch = bytecodePatch( @@ -12,7 +12,7 @@ val removeBizBoardPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val method = removeBizBoardFingerprint.method + val method = measuringBizBoardFingerprint.method method.addInstructions( 0, diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt index 79f77cf07..e92aa892d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveFocusAdPatch.kt @@ -2,7 +2,7 @@ package app.revanced.patches.kakaotalk.ads import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.ads.fingerprints.removeFocusAdFingerprint +import app.revanced.patches.kakaotalk.ads.fingerprints.loadFocusAdFingerprint val removeFocusAdPatch = bytecodePatch( name = "Remove focus ad", @@ -11,7 +11,7 @@ val removeFocusAdPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - removeFocusAdFingerprint.method.addInstructions( + loadFocusAdFingerprint.method.addInstructions( 0, """ const/4 v0, 0x1 diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt index fa2df6351..edcd937a0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatch.kt @@ -2,7 +2,7 @@ package app.revanced.patches.kakaotalk.ads import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.ads.fingerprints.removeOlkChatRoomListAdFingerprint +import app.revanced.patches.kakaotalk.ads.fingerprints.addOlkChatRoomListAdFingerprint import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint @Suppress("unused") @@ -16,7 +16,7 @@ val removeOlkChatRoomListAdPatch = bytecodePatch( val findUnit = kotlinUnitInstanceFingerprint.method val unitClass = findUnit.definingClass - val method = removeOlkChatRoomListAdFingerprint.method + val method = addOlkChatRoomListAdFingerprint.method // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. // If it changes, we need to fix it diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt index 10e0e1786..3fb5ba077 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveBizBoardFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val removeBizBoardFingerprint = fingerprint { +internal val measuringBizBoardFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC) returns("V") parameters("I", "I") diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt index c1840d920..2187519c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveFocusAdFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val removeFocusAdFingerprint = fingerprint { +internal val loadFocusAdFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC) parameters("Lcom/kakao/adfit/ads/focus/FocusAdLoader\$OnAdLoadListener;") returns("Z") diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt index f424d383f..468416b83 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveOlkChatRoomListAdFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val removeOlkChatRoomListAdFingerprint = fingerprint { +internal val addOlkChatRoomListAdFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/Object;") returns("Ljava/lang/Object;") diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt index 1e9fdebc5..594d2f9fd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/Remove99ClampPatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.chatlog 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.remove99ClampFingerprint +import app.revanced.patches.kakaotalk.chatlog.fingerprints.processWatermarkCountFingerprint import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t @@ -16,7 +16,7 @@ val remove99ClampPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val method = remove99ClampFingerprint.method + val method = processWatermarkCountFingerprint.method method.instructions .filterIsInstance() diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt index 26708c068..933c356fc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatlog/fingerprints/Remove99ClampFingerprint.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.chatlog.fingerprints import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags -internal val remove99ClampFingerprint = fingerprint { +internal val processWatermarkCountFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/Object;") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt index c0a92d43b..faf73310d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/Remove300PlusLimitPatch.kt @@ -3,8 +3,8 @@ package app.revanced.patches.kakaotalk.chatroom 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.chatroom.fingerprints.remove300PlusLimitBaseChatRoomFingerprint -import app.revanced.patches.kakaotalk.chatroom.fingerprints.remove300PlusLimitOpenChatRoomFingerprint +import app.revanced.patches.kakaotalk.chatroom.fingerprints.limit300PlusBaseChatRoomFingerprint +import app.revanced.patches.kakaotalk.chatroom.fingerprints.limit300PlusOpenChatRoomFingerprint import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t @@ -17,7 +17,7 @@ val remove300PlusLimitBaseChatRoomPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val method = remove300PlusLimitBaseChatRoomFingerprint.method + val method = limit300PlusBaseChatRoomFingerprint.method val branches = method.instructions .filterIsInstance() @@ -43,7 +43,7 @@ val remove300PlusLimitOpenChatRoomPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val method = remove300PlusLimitOpenChatRoomFingerprint.method + val method = limit300PlusOpenChatRoomFingerprint.method method.instructions .filterIsInstance() diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt index f81510d3f..7a01753c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/chatroom/fingerprints/Remove300PlusLimitFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags @Suppress("unused") -internal val remove300PlusLimitBaseChatRoomFingerprint = fingerprint { +internal val limit300PlusBaseChatRoomFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters("Lcom/kakao/talk/widget/ViewBindable;") @@ -12,7 +12,7 @@ internal val remove300PlusLimitBaseChatRoomFingerprint = fingerprint { } @Suppress("unused") -internal val remove300PlusLimitOpenChatRoomFingerprint = fingerprint { +internal val limit300PlusOpenChatRoomFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt index 5c4c10ebf..fd19b2f07 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/ForceEnableEmoticonPlusPatch.kt @@ -2,7 +2,7 @@ package app.revanced.patches.kakaotalk.emoticon import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.emoticon.fingerprints.forceEnableEmoticonPlusFingerprint +import app.revanced.patches.kakaotalk.emoticon.fingerprints.isEnableEmoticonPlusFingerprint @Suppress("unused") val forceEnableEmoticonPlusPatch = bytecodePatch( @@ -12,7 +12,7 @@ val forceEnableEmoticonPlusPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - forceEnableEmoticonPlusFingerprint.method.addInstructions( + isEnableEmoticonPlusFingerprint.method.addInstructions( 0, """ const/4 v0, 0x1 diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt index ab6fc8365..149f48a44 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/emoticon/fingerprints/ForceEnableEmoticonPlusFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val forceEnableEmoticonPlusFingerprint = fingerprint { +internal val isEnableEmoticonPlusFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("Z") parameters() diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt index 4ea5f1deb..008f65e64 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/GhostModePatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.ghost import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint -import app.revanced.patches.kakaotalk.ghost.fingerprints.ghostModeFingerprint +import app.revanced.patches.kakaotalk.ghost.fingerprints.sendCurrentActionFingerprint @Suppress("unused") val ghostMode = bytecodePatch( @@ -16,7 +16,7 @@ val ghostMode = bytecodePatch( val findUnit = kotlinUnitInstanceFingerprint.method val unitClass = findUnit.definingClass - val method = ghostModeFingerprint.method + val method = sendCurrentActionFingerprint.method // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. // If it changes, we need to fix it diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt index f2ae38496..a5cbb99ac 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ghost/fingerprints/GhostModeFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val ghostModeFingerprint = fingerprint { +internal val sendCurrentActionFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/Object;") parameters("Ljava/lang/Object;") diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt index bc5b107bc..9d8c5fa51 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassMoatCheckPatch.kt @@ -5,8 +5,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassMoatCheckFingerprintOne -import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassMoatCheckFingerprintTwo +import app.revanced.patches.kakaotalk.integrity.fingerprints.moatCheckResultFingerprintOne +import app.revanced.patches.kakaotalk.integrity.fingerprints.moatCheckResultFingerprintTwo import app.revanced.patches.kakaotalk.integrity.fingerprints.postprocessMoatCheckFailedFingerprint import app.revanced.util.getReference import com.android.tools.smali.dexlib2.Opcode @@ -73,7 +73,7 @@ val bypassMoatCheckPatch = bytecodePatch( } } - patch(bypassMoatCheckFingerprintOne) - patch(bypassMoatCheckFingerprintTwo) + patch(moatCheckResultFingerprintOne) + patch(moatCheckResultFingerprintTwo) } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt index b59a1b8b7..76baf286c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/BypassRequestChecksumsPatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.integrity import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.kakaotalk.common.fingerprints.kotlinUnitInstanceFingerprint -import app.revanced.patches.kakaotalk.integrity.fingerprints.bypassRequestChecksumsFingerprint +import app.revanced.patches.kakaotalk.integrity.fingerprints.requestChecksumsFingerprint @Suppress("unused") val bypassRequestChecksumPatch = bytecodePatch( @@ -16,7 +16,7 @@ val bypassRequestChecksumPatch = bytecodePatch( val findUnit = kotlinUnitInstanceFingerprint.method val unitClass = findUnit.definingClass - val method = bypassRequestChecksumsFingerprint.method + val method = requestChecksumsFingerprint.method // I tried to find the field name, but it's pretty obvious to me, so I hardcode it. // If it changes, we need to fix it diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt index 7692cd653..bb88bd449 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassMoatCheckFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val bypassMoatCheckFingerprintOne = fingerprint { +internal val moatCheckResultFingerprintOne = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/Object;", "Ljava/lang/Object;", "Ljava/lang/Object;") returns("Ljava/lang/Object;") @@ -31,7 +31,7 @@ internal val bypassMoatCheckFingerprintOne = fingerprint { ) } -internal val bypassMoatCheckFingerprintTwo = fingerprint { +internal val moatCheckResultFingerprintTwo = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/Object;", "Ljava/lang/Object;", "Ljava/lang/Object;") returns("Ljava/lang/Object;") diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt index ac9820864..63cba53da 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/integrity/fingerprints/BypassRequestChecksumsFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val bypassRequestChecksumsFingerprint = fingerprint { +internal val requestChecksumsFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Ljava/lang/Object;") strings( diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt index 7c50ab34c..40925b368 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/RemoveShopTabPatch.kt @@ -3,7 +3,7 @@ package app.revanced.patches.kakaotalk.misc import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.kakaotalk.misc.fingerprints.removeShopTabFingerprint +import app.revanced.patches.kakaotalk.misc.fingerprints.addNavigationTabFingerprint import app.revanced.util.getReference import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c @@ -18,7 +18,7 @@ val removeShopTabPatch = bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val method = removeShopTabFingerprint.method + val method = addNavigationTabFingerprint.method val insns = method.instructions val matches = insns.mapIndexedNotNull { idx, inst -> diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt index 1fa6bb112..394981932 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/RemoveShopTabFingerprint.kt @@ -4,7 +4,7 @@ import app.revanced.patcher.fingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val removeShopTabFingerprint = fingerprint { +internal val addNavigationTabFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") parameters() From d62649da49b7bb6e20a6b6c9a1ca492a994b1832 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 21 May 2025 17:29:43 +0900 Subject: [PATCH 32/36] feat(kakaotalk): add patch and fingerprint to remove native ad --- patches/api/patches.api | 4 +++ .../kakaotalk/ads/RemoveNativeAdPatch.kt | 24 +++++++++++++ .../fingerprints/RemoveNativeAdFingerprint.kt | 34 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveNativeAdPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveNativeAdFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 89fd4ba71..81506e79e 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -256,6 +256,10 @@ public final class app/revanced/patches/kakaotalk/ads/RemoveMoreTabAdPatchKt { public static final fun getRemoveMoreTabAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/ads/RemoveNativeAdPatchKt { + public static final fun getRemoveNativeAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/ads/RemoveOlkChatRoomListAdPatchKt { public static final fun getRemoveOlkChatRoomListAdPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveNativeAdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveNativeAdPatch.kt new file mode 100644 index 000000000..34147c0f9 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/RemoveNativeAdPatch.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.kakaotalk.ads + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.ads.fingerprints.loadNativeAdFingerprint + +val removeNativeAdPatch = bytecodePatch( + name = "Remove native ad", + description = "Removes the native ad from the app.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + val method = loadNativeAdFingerprint.method + + method.addInstructions( + 0, + """ + const/4 v0, 0x1 + return v0 + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveNativeAdFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveNativeAdFingerprint.kt new file mode 100644 index 000000000..384fd0d10 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/ads/fingerprints/RemoveNativeAdFingerprint.kt @@ -0,0 +1,34 @@ +package app.revanced.patches.kakaotalk.ads.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val loadNativeAdFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("I", "Lcom/kakao/adfit/ads/media/NativeAdLoader\$AdLoadListener;") + returns("Z") + strings( + "listener", + " owner is destroyed.", + " loading is already started.", + "Request Native AD", + " loading is started.", + "Native ad is cached. [id = ", + "] [dsp = ", + "] [count = ", + "Invalid Count: " + ) + opcodes( + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.IF_LEZ, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.CONST_4, + Opcode.IF_NE, + ) + custom { method, classDef -> method.name == "load" } +} \ No newline at end of file From 0fac05f134c1940a5f39b6d63a9f180266f653d6 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Wed, 21 May 2025 18:23:43 +0900 Subject: [PATCH 33/36] feat(kakaotalk): add patch and fingerprint to force enable debug mode --- patches/api/patches.api | 4 +++ .../misc/ForceEnableDebugModePatch.kt | 31 +++++++++++++++++++ .../ForceEnableDebugModeFingerprint.kt | 24 ++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/ForceEnableDebugModePatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/ForceEnableDebugModeFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index 81506e79e..ee1d3f881 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -297,6 +297,10 @@ public final class app/revanced/patches/kakaotalk/integrity/VerifyingSignaturePa public static final fun getVerifyingSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/kakaotalk/misc/ForceEnableDebugModePatchKt { + public static final fun getForceEnableDebugModePatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/misc/RemoveShopTabPatchKt { public static final fun getRemoveShopTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/ForceEnableDebugModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/ForceEnableDebugModePatch.kt new file mode 100644 index 000000000..d72ba6ed2 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/ForceEnableDebugModePatch.kt @@ -0,0 +1,31 @@ +package app.revanced.patches.kakaotalk.misc + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.kakaotalk.misc.fingerprints.configConstructorFingerprint +import com.android.tools.smali.dexlib2.Opcode + +@Suppress("unused") +val forceEnableDebugModePatch = bytecodePatch( + name = "Force enable debug mode", + description = "Enables debug mode in the app.", +) { + compatibleWith("com.kakao.talk"("25.4.2")) + + execute { + val method = configConstructorFingerprint.method + val insns = method.instructions + val idxReturn = insns.indexOfFirst { it.opcode == Opcode.RETURN_VOID } // RETURN_VOID + + val clazz = method.definingClass + + method.addInstructions( + idxReturn, + """ + const/4 v0, 0x1 + sput-boolean v0, $clazz->a:Z + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/ForceEnableDebugModeFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/ForceEnableDebugModeFingerprint.kt new file mode 100644 index 000000000..3b3206807 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/misc/fingerprints/ForceEnableDebugModeFingerprint.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.kakaotalk.misc.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val configConstructorFingerprint = fingerprint { + accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR) + returns("V") + parameters() + strings("google", "one", "getBytes(...)") + opcodes( + Opcode.SGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.CONST_4, + Opcode.CONST_4, + Opcode.IF_EQ, + Opcode.MOVE, + Opcode.GOTO, + ) +} \ No newline at end of file From 46a97d9e140fc8aa80cdda4a8d2c3091d663111e Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Thu, 22 May 2025 14:32:37 +0900 Subject: [PATCH 34/36] feat(kakaotalk): add patch and fingerprints to allow replying to feed messages --- patches/api/patches.api | 4 ++ .../kakaotalk/send/AllowReplyToFeedPatch.kt | 44 +++++++++++++++ .../AllowReplyToFeedFingerprint.kt | 53 +++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/fingerprints/AllowReplyToFeedFingerprint.kt diff --git a/patches/api/patches.api b/patches/api/patches.api index ee1d3f881..382490791 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -305,6 +305,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/send/AllowReplyToFeedPatchKt { + public static final fun getAllowReplyToFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/kakaotalk/versioninfo/VersionInfoPatchKt { public static final fun getVersionInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt new file mode 100644 index 000000000..7d04db0f4 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt @@ -0,0 +1,44 @@ +package app.revanced.patches.kakaotalk.send + +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.instructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patches.kakaotalk.send.fingerprints.allowSwipeReplyToFeedFingerprint +import app.revanced.patches.kakaotalk.send.fingerprints.realActionForReplyFingerprint +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21t + +@Suppress("unused") +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")) + + execute { + val patch: (Fingerprint, String, Boolean) -> Unit = { fp, register, bool -> + val method = fp.method + val insns = method.instructions + + val idxIfnez = insns.indexOfFirst { it is Instruction21t && it.opcode == Opcode.IF_NEZ } + + val idxInvoke = insns.subList(0, idxIfnez) + .indexOfLast { it.opcode == Opcode.INVOKE_VIRTUAL } + + (idxInvoke until idxIfnez).toList() + .sortedDescending() + .forEach { method.removeInstruction(it) } + + method.addInstructions( + idxInvoke, + """ + const/4 $register, ${if (bool) "0x1" else "0x0"} + """.trimIndent() + ) + } + + patch(realActionForReplyFingerprint, "v0", false) + patch(allowSwipeReplyToFeedFingerprint, "p2", false) + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/fingerprints/AllowReplyToFeedFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/fingerprints/AllowReplyToFeedFingerprint.kt new file mode 100644 index 000000000..b86dc6f07 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/fingerprints/AllowReplyToFeedFingerprint.kt @@ -0,0 +1,53 @@ +package app.revanced.patches.kakaotalk.send.fingerprints + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal val realActionForReplyFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) + returns("V") + strings( + "chatLog", + "chatRoom" + ) + opcodes( + Opcode.CONST_STRING, + Opcode.CONST_STRING, + Opcode.CONST, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CONST_4, + Opcode.INVOKE_DIRECT, + Opcode.IPUT_OBJECT, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT, + Opcode.IF_NEZ, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT_OBJECT, + Opcode.SGET_OBJECT, + Opcode.IF_NE, + Opcode.GOTO_16 + ) +} + +internal val allowSwipeReplyToFeedFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + parameters("Landroidx/recyclerview/widget/RecyclerView;", "Landroidx/recyclerview/widget/RecyclerView\$D;") + returns("I") + strings("recyclerView", "viewHolder") + opcodes( + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.CONST_STRING, + Opcode.INVOKE_STATIC, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.CONST_4, + Opcode.CONST_4, + ) + custom { method, classDef -> method.name == "getMovementFlags" } +} \ No newline at end of file From bb05341cdb5732a21b183b6eb3b0376fe15a1083 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Thu, 22 May 2025 14:40:29 +0900 Subject: [PATCH 35/36] feat(kakaotalk): refactor patch to simplify reply handling for feed messages --- .../kakaotalk/send/AllowReplyToFeedPatch.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt index 7d04db0f4..0292032d0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt @@ -4,9 +4,11 @@ import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patches.kakaotalk.send.fingerprints.allowSwipeReplyToFeedFingerprint import app.revanced.patches.kakaotalk.send.fingerprints.realActionForReplyFingerprint import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11n import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21t @Suppress("unused") @@ -17,11 +19,12 @@ val allowReplyToFeedPatch = app.revanced.patcher.patch.bytecodePatch( compatibleWith("com.kakao.talk"("25.4.2")) execute { - val patch: (Fingerprint, String, Boolean) -> Unit = { fp, register, bool -> + val patch: (Fingerprint) -> Unit = { fp -> val method = fp.method val insns = method.instructions val idxIfnez = insns.indexOfFirst { it is Instruction21t && it.opcode == Opcode.IF_NEZ } + val idxIfnezTarget = (insns[idxIfnez] as Instruction21t).registerA val idxInvoke = insns.subList(0, idxIfnez) .indexOfLast { it.opcode == Opcode.INVOKE_VIRTUAL } @@ -30,15 +33,17 @@ val allowReplyToFeedPatch = app.revanced.patcher.patch.bytecodePatch( .sortedDescending() .forEach { method.removeInstruction(it) } - method.addInstructions( + method.replaceInstruction( idxInvoke, - """ - const/4 $register, ${if (bool) "0x1" else "0x0"} - """.trimIndent() + BuilderInstruction11n( + Opcode.CONST_4, + idxIfnezTarget, + 0x0, + ) ) } - patch(realActionForReplyFingerprint, "v0", false) - patch(allowSwipeReplyToFeedFingerprint, "p2", false) + patch(realActionForReplyFingerprint) + patch(allowSwipeReplyToFeedFingerprint) } } \ No newline at end of file From c2c0b8e94a6b9824fb83c484cb6f91602e32fb55 Mon Sep 17 00:00:00 2001 From: naijun0403 Date: Fri, 23 May 2025 09:07:38 +0900 Subject: [PATCH 36/36] feat(kakaotalk): remove unused import for instruction extensions in AllowReplyToFeedPatch --- .../app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt index 0292032d0..8d6dd3340 100644 --- a/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/kakaotalk/send/AllowReplyToFeedPatch.kt @@ -1,7 +1,6 @@ package app.revanced.patches.kakaotalk.send import app.revanced.patcher.Fingerprint -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction