SendAtText.cpp 3.4 KB
Newer Older
L
ljc545w 已提交
1 2
#include "pch.h"

L
ljc545w 已提交
3
// 发送艾特消息CALL偏移
L
ljc545w 已提交
4
#define SendAtTextCallOffset 0x78BC1D30 - 0x786A0000
L
ljc545w 已提交
5
// 清空缓存CALL偏移
L
ljc545w 已提交
6
#define DeleteAtTextCacheCallOffset 0x78757780 - 0x786A0000
L
ljc545w 已提交
7

L
ljc545w 已提交
8 9 10 11 12 13 14
/*
* 外部调用时传递的参数结构
* chatroomid:群聊ID的保存地址
* wxidlist:艾特列表的保存地址,真实类型应当是`wchar_t**`
* wxmsg:发送的内容保存地址
* length:艾特的人数量,用于指示wxidlist长度
*/
15
#ifndef USE_SOCKET
L
ljc545w 已提交
16 17 18
struct SendAtTextStruct
{
    DWORD chatroomid;
L
ljc545w 已提交
19
    DWORD wxidlist;
L
ljc545w 已提交
20
    DWORD wxmsg;
21
    DWORD length;
L
ljc545w 已提交
22
    BOOL  AutoNickName;
L
ljc545w 已提交
23
};
24
#endif
L
ljc545w 已提交
25

L
ljc545w 已提交
26 27 28 29 30 31 32 33
/*
* 内存中使用的参数结构
* 构造与Release版本vector动态数组相仿
* 成员类型:`WxString`
* AtUser:类似`vector`的`data`方法,保存数组首个成员的地址
* addr_end1:数组尾地址
* addr_end2:数组尾地址
*/
L
ljc545w 已提交
34
struct AtStruct {
35
    DWORD AtUser;
L
ljc545w 已提交
36 37 38 39
    DWORD addr_end1;
    DWORD addr_end2;
};

L
ljc545w 已提交
40 41 42 43 44
/*
* 供外部调用的发送艾特消息接口
* lpParameter:SendAtTextStruct类型结构体指针
* return:void
*/
45
#ifndef USE_SOCKET
L
ljc545w 已提交
46 47 48 49
void SendAtTextRemote(LPVOID lpParameter) {
    SendAtTextStruct* rp = (SendAtTextStruct*)lpParameter;
    wchar_t* wsChatRoomId = (WCHAR*)rp->chatroomid;
    wchar_t* wsTextMsg = (WCHAR*)rp->wxmsg;
50 51
    if (rp->length == 0)
        return;
L
ljc545w 已提交
52 53
    else if (rp->length == 1)
        SendAtText(wsChatRoomId, (DWORD*)&rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
54
    else
L
ljc545w 已提交
55
        SendAtText(wsChatRoomId, (DWORD*)rp->wxidlist, wsTextMsg, rp->length, rp->AutoNickName);
L
ljc545w 已提交
56
}
57
#endif
L
ljc545w 已提交
58

L
ljc545w 已提交
59 60 61 62 63 64
/*
* 发送艾特消息的具体实现
* wsChatRoomId:群聊ID
* wsWxId:艾特的人列表
* wsTextMsg:发送的消息内容
* length:艾特的人数量
L
ljc545w 已提交
65
* AutoNickName:是否自动填充被艾特人昵称
L
ljc545w 已提交
66 67
* return:void
*/
L
ljc545w 已提交
68
void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsTextMsg,int length,BOOL AutoNickName) {
L
ljc545w 已提交
69
    // +1的作用是补充一个空结构体,将`AtStruct`尾地址设定为空结构的首地址即可
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
    WxString* AtUsers = new WxString[length + 1];
    wstring AtMessage = L"";
    int querySuccess = 0;
    for (int i = 0; i < length; i++) {
        wchar_t* nickname = NULL;
        if (!lstrcmpW((wchar_t*)wsWxId[i], (wchar_t*)L"notify@all")) {
            nickname = (wchar_t*)L"所有人";
        }
        else
            nickname = GetUserNickNameByWxId((wchar_t*)wsWxId[i]);
        if (!nickname)
            continue;
        WxString temp = { 0 };
        temp.buffer = (wchar_t*)wsWxId[i];
        temp.length = wcslen((wchar_t*)wsWxId[i]);
        temp.maxLength = wcslen((wchar_t*)wsWxId[i]) * 2;
L
ljc545w 已提交
86 87 88 89
        memcpy(&AtUsers[querySuccess], &temp, sizeof(WxString));
        if (AutoNickName) {
            AtMessage = AtMessage + L"@" + nickname + L" ";
        }
90 91 92 93
        querySuccess++;
    }
    AtMessage += wsTextMsg;
    if (!querySuccess)
L
ljc545w 已提交
94 95
        return;
    WxBaseStruct wxChatRoomId(wsChatRoomId);
96
    WxBaseStruct wxTextMsg((wchar_t*)AtMessage.c_str());
L
ljc545w 已提交
97
    AtStruct at = { 0 };
98 99 100
    at.AtUser = (DWORD)AtUsers;
    at.addr_end1 = (DWORD)&AtUsers[querySuccess];
    at.addr_end2 = (DWORD)&AtUsers[querySuccess];
L
ljc545w 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

    wchar_t** pWxmsg = &wxTextMsg.buffer;
    char buffer[0x3B0] = { 0 };

    DWORD dllBaseAddress = GetWeChatWinBase();
    DWORD callAddress = dllBaseAddress + SendAtTextCallOffset;
    DWORD DeleteTextCacheCall = dllBaseAddress + DeleteAtTextCacheCallOffset;

    __asm {
        lea eax, at;
        push 0x1;
        push eax;
        mov edi, pWxmsg;
        push edi;
        lea edx, wxChatRoomId;
        lea ecx, buffer;
        call callAddress;
        add esp, 0xC;
        lea ecx, buffer;
        call DeleteTextCacheCall;
    }
122 123
    delete[] AtUsers;
    AtUsers = NULL;
L
ljc545w 已提交
124
}