From d2ba5528b7fb06e094623b3fee95a190321f4b97 Mon Sep 17 00:00:00 2001 From: ACh Sulfate Date: Mon, 17 Jul 2023 22:28:41 +0800 Subject: [PATCH] fix: RevokeMsgHook: NT: recall operator --- app/src/main/cpp/ntkernel/NtRecallMsgHook.cc | 21 ++++++++------- .../java/cc/ioctl/hook/msg/RevokeMsgHook.java | 26 ++++++++++++------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc b/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc index 664625e066..6b9e39462d 100644 --- a/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc +++ b/app/src/main/cpp/ntkernel/NtRecallMsgHook.cc @@ -148,8 +148,8 @@ class RevokeMsgInfoAccess { }; -void NotifyRecallSysMsgEvent(int chatType, const std::string& peerUid, const std::string& recallOpUid, const std::string& toUid, - uint64_t random64, uint64_t timeSeconds, uint64_t msgUid, uint64_t msgSeq, uint32_t msgClientSeq) { +void NotifyRecallSysMsgEvent(int chatType, const std::string& peerUid, const std::string& recallOpUid, const std::string& msgAuthorUid, + const std::string& toUid, uint64_t random64, uint64_t timeSeconds, uint64_t msgUid, uint64_t msgSeq, uint32_t msgClientSeq) { JavaVM* vm = HostInfo::GetJavaVM(); if (vm == nullptr) { LOGE("NotifyRecallSysMsgEvent fatal vm == null"); @@ -176,8 +176,8 @@ void NotifyRecallSysMsgEvent(int chatType, const std::string& peerUid, const std // call java method env->CallStaticVoidMethod(klassRevokeMsgHook, handleRecallSysMsgFromNtKernel, jint(chatType), env->NewStringUTF(peerUid.c_str()), env->NewStringUTF(recallOpUid.c_str()), - env->NewStringUTF(toUid.c_str()), jlong(random64), jlong(timeSeconds), - jlong(msgUid), jlong(msgSeq), jint(msgClientSeq)); + env->NewStringUTF(msgAuthorUid.c_str()), env->NewStringUTF(toUid.c_str()), + jlong(random64), jlong(timeSeconds), jlong(msgUid), jlong(msgSeq), jint(msgClientSeq)); // check if exception occurred if (env->ExceptionCheck()) { env->ExceptionDescribe(); @@ -192,12 +192,12 @@ void NotifyRecallSysMsgEvent(int chatType, const std::string& peerUid, const std void NotifyRecallMsgEventForC2c(const std::string& fromUid, const std::string& toUid, uint64_t random64, uint64_t timeSeconds, uint64_t msgUid, uint64_t msgSeq, uint32_t msgClientSeq) { - NotifyRecallSysMsgEvent(1, fromUid, fromUid, toUid, random64, timeSeconds, msgUid, msgSeq, msgClientSeq); + NotifyRecallSysMsgEvent(1, fromUid, fromUid, fromUid, toUid, random64, timeSeconds, msgUid, msgSeq, msgClientSeq); } -void NotifyRecallMsgEventForGroup(const std::string& peerUid, const std::string& recallOpUid, +void NotifyRecallMsgEventForGroup(const std::string& peerUid, const std::string& recallOpUid, const std::string& msgAuthorUid, uint64_t random64, uint64_t timeSeconds, uint64_t msgSeq) { - NotifyRecallSysMsgEvent(2, peerUid, recallOpUid, peerUid, random64, timeSeconds, 0, msgSeq, 0); + NotifyRecallSysMsgEvent(2, peerUid, recallOpUid, msgAuthorUid, peerUid, random64, timeSeconds, 0, msgSeq, 0); } @@ -272,6 +272,7 @@ void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[mayb } std::array vectorResultStub = {nullptr, nullptr, nullptr}; vcall_x8<0xf0, 8, int>(optMsgRecall[0], &vectorResultStub, 3); + std::string recallOpUid = ThunkGetStringProperty(optMsgRecall[0], 1); const auto& msgInfoList = *reinterpret_cast*>(&vectorResultStub); if (msgInfoList.empty()) { LOGE("HandleGroupRecallSysMsgCallback: on recall group sys msg! no any msg info"); @@ -282,12 +283,12 @@ void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[mayb uint32_t msgSeq = ThunkGetInt32Property(msgInfo._unk0_8, 1); uint32_t random = ThunkGetInt32Property(msgInfo._unk0_8, 3); uint64_t time = ThunkGetInt64Property(msgInfo._unk0_8, 2); - std::string recallOpUid = ThunkGetStringProperty(msgInfo._unk0_8, 6); + std::string msgAuthorUid = ThunkGetStringProperty(msgInfo._unk0_8, 6); // Unfortunately, I didn't find a way to find the origMsgSenderUid. // The only thing we can do is to get message by msgSeq, and get senderUid from it, iff we have the message. - NotifyRecallMsgEventForGroup(peerUid, recallOpUid, random, time, msgSeq); + NotifyRecallMsgEventForGroup(peerUid, recallOpUid, msgAuthorUid, random, time, msgSeq); } } @@ -502,7 +503,7 @@ Java_cc_ioctl_hook_msg_RevokeMsgHook_nativeInitNtKernelRecallMsgHook(JNIEnv* env klassRevokeMsgHook = (jclass) env->NewGlobalRef(clazz); gInstanceRevokeMsgHook = env->NewGlobalRef(thiz); handleRecallSysMsgFromNtKernel = env->GetStaticMethodID(clazz, "handleRecallSysMsgFromNtKernel", - "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJJI)V"); + "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JJJJI)V"); if (handleRecallSysMsgFromNtKernel == nullptr) { LOGE("InitInitNtKernelRecallMsgHook failed, GetStaticMethodID failed"); return false; diff --git a/app/src/main/java/cc/ioctl/hook/msg/RevokeMsgHook.java b/app/src/main/java/cc/ioctl/hook/msg/RevokeMsgHook.java index 965d9c64ee..22ec52ae9d 100644 --- a/app/src/main/java/cc/ioctl/hook/msg/RevokeMsgHook.java +++ b/app/src/main/java/cc/ioctl/hook/msg/RevokeMsgHook.java @@ -374,19 +374,19 @@ private void onRevokeMsgLegacy(Object revokeMsgInfo) throws Exception { * We are not allowed to throw any exception in this method. */ @Keep - private static void handleRecallSysMsgFromNtKernel(int chatType, String peerUid, String recallOpUid, String toUid, - long random64, long timeSeconds, long msgUid, long msgSeq, int msgClientSeq) { + private static void handleRecallSysMsgFromNtKernel(int chatType, String peerUid, String recallOpUid, String msgAuthorUid, + String toUid, long random64, long timeSeconds, long msgUid, long msgSeq, int msgClientSeq) { SyncUtils.async(() -> { try { - RevokeMsgHook.INSTANCE.onRecallSysMsgForNT(chatType, peerUid, recallOpUid, toUid, random64, timeSeconds, - msgUid, msgSeq, msgClientSeq); + RevokeMsgHook.INSTANCE.onRecallSysMsgForNT(chatType, peerUid, recallOpUid, msgAuthorUid, toUid, + random64, timeSeconds, msgUid, msgSeq, msgClientSeq); } catch (Exception | LinkageError | AssertionError e) { RevokeMsgHook.INSTANCE.traceError(e); } }); } - private void onRecallSysMsgForNT(int chatType, String peerUid, String recallOpUid, String toUid, + private void onRecallSysMsgForNT(int chatType, String peerUid, String recallOpUid, String msgAuthorUid, String toUid, long random64, long timeSeconds, long msgUid, long msgSeq, int msgClientSeq) throws ReflectiveOperationException { if (TextUtils.isEmpty(peerUid)) { Log.e("onRecallSysMsgForNT fatal: peerUid is empty"); @@ -404,6 +404,10 @@ private void onRecallSysMsgForNT(int chatType, String peerUid, String recallOpUi Log.e("onRecallSysMsgForNT fatal: selfUid is empty"); return; } + if (TextUtils.isEmpty(msgAuthorUid)) { + Log.e("onRecallSysMsgForNT fatal: msgAuthorUid is empty"); + return; + } if (selfUid.equals(recallOpUid)) { // ignore msg revoked by self return; @@ -452,7 +456,6 @@ private void onRecallSysMsgForNT(int chatType, String peerUid, String recallOpUi if (msgObject != null && msgObject.getMsgType() != 1 && !(msgObject.getMsgType() == 5 && msgObject.getSubMsgType() == 4)) { // good, we have the original message // then, is the original message sent by the operator? - String msgAuthorUid = msgObject.getSenderUid(); long msgAuthorUin = msgObject.getSenderUin(); String msgAuthorName = getMsgSenderReferenceName(msgObject, true); if (recallOpUid.equals(msgAuthorUid)) { @@ -470,10 +473,15 @@ private void onRecallSysMsgForNT(int chatType, String peerUid, String recallOpUi summary = operatorName + "尝试撤回" + msgAuthorName + "的一条消息"; } } else { - // we don't have the original message, so we can't get the sender's name + // we don't have the original message + String msgAuthorName = ContactUtils.getDisplayNameForUid(msgAuthorUid, peerUid); + String msgAuthorUin = RelationNTUinAndUidApi.getUinFromUid(msgAuthorUid); + // msgAuthorUin may be empty, in the case when in a group chat, NT kernel are not so familiar with the one builder.append(new NtGrayTipHelper.NtGrayTipJsonBuilder.UserItem(String.valueOf(operatorUin), recallOpUid, operatorName)); - builder.appendText("撤回了一条消息(没收到) [seq=" + msgSeq + "]"); - summary = operatorName + "撤回了一条消息(没收到)"; + builder.appendText("撤回了"); + builder.append(new NtGrayTipHelper.NtGrayTipJsonBuilder.UserItem(String.valueOf(msgAuthorUin), msgAuthorUid, msgAuthorName)); + builder.appendText("的一条消息(没收到) [seq=" + msgSeq + "]"); + summary = operatorName + "撤回了" + msgAuthorName + "的一条消息(没收到)"; } } else { throw new AssertionError("onRecallSysMsgForNT chatType=" + chatType);