GetHistoryPublicMsg.cpp 5.2 KB
Newer Older
L
ljc545w 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
#include "pch.h"
#include <sys/timeb.h>

#define GetHistoryPublicMsgCall1Offset 0x5B3F5CA0 - 0x5B050000
#define GetHistoryPublicMsgCall2Offset 0x65555C80 - 0x650A0000
#define GetHistoryPublicMsgHandleOffset 0x66C78701 - 0x650A0000

#define GetHistoryPublicHookAddrOffset 0x794EFC9E - 0x78ED0000
#define GetHistoryPublicJmpBackAddrOffset 0x794EFD14 - 0x78ED0000

static BOOL H5ExtBufHooked = FALSE;
static char H5ExtBufOldAsmCode[5] = {0};
static DWORD HookAddr = 0;
static DWORD JmpBackAdrr = 0;
static string response = "";

static unsigned long long systemtime()
{
    timeb t;
    ftime(&t);
    return t.time * 1000 + t.millitm;
}

void GetResponseData(DWORD addr1, DWORD addr2)
{
    char *buffer = (char *)(*(DWORD *)addr1);
    int length = *(int *)(addr1 + 0x10);
    if (length != 0)
    {
        string json_data(buffer, length);
        response = json_data;
    }
    else
    {
        int err_msg_len = *(int *)(addr2 + 0x10);
        char *err_buffer = (err_msg_len <= 0xF) ? (char *)addr2 : (char *)(*(DWORD *)addr2);
        string err_msg(err_buffer, err_msg_len);
        response = err_msg;
    }
#ifndef USE_SOCKET
    response = utf8_to_gb2312(response.c_str());
#endif
}

_declspec(naked) void dealH5ExtBuf()
{
    __asm {
        pushad;
        pushfd;
        mov ecx,dword ptr ds:[ebp - 0x5C];
        sub ecx,0x40;
        add ecx,0x1D4;
        mov ecx,dword ptr ds:[ecx];
        add ecx,0x8;
        mov eax,dword ptr ds:[ecx];
        add eax,0x8;
        mov ecx,dword ptr ds:[eax];
        sub eax,0x4;
        mov eax,dword ptr ds:[eax];
        push eax;
        push ecx;
        call GetResponseData;
        add esp,0x8;
        popfd;
        popad;
        mov edi,dword ptr ds:[ebp - 0x5C];
        jmp JmpBackAdrr;
    }
}

void HookH5ExtBuf()
{
    if (H5ExtBufHooked)
        return;
    DWORD WeChatWinBase = GetWeChatWinBase();
    HookAddr = WeChatWinBase + GetHistoryPublicHookAddrOffset;
    JmpBackAdrr = WeChatWinBase + GetHistoryPublicJmpBackAddrOffset;
    HookAnyAddress(HookAddr, (LPVOID)dealH5ExtBuf, H5ExtBufOldAsmCode);
    H5ExtBufHooked = TRUE;
}

void UnHookH5ExtBuf()
{
    if (!H5ExtBufHooked)
        return;
    UnHookAnyAddress(HookAddr, H5ExtBufOldAsmCode);
    H5ExtBufHooked = FALSE;
}

BOOL __stdcall GetHistoryPublicMsg(wchar_t *PublicId, wchar_t *Offset)
{
    response = "";
    HookH5ExtBuf();
    DWORD WeChatWinBase = GetWeChatWinBase();
    DWORD GetHistoryPublicMsgCall1 = WeChatWinBase + GetHistoryPublicMsgCall1Offset;
    DWORD GetHistoryPublicMsgCall2 = WeChatWinBase + GetHistoryPublicMsgCall2Offset;
    DWORD GetHistoryPublicMsgHandle = WeChatWinBase + GetHistoryPublicMsgHandleOffset;
    wstring format_str1 = L"weixin://resourceid/Subscription/profile.html?userName=%ws&subscribed=1&from=217&localOpenTime=%llu&wechatVersion=%d";
    int version = GetWeChatVerInt();
    unsigned long long timestamp = systemtime();
    wchar_t buffer[0x400] = {0};
    swprintf_s(buffer, format_str1.c_str(), PublicId, timestamp, version);
    wstring page_uri(buffer);
    wstring cgi_uri = L"/cgi-bin/mmbiz-bin/bizattr/bizprofilev2h5";
    ZeroMemory(buffer, 800);
    if (Offset != NULL)
    {
        wstring format_str2 = L"{\"BizUserName\":\"%ws\",\"Offset\":\"%ws\",\"ActionType\":1,\"PageSize\":10,\"BizSessionID\":1662700879,\"Scene\":207,\"PreLoad\":0}";
        swprintf_s(buffer, format_str2.c_str(), PublicId, Offset);
    }
    else
    {
        wstring format_str2 = L"{\"BizUserName\":\"%ws\",\"ActionType\":0,\"PageSize\":10,\"BizSessionID\":1662700879,\"Scene\":207,\"PreLoad\":0}";
        swprintf_s(buffer, format_str2.c_str(), PublicId);
    }
    wstring json_data(buffer);
    int h5ExtType = 0x16B6;
    wstring subscriptions = L"subscriptions";
    wstring index = L"3_1011_7";
    WxString p_page_uri(page_uri);
    WxString p_cgi_uri(cgi_uri);
    WxString p_json_data(json_data);
    WxString p_subscriptions(subscriptions);
    WxString p_index(index);
    int isSuccess = 0;
    __asm {
        pushad;
        pushfd;
        call GetHistoryPublicMsgCall1;
        push dword ptr ds:[GetHistoryPublicMsgHandle];
        lea ecx,p_subscriptions;
        push ecx;
        push dword ptr ds:[h5ExtType];
        lea ecx,p_json_data;
        push ecx;
        lea ecx,p_cgi_uri;
        push ecx;
        lea ecx,p_page_uri;
        push ecx;
        lea ecx,p_index;
        push ecx;
        mov ecx,eax;
        call GetHistoryPublicMsgCall2;
        mov isSuccess,eax;
        popfd;
        popad;
    }
    if (!H5ExtBufHooked || isSuccess == 0) return FALSE;
    return TRUE;
}

#ifndef USE_SOCKET
struct PublicMsgResponseStruct
{
    DWORD buffer = 0;
    DWORD length = 0;
} static resp;
DWORD GetHistoryPublicMsgRemote(LPVOID param)
{
    GetPublicMsgStruct *gpms = (GetPublicMsgStruct *)param;
    BOOL ret = GetHistoryPublicMsg(gpms->PublicId, gpms->Offset);
    while (ret && response.length() == 0)
        Sleep(200);
    resp.buffer = (DWORD)response.c_str();
    resp.length = response.length();
    return (DWORD)&resp;
}
#else
string __stdcall GetHistoryPublicMsg(wstring PublicId, wstring Offset)
{
    wchar_t *pOffset = Offset.length() == 0 ? NULL : (wchar_t *)Offset.c_str();
    BOOL ret = GetHistoryPublicMsg((wchar_t *)PublicId.c_str(), pOffset);
    while (ret && response.length() == 0)
        Sleep(200);
    return response;
}
#endif