Skip to content

Commit

Permalink
fix: RevokeMsgHook: NT: recall operator
Browse files Browse the repository at this point in the history
  • Loading branch information
cinit committed Jul 17, 2023
1 parent 6e9d26e commit d2ba552
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 19 deletions.
21 changes: 11 additions & 10 deletions app/src/main/cpp/ntkernel/NtRecallMsgHook.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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();
Expand All @@ -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);
}


Expand Down Expand Up @@ -272,6 +272,7 @@ void HandleGroupRecallSysMsgCallback([[maybe_unused]] void* x0, void* x1, [[mayb
}
std::array<void*, 3> 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<const std::vector<RevokeMsgInfoAccess::UnknownObjectStub16>*>(&vectorResultStub);
if (msgInfoList.empty()) {
LOGE("HandleGroupRecallSysMsgCallback: on recall group sys msg! no any msg info");
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand Down
26 changes: 17 additions & 9 deletions app/src/main/java/cc/ioctl/hook/msg/RevokeMsgHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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;
Expand Down Expand Up @@ -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)) {
Expand All @@ -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);
Expand Down

0 comments on commit d2ba552

Please sign in to comment.