Repository: TonyChen56/WeChatRobot Branch: master Commit: 45e4b1b49856 Files: 108 Total size: 258.0 KB Directory structure: gitextract_n0tizw0f/ ├── CLAUDE.md ├── README.md ├── README_DETAILS.md ├── WeChat 3.2.1.154安装包下载.txt ├── WeChatHelper/ │ ├── CAutoFunction.cpp │ ├── CAutoFunction.h │ ├── CPublic.cpp │ ├── CPublic.h │ ├── ChatRecord.cpp │ ├── ChatRecord.h │ ├── ChatRoomOperate.cpp │ ├── ChatRoomOperate.h │ ├── FriendList.cpp │ ├── FriendList.h │ ├── Function.cpp │ ├── Function.h │ ├── InitWeChat.cpp │ ├── InitWeChat.h │ ├── Login.cpp │ ├── Login.h │ ├── MainWindow.cpp │ ├── MainWindow.h │ ├── SelfInformation.cpp │ ├── SelfInformation.h │ ├── WeChatHelper.cpp │ ├── WeChatHelper.vcxproj │ ├── WeChatHelper.vcxproj.filters │ ├── WeChatHelper.vcxproj.user │ ├── WndMsgLoop.cpp │ ├── WndMsgLoop.h │ ├── data.h │ ├── dllmain.cpp │ ├── message.h │ ├── offset.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h ├── WeChatRobot/ │ ├── CAboutAuthor.cpp │ ├── CAboutAuthor.h │ ├── CAddChatRoomMember.cpp │ ├── CAddChatRoomMember.h │ ├── CAddUser.cpp │ ├── CAddUser.h │ ├── CChatRecords.cpp │ ├── CChatRecords.h │ ├── CChatRoomMember.cpp │ ├── CChatRoomMember.h │ ├── CCreateChatRoom.cpp │ ├── CCreateChatRoom.h │ ├── CDecryptImage.cpp │ ├── CDecryptImage.h │ ├── CFollowAccount.cpp │ ├── CFollowAccount.h │ ├── CFriendInfo.cpp │ ├── CFriendInfo.h │ ├── CFriendList.cpp │ ├── CFriendList.h │ ├── CFunctions.cpp │ ├── CFunctions.h │ ├── CInformation.cpp │ ├── CInformation.h │ ├── CInjectTools.cpp │ ├── CInjectTools.h │ ├── CInviteGroupMember.cpp │ ├── CInviteGroupMember.h │ ├── CMain.cpp │ ├── CMain.h │ ├── CModifyVersion.cpp │ ├── CModifyVersion.h │ ├── CMultiOpen.cpp │ ├── CMultiOpen.h │ ├── CMyTableCtrl.cpp │ ├── CMyTableCtrl.h │ ├── COpenUrl.cpp │ ├── COpenUrl.h │ ├── CPay.cpp │ ├── CPay.h │ ├── CRoomAnnouncement.cpp │ ├── CRoomAnnouncement.h │ ├── CSendChatRoomAt.cpp │ ├── CSendChatRoomAt.h │ ├── CSendMsg.cpp │ ├── CSendMsg.h │ ├── CSendXmlAricle.cpp │ ├── CSendXmlAricle.h │ ├── CSendXmlCard.cpp │ ├── CSendXmlCard.h │ ├── CSetRemark.cpp │ ├── CSetRemark.h │ ├── CSetRoomName.cpp │ ├── CSetRoomName.h │ ├── WeChatRobot.aps │ ├── WeChatRobot.cpp │ ├── WeChatRobot.h │ ├── WeChatRobot.rc │ ├── WeChatRobot.vcxproj │ ├── WeChatRobot.vcxproj.filters │ ├── WeChatRobot.vcxproj.user │ ├── WeChatRobotDlg.cpp │ ├── WeChatRobotDlg.h │ ├── data.h │ ├── message.h │ ├── res/ │ │ └── WeChatRobot.rc2 │ ├── resource.h │ ├── stdafx.cpp │ ├── stdafx.h │ └── targetver.h └── WeChatRobot.sln ================================================ FILE CONTENTS ================================================ ================================================ FILE: CLAUDE.md ================================================ # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **WeChatRobot** is a PC WeChat automation tool consisting of two components: 1. **WeChatRobot.exe** - MFC-based GUI client application that provides the user interface 2. **WeChatHelper.dll** - DLL injected into WeChat process to hook WeChat functions and perform operations The project uses **WM_COPYDATA** for inter-process communication between the client and the injected DLL. ⚠️ **Important Notice**: This project is a legacy WeChat hooking tool and has not been maintained for a long time. It is provided for learning purposes only and targets a specific old version of WeChat (2.6.8.52). ## Build System ### Requirements - **Visual Studio 2017** (VS 141 toolset) with C++ desktop development workload - Windows SDK version 10.0.17763.0 - MFC (statically linked in Win32, dynamically linked in x64) - OpenSSL 1.0.2l-win32-msvc100 (for WeChatRobot Debug Win32 build) ### Build Configurations The solution supports two platforms and two configurations: **Platforms:** - Win32 (x86) - x64 **Configurations:** - Debug - Release ### Build Commands Open `WeChatRobot.sln` in Visual Studio 2017 and build using: ```bash # Build entire solution msbuild WeChatRobot.sln /p:Configuration=Release /p:Platform=x64 # Build specific project msbuild WeChatRobot\WeChatRobot.vcxproj /p:Configuration=Release /p:Platform=x64 msbuild WeChatHelper\WeChatHelper.vcxproj /p:Configuration=Release /p:Platform=x64 # Clean build msbuild WeChatRobot.sln /t:Clean /p:Configuration=Release ``` **Build Outputs:** - `WeChatRobot.exe` → Release/ - `WeChatHelper.dll` → Release/ ## Architecture ### Project Structure ``` WeChatRobot/ ├── WeChatRobot/ # MFC GUI Client Application │ ├── *.cpp/*.h # Dialog implementations for each feature │ ├── data.h # Client-side data structures │ ├── message.h # Message definitions │ ├── WeChatRobot.vcxproj # Client project file │ └── WeChatRobot.rc # MFC resource file │ ├── WeChatHelper/ # DLL Injected into WeChat │ ├── *.cpp/*.h # Hook implementations │ ├── data.h # Server-side data structures │ ├── offset.h # WeChat function offsets/addresses │ ├── message.h # Message structures │ └── WeChatHelper.vcxproj # DLL project file │ ├── assets/ # Documentation images ├── Release/ # Build outputs └── WeChatRobot.sln # Visual Studio solution ``` ### Component Communication **WeChatRobot (Client):** - MFC dialog-based application - Provides GUI for all operations - Sends commands to WeChatHelper via WM_COPYDATA - Receives data back from WeChatHelper - Handles user interactions and displays results **WeChatHelper (Server/DLL):** - Injected into WeChat process via `CInjectTools` - Hooks WeChat functions using addresses defined in `offset.h` - Intercepts messages, handles, and operations - Communicates back to WeChatRobot via WM_COPYDATA ### Key Data Structures **Communication Structures** (defined in both `data.h` files): - `MessageStruct` - Generic communication messages - `ChatMessageData` - Chat message data (type, source, sender, content) - `PersonalInformation` - WeChat user profile information - `UserInfo` / `UserInfoDetail` - Friend/group member information - `XmlCardMessage` - WeChat card messages - `AtMsg` - @ message in groups - `SendXmlArticleStruct` - XML article messages **Message Types** are handled via the message structures in `message.h`. ### Core Offset Addresses The `WeChatHelper/offset.h` file contains hardcoded offsets for WeChat 2.6.8.52: - Function hooks: `WxSendMessage`, `WxReciveMessage`, `WxFriendList`, etc. - Data offsets: `MsgContentOffset`, `MsgSourceOffset`, `WxidOffset`, etc. - Self info base: `WxSelfInfoBase` with various member offsets ⚠️ These offsets are version-specific and will not work with newer WeChat versions. ## Development Workflow ### Adding New Features 1. **In WeChatRobot (Client):** - Create new dialog class (e.g., `CNewFeature.cpp/h`) - Add to resource file (`WeChatRobot.rc`) - Implement UI and command handling - Send WM_COPYDATA messages to WeChatHelper 2. **In WeChatHelper (Server):** - Implement hook/operation logic - Handle WM_COPYDATA messages - Use offsets from `offset.h` for hooking ### Inter-Process Communication **Sending from WeChatRobot:** ```cpp COPYDATASTRUCT cds; cds.dwData = COMMAND_TYPE; cds.cbData = sizeof(DataStruct); cds.lpData = &dataStruct; // Send to WeChatHelper window ::SendMessage(helperWindowHWND, WM_COPYDATA, (WPARAM)this->m_hWnd, (LPARAM)&cds); ``` **Receiving in WeChatHelper:** ```cpp BOOL CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_COPYDATA) { COPYDATASTRUCT* pCopyData = (COPYDATASTRUCT*)lParam; // Process command based on pCopyData->dwData } } ``` ### Testing 1. Start WeChat (version 2.6.8.52) 2. Copy `WeChatRobot.exe` and `WeChatHelper.dll` to same directory 3. Run `WeChatRobot.exe` 4. Click "注入" to inject DLL into WeChat process 5. Test features through the GUI ## Technical Notes ### Dependency Injection The `CInjectTools` class handles DLL injection into WeChat process. It locates the WeChat window and uses Windows API to inject `WeChatHelper.dll`. ### Hooking Mechanism WeChatHelper uses function hooking to intercept WeChat operations: - Calculates actual function addresses using base address + offset - Hooks functions by replacing prologue with jump instructions - Intercepts messages before they're processed by WeChat ### Message Handling All chat messages are intercepted and parsed. The system extracts: - Message type (text, image, file, etc.) - Sender information - Message content - Source (group or individual chat) ### Known Limitations - **Version锁定**: Only works with WeChat 2.6.8.52 - **Architecture依赖**: Uses hardcoded offsets that change between versions - **稳定性**: 多年未维护,可能存在兼容性问题 - **仅供学习**: 不应用于生产环境或商业用途 ## Security Considerations ⚠️ **Warning**: This project involves: - DLL injection into another process - Function hooking and code interception - Reverse engineering of proprietary software Use only for educational purposes in controlled environments. Do not use for: - Violating WeChat's terms of service - Unauthorized automation or spam - Commercial applications - Any illegal activities ## Documentation and Resources - **README.md** - Project overview and feature list with screenshots - **assets/** - Screenshots and documentation images - **CSDN Blog Posts** (referenced in README): - PC微信逆向:HOOK拦截二维码 - PC微信逆向:发送与接收消息分析 - PC微信逆向:数据库文件解密 ## Common Tasks ### Building for Production Use Release configuration with static MFC linking for standalone executables: - Win32 Release: Static MFC linking - x64 Release: Dynamic MFC linking with Whole Program Optimization ### Debugging Use Debug configuration to troubleshoot issues: - Debug information enabled - Runtime checks enabled - Multi-threaded debug runtime library ### Adding New Message Types 1. Define struct in both `WeChatRobot/data.h` and `WeChatHelper/data.h` 2. Add to `MessageUnion` in WeChatHelper's data.h 3. Implement handler in both projects 4. Update WM_COPYDATA command types ### Modifying Offsets When WeChat updates, new offsets must be found using: - Debugger (x64dbg/OllyDbg) - Disassembler (IDA Pro) - Memory scanning tools Process: 1. Attach debugger to WeChat 2. Locate target function 3. Find data structure offsets 4. Update `offset.h` 5. Rebuild and test ## Legal and Ethical Use **This project is provided "as is" for educational purposes only.** - Use only on your own systems - Do not violate WeChat's terms of service - Respect user privacy and data protection laws - Do not use for spam, harassment, or illegal activities - Authors disclaim all liability for misuse The author explicitly states this project is not maintained and should be used for learning about Windows programming, MFC, and reverse engineering techniques only. ================================================ FILE: README.md ================================================ # WeChatRobot > ⚠️ **本项目已停止维护,仅供学习参考** 📖 **完整项目文档请查看:[README_DETAILS.md](README_DETAILS.md)** --- ## 个人动态 微信相关的项目已经不在维护 最近**全职在做海外SaaS产品**,目前已经实现**月入千刀**,正在向**月入万刀**的目标前进! **如果你也对此有兴趣,欢迎关注我的社媒** **如果你也在做同样的事情,欢迎在推特私信和我交流** ## 推特 @guishou_56 ![推特](assets/推特.png) ### 公众号 Niko的出海记录 ![公众号](assets/公众号.png) ## 即刻 Niko_ ![即刻](assets/即刻.jpg) --- ## 鬼手社交小课堂 技术大哥们,加我之前请务必学习一下我的什么叫有效社交和无效社交 ### 无效社交 ![无效社交](assets/339745f975e9ea32d43a623e2fbaae7f.jpg) 上来直接躺尸,不懂商业互吹,不懂提供价值=无效社交;”看看有没有合作机会“,中译中,“看看有没有白嫖的机会” 从github加过来的,我没见过一个会主动夸人的;加之前想清楚能给我提供什么价值,提供不了请不要加好友,我还得删,挺累的 我本来不想说的这么直接,但是没办法,搞技术的情商实在太低了,搞的我烦不胜烦,不直接不行! ## 有效社交 ![有效社交](assets/fsfdsfds.jpg) 有效社交=上来肯定对方+商业互吹+自我介绍+提供价值 ================================================ FILE: README_DETAILS.md ================================================ # 项目详细信息 ## 实现功能 ![WeChatHelper](assets/WeChatHelper.png) ## 项目介绍 编译环境为VS2017 只支持微信2.6.8.52版本。附上2.6.8.52微信版本的安装包 链接:https://pan.baidu.com/s/1kZTBDPHNSSbyC1tVP-Lj8g 提取码:d9oj ![1563679851680](assets/1563679851680.png) ![1563679859287](assets/1563679859287.png) 项目分为两个端,WeChatRobot和WeChatHelper。WeChatRobot作为客户端负责和服务端进行通信,将服务端传回的数据显示到界面。WeChatHelper作为服务端,注入到微信进程,进行取数据和HOOK的相关操作,并且将取回的数据发回给客户端。 客户端和服务端之间采用WM_COPYDATA的方式进行进程通讯,互相传输数据 ## 效果演示 下面演示部分效果 ### 初始化 将WeChatRobot.exe和WeChatHelper.dll放在同一个目录下,先打开微信,再打开exe ![1563680573456](assets/1563680573456.png) ### 截取二维码 ![1563680585192](assets/1563680585192.png) 点击显示二维码 微信会自动跳转并截取二维码显示到客户端,再次点击可以刷新二维码 ### 检测微信登陆状态&显示所有联系人 ![显示联系人](assets/显示联系人.gif) 这里由于WM_COPYDATA通信状态下是阻塞的原因 所以联系人多的话可能会有些卡顿 ### 发送文本 图片 和文件消息 ![发送文本 图片 文件消息](assets/发送文本 图片 文件消息.gif) ### 添加&删除好友 ![添加和删除好友](assets/添加和删除好友.gif) ### 接收并显示所有类型消息 ![1563686929418](assets/1563686929418.png) ### 无限多开 ![1563687391099](assets/1563687391099.png) ### 解密数据库 ![解密数据库](assets/解密数据库.gif) ### 自动聊天 ![自动聊天](assets/自动聊天.gif) ### 自动收款 ![自动收款](assets/自动收款.gif) ### 自动提取微信表情 微信的表情加密存放在下面的目录 ``C:\Users\GuiShou\Documents\WeChat Files\crt873217126\FileStorage\CustomEmotion`` ![1563686532775](assets/1563686532775.png) 这个功能会将所有的未加密的表情存放到Temp目录下的WeChatExpressions文件夹里 还有很多效果,就不一一录制演示Gif了 ## 技术细节 PCXX逆向:使用HOOK拦截二维码:https://blog.csdn.net/qq_38474570/article/details/92798577 PCXX逆向:发送与接收消息的分析与代码实现:https://blog.csdn.net/qq_38474570/article/details/93339861 PC微信逆向:两种姿势教你解密数据库文件:https://blog.csdn.net/qq_38474570/article/details/96606530 ## 声明 **本项目仅供技术研究,请勿用于任何商业用途,请勿用于非法用途,如有任何人凭此做何非法事情,均于作者无关,特此声明。** ================================================ FILE: WeChat 3.2.1.154安装包下载.txt ================================================ 链接:https://pan.baidu.com/s/1Eqmwo3vt-RRh4rVxCM5v8g 提取码:1x09 --来自百度网盘超级会员V6的分享 ================================================ FILE: WeChatHelper/CAutoFunction.cpp ================================================ #include "stdafx.h" #include "CAutoFunction.h" #include "Function.h" #include #include //_mkdirͷļ #include //_accessͷļ #include #include #include #include "ChatRecord.h" #include #include #include #include #pragma comment(lib,"Shlwapi.lib") #pragma comment(lib,"Wininet.lib") //------------------------------------------------------------------------------------------------ BYTE bjmpcode[5] = { 0 }; DWORD dwReternAddress = (DWORD)GetModuleHandle(L"WeChatWin.dll") + WxGetExpressionsAddr + 5; //صַ DWORD dwCallAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll") + WxGetExpressionsCallAddr; //************************************************************ // : AgreeUserRequest // ˵: ͬ // : GuiShou // ʱ : 2019/7/17 // : v1 v2 // ֵ: void //************************************************************ void AgreeUserRequest(wchar_t* v1, wchar_t* v2) { DWORD base = GetWeChatWinBase(); DWORD callAdd1 = base + WxAgreeUserRequestCall1; DWORD callAdd2 = base + WxAgreeUserRequestCall2; DWORD callAdd3 = base + WxAgreeUserRequestCall3; DWORD callAdd4 = base + WxAgreeUserRequestCall4; DWORD params = base + WxAgreeUserRequestParam; DWORD* asmP = (DWORD*)params; v1Info userInfoV1 = { 0 }; v2Info userInfoV2 = { 0 }; userInfoV1.v2 = (DWORD)&userInfoV2.fill; userInfoV1.v1 = v1; userInfoV1.v1Len = wcslen(v1); userInfoV1.maxV1Len = wcslen(v1) * 2; userInfoV2.v2 = v2; userInfoV2.v2Len = wcslen(v2); userInfoV2.maxV2Len = wcslen(v2) * 2; char* asmUser = (char*)&userInfoV1.fill; char buff[0x14] = { 0 }; char buff2[0x48] = { 0 }; char* asmBuff = buff2; __asm { mov ecx, asmUser; push 0x11; sub esp, 0x14; push esp; call callAdd1; mov ecx, asmUser; lea eax, buff; push eax; call callAdd2; mov esi, eax; sub esp, 0x8; mov ecx, asmP; call callAdd3; mov ecx, asmBuff; mov edx, ecx; push edx; push eax; push esi; call callAdd4; } } //************************************************************ // : AutoAgreeUserRequest // ˵: Զͬ // : GuiShou // ʱ : 2019/7/17 // : msg Ϣ // ֵ: void //************************************************************ void AutoAgreeUserRequest(wstring msg) { int v1strat = msg.find(L"v3_"); int v1end = msg.find(L"@stranger"); wstring v1; v1 = msg.substr(v1strat, v1end - v1strat + 9); //ҵv2 int v2strat = msg.find(L"v4_"); int v2end = msg.rfind(L"@stranger"); wstring v2; v2 = msg.substr(v2strat, v2end - v2strat + 9); //ͬcall AgreeUserRequest((wchar_t*)v1.c_str(), (wchar_t*)v2.c_str()); } //************************************************************ // : CllectMoney // ˵: տ // : GuiShou // ʱ : 2019/7/15 // : transferid תID wxid ΢ID // ֵ: void //************************************************************ void CllectMoney(wchar_t* transferid, wchar_t* wxid) { CllectMoneyStruct cllect; cllect.ptransferid = transferid; cllect.transferidLen = wcslen(transferid) + 1; cllect.transferidMaxLen = (wcslen(transferid) + 1) * 2; cllect.pwxid = wxid; cllect.wxidLen = wcslen(wxid) + 1; cllect.wxidMaxLen = (wcslen(wxid) + 1) * 2; char* asmBuff = (char*)&cllect.ptransferid; DWORD dwWeChatWinAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); DWORD dwCall1 = dwWeChatWinAddr + WxCllectMoneyCall1; DWORD dwCall2 = dwWeChatWinAddr + WxCllectMoneyCall2; __asm { sub esp, 0x30; mov ecx, esp; mov eax, asmBuff; push eax; call dwCall1; call dwCall2; add esp, 0x30; } } //************************************************************ // : AutoCllectMoney // ˵: Զտ // : GuiShou // ʱ : 2019/7/17 // : msg Ϣ // ֵ: void //************************************************************ void AutoCllectMoney(wstring msg,wchar_t* wxid) { // ҵַλ int pos1 = msg.find(L""); //ҵ]]>ַλ int pos2 = msg.find(L"]]>"); //ȡַ wstring noneed = L"tm_year + 1900, ptminfo->tm_mon + 1, ptminfo->tm_mday, ptminfo->tm_hour, ptminfo->tm_min, ptminfo->tm_sec); //ƴ· char filepath[MAX_PATH] = { 0 }; sprintf_s(filepath, "%s%s%s", filedir, currenttime, filepostfix); //ļ HANDLE hFile = CreateFileA(filepath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { MessageBoxA(NULL, "ļʧ", "", 0); return; } //дļ DWORD dwWrite = 0; WriteFile(hFile, (LPCVOID)filedata, filedatalen, &dwWrite, 0); //رվ CloseHandle(hFile); } //************************************************************ // : CreateDir // ˵: Ŀ¼ // : GuiShou // ʱ : 2019/7/21 // : dir Ŀ¼ // ֵ: void //************************************************************ void CreateDir(const char *dir) { int m = 0, n; string str1, str2; str1 = dir; str2 = str1.substr(0, 2); str1 = str1.substr(3, str1.size()); while (m >= 0) { m = str1.find('\\'); str2 += '\\' + str1.substr(0, m); n = _access(str2.c_str(), 0); //жϸĿ¼Ƿ if (n == -1) { _mkdir(str2.c_str()); //Ŀ¼ } str1 = str1.substr(m + 1, str1.size()); } } //************************************************************ // : GetXmlContent // ˵: ȡҪXML // : GuiShou // ʱ : 2019/11/15 // : fullxmlcontent XML str1 ҪȡXMLߵַ str2 ҪȡXMLұߵַ // ֵ: wstring ҪȡXML //************************************************************ wstring GetXmlContent(wstring fullxmlcontent, wstring str1, wstring str2) { wstring targetstring; // ҵַλ int pos1 = fullxmlcontent.find(str1); //ҵַλ int pos2 = fullxmlcontent.find(str2); if (pos1==wstring::npos|| pos2== wstring::npos) { return L"NULL"; } //ȡַ wstring noneedString1 = str1; int noneedLen1 = noneedString1.length(); targetstring = fullxmlcontent.substr(pos1 + noneedLen1, pos2 - pos1 - noneedLen1); return targetstring; } ================================================ FILE: WeChatHelper/CAutoFunction.h ================================================ #pragma once #include void AgreeUserRequest(wchar_t* v1, wchar_t* v2); //ͬ void AutoAgreeUserRequest(wstring msg); //Զͬ void CllectMoney(wchar_t* transferid, wchar_t* wxid); //տ void AutoCllectMoney(wstring msg, wchar_t* wxid); //Զտ void AddCardUser(wchar_t* v1, wchar_t* msg); //Ƭ void AutoAddCardUser(wstring msg); //ԶƬ void CreateDir(const char *dir); //Ŀ¼ void ExtractExpression(); //ȡ void HookExtractExpression();//HOOKȡ void __stdcall OutputExpression(DWORD dwExpressionAddr); // void CreateFileWithCurrentTime(char* filedir, char* filepostfix, DWORD filedata, DWORD filedatalen); //õǰʱ䴴ļ wstring GetXmlContent(wstring fullxmlcontent, wstring str1, wstring str2); //ȡҪXML ================================================ FILE: WeChatHelper/CPublic.cpp ================================================ #include "stdafx.h" #include "CPublic.h" //************************************************************ // : HookAnyAddress // ˵: Hookַ // : GuiShou // ʱ : 2019/11/13 // : dwHookAddr ҪHOOKĵַ dwJmpAddressתĵַ dwBackAddress صĵַ // ֵ: void //************************************************************ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress) { //װת BYTE jmpCode[5] = { 0 }; jmpCode[0] = 0xE9; //ƫ *(DWORD*)& jmpCode[1] = (DWORD)dwJmpAddress - dwHookAddr - 5; // ǰڻԭ DWORD OldProtext = 0; // ΪҪдݣΪDzдģҪ޸ VirtualProtect((LPVOID)dwHookAddr, 5, PAGE_EXECUTE_READWRITE, &OldProtext); //дԼĴ memcpy((void*)dwHookAddr, jmpCode, 5); // ִ˲֮Ҫлԭ VirtualProtect((LPVOID)dwHookAddr, 5, OldProtext, &OldProtext); } //************************************************************ // : GetWeChatWinBase // ˵: ȡWeChatWinַ // : GuiShou // ʱ : 2019/11/13 // : void // ֵ: void //************************************************************ DWORD GetWeChatWinBase() { return (DWORD)GetModuleHandle(TEXT("WeChatWin.dll")); } //************************************************************ // : UTF8ToUnicode // ˵: UTF8תΪUnicode(΢ĬϱΪUTF8) // : GuiShou // ʱ : 2019/7/7 // : str Ҫתַ // ֵ: wchar_t صַ //************************************************************ wchar_t * UTF8ToUnicode(const char* str) { int textlen = 0; wchar_t * result; textlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); result = (wchar_t *)malloc((textlen + 1) * sizeof(wchar_t)); memset(result, 0, (textlen + 1) * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, str, -1, (LPWSTR)result, textlen); return result; } wstring UTF8ToUnicode2(const char* str) { int textlen = 0; wchar_t* result; textlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); result = (wchar_t *)malloc((textlen + 1) * sizeof(wchar_t)); memset(result, 0, (textlen + 1) * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8, 0, str, -1, (LPWSTR)result, textlen); wstring tempstr(result); free(result); result = NULL; return tempstr; } void DebugCode(LPVOID pAddress) { char buff[40] = { 0 }; sprintf_s(buff, "%p", pAddress); MessageBoxA(0, buff, "ַ", 0); } ================================================ FILE: WeChatHelper/CPublic.h ================================================ #pragma once #include using namespace std; void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress); //HOOKַ DWORD GetWeChatWinBase(); //ȡWeChatWinַ wchar_t * UTF8ToUnicode(const char* str); wstring UTF8ToUnicode2(const char* str); void DebugCode(LPVOID pAddress); ================================================ FILE: WeChatHelper/ChatRecord.cpp ================================================ #include "stdafx.h" #include #include #pragma comment(lib,"Shlwapi.lib") #include "ChatRecord.h" #include "FriendList.h" #include "CAutoFunction.h" #include "Function.h" #include #include #pragma comment(lib,"ws2_32.lib") using namespace std; #define SERVER_ADDRESS "127.0.0.1" //IPַ #define PORT 8080 //Ķ˿ں #define MSGSIZE 1024 //շĴС BOOL g_AutoChat = FALSE; //ǷԶ BOOL isSendTuLing = FALSE; //ǷѾ˻ wchar_t tempwxid[50]; //΢ID //صַ DWORD RetkReciveMsgAddr = GetWeChatWinBase() + WxReciveMessage + 5; //ǵcallĵַ DWORD OverReciveMsgCallAddr = GetWeChatWinBase() + WxReciveMessageCall; //************************************************************ // : HookChatRecord // ˵: HOOK¼ // : GuiShou // ʱ : 2019/7/6 // : void // ֵ: void //************************************************************ void HookChatRecord() { HookAnyAddress(GetWeChatWinBase() + WxReciveMessage, RecieveWxMesage); } //************************************************************ // : RecieveMesage // ˵: Ϣ // : GuiShou // ʱ : 2019/7/6 // : void // ֵ: void //************************************************************ __declspec(naked) void RecieveWxMesage() { //ֳ __asm { pushad; push eax; call SendWxMessage; popad; //ñǵcall call OverReciveMsgCallAddr; //תصַ jmp RetkReciveMsgAddr; } } //************************************************************ // : ReceiveMsgProc // ˵: Ϣ̻߳ص // : GuiShou // ʱ : 2019/11/8 // : Context // ֵ: void //************************************************************ void DealWithMsg(LPVOID Context) { try { ChatMessageData* msg = (ChatMessageData*)Context; BOOL isFriendMsg = FALSE; //ǷǺϢ BOOL isImageMessage = FALSE; //ǷͼƬϢ BOOL isRadioMessage = FALSE; //ǷƵϢ BOOL isVoiceMessage = FALSE; //ǷϢ BOOL isBusinessCardMessage = FALSE; //ǷƬϢ BOOL isExpressionMessage = FALSE; //ǷƬϢ BOOL isLocationMessage = FALSE; //ǷλϢ BOOL isSystemMessage = FALSE; //ǷϵͳϢ BOOL isPos_File_Money_XmlLink = FALSE; //Ƿλ ļ ת˺Ϣ BOOL isFriendRequestMessage = FALSE; //ǷǺϢ BOOL isOther = FALSE; //ǷϢ switch (msg->dwtype) { case 0x01: memcpy(msg->sztype, L"", sizeof(L"")); break; case 0x03: memcpy(msg->sztype, L"ͼƬ", sizeof(L"ͼƬ")); isImageMessage = TRUE; break; case 0x22: memcpy(msg->sztype, L"", sizeof(L"")); isVoiceMessage = TRUE; break; case 0x25: memcpy(msg->sztype, L"ȷ", sizeof(L"ȷ")); isFriendRequestMessage = TRUE; break; case 0x28: memcpy(msg->sztype, L"POSSIBLEFRIEND_MSG", sizeof(L"POSSIBLEFRIEND_MSG")); isOther = TRUE; break; case 0x2A: memcpy(msg->sztype, L"Ƭ", sizeof(L"Ƭ")); isBusinessCardMessage = TRUE; break; case 0x2B: memcpy(msg->sztype, L"Ƶ", sizeof(L"Ƶ")); isRadioMessage = TRUE; break; case 0x2F: //ʯͷ memcpy(msg->sztype, L"", sizeof(L"")); isExpressionMessage = TRUE; break; case 0x30: memcpy(msg->sztype, L"λ", sizeof(L"λ")); isLocationMessage = TRUE; break; case 0x31: //ʵʱλ //ļ //ת // //տ memcpy(msg->sztype, L"ʵʱλáļתˡ", sizeof(L"ʵʱλáļתˡ")); isPos_File_Money_XmlLink = TRUE; break; case 0x32: memcpy(msg->sztype, L"VOIPMSG", sizeof(L"VOIPMSG")); isOther = TRUE; break; case 0x33: memcpy(msg->sztype, L"΢ųʼ", sizeof(L"΢ųʼ")); isOther = TRUE; break; case 0x34: memcpy(msg->sztype, L"VOIPNOTIFY", sizeof(L"VOIPNOTIFY")); isOther = TRUE; break; case 0x35: memcpy(msg->sztype, L"VOIPINVITE", sizeof(L"VOIPINVITE")); isOther = TRUE; break; case 0x3E: memcpy(msg->sztype, L"СƵ", sizeof(L"СƵ")); isRadioMessage = TRUE; break; case 0x270F: memcpy(msg->sztype, L"SYSNOTICE", sizeof(L"SYSNOTICE")); isOther = TRUE; break; case 0x2710: //ϵͳϢ // memcpy(msg->sztype, L"ϵͳϢ", sizeof(L"ϵͳϢ")); isSystemMessage = TRUE; break; case 0x2712: //Ϣ memcpy(msg->sztype, L"Ϣ", sizeof(L"Ϣ")); break; default: break; } wstring fullmessgaedata(msg->content); //Ϣ wchar_t* tempcontent = msg->content; //Ϣ //΢IDжǷǺϢ wstring wxid_wstr = msg->wxid; if (wxid_wstr.find(L"@im.chatroom") != wxid_wstr.npos) { memcpy(msg->source, L"ҵ΢ȺϢ", sizeof(L"ҵ΢ȺϢ")); } else if (wxid_wstr.find(L"@chatroom") != wxid_wstr.npos) { memcpy(msg->source, L"ȺϢ", sizeof(L"ȺϢ")); } else { memcpy(msg->source, L"Ϣ", sizeof(L"Ϣ")); isFriendMsg = TRUE; memcpy(msg->sendername, L"NULL", sizeof(L"NULL")); } //΢IDתΪ΢dz/Ⱥ wstring transformwxid(msg->wxid); swprintf_s(msg->wxname, L"%s", GetNickNameByWxid(transformwxid).c_str()); //Ⱥ΢IDתΪdz if (isFriendMsg == FALSE) { //΢IDȡϸϢ swprintf_s(msg->sendername, L"%s", GetNicknameByWxid(msg->sender)); } //ʾϢ ޷ʾϢ ֹ if (StrStrW(msg->wxid, L"gh")) { isFriendMsg = FALSE; //˷Ϣ ϢѾ͸ if ((StrCmpW(msg->wxid, ChatRobotWxID) == 0) && isSendTuLing) { SendTextMessage(tempwxid, msg->content); isSendTuLing = FALSE; } //΢IDΪgh_3dfda90e39d6 ˵տϢ else if ((StrCmpW(msg->wxid, L"gh_3dfda90e39d6") == 0)) { swprintf_s(msg->content, L"%s", L"΢տ"); } else { //΢IDдgh ˵ǹں swprintf_s(msg->content, L"%s", L"ںŷ,ֻϲ鿴"); } } //ͼƬϢ else if (isImageMessage == TRUE) { swprintf_s(msg->content, L"%s", L"յͼƬϢ"); } else if (isRadioMessage == TRUE) { swprintf_s(msg->content, L"%s", L"յƵϢ,ֻϲ鿴"); } else if (isVoiceMessage == TRUE) { swprintf_s(msg->content, L"%s", L"յϢ,ֻϲ鿴"); } else if (isBusinessCardMessage == TRUE) { //ԶƬ //AutoAddCardUser(fullmessgaedata); swprintf_s(msg->content, L"%s", L"յƬϢ,ԶӺ"); } else if (isExpressionMessage == TRUE) { swprintf_s(msg->content, L"%s", L"յϢ,ֻϲ鿴"); } else if (isFriendRequestMessage == TRUE) { //Զͨ AutoAgreeUserRequest(fullmessgaedata); swprintf_s(msg->content, L"%s", L"յ,Զͨ"); } //XMLºԶתϢ else if (isPos_File_Money_XmlLink == TRUE) { //жǷתϢ //жǷתϢ if (StrStrW(tempcontent, L"2000")) { //Զտ memcpy(msg->sztype, L"תϢ", sizeof(L"תϢ")); AutoCllectMoney(fullmessgaedata, msg->wxid); swprintf_s(msg->content, L"%s", L"յתϢ,Զտ"); } //5 XMLºͽȺ else if (StrStrW(tempcontent, L"5")) { //Ⱥ if (fullmessgaedata.find(L"") != wstring::npos&&fullmessgaedata.find(L"sztype, L"Ⱥ", sizeof(L"Ⱥ")); swprintf_s(msg->content, L"%s", L"յȺ,ֻϲ鿴"); } //ѡ֪ͨ else if (fullmessgaedata.find(L"ѡ֪ͨ") != wstring::npos) { memcpy(msg->sztype, L"ѡ", sizeof(L"ѡ")); swprintf_s(msg->content, L"%s", L"ںѡ֪ͨ,ֻϲ鿴"); } else { // ˵XML memcpy(msg->sztype, L"XMLϢ", sizeof(L"XMLϢ")); swprintf_s(msg->content, L"%s", L"յXMLϢ,ֻϲ鿴"); } } //ļϢ else if (StrStrW(tempcontent, L"6")) { memcpy(msg->sztype, L"ļϢ", sizeof(L"ļϢ")); swprintf_s(msg->content, L"%s", L"յļ 뼰ʱ鿴"); } //ʵʱλϢ else if (StrStrW(tempcontent, L"17")) { memcpy(msg->sztype, L"ʵʱλ", sizeof(L"ʵʱλ")); swprintf_s(msg->content, L"%s", L"յʵʱλ ֻϲ鿴"); } //ϲת¼ else if (StrStrW(tempcontent, L"¼")) { memcpy(msg->sztype, L"¼Ϣ", sizeof(L"¼Ϣ")); swprintf_s(msg->content, L"%s", L"յϲת¼ ֻϲ鿴"); } } else if (isLocationMessage == TRUE) { swprintf_s(msg->content, L"%s", L"յλϢ,ֻϲ鿴"); } else if (isSystemMessage == TRUE) { //ﴦȺϢ if ((StrStrW(tempcontent, L"ƳȺ") || StrStrW(tempcontent, L"Ⱥ"))) { wcscpy_s(msg->content, wcslen(tempcontent) + 1, tempcontent); } else { swprintf_s(msg->content, L"%s", L"յϵͳϢ,ֻϲ鿴"); } } //Ϣ֮ else { //жϢ ȳͲʾ if (wcslen(tempcontent) > 200) { swprintf_s(msg->content, L"%s", L"Ϣݹ Ѿ"); } } //ﴦԶ if (isFriendMsg == TRUE && g_AutoChat == TRUE && isSendTuLing == FALSE) { //һ΢ID wcscpy_s(tempwxid, wcslen(msg->wxid) + 1, msg->wxid); //õϢ SendTextMessage((wchar_t*)ChatRobotWxID, msg->content); isSendTuLing = TRUE; } //͵ƶ HWND hWnd = FindWindow(NULL, TEXT("΢")); if (hWnd == NULL) { OutputDebugStringA("δҵ΢ִ"); return; } COPYDATASTRUCT chatmsg; chatmsg.dwData = WM_ShowChatRecord;//һֵ, ־ chatmsg.cbData = sizeof(ChatMessageData);// strlen(szSendBuf);//͵ݵij chatmsg.lpData = msg;// szSendBuf;//͵ݵʼַ(ΪNULL) SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&chatmsg); delete msg; } catch (...) { OutputDebugStringA("¼쳣"); } } //************************************************************ // : SendMessage // ˵: յϢ͸ͻ // : GuiShou // ʱ : 2019/7/6 // : void // ֵ: void //************************************************************ void __stdcall SendWxMessage(DWORD r_eax) { if (IsBadReadPtr((void*)r_eax, 4) || IsBadReadPtr((void*)(r_eax + MsgTypeOffset), 4) || IsBadReadPtr((void*)(r_eax + MsgContentOffset), 4) || IsBadReadPtr((void*)(r_eax + WxidOffset), 4) || IsBadReadPtr((void*)(r_eax + GroupMsgSenderOffset), 4)) { return; } try { ChatMessageData* msg = new ChatMessageData; //ȡϢ msg->dwtype = *((DWORD*)(r_eax + MsgTypeOffset)); //ȡϢ LPVOID pContent = *((LPVOID *)(r_eax + MsgContentOffset)); swprintf_s(msg->content, L"%s", (wchar_t*)pContent); //ȡ΢ID/ȺID LPVOID pWxid = *((LPVOID *)(r_eax + WxidOffset)); swprintf_s(msg->wxid, L"%s", (wchar_t*)pWxid); if (StrStrW(msg->wxid, L"gh_")) { return; } //ȡϢ LPVOID pSender = *((LPVOID *)(r_eax + GroupMsgSenderOffset)); swprintf_s(msg->sender, L"%s", (wchar_t*)pSender); //ȡϢ LPVOID pSource = *((LPVOID *)(r_eax + MsgSourceOffset)); swprintf_s(msg->source, L"%s", (wchar_t*)pSource); //̴߳Ϣ HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DealWithMsg, msg, 0, NULL); CloseHandle(hThread); } catch (...) { OutputDebugStringA("Ϣ쳣...."); } } //************************************************************ // : GetMsgByAddress // ˵: ӵַлȡϢ // : GuiShou // ʱ : 2019/7/6 // : DWORD memAddress Ŀַ // ֵ: LPCWSTR Ϣ //************************************************************ std::wstring GetMsgByAddress(DWORD memAddress) { wstring tmp; DWORD msgLength = *(DWORD*)(memAddress + 4); if (msgLength > 0) { WCHAR* msg = new WCHAR[msgLength + 1]{ 0 }; wmemcpy_s(msg, msgLength + 1, (WCHAR*)(*(DWORD*)memAddress), msgLength + 1); tmp = msg; delete[]msg; } return tmp; } ================================================ FILE: WeChatHelper/ChatRecord.h ================================================ #pragma once #include void HookChatRecord(); //HOOK¼ void RecieveWxMesage(); //΢Ϣ void __stdcall SendWxMessage(DWORD r_eax); //΢Ϣͻ std::wstring GetMsgByAddress(DWORD memAddress); //ӵַлȡϢ ================================================ FILE: WeChatHelper/ChatRoomOperate.cpp ================================================ #include "stdafx.h" #include "ChatRoomOperate.h" #include //************************************************************ // : SetWxRoomAnnouncement // ˵: Ⱥ // : GuiShou // ʱ : 2019/7/4 // : chartoomwxid ȺID Announcement Ⱥ // ֵ: void //************************************************************ void SetWxRoomAnnouncement(wchar_t* chatroomwxid, wchar_t* Announcement) { //ȡWeChatWinĻַ DWORD callAdrress = GetWeChatWinBase()+ WxSetRoomAnnouncement; //װ CHAR bufferA[0xD0] = { 0 }; DWORD* bufA = (DWORD*)& bufferA; CHAR buffer[0xD0] = { 0 }; DWORD* buf = (DWORD*)& buffer; buf[0] = (DWORD)chatroomwxid; buf[1] = wcslen(chatroomwxid); buf[2] = wcslen(chatroomwxid) * 2; buf[3] = 0; buf[4] = 0; buf[0 + 5] = (DWORD)Announcement; buf[1 + 5] = wcslen(Announcement); buf[2 + 5] = wcslen(Announcement) * 2; buf[3 + 5] = 0; buf[4 + 5] = 0; bufA[0] = (DWORD)& buffer; bufA[1] = bufA[0] + 0x60; bufA[2] = bufA[0] + 0x60; DWORD r_esp = 0; __asm { //ջĴ mov r_esp, esp; lea eax, bufferA; push eax; call callAdrress; //ָջĴ mov eax, r_esp; mov esp, eax; } } //************************************************************ // : QuitChatRoom // ˵: ˳Ⱥ // : GuiShou // ʱ : 2019/7/9 // : chartoomwxid ȺID // ֵ: void //************************************************************ void QuitChatRoom(wchar_t* chatroomwxid) { DWORD dwBaseAddress = GetWeChatWinBase(); DWORD dwCallAddr = dwBaseAddress + WxQuitChatRoom; // GeneralStruct structWxid(chatroomwxid); DWORD* asmMsg = (DWORD*)&structWxid.pstr; __asm { mov ebx, asmMsg; push ebx; call dwCallAddr; } } //************************************************************ // : AddGroupMember // ˵: ȺԱ // : GuiShou // ʱ : 2019/7/9 // : chartoomwxid ȺID wxid ΢ID // ֵ: void //************************************************************ void AddGroupMember(wchar_t* chatroomwxid, wchar_t* wxid) { DWORD dwBase = GetWeChatWinBase(); DWORD dwCallAddr1 = dwBase + WxAddGroupMemberCall1; DWORD dwCallAddr2 = dwBase + WxAddGroupMemberCall2; DWORD dwCallAddr3 = dwBase + WxAddGroupMemberCall3; DWORD dwCallAddr4 = dwBase + WxAddGroupMemberCall4; DWORD dwParam = dwBase + WxAddGroupMemberParam1; DWORD dwParam2 = dwBase + WxAddGroupMemberParam2; //Ҫ GeneralStruct wxidStruct(wxid); RoomIdStruct chatroomStruct = { 0 }; chatroomStruct.str = chatroomwxid; chatroomStruct.strLen = wcslen(chatroomwxid)*2; chatroomStruct.maxLen = wcslen(chatroomwxid) * 4; char wxidBuff[0xC] = { 0 }; char tempWxid[0x14] = { 0 }; char tempBuff[0x14] = { 0 }; char* pWxid = (char*)&wxidStruct.pstr; char* pChatRoom = (char*)&chatroomStruct.fill2; __asm { pushad; lea esi, wxidBuff; mov ecx, esi; mov eax, pWxid; push eax; call dwCallAddr1; push 0; push dwParam; lea ecx, tempWxid; call dwCallAddr2; sub esp, 0x14; mov ecx, pChatRoom; mov eax, esp; push eax; call dwCallAddr3; push esi; mov ecx, dwParam2; call dwCallAddr4; popad; } } //************************************************************ // : ShowChatRoomUser // ˵: ʾȺԱ // : GuiShou // ʱ : 2019/7/13 // : void // ֵ: void //************************************************************ void ShowChatRoomUser(wchar_t* chatroomwxid) { //׼ DWORD dwWxidArr = 0; //΢IDݵĵַ char buff[0x164] = { 0 }; char userListBuff[0x174] = { 0 }; // GeneralStruct pWxid(chatroomwxid); char* asmWxid = (char *)&pWxid.pstr; //call DWORD dwCall1 = GetWeChatWinBase() + WxGetRoomUserWxidCall1; DWORD dwCall2 = GetWeChatWinBase() + WxGetRoomUserWxidCall2; DWORD dwCall3 = GetWeChatWinBase() + WxGetRoomUserWxidCall3; DWORD dwCall4 = GetWeChatWinBase() + WxGetRoomUserWxidCall4; //ȡȺԱ __asm { lea ecx, buff[16]; call dwCall1; lea eax, buff[16]; push eax; mov ebx, asmWxid; push ebx; call dwCall2; mov ecx, eax; call dwCall3; lea eax, buff; push eax; lea ecx, buff[16]; call dwCall4; mov dwWxidArr, eax; } //õ΢ID wchar_t test[0x100] = { 0 }; wchar_t tempWxid[0x100] = { 0 }; char tempWxidA[0x100] = { 0 }; DWORD userList = *((DWORD *)dwWxidArr); //userList΢IDб 3.1ASCIIʽ΢ID DWORD testTmp = dwWxidArr + 0xB4; int Len = *((int *)testTmp); //ȡ΢IDĸ for (int i = 0; i < Len; i++) { DWORD temWxidAdd = userList + (i * 0x18); //0x18ÿ΢IDļ int flags = (int)(*((LPVOID*)(temWxidAdd + 0x14))); if (flags == 0xF) { sprintf_s(tempWxidA, "%s", (char*)temWxidAdd); } else { sprintf_s(tempWxidA, "%s", (char*)*((LPVOID *)temWxidAdd)); } USES_CONVERSION; //2.ͨ΢IDȡȺԱϢ GetUserInfoByWxid(A2W(tempWxidA)); } //֮Ϣ HWND hWnd = FindWindow(NULL, TEXT("ChatRoomMember")); if (hWnd == NULL) { OutputDebugStringA("δҵChatRoomMember"); return; } COPYDATASTRUCT userinfodata; userinfodata.dwData = WM_ShowChatRoomMembersDone;//һֵ, ־ userinfodata.cbData = 0;// strlen(szSendBuf);//͵ݵij userinfodata.lpData = NULL;// szSendBuf;//͵ݵʼַ(ΪNULL) SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&userinfodata); } //************************************************************ // : GetUserInfoByWxid // ˵: ͨ΢IDȡûϢ // : GuiShou // ʱ : 2019/7/13 // : userwxid ΢ID // ֵ: void //************************************************************ void GetUserInfoByWxid(wchar_t* userwxid) { DWORD WechatBase = (DWORD)GetModuleHandle(L"WeChatWin.dll"); DWORD dwCall1 = WechatBase + WxGetUserInfoWithNoNetworkCall1; DWORD dwCall2 = WechatBase + WxGetUserInfoWithNoNetworkCall2; DWORD dwCall3 = WechatBase + WxGetUserInfoWithNoNetworkCall3; char buff[0x508] = { 0 }; char * asmHeadBuff = buff; char * asmBuff = &buff[0x18]; GeneralStruct pWxid(userwxid); char* asmWxid = (char*)&pWxid.pstr; __asm { pushad; mov edi, asmWxid; //΢IDṹ mov eax, asmBuff; // push eax; sub esp, 0x14; mov ecx, esp; push - 0x1; mov dword ptr ds : [ecx], 0x0; mov dword ptr ds : [ecx + 0x4], 0x0; mov dword ptr ds : [ecx + 0x8], 0x0; mov dword ptr ds : [ecx + 0xC], 0x0; mov dword ptr ds : [ecx + 0x10], 0x0; push dword ptr ds : [edi]; //΢ID call dwCall1; //call1 call dwCall2; //call2 mov eax, asmHeadBuff; push eax; mov ecx, asmBuff; call dwCall3; popad } LPVOID lpWxid = *((LPVOID *)((DWORD)buff + 0x20)); //΢ID LPVOID lpWxcount = *((LPVOID *)((DWORD)buff + 0x34)); //΢˺ LPVOID lpNickName = *((LPVOID *)((DWORD)buff + 0x7C)); //dz //װṹ UserInfo *userinfo = new UserInfo; swprintf_s(userinfo->UserId, L"%s", (wchar_t*)lpWxid); swprintf_s(userinfo->UserNickName, L"%s", (wchar_t*)lpNickName); swprintf_s(userinfo->UserNumber, L"%s", (wchar_t*)lpWxcount); //͵ͻ HWND hWnd = FindWindow(NULL, TEXT("ChatRoomMember")); if (hWnd == NULL) { OutputDebugStringA("δҵChatRoomMember"); return; } COPYDATASTRUCT userinfodata; userinfodata.dwData = WM_ShowChatRoomMembers;//һֵ, ־ userinfodata.cbData = sizeof(UserInfo);// strlen(szSendBuf);//͵ݵij userinfodata.lpData = userinfo;// szSendBuf;//͵ݵʼַ(ΪNULL) SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&userinfodata); delete userinfo; } //************************************************************ // : SetRoomName // ˵: ޸Ⱥ // : GuiShou // ʱ : 2019/7/14 // : roomwxid ȺID roomnameȺ // ֵ: void //************************************************************ void SetRoomName(wchar_t* roomwxid, wchar_t* roomname) { GeneralStruct pRoomwxid(roomwxid); GeneralStruct pRoomname(roomname); char* asmWxid = (char*)&pRoomwxid.pstr; char* asmRoomname = (char*)&pRoomname.pstr; DWORD dwWeChatWinAddr = GetWeChatWinBase(); DWORD dwCall1 = dwWeChatWinAddr + WxSetRoomName; __asm { mov edx, asmRoomname; mov ecx, asmWxid; call dwCall1; } } //************************************************************ // : SendRoomAtMsg // ˵: ͰϢ // : GuiShou // ʱ : 2019/7/26 // : chatroomid ȺID memberwxid ȺԱ΢ID membernicknameȺԱdz msg Ϣ // ֵ: void //************************************************************ void SendRoomAtMsg(wchar_t* chatroomid, wchar_t* memberwxid, wchar_t* membernickname, wchar_t* msg) { //callװݸʽ DWORD dwDllBase = GetWeChatWinBase(); DWORD dwPackageMsgDataCall = dwDllBase + WxPackageMsgData; DWORD dwSendTextCall = dwDllBase + WxSendMessage; //װı wchar_t tempmsg[500] = { 0 }; swprintf_s(tempmsg, L"@%s %s", membernickname, msg); //װ΢IDݽṹ GeneralStruct wxid(memberwxid); //װȺIDݽṹ GeneralStruct roomid(chatroomid); //װϢıݽṹ GeneralStruct textcontent(tempmsg); //0x81C BYTE buff[0x81C] = { 0 }; //΢IDݽṹָ wchar_t* pWxid = (wchar_t*)&wxid.pstr; //ȺIDݽṹָ wchar_t* pRoomId = (wchar_t*)&roomid.pstr; //Ϣıݽṹָ wchar_t* pTextContent = (wchar_t*)&textcontent.pstr; //װݽṹ建 char databuff[16] = { 0 }; //װݸʽcall __asm { mov eax, pWxid; //΢IDṹ push eax; lea ecx, databuff; call dwPackageMsgDataCall; } //callͰϢ __asm { mov edx, pRoomId; //ȺIDṹ lea eax, databuff; //װݽṹ push 0x1; push eax; mov ebx, pTextContent; //Ϣıָ push ebx; lea ecx, buff; //0x81C call dwSendTextCall; //Ϣcall add esp, 0xC; } } //************************************************************ // : DelRoomMember // ˵: ɾȺԱ // : GuiShou // ʱ : 2019/7/26 // : roomid ȺID memberwxid ȺԱ΢ID // ֵ: void //************************************************************ void DelRoomMember(wchar_t* roomid, wchar_t* memberwxid) { //õcallݵַ DWORD dwCall1 = GetWeChatWinBase() + WxDelRoomMemberCall1; DWORD dwCall2 = GetWeChatWinBase() + WxDelRoomMemberCall2; DWORD dwCall3 = GetWeChatWinBase() + WxDelRoomMemberCall3; //װȺIDṹ GeneralStruct roomiddata(roomid); //װ΢IDṹ wchar_t wxidbuff[0xD0] = { 0 }; DWORD* dwBuff = (DWORD*)&wxidbuff; dwBuff[0] = (DWORD)memberwxid; dwBuff[1] = wcslen(memberwxid); dwBuff[2] = wcslen(memberwxid) * 2; dwBuff[3] = 0; dwBuff[4] = 0; wchar_t datatbuffer[0xD0] = { 0 }; DWORD* dwDatabuf = (DWORD*)&datatbuffer; dwDatabuf[0] = (DWORD)& wxidbuff; dwDatabuf[1] = dwDatabuf[0] + 0x14; dwDatabuf[2] = dwDatabuf[0] + 0x14; __asm { pushad; sub esp, 0x14; mov ecx, esp; lea ebx, roomiddata.pstr; push ebx; call dwCall1; lea edi, datatbuffer; push edi; call dwCall2; mov ecx, eax; call dwCall3; popad; } } ================================================ FILE: WeChatHelper/ChatRoomOperate.h ================================================ #pragma once void SetWxRoomAnnouncement(wchar_t* chatroomwxid,wchar_t* Announcement); //Ⱥ void QuitChatRoom(wchar_t* chatroomwxid); //˳Ⱥ void AddGroupMember(wchar_t* chatroomwxid, wchar_t* wxid); //ȺԱ void ShowChatRoomUser(wchar_t* chatroomwxid); //ʾȺԱ void GetUserInfoByWxid(wchar_t* userwxid); //ͨ΢IDȡûϢ void SetRoomName(wchar_t* roomwxid, wchar_t* roomname); //޸Ⱥ void DelRoomMember(wchar_t* roomid, wchar_t* memberwxid); //ɾȺԱ void SendRoomAtMsg(wchar_t* chatroomid, wchar_t* memberwxid, wchar_t* membernickname, wchar_t* msg); //ͰϢ ================================================ FILE: WeChatHelper/FriendList.cpp ================================================ #include "stdafx.h" #include "FriendList.h" #include "shellapi.h" #include #include #include #include #include #include #include "ChatRecord.h" #pragma comment(lib, "Version.lib") //кбmap map g_userinfolist; DWORD overWritedCallAdd= GetWeChatWinBase() + WxFriendListCall; DWORD jumBackAddress= GetWeChatWinBase() + WxFriendList+5; //Ƽб wstring g_referencenumber[11] = { L"fmessage",L"qqmail",L"medianote",L"qmessage",L"newsapp",L"filehelper" L"weixin", L"tmessage", L"mphelper",L"gh_7aac992b0363", L"qqsafe" }; //************************************************************ // : HookGetFriendList // ˵: HOOKȡбcall // : GuiShou // ʱ : 2019/7/4 // : void // ֵ: void //************************************************************ void HookGetFriendList() { HookAnyAddress(GetWeChatWinBase() + WxFriendList, GetUserListInfo); } //************************************************************ // : GetUserListInfo // ˵: ȡûϢ // : GuiShou // ʱ : 2019/7/4 // : void // ֵ: void //************************************************************ __declspec(naked) void GetUserListInfo() { __asm { pushad; push esi; call SendUserListInfo; popad; //䱻ǵĴ call overWritedCallAdd; //رHOOKָһָ jmp jumBackAddress } } //************************************************************ // : ReSendUser // ˵: ٴηͺϢ // : GuiShou // ʱ : 2019/7/4 // : user // ֵ: void //************************************************************ void ReSendUser(UserListInfo* user) { HWND hWnd = NULL; while (true) { //͵ƶ hWnd = FindWindow(NULL, TEXT("΢")); if (hWnd == NULL) { Sleep(200); continue; } break; } COPYDATASTRUCT userinfo; userinfo.dwData = WM_GetFriendList;//һֵ, ־ userinfo.cbData = sizeof(UserListInfo);// strlen(szSendBuf);//͵ݵij userinfo.lpData = user;// szSendBuf;//͵ݵʼַ(ΪNULL) SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&userinfo); delete user; } //************************************************************ // : SendUserListInfo // ˵: ͺб // : GuiShou // ʱ : 2019/7/4 // : r_esi бڵָ // ֵ: void //************************************************************ void __stdcall SendUserListInfo(DWORD r_esi) { //΢źšȺ wstring wxid = GetMsgByAddress(r_esi + 0x8); wstring nickname = GetMsgByAddress(r_esi + 0x64); //бȥ map::iterator it; it = g_userinfolist.find(wxid); //ֵend() ˵ҵ ֱӷطֹظ if (it != g_userinfolist.end()) { return; } //ûҵ 뵽 g_userinfolist.insert(make_pair(wxid, nickname)); //ųƼб for (int i = 0; i < 11; i++) { if (g_referencenumber[i] == wxid) { return; } } unique_ptr user(new UserListInfo); LPVOID pUserWxid = *((LPVOID *)(r_esi + 0x8)); //΢ID LPVOID pUserNumber = *((LPVOID *)(r_esi + 0x1C)); //΢ź LPVOID pUserNick = *((LPVOID *)(r_esi + 0x64)); //dz LPVOID pUserReMark = *((LPVOID *)(r_esi + 0x50)); //ע swprintf_s(user->UserId, L"%s", (wchar_t*)pUserWxid); swprintf_s(user->UserNumber, L"%s", (wchar_t*)pUserNumber); swprintf_s(user->UserNickName, L"%s", (wchar_t*)pUserNick); swprintf_s(user->UserRemark, L"%s", (wchar_t*)pUserReMark); //͵ƶ HWND hWnd = FindWindow(NULL, TEXT("΢")); if (hWnd == NULL) { UserListInfo* outuser = new UserListInfo; swprintf_s(outuser->UserId, L"%s", (wchar_t*)pUserWxid); swprintf_s(outuser->UserNumber, L"%s", (wchar_t*)pUserNumber); swprintf_s(outuser->UserNickName, L"%s", (wchar_t*)pUserNick); swprintf_s(outuser->UserRemark, L"%s", (wchar_t*)pUserReMark); HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReSendUser, outuser, 0, NULL); CloseHandle(hThread); } COPYDATASTRUCT userinfo; userinfo.dwData = WM_GetFriendList;//һֵ, ־ userinfo.cbData = sizeof(UserListInfo);// strlen(szSendBuf);//͵ݵij userinfo.lpData = user.get();// szSendBuf;//͵ݵʼַ(ΪNULL) SendMessage(hWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&userinfo); } //************************************************************ // : SendTextMessage // ˵: ıϢ // : GuiShou // ʱ : 2019/7/4 // : wxid ΢ID msgϢ // ֵ: void //************************************************************ void SendTextMessage(wchar_t* wxid, wchar_t* msg) { //õϢcallĵַ DWORD dwSendCallAddr = GetWeChatWinBase() + WxSendMessage; //װ΢ID/ȺIDĽṹ GeneralStruct id(wxid); //Ϣ GeneralStruct text(msg); //ȡ΢IDϢĵַ char* pWxid = (char*)&id.pstr; char* pWxmsg = (char*)&text.pstr; char buff[0x81C] = { 0 }; char buff2[0x81C] = { 0 }; //΢ŷϢcall __asm { push 0x1; lea edi, buff2; push edi; mov ebx, pWxmsg; push ebx; lea ecx, buff; mov edx, pWxid; call dwSendCallAddr; add esp, 0xC; } } //************************************************************ // : SendFileMessage // ˵: ļϢ // : GuiShou // ʱ : 2019/7/4 // : wxid ΢ID filepath ļ· // ֵ: void //************************************************************ void SendFileMessage(wchar_t* wxid, wchar_t* filepath) { //Ҫĵַ DWORD dwBase = GetWeChatWinBase(); DWORD dwCall1 = dwBase + WxFileMessage1; DWORD dwCall2 = dwBase + WxFileMessage2; DWORD dwCall3 = dwBase + WxFileMessage3; // DWORD dwCall4 = dwBase + WxFileMessage4; //Ϣ DWORD dwParams = dwBase + WxFileMessageParam; char buff[0x528] = { 0 }; //Ҫ GeneralStruct wxidStruct(wxid); GeneralStruct filePathStruct(filepath); //ȡҪݵĵַ char* pFilePath = (char*)&filePathStruct.pstr; char* pWxid = (char*)&wxidStruct.pstr; __asm { pushad; sub esp, 0x14; lea eax, buff; mov ecx, esp; push eax; call dwCall2; push 0; sub esp, 0x14; mov ecx, esp; push - 0x1; push dwParams; call dwCall1; sub esp, 0x14; mov ecx, esp; mov ebx, pFilePath; push ebx; call dwCall2; sub esp, 0x14; mov eax, pWxid; mov ecx, esp; push eax; call dwCall2; lea eax, buff; push eax; call dwCall3; mov ecx, eax; call dwCall4; popad; } } //************************************************************ // : SendImageMessage // ˵: ͼƬϢ // : GuiShou // ʱ : 2019/7/7 // : wxid ΢ID filepath ͼƬ· // ֵ: void //************************************************************ void SendImageMessage(wchar_t* wxid, wchar_t* filepath) { //װ΢IDݽṹ GeneralStruct imagewxid(wxid); //װļ·ݽṹ GeneralStruct imagefilepath(filepath); char buff[0x528] = { 0 }; char buff2[0x60] = { 0 }; DWORD dwCall3 = GetWeChatWinBase() + WxSendImageCall3; DWORD dwCall1 = GetWeChatWinBase()+ WxSendImageCall1; DWORD dwCall2 = GetWeChatWinBase() + WxSendImageCall2; //΢ŷͼƬGidCreateBimapFileCM ֮ͼƬһֱռ ޷ɾ patchĴ unsigned char oldcode[5] = {0}; unsigned char fix[5] = { 0x31,0xC0,0x90,0x90,0x90 }; DWORD dwPathcAddr = GetWeChatWinBase() + WxPatchAddr; //޸Ĵ DWORD dwOldAttr = 0; VirtualProtect((LPVOID)dwPathcAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldAttr); //ȱԭָ memcpy(oldcode, (LPVOID)dwPathcAddr, 5); //Patch memcpy((LPVOID)dwPathcAddr, fix, 5); __asm { pushad; sub esp, 0x14; lea eax, buff2; mov ecx, esp; push eax; call dwCall3; lea ebx, imagefilepath; push ebx; lea eax, imagewxid; push eax; lea eax, buff; push eax; call dwCall1; mov ecx, eax; call dwCall2; popad; } //ָ֮ memcpy((LPVOID)dwPathcAddr, oldcode, 5); //ָ VirtualProtect((LPVOID)dwPathcAddr, 5, dwOldAttr, &dwOldAttr); } //************************************************************ // : WxDeleteUser // ˵: ɾ // : GuiShou // ʱ : 2019/7/8 // : wxid ΢ID // ֵ: void //************************************************************ void DeleteUser(wchar_t* wxid) { DWORD dwBaseAddress = GetWeChatWinBase(); // GeneralStruct structWxid(wxid); DWORD* asmMsg = (DWORD*)&structWxid.pstr; DWORD dwCallAddr = dwBaseAddress + WxDeleteUser; __asm { mov ecx, 0; push ecx; mov esi, asmMsg; push esi; call dwCallAddr; } } //************************************************************ // : SendXmlCard // ˵: XMLƬ // : GuiShou // ʱ : 2019/7/10 // : RecverWxid ΢ID SendWxidҪ͵΢ID NickName΢dz // ֵ: void //************************************************************ void SendXmlCard(wchar_t* RecverWxid, wchar_t* SendWxid, wchar_t* NickName) { wchar_t xml[0x2000] = { 0 }; swprintf_s(xml, L"", SendWxid, NickName, SendWxid); GeneralStruct pWxid(RecverWxid); GeneralStruct pXml(xml); char* asmWxid = (char *)&pWxid.pstr; char* asmXml = (char *)&pXml.pstr; char buff[0x20C] = { 0 }; DWORD callAdd = GetWeChatWinBase() + WxSendXmlCard; __asm { mov eax, asmXml push 0x2A mov edx, asmWxid push 0x0 push eax lea ecx, buff call callAdd add esp, 0xC } } //************************************************************ // : wstringToString // ˵: wstringתString // : GuiShou // ʱ : 2019/9/17 // : wstr // ֵ: string //************************************************************ std::string wstringToString(const std::wstring& wstr) { LPCWSTR pwszSrc = wstr.c_str(); int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL); if (nLen == 0) return std::string(""); char* pszDst = new char[nLen]; if (!pszDst) return std::string(""); WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL); std::string str(pszDst); delete[] pszDst; pszDst = NULL; return str; } //************************************************************ // : GetNickNameByWxid // ˵: ݺб΢ID/ȺIDȡ΢dz/Ⱥdz // : GuiShou // ʱ : 2020/2/10 // : nickname dz // ֵ: void //************************************************************ wstring GetNickNameByWxid(wstring wxid) { map::iterator it; it = g_userinfolist.find(wxid); if (it != g_userinfolist.end()) { return it->second; } else { return L"NULL"; } } //************************************************************ // : GetNicknameByWxid // ˵: ΢IDȡdz // : GuiShou // ʱ : 2020/2/10 // : wxid ΢ID // ֵ: wchar_t* dz //************************************************************ wchar_t* GetNicknameByWxid(wchar_t* userwxid) { DWORD dwCall1 = GetWeChatWinBase() + WxGetUserInfoByWxidCall1; DWORD dwCall2 = GetWeChatWinBase() + WxGetUserInfoByWxidCall2; DWORD dwCall3 = GetWeChatWinBase() + WxGetUserInfoByWxidCall3; GeneralStruct pWxid(userwxid); char* asmWxid = (char*)& pWxid.pstr; char buff[0x3D8] = { 0 }; DWORD userData = 0; //ûݵĵַ __asm { pushad; lea edi, buff; push edi; sub esp, 0x14; mov eax, asmWxid; mov ecx, esp; push eax; call dwCall1; call dwCall2; call dwCall3; mov userData, edi; popad; } wchar_t tempnickname[100] = { 0 }; DWORD wxNickAdd = userData + 0x64; //dz swprintf_s(tempnickname, L"%s", (wchar_t*)(*((LPVOID*)wxNickAdd))); wchar_t* nickname = new wchar_t[100]{ 0 }; memcpy(nickname, tempnickname, wcslen(tempnickname) * 2); return nickname; } ================================================ FILE: WeChatHelper/FriendList.h ================================================ #pragma once void HookGetFriendList(); //HOOKȡбcall void GetUserListInfo(); //ȡб void __stdcall SendUserListInfo(DWORD r_esi); //ͺб void SendTextMessage(wchar_t* wxid, wchar_t* msg); //ıϢ void SendFileMessage(wchar_t* wxid, wchar_t* filepath); //ļϢ void SendImageMessage(wchar_t* wxid, wchar_t* filepath);//ͼƬϢ void DeleteUser(wchar_t* wxid); //ɾ void SendXmlCard(wchar_t* RecverWxid, wchar_t* SendWxid, wchar_t* NickName); //XMLƬ std::string wstringToString(const std::wstring& wstr); wchar_t* GetNicknameByWxid(wchar_t* userwxid); wstring GetNickNameByWxid(wstring wxid); ================================================ FILE: WeChatHelper/Function.cpp ================================================ #include "stdafx.h" #include "Function.h" #include #include #include "FriendList.h" vector g_wxidgroup; //嶯̬΢ID //************************************************************ // : AddWxUser // ˵: Ӻ // : GuiShou // ʱ : 2019/7/13 // : wxid ΢ID msgӺʱҪ͵Ϣ // ֵ: void //************************************************************ void AddWxUser(wchar_t* wxid, wchar_t* msg) { DWORD dwWeChatWinAddr = GetWeChatWinBase(); DWORD dwParam1 = dwWeChatWinAddr + WxAddWxUserParam1; DWORD dwCall1 = dwWeChatWinAddr + WxAddWxUserCall1; DWORD dwCall2 = dwWeChatWinAddr + WxAddWxUserCall2; DWORD dwCall3 = dwWeChatWinAddr + WxAddWxUserCall3; DWORD dwCall4 = dwWeChatWinAddr + WxAddWxUserCall4; DWORD dwCall5 = dwWeChatWinAddr + WxAddWxUserCall5; GeneralStruct pWxid(wxid); GeneralStruct pMsg(msg); char* asmWxid = (char*)&pWxid.pstr; char* asmMsg = (char*)&pMsg.pstr; DWORD asmMsgText = (DWORD)pMsg.pstr; char buff3[0x100] = { 0 }; char* buff = buff3; __asm { sub esp, 0x18; mov ecx, esp; push dwParam1; call dwCall1; sub esp, 0x18; mov eax, buff; mov ecx, esp; push eax; call dwCall2; push 0x6; sub esp, 0x14; mov ecx, esp; push -0x1; mov edi, msg; push edi; call dwCall3; push 0x2; sub esp, 0x14; mov ecx, esp; mov ebx, asmWxid; push ebx; call dwCall4; mov ecx, eax; call dwCall5; } } //************************************************************ // : OpenUrl // ˵: ΢ // : GuiShou // ʱ : 2019/9/10 // : void // ֵ: void //************************************************************ void OpenUrl(wchar_t* Url) { GeneralStruct pUrl(Url); char* asmpUrl = (char*)&pUrl.pstr; DWORD dwWeChatWinAddr = GetWeChatWinBase(); DWORD callAdd1 = dwWeChatWinAddr + WxOpenUrlCall1; DWORD callAdd2 = dwWeChatWinAddr + WxOpenUrlCall2; __asm { pushad sub esp, 0x14 mov eax, asmpUrl mov ecx, esp push eax call callAdd1 call callAdd2 add esp, 0x14 popad } } //************************************************************ // : AntiRevoke // ˵: // : GuiShou // ʱ : 2019/7/15 // : void // ֵ: void //************************************************************ void AntiRevoke() { unsigned char fix[1] = { 0xEB }; DWORD dwPathcAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll") + WxAntiRevoke; //޸Ĵ DWORD dwOldAttr = 0; VirtualProtect((LPVOID)dwPathcAddr, 1, PAGE_EXECUTE_READWRITE, &dwOldAttr); //Patch memcpy((LPVOID)dwPathcAddr, fix, 1); //ָ VirtualProtect((LPVOID)dwPathcAddr, 5, dwOldAttr, &dwOldAttr); } ================================================ FILE: WeChatHelper/Function.h ================================================ #pragma once #include using namespace std; void AddWxUser(wchar_t* wxid, wchar_t* msg); //Ӻ void AntiRevoke(); // void OpenUrl(wchar_t * Url); //΢ ================================================ FILE: WeChatHelper/InitWeChat.cpp ================================================ #include "stdafx.h" #include #include #pragma comment(lib,"Version.lib") //************************************************************ // : IsWxVersionValid // ˵: ΢Ű汾Ƿƥ // : GuiShou // ʱ : 2019/6/30 // : void // ֵ: BOOL //************************************************************ BOOL IsWxVersionValid() { DWORD wxBaseAddress = (DWORD)GetModuleHandle(TEXT("WeChatWin.dll")); const string wxVersoin = "3.2.1.154"; WCHAR VersionFilePath[MAX_PATH]; if (GetModuleFileName((HMODULE)wxBaseAddress, VersionFilePath, MAX_PATH) == 0) { return FALSE; } string asVer = ""; VS_FIXEDFILEINFO* pVsInfo; unsigned int iFileInfoSize = sizeof(VS_FIXEDFILEINFO); int iVerInfoSize = GetFileVersionInfoSize(VersionFilePath, NULL); if (iVerInfoSize != 0) { char* pBuf = new char[iVerInfoSize]; if (GetFileVersionInfo(VersionFilePath, 0, iVerInfoSize, pBuf)) { if (VerQueryValue(pBuf, TEXT("\\"), (void**)& pVsInfo, &iFileInfoSize)) { int s_major_ver = (pVsInfo->dwFileVersionMS >> 16) & 0x0000FFFF; int s_minor_ver = pVsInfo->dwFileVersionMS & 0x0000FFFF; int s_build_num = (pVsInfo->dwFileVersionLS >> 16) & 0x0000FFFF; int s_revision_num = pVsInfo->dwFileVersionLS & 0x0000FFFF; //Ѱ汾ַ strstream wxVer; wxVer << s_major_ver << "." << s_minor_ver << "." << s_build_num << "." << s_revision_num; wxVer >> asVer; } } delete[] pBuf; } //汾ƥ if (asVer == wxVersoin) { return TRUE; } //汾ƥ return FALSE; } //************************************************************ // : CheckIsLogin // ˵: ΢Ƿ½ // : GuiShou // ʱ : 2019/6/30 // : void // ֵ: void //************************************************************ void CheckIsLogin() { //ȡWeChatWinĻַ DWORD dwWeChatWinAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); while (true) { DWORD dwIsLogin = dwWeChatWinAddr + LoginSign_Offset; if (*(DWORD*)dwIsLogin != 0) { //ҵ½ھ HWND hLogin = FindWindow(NULL, L"Login"); if (hLogin == NULL) { OutputDebugStringA("δҵLogin"); return; } COPYDATASTRUCT login_msg; login_msg.dwData = WM_Login; login_msg.lpData = NULL; login_msg.cbData = 0; //Ϣƶ SendMessage(hLogin, WM_COPYDATA, (WPARAM)hLogin, (LPARAM)&login_msg); break; } Sleep(500); } } ================================================ FILE: WeChatHelper/InitWeChat.h ================================================ #pragma once #include "stdafx.h" BOOL IsWxVersionValid(); //鵱ǰ΢Ű汾 void CheckIsLogin(); //΢Ƿ½ ================================================ FILE: WeChatHelper/Login.cpp ================================================ #include "stdafx.h" #include "Login.h" DWORD dwRetAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll") + WxQrCodeOffset + 5; //صַ DWORD dwOverAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll") + WxQrCodeOffsetCall; //ǵcall //************************************************************ // : HookQrCode // ˵: HOOK΢Ŷά // : GuiShou // ʱ : 2019/6/30 // : DWORD dwHookOffset Ҫhookƫ // ֵ: void //************************************************************ void HookQrCode() { HookAnyAddress(GetWeChatWinBase()+ WxQrCodeOffset, ShowPic); } //************************************************************ // : ShowPic // ˵: ʾά // : GuiShou // ʱ : 2019/6/16 // : void // ֵ: void //************************************************************ void __declspec(naked) ShowPic() { __asm { pushad; pushfd; push ecx; call SaveImg; popfd; popad; call dwOverAddr; jmp dwRetAddr; } } //************************************************************ // : SaveImg // ˵: άͼƬ // : GuiShou // ʱ : 2019/6/30 // : DWORD qrcode άͼƬڵĵַ // ֵ: void //************************************************************ void __stdcall SaveImg(DWORD qrcode) { //ȡͼƬ DWORD dwPicLen = qrcode + 0x4; size_t cpyLen = (size_t)*((LPVOID*)dwPicLen); //ͼƬ char PicData[0xFFF] = { 0 }; memcpy(PicData, *((LPVOID*)qrcode), cpyLen); char szTempPath[MAX_PATH] = { 0 }; char szPicturePath[MAX_PATH] = { 0 }; GetTempPathA(MAX_PATH, szTempPath); sprintf_s(szPicturePath, "%s%s", szTempPath, "qrcode.png"); //ļдTempĿ¼ HANDLE hFile = CreateFileA(szPicturePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == NULL) { OutputDebugStringA("ͼƬļʧ"); return; } DWORD dwRead = 0; if (WriteFile(hFile, PicData, cpyLen, &dwRead, NULL) == 0) { OutputDebugStringA("дͼƬļʧ"); return; } CloseHandle(hFile); } //************************************************************ // : GotoQrCode // ˵: תά봰 // : GuiShou // ʱ : 2019/6/16 // : void // ֵ: void //************************************************************ void GotoQrCode() { DWORD dwBaseAddress = (DWORD)GetModuleHandle(L"WeChatWin.dll"); DWORD dwCallAddr1 = dwBaseAddress + WxGoToQrCode1; DWORD dwCallAddr2 = dwBaseAddress + WxGoToQrCode2; __asm { call dwCallAddr1; mov ecx, eax; call dwCallAddr2; } } ================================================ FILE: WeChatHelper/Login.h ================================================ #pragma once #include "stdafx.h" void HookQrCode(); //HOOKά void ShowPic(); //ʾά void __stdcall SaveImg(DWORD qrcode); //ά void GotoQrCode(); //תά ================================================ FILE: WeChatHelper/MainWindow.cpp ================================================ #include "stdafx.h" #include "MainWindow.h" void LogoutWeChat() { DWORD dwBaseAddress = (DWORD)GetModuleHandle(L"WeChatWin.dll"); DWORD dwCallAddress = dwBaseAddress + WxLogout; HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dwCallAddress, 0, NULL, 0); if (hThread != 0) { CloseHandle(hThread); } } ================================================ FILE: WeChatHelper/MainWindow.h ================================================ #pragma once #include "stdafx.h" void LogoutWeChat(); ================================================ FILE: WeChatHelper/SelfInformation.cpp ================================================ #include "stdafx.h" #include "SelfInformation.h" #include "Function.h" #include "CPublic.h" //************************************************************ // : GetSelfInformation // ˵: ȡϢ // : GuiShou // ʱ : 2019/12/4 // : void // ֵ: void //************************************************************ //void GetInformation() //{ // Information *info = new Information; // char tempcontent[0x300]; // //ȡWeChatWinĻַ // DWORD dwWeChatWinAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); // // //΢ID Ҫ΢ź ΢źָ ΢źַ // memset(tempcontent, 0, 0x300); // DWORD pWxid = dwWeChatWinAddr + 0x161C814; // //С6ߴ20 ˵طǸָ // sprintf_s(tempcontent, "%s", (char*)(dwWeChatWinAddr + 0x161C814)); // if (strlen(tempcontent) < 0x6 || strlen(tempcontent) > 0x14) // { // //˵µ΢ź ΢IDõַ // sprintf_s(tempcontent, "%s", (char*)(*(DWORD*)(dwWeChatWinAddr + 0x161C814))); // } // else // { // sprintf_s(tempcontent, "%s", (char*)(dwWeChatWinAddr + 0x161C814)); // } // wcscpy_s(info->wxid, wcslen(UTF8ToUnicode(tempcontent)) + 1, UTF8ToUnicode(tempcontent)); // // //΢ID // //char wxid[0x1000] = { 0 }; // //DWORD pWxid = dwWeChatWinAddr + 0x161C814; // //sprintf_s(wxid, "%s", (char*)(*(DWORD*)pWxid)); // //if (strlen(wxid) < 40) // //{ // // wcscpy_s(info->wxid, wcslen(UTF8ToUnicode(wxid)) + 1, UTF8ToUnicode(wxid)); // //} // //else // //{ // // wcscpy_s(info->wxid, wcslen(L"΢IDʱ޷ʾ") + 1, L"΢IDʱ޷ʾ"); // //} // // //΢Ա // char sex[4] = { 0 }; // memcpy(sex, (void*)(pWxid + 0x160), 1); // // if (sex[0] == 1) // { // wcscpy_s(info->wxsex, wcslen(L"") + 1, L""); // } // if (sex[0] == 2) // { // wcscpy_s(info->wxsex, wcslen(L"Ů") + 1, L"Ů"); // } // // //΢dz // char nickname[40] = { 0 }; // if (*(DWORD*)(pWxid + 0x78 + 0x14) == 0xF) // { // sprintf_s(nickname, "%s", (char*)(pWxid + 0x78)); // wcscpy_s(info->nickname, wcslen(UTF8ToUnicode(nickname)) + 1, UTF8ToUnicode(nickname)); // } // else // { // DWORD pNickName = pWxid + 0x78; // sprintf_s(nickname, "%s", (char*)(*(DWORD*)pNickName)); // wcscpy_s(info->nickname, wcslen(UTF8ToUnicode(nickname)) + 1, UTF8ToUnicode(nickname)); // } // // //΢˺ // char wxcount[40] = { 0 }; // sprintf_s(wxcount, "%s", (char*)(pWxid + 0x1DC)); // wcscpy_s(info->wxcount, wcslen(UTF8ToUnicode(wxcount)) + 1, UTF8ToUnicode(wxcount)); // // //ֻ // char phone[40] = { 0 }; // sprintf_s(phone, "%s", (char*)(pWxid + 0xAC)); // wcscpy_s(info->phonenumber, wcslen(UTF8ToUnicode(phone)) + 1, UTF8ToUnicode(phone)); // // //½豸 // char device[15] = { 0 }; // sprintf_s(device, "%s", (char*)(pWxid + 0x4B4)); // wcscpy_s(info->device, wcslen(UTF8ToUnicode(device)) + 1, UTF8ToUnicode(device)); // // // // char nation[10] = { 0 }; // sprintf_s(nation, "%s", (char*)(pWxid + 0x254)); // wcscpy_s(info->nation, wcslen(UTF8ToUnicode(nation)) + 1, UTF8ToUnicode(nation)); // // //ʡ // char province[20] = { 0 }; // sprintf_s(province, "%s", (char*)(pWxid + 0x164)); // wcscpy_s(info->province, wcslen(UTF8ToUnicode(province)) + 1, UTF8ToUnicode(province)); // // // // char city[20] = { 0 }; // sprintf_s(city, "%s", (char*)(pWxid + 0x17C)); // wcscpy_s(info->city, wcslen(UTF8ToUnicode(city)) + 1, UTF8ToUnicode(city)); // // // //Сͷ // char header[0x100] = { 0 }; // DWORD pHeader = pWxid + 0x358; // sprintf_s(header, "%s", (char*)(*(DWORD*)pHeader)); // wcscpy_s(info->smallheader, wcslen(UTF8ToUnicode(header)) + 1, UTF8ToUnicode(header)); // // // //ͷ // char bigheader[0x100] = { 0 }; // DWORD pbigheader = pWxid + 0x340; // sprintf_s(bigheader, "%s", (char*)(*(DWORD*)pbigheader)); // wcscpy_s(info->bigheader, wcslen(UTF8ToUnicode(bigheader)) + 1, UTF8ToUnicode(bigheader)); // // //͵ͻ // HWND hInformation = FindWindow(NULL, L"Information"); // if (hInformation == NULL) // { // OutputDebugStringA("δҵInformation"); // return; // } // COPYDATASTRUCT information_msg; // information_msg.dwData = WM_GetInformation; // information_msg.lpData = info; // information_msg.cbData = sizeof(Information); // //Ϣƶ // SendMessage(hInformation, WM_COPYDATA, (WPARAM)hInformation, (LPARAM)&information_msg); // // delete info; //} void GetInformation() { unique_ptr info(new PersonalInformation); DWORD dwWeChatWin = GetWeChatWinBase(); char tempcontent[0x300]; //΢ź memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxCount)); //жǷΪ0 0˵΢źΪ if (tempcontent[0] == 0) { wcscpy_s(info->wxcount, wcslen(L"NULL") + 1, L"NULL"); } else { wcscpy_s(info->wxcount, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); } //΢ID Ҫ΢ź ΢źָ ΢źַ memset(tempcontent, 0, 0x300); DWORD pWxid = dwWeChatWin + WxID; //С6ߴ20 ˵طǸָ sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxID)); if (strlen(tempcontent) < 0x6 || strlen(tempcontent) > 0x14) { //˵µ΢ź ΢IDõַ sprintf_s(tempcontent, "%s", (char*)(*(DWORD*)(dwWeChatWin + WxID))); } else { sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxID)); } wcscpy_s(info->wxid, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //Сͷ memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(*(DWORD*)(dwWeChatWin + WxSmallHeader))); wcscpy_s(info->smallheader, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //ͷ memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(*(DWORD*)(dwWeChatWin + WxBigHeader))); wcscpy_s(info->bigheader, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); // memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxNation)); wcscpy_s(info->nation, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //ʡ memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxProvince)); wcscpy_s(info->province, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); // memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxCity)); wcscpy_s(info->city, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //ֻ memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxPhoneNumber)); wcscpy_s(info->phonenumber, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //dz memset(tempcontent, 0, 0x300); if (*(DWORD*)(dwWeChatWin + WxNickName + 0x14) == 0xF) { sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxNickName)); } else { sprintf_s(tempcontent, "%s", (char*)(*(DWORD*)(dwWeChatWin + WxNickName))); } wcscpy_s(info->nickname, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //Ŀ¼ swprintf_s(info->cachedir, L"%s", (wchar_t*)(*(DWORD*)(dwWeChatWin + WxCacheDir))); //½豸 memset(tempcontent, 0, 0x300); sprintf_s(tempcontent, "%s", (char*)(dwWeChatWin + WxDevice)); wcscpy_s(info->device, wcslen(UTF8ToUnicode2(tempcontent).c_str()) + 1, UTF8ToUnicode2(tempcontent).c_str()); //Ա DWORD nSex = *(DWORD*)(dwWeChatWin + WxSex); if (nSex == 1) { wcscpy_s(info->wxsex, wcslen(L"") + 1, L""); } else if (nSex == 2) { wcscpy_s(info->wxsex, wcslen(L"Ů") + 1, L"Ů"); } else { wcscpy_s(info->wxsex, wcslen(L"δ") + 1, L"δ"); } HWND hInformation = FindWindow(NULL, L"Information"); if (hInformation == NULL) { OutputDebugStringA("δҵInformation"); return; } COPYDATASTRUCT information_msg; information_msg.dwData = WM_GetInformation; information_msg.lpData = info.get(); information_msg.cbData = sizeof(PersonalInformation); //Ϣƶ SendMessage(hInformation, WM_COPYDATA, (WPARAM)hInformation, (LPARAM)&information_msg); } ================================================ FILE: WeChatHelper/SelfInformation.h ================================================ #pragma once void GetInformation(); ================================================ FILE: WeChatHelper/WeChatHelper.cpp ================================================ // WeChatHelper.cpp : 定义 DLL 应用程序的导出函数。 // #include "stdafx.h" ================================================ FILE: WeChatHelper/WeChatHelper.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 15.0 {6B65B0BF-7949-4C08-904B-5F51D8D3988F} Win32Proj WeChatHelper 10.0.17763.0 DynamicLibrary true v141 Unicode DynamicLibrary false v141 false Unicode DynamicLibrary true v141 Unicode DynamicLibrary false v141 true Unicode true true false false Use Level3 Disabled true WIN32;_DEBUG;WECHATHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Default false Windows true Use Level3 Disabled true _DEBUG;WECHATHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Windows true Use Level3 Disabled true true true WIN32;NDEBUG;WECHATHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true MultiThreaded Windows true true true Use Level3 MaxSpeed true true true NDEBUG;WECHATHELPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true Windows true true true Create Create Create Create ================================================ FILE: WeChatHelper/WeChatHelper.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {0b9b27f1-635b-4b63-9580-930b8d72841d} {4b5b4735-0ae3-4e6b-8cdb-2af5f879882b} {fc4286b8-5328-472a-a362-c3b84ee68237} {4b22a285-3804-41a4-a099-5f661e054c87} {eefc2ad3-9bc5-47a6-aa77-b4e015e0ea95} {db5c4a94-9e79-4224-afae-c1f02e131232} {6b03db46-3e31-4358-88dc-52c5eccc57c9} {cb6e8977-d569-4964-b82f-3493e8e177de} {6267f3a4-1be9-4758-b7a7-014ced3b6ad0} {9791c407-f3b4-44c9-843a-f9b5d6fdab8d} {d493d5fb-ef85-41d0-9d36-6bf3bdce98c9} {680edb83-20e0-4c82-86cb-c20dc4961136} {e391b322-e0a0-4eb2-88b8-0eaa4a819d2c} {05fd2c1f-b15c-4077-b8d7-3d72ac79a0e4} {88bc72d9-339d-44e6-927b-1743ff5c1beb} {53948c82-56cf-4eca-acab-1b2031c1c890} {60dea528-288d-4c73-9274-bc0b03f2f4f9} 头文件 初始化微信 自定义数据\自定义消息 自定义数据\偏移 窗口消息循环 头文件 登陆窗口 主窗口 聊天记录 好友列表\群相关操作 好友列表\好友列表 自动功能 自定义数据\结构体 公共类 功能窗口\个人信息 功能窗口\功能窗口 源文件 源文件 源文件 初始化微信 窗口消息循环 登陆窗口 主窗口 聊天记录 好友列表\好友列表 好友列表\群相关操作 自动功能 公共类 功能窗口\个人信息 功能窗口\功能窗口 ================================================ FILE: WeChatHelper/WeChatHelper.vcxproj.user ================================================  Auto WindowsLocalDebugger ================================================ FILE: WeChatHelper/WndMsgLoop.cpp ================================================ #include "stdafx.h" #include "WndMsgLoop.h" #include "InitWeChat.h" #include "Login.h" #include "MainWindow.h" #include "FriendList.h" #include "ChatRecord.h" #include "Function.h" #include "ChatRoomOperate.h" #include "CAutoFunction.h" #include "SelfInformation.h" #include extern BOOL g_AutoChat; //Զ //************************************************************ // : RegisterWindow // ˵: ʼ // : GuiShou // ʱ : 2019/6/30 // : HMODULE hModule // ֵ: void //************************************************************ void InitWindow(HMODULE hModule) { //鵱ǰ΢Ű汾 if (IsWxVersionValid()) { //ȡWeChatWinĻַ DWORD dwWeChatWinAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); //΢Ƿ½ DWORD dwIsLogin = dwWeChatWinAddr + LoginSign_Offset; if (*(DWORD*)dwIsLogin == 0) //0˵΢δ¼ { //̳߳΢ŵ½״̬ HANDLE hThread= CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CheckIsLogin, 0, 0, NULL); CloseHandle(hThread); //HOOKȡбcall HookGetFriendList(); //HOOKϢ HookChatRecord(); // AntiRevoke(); //HOOKȡ //HookExtractExpression(); //עᴰ RegisterWindow(hModule); } else { //΢Ѿ½ Ϣͻ HWND hLogin = FindWindow(NULL, L"Login"); if (hLogin == NULL) { OutputDebugStringA("δҵLogin"); return; } COPYDATASTRUCT login_msg; login_msg.dwData = WM_AlreadyLogin; login_msg.lpData = NULL; login_msg.cbData = 0; //Ϣƶ SendMessage(hLogin, WM_COPYDATA, (WPARAM)hLogin, (LPARAM)&login_msg); } } else { MessageBoxA(NULL, "ǰ΢Ű汾ƥ䣬WeChat 3.2.1.154", "", MB_OK); } } //************************************************************ // : RegisterWindow // ˵: עᴰ // : GuiShou // ʱ : 2019/6/30 // : HMODULE hModule ھ // ֵ: void //************************************************************ void RegisterWindow(HMODULE hModule) { //1 һ WNDCLASS wnd; wnd.style = CS_VREDRAW | CS_HREDRAW;// wnd.lpfnWndProc = WndProc;//ڻصָ. wnd.cbClsExtra = NULL; wnd.cbWndExtra = NULL; wnd.hInstance = hModule; wnd.hIcon = NULL; wnd.hCursor = NULL; wnd.hbrBackground = (HBRUSH)COLOR_WINDOW; wnd.lpszMenuName = NULL; wnd.lpszClassName = TEXT("WeChatHelper"); //2 עᴰ RegisterClass(&wnd); //3 HWND hWnd = CreateWindow( TEXT("WeChatHelper"), // TEXT("WeChatHelper"),// WS_OVERLAPPEDWINDOW,//ڷ 10, 10, 500, 300, //λ NULL, //ھ NULL, //˵ hModule, //ʵ NULL //WM_CREATEϢʱĸӲ ); //4 ʾ ShowWindow(hWnd, SW_HIDE); UpdateWindow(hWnd); //5 ϢѭϢã MSG msg = {}; // 5.1ȡϢ while (GetMessage(&msg, 0, 0, 0)) { // 5.2Ϣ TranslateMessage(&msg); // 5.3תϢص DispatchMessage(&msg); } } //************************************************************ // : WndProc // ˵: ص ںͿƶͨ // : GuiShou // ʱ : 2019/6/30 // : HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam // ֵ: LRESULT //************************************************************ LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam) { if (Message == WM_COPYDATA) { COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam; //ͨϢṹ MessageUnion *msg = (MessageUnion*)pCopyData->lpData; switch (pCopyData->dwData) { //ʾά case WM_ShowQrPicture: { GotoQrCode(); HookQrCode(); } break; //˳΢ case WM_Logout: { LogoutWeChat(); } break; //ıϢ case WM_SendTextMessage: { SendTextMessage(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //ļϢ case WM_SendFileMessage: { SendFileMessage(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //ͼƬϢ case WM_SendImageMessage: { SendImageMessage(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //ȡϢ case WM_GetInformation: { GetInformation(); } break; //Ⱥ case WM_SetRoomAnnouncement: { SetWxRoomAnnouncement(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //ɾ case WM_DeleteUser: { DeleteUser((wchar_t*)pCopyData->lpData); } break; //˳Ⱥ case WM_QuitChatRoom: { QuitChatRoom((wchar_t*)pCopyData->lpData); } break; //ȺԱ case WM_AddGroupMember: { AddGroupMember(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //Ƭ case WM_SendXmlCard: { SendXmlCard(msg->xmlcardmsg.RecverWxid, msg->xmlcardmsg.SendWxid, msg->xmlcardmsg.NickName); } break; //ʾȺԱ case WM_ShowChatRoomMembers: { ShowChatRoomUser((wchar_t*)pCopyData->lpData); } break; //Ӻ case WM_AddUser: { AddWxUser(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //޸Ⱥ case WM_SetRoomName: { SetRoomName(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //Զ case WM_AutoChat: { g_AutoChat = TRUE; } break; //ȡԶ case WM_CancleAutoChat: { g_AutoChat = FALSE; } break; //ͰϢ case WM_SendAtMsg: { SendRoomAtMsg(msg->atmsg.chatroomid, msg->atmsg.membermsgdata1, msg->atmsg.membernickname, msg->atmsg.msgmsgdata2); } break; //ɾȺԱ case WM_DelRoomMember: { DelRoomMember(msg->genericmsg.msgdata1, msg->genericmsg.msgdata2); } break; //URL case WM_OpenUrl: { OpenUrl((wchar_t*)pCopyData->lpData); } break; default: break; } } return DefWindowProc(hWnd, Message, wParam, lParam); } ================================================ FILE: WeChatHelper/WndMsgLoop.h ================================================ #pragma once #include "stdafx.h" void InitWindow(HMODULE hModule); //ʼ void RegisterWindow(HMODULE hModule); //עᴰ LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam); //ڻص ================================================ FILE: WeChatHelper/data.h ================================================ #pragma once //΢ͨýṹ struct GeneralStruct { wchar_t* pstr; int iLen; int iMaxLen; int full1; int full2; GeneralStruct(wchar_t* pString) { pstr = pString; iLen = wcslen(pString); iMaxLen = iLen * 2; full1 = 0; full2 = 0; } }; //洢WM_COPYDATAϢͨ union MessageUnion { //ͨϢṹ struct MessageStruct { wchar_t msgdata1[MAX_PATH]; wchar_t msgdata2[MAX_PATH]; }genericmsg; //ƬϢṹ struct XmlCardMessage { wchar_t RecverWxid[50]; //ߵ΢ID wchar_t SendWxid[50]; //Ҫ͵΢ID wchar_t NickName[50]; //dz }xmlcardmsg; //ͰϢ struct AtMsg { wchar_t chatroomid[50] = { 0 }; wchar_t membermsgdata1[50] = { 0 }; wchar_t membernickname[50] = { 0 }; wchar_t msgmsgdata2[100] = { 0 }; }atmsg; //XMLϢ struct SendXmlArticleStruct { wchar_t title[50]; wchar_t subtitle[50]; wchar_t urllink[200]; wchar_t picpath[260]; wchar_t selfwxid[50]; wchar_t recverwxid[50]; }xmlartmsg; }; //ϢĽṹ struct PersonalInformation { wchar_t wxid[40]; //΢ID wchar_t wxcount[40]; //΢˺ wchar_t v1[150]; //V1 wchar_t nickname[50]; //΢dz wchar_t remark[50]; //ע wchar_t wxsex[10]; //Ա wchar_t phonenumber[30]; //ֻ wchar_t device[20]; //½豸 wchar_t nation[20]; // wchar_t province[20]; //ʡ wchar_t city[20]; // wchar_t area[20]; // wchar_t language[10]; // wchar_t bigheader[0x100]; //ͷ wchar_t smallheader[0x100]; //Сͷ wchar_t signature[50]; //ǩ wchar_t background[0x100]; //Ȧ wchar_t cachedir[MAX_PATH]; //Ŀ¼ wchar_t startdir[MAX_PATH]; //Ŀ¼ }; //޸ıעṹ 0x22Bλñ1 struct SetRemarkStruct { int full1 = 0x800; //4 int full2 = 0; //8 wchar_t* UnicodeWxid; //0xC int UnicodeWxidLen; //0x10 int UnicodeWxidMaxLen; //0x14 int full5 = 0; //0x18 int full6 = 0; //0x1C char full3[0x34] = { 0 }; //0x20 wchar_t* Remark; //0x54 int RemarkLen; //0x58 int RemarkMaxLen; //0x5C int full7 = 0; //0x60 int full8 = 0; //0x64 char full9[0x1C3] = { 0 }; //0x68 int full10 = 1; //0x228 char full11[0x259] = { 0 }; //0x68 }; //¼Ϣṹ struct ChatMessageData { DWORD dwtype; //Ϣ wchar_t sztype[0x20]; //Ϣ wchar_t source[0x400]; //ϢԴ wchar_t wxid[0x40]; //΢ID/ȺID wchar_t wxname[0x200]; //΢/Ⱥ wchar_t sender[0x100]; //Ϣ wchar_t sendername[0x100]; //Ϣdz wchar_t content[0x5000]; //Ϣ }; //V1 struct v1Info { int fill = 0; wchar_t* v1 = 0; int v1Len; int maxV1Len; char fill2[0x41C] = { 0 }; DWORD v2 = { 0 }; }; //V2 struct v2Info { char fill[0x24C] = { 0 }; DWORD fill3 = 0x25; char fill4[0x40] = { 0 }; wchar_t* v2; int v2Len; int maxV2Len; char fill2[0x8] = { 0 }; }; //տṹ struct CllectMoneyStruct { wchar_t* ptransferid; int transferidLen; int transferidMaxLen; char full[0x8] = { 0 }; wchar_t* pwxid; int wxidLen; int wxidMaxLen; char full2[0x8] = { 0 }; }; //ͼƬṹ struct DwonImgStruct { //92C char fill[0x14] = { 0 }; DWORD params = 0; DWORD params1 = 0; char fill2[0x10] = { 0 }; DWORD params2 = 0; char fill3[0x38] = { 0 }; wchar_t * imgXml; int xmlLen = 0; int xmlMaxLen = 0; char fill4[0xC8] = { 0 }; wchar_t * thumbImgPath; int thumbLen = 0; int thumbMaxLen = 0; char fill5[0x8] = { 0 }; wchar_t * hImgPath; int hImgLen = 0; int hImgMaxLen = 0; char fill6[0x700] = { 0 }; }; //ͨ΢IDȡûϢṹ struct UserInfo { wchar_t UserId[0x100]; wchar_t UserNumber[0x100]; wchar_t UserNickName[0x100]; }; //бϢṹ struct UserListInfo { wchar_t UserId[80]; wchar_t UserNumber[80]; wchar_t UserRemark[80]; wchar_t UserNickName[80]; }; //ϸϢ struct UserInfoDetail { wchar_t UserId[50]; //΢ID wchar_t UserNumber[50]; //΢˺ wchar_t V1[200]; //V1 wchar_t Remark[50]; //ע wchar_t UserNickName[50]; //΢dz wchar_t smallHeader[1024] = { 0 }; //Сͷ wchar_t bigHeader[1024] = { 0 }; //ͷ }; //ȺȺIDṹ struct RoomIdStruct { char fill2[0x8] = { 0 }; wchar_t* str; int strLen = 0; int maxLen = 0; char fill[0x8] = { 0 }; }; ================================================ FILE: WeChatHelper/dllmain.cpp ================================================ // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "stdafx.h" #include "WndMsgLoop.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { //启动线程来初始化界面 HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)InitWindow, hModule, 0, NULL); CloseHandle(hThread); } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } ================================================ FILE: WeChatHelper/message.h ================================================ #pragma once #define WM_Login 0 #define WM_ShowQrPicture 1 #define WM_Logout 2 #define WM_GetFriendList 3 #define WM_ShowChatRecord 4 #define WM_SendTextMessage 5 #define WM_SendFileMessage 6 #define WM_GetInformation 7 #define WM_SendImageMessage 8 #define WM_SetRoomAnnouncement 9 #define WM_DeleteUser 10 #define WM_QuitChatRoom 11 #define WM_AddGroupMember 12 #define WM_SendXmlCard 13 #define WM_ShowChatRoomMembers 14 #define WM_ShowChatRoomMembersDone 15 #define WM_DecryptDatabase 16 #define WM_AddUser 17 #define WM_SetRoomName 18 #define WM_AutoChat 19 #define WM_CancleAutoChat 20 #define WM_AlreadyLogin 21 #define WM_SendAtMsg 22 #define WM_DelRoomMember 23 #define WM_OpenUrl 24 #define WM_InviteGroupMember 26 #define WM_SendXmlArticle 27 #define WM_GetFriendInfomations 28 #define WM_TimerToSend 29 #define WM_CancelTimerToSend 30 #define WM_SetRemark 31 #define WM_CreateChatRoom 32 #define WM_ModifyVersion 33 #define WM_DecodeImage 34 #define WM_SendVideoMessage 35 #define WM_SendGifMessage 36 #define WM_TopMsg 37 #define WM_CancleTopMsg 38 #define WM_OpenNewMsgNotify 39 #define WM_MsgNoDisturb 40 #define WM_FollowPublicAccount 41 #define WM_KeywordsReplyOpen 43 #define WM_KeywordsReplyClose 44 #define WM_TimerID 888 //΢ID #define ChatRobotWxID L"gh_f0e9306d8d03" ================================================ FILE: WeChatHelper/offset.h ================================================ #pragma once #define WxFriendList 0x5244A8 //好友列表 1 #define WxFriendListCall 0x64550 //好友列表 1 #define WxReciveMessage 0x3DF42C //接收消息 1 #define WxReciveMessageCall 0x87A70 //接收消息 1 #define WxGoToQrCode1 0x264830 //跳转到二维码 1 #define WxGoToQrCode2 0x3ADE40 //跳转到二维码 1 #define WxQrCodeOffset 0x266AAC //获取二维码 1 #define WxQrCodeOffsetCall 0x58BD30 //获取二维码 1 #define WxSendMessage 0x3B63B0 //发送文本消息 1 #define WxLogout 0x4E7210 //退出 1 #define WxFileMessage1 0x58DA10 //发送文件消息 1 #define WxFileMessage2 0x58DA50 //发送文件消息 1 #define WxFileMessage3 0x68D00 //发送文件消息 1 #define WxFileMessage4 0x2C1960 //发送文件消息 1 #define WxFileMessageParam 0x17FFE10 //发送文件消息 1 #define WxSendImageCall3 0x58DA50 //发送图片消息 1 #define WxSendImageCall1 0x639F0 //发送图片消息 1 #define WxSendImageCall2 0x3B5C70 //发送图片消息 1 #define WxPatchAddr 0x3B2AE6 //发送图片消息 1 #define WxSetRoomAnnouncement 0x3074E0 //发送群公告 1 #define WxDeleteUser 0x325C80 //删除好友 1 #define WxQuitChatRoom 0x3045B0 //退出群聊 1 #define WxAddGroupMemberCall1 0x827B0 //添加群成员 1 #define WxAddGroupMemberCall2 0x58DB60 //添加群成员 1 #define WxAddGroupMemberCall3 0x932D0 //添加群成员 1 #define WxAddGroupMemberCall4 0x2FF220 //添加群成员 1 #define WxAddGroupMemberParam1 0x1AD1B34 //添加群成员 1 #define WxAddGroupMemberParam2 0x1AD2358 //添加群成员 1 #define WxSendXmlCard 0x3B63B0 //发送名片 1 #define WxGetRoomUserWxidCall1 0x512DD0 //获取群成员ID 1 #define WxGetRoomUserWxidCall2 0x379A90 //获取群成员ID 1 #define WxGetRoomUserWxidCall3 0x5193F0 //获取群成员ID 1 #define WxGetRoomUserWxidCall4 0x5137F0 //获取群成员ID 1 #define WxGetUserInfoWithNoNetworkCall1 0x58DDD0 //根据微信ID获取用户信息 1 #define WxGetUserInfoWithNoNetworkCall2 0x3245E0 //根据微信ID获取用户信息 1 #define WxGetUserInfoWithNoNetworkCall3 0x4FD8F0 //根据微信ID获取用户信息 1 #define WxGetUserInfoByWxidCall1 0x58DA50 //根据微信ID获取用户信息 1 #define WxGetUserInfoByWxidCall2 0x63930 //根据微信ID获取用户信息 1 #define WxGetUserInfoByWxidCall3 0x3245E0 //根据微信ID获取用户信息 1 #define WxAddWxUserParam1 0x1730C30 //添加好友 1 #define WxAddWxUserCall1 0x57860 //添加好友 1 #define WxAddWxUserCall2 0x83780 //添加好友 1 #define WxAddWxUserCall3 0x58DA10 //添加好友 1 #define WxAddWxUserCall4 0x58DA50 //添加好友 1 #define WxAddWxUserCall5 0x322B20 //添加好友 1 #define WxSetRoomName 0x303A50 //修改群名称 1 #define WxCllectMoneyCall1 0x9C5310 //收款 1 #define WxCllectMoneyCall2 0x9C5390 //收款 1 #define WxAgreeUserRequestCall1 0x1F0360 //同意好友请求 1 #define WxAgreeUserRequestCall2 0x5D860 //同意好友请求 1 #define WxAgreeUserRequestCall3 0x10FFA0 //同意好友请求 1 #define WxAgreeUserRequestCall4 0x1D7180 //同意好友请求 1 #define WxAgreeUserRequestParam 0x1AB2E98 //同意好友请求 1 #define WxGetExpressionsAddr 0x2D3C68 //提取微信表情 没啥用 去除 #define WxGetExpressionsCallAddr 0x2D7E60 //提取微信表情 没啥用 去除 #define WxDelRoomMemberCall1 0x58DA50 //删除群成员 1 #define WxDelRoomMemberCall2 0x7CD80 //删除群成员 1 #define WxDelRoomMemberCall3 0x2FF410 //删除群成员 1 #define WxOpenUrlCall1 0x58DA50 //打开浏览器 1 #define WxOpenUrlCall2 0x9C9CA0 //打开浏览器 1 #define WxPackageMsgData 0x827B0 //组装艾特消息数据结构 1 #define WxAntiRevoke 0x3DED99 //防撤回 1 //聊天记录偏移 #define MsgTypeOffset 0x30 //消息类型的偏移 #define MsgContentOffset 0x68 //消息内容的偏移 #define MsgSourceOffset 0x1B8 //消息来源的偏移 #define WxidOffset 0x40 //微信ID/群ID偏移 #define GroupMsgSenderOffset 0x164 //群消息发送者偏移 //个人信息 基址 #define WxSelfInfoBase 0x1AD1AF0 // 1 // 登陆标志位 #define LoginSign_Offset 0x1AD4858 // 1 //微信ID ASCII指针 #define WxID WxSelfInfoBase+0x44 // //大头像 ASCII指针 #define WxBigHeader WxSelfInfoBase+0x384 // //小头像 ASCII指针 #define WxSmallHeader WxSelfInfoBase+0x39C // //国家 ASCII字符 #define WxNation WxSelfInfoBase+0x298 // //微信号 ASCII字符 #define WxCount WxSelfInfoBase+0x220 // //城市 ASCII字符 #define WxProvince WxSelfInfoBase+0x1A8 // //地区 ASCII字符 #define WxCity WxSelfInfoBase+0x1C0 // //手机号 ASCII字符 #define WxPhoneNumber WxSelfInfoBase+0xF0 // //昵称 ASCII字符 #define WxNickName WxSelfInfoBase+0xBC // //缓存目录 Unicode指针 #define WxCacheDir WxSelfInfoBase+0x10 // //登陆设备 ASCII字符 #define WxDevice WxSelfInfoBase+0x510 // //性别 #define WxSex WxSelfInfoBase+0x1A4 // ================================================ FILE: WeChatHelper/stdafx.cpp ================================================ #include "stdafx.h" #include "message.h" ================================================ FILE: WeChatHelper/stdafx.h ================================================ // stdafx.h: 标准系统包含文件的包含文件, // 或是经常使用但不常更改的 // 项目特定的包含文件 // #pragma once #include "targetver.h" #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容 // Windows 头文件 #include #include #include #include "offset.h" #include "data.h" #include "message.h" #include "CPublic.h" #include using namespace std; // 在此处引用程序需要的其他标头 ================================================ FILE: WeChatHelper/targetver.h ================================================ #pragma once // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并 // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 #include ================================================ FILE: WeChatRobot/CAboutAuthor.cpp ================================================ // CAboutAuthor.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CAboutAuthor.h" #include "afxdialogex.h" // CAboutAuthor 对话框 IMPLEMENT_DYNAMIC(CAboutAuthor, CDialogEx) CAboutAuthor::CAboutAuthor(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_ABOUT_AUTHOR, pParent) , m_kanxue(_T("")) , m_wuaipojie(_T("")) , m_csdn(_T("")) , m_email(_T("")) , m_github(_T("")) { } CAboutAuthor::~CAboutAuthor() { } void CAboutAuthor::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_kanxue); DDX_Text(pDX, IDC_EDIT2, m_wuaipojie); DDX_Text(pDX, IDC_EDIT3, m_csdn); DDX_Text(pDX, IDC_EDIT4, m_email); DDX_Text(pDX, IDC_EDIT5, m_github); } BEGIN_MESSAGE_MAP(CAboutAuthor, CDialogEx) ON_WM_DESTROY() END_MESSAGE_MAP() // CAboutAuthor 消息处理程序 BOOL CAboutAuthor::OnInitDialog() { CDialogEx::OnInitDialog(); m_kanxue = L"鬼手56"; m_wuaipojie = L"鬼手56"; m_github = L"https://github.com/TonyChen56"; m_csdn = L"https://blog.csdn.net/qq_38474570"; m_email = L"tonychen56@qq.com"; UpdateData(FALSE); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } ================================================ FILE: WeChatRobot/CAboutAuthor.h ================================================ #pragma once // CAboutAuthor 对话框 class CAboutAuthor : public CDialogEx { DECLARE_DYNAMIC(CAboutAuthor) public: CAboutAuthor(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CAboutAuthor(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUT_AUTHOR }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); CString m_kanxue; CString m_wuaipojie; CString m_csdn; CString m_email; CString m_github; }; ================================================ FILE: WeChatRobot/CAddChatRoomMember.cpp ================================================ // CAddChatRoomMember.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CAddChatRoomMember.h" #include "afxdialogex.h" // CAddChatRoomMember 对话框 IMPLEMENT_DYNAMIC(CAddChatRoomMember, CDialogEx) CAddChatRoomMember::CAddChatRoomMember(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_ADD_MEMBER, pParent), m_ChatRoomWxid(TempWxid) , m_wxid(_T("")) { } CAddChatRoomMember::~CAddChatRoomMember() { } void CAddChatRoomMember::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_ChatRoomWXID, m_wxid); } BEGIN_MESSAGE_MAP(CAddChatRoomMember, CDialogEx) ON_BN_CLICKED(IDC_MAKE_SURE, &CAddChatRoomMember::OnBnClickedMakeSure) END_MESSAGE_MAP() //************************************************************ // 函数名称: OnBnClickedMakeSure // 函数说明: 响应确定按钮 // 作 者: GuiShou // 时 间: 2019/7/9 // 参 数: void // 返 回 值: void //*********************************************************** void CAddChatRoomMember::OnBnClickedMakeSure() { UpdateData(TRUE); MessageStruct* addgroupmember = new MessageStruct(m_ChatRoomWxid, m_wxid); //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT addgroupdata; addgroupdata.dwData = WM_AddGroupMember; addgroupdata.cbData = sizeof(MessageStruct); addgroupdata.lpData = addgroupmember; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&addgroupdata); delete addgroupmember; m_wxid = ""; UpdateData(FALSE); } ================================================ FILE: WeChatRobot/CAddChatRoomMember.h ================================================ #pragma once // CAddChatRoomMember 对话框 class CAddChatRoomMember : public CDialogEx { DECLARE_DYNAMIC(CAddChatRoomMember) public: CAddChatRoomMember(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CAddChatRoomMember(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ADD_MEMBER }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_wxid; //用户输入的微信ID CString m_ChatRoomWxid; //从好友列表窗口传过来的群ID afx_msg void OnBnClickedMakeSure(); }; ================================================ FILE: WeChatRobot/CAddUser.cpp ================================================ // CAddUser.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CAddUser.h" #include "afxdialogex.h" // CAddUser 对话框 IMPLEMENT_DYNAMIC(CAddUser, CDialogEx) CAddUser::CAddUser(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_ADD_USER, pParent) , m_wxid(_T("wxid_fineonxis3f012")) , m_content(_T("添加好友测试")) { } CAddUser::~CAddUser() { } void CAddUser::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_wxid); DDX_Text(pDX, IDC_EDIT2, m_content); } BEGIN_MESSAGE_MAP(CAddUser, CDialogEx) ON_BN_CLICKED(IDC_ADD_USER, &CAddUser::OnBnClickedAddUser) END_MESSAGE_MAP() // CAddUser 消息处理程序 //************************************************************ // 函数名称: OnBnClickedAddUser // 函数说明: 响应添加好友按钮 // 作 者: GuiShou // 时 间: 2019/7/13 // 参 数: void // 返 回 值: void //*********************************************************** void CAddUser::OnBnClickedAddUser() { UpdateData(TRUE); MessageStruct* addUser = new MessageStruct(m_wxid, m_content); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT adduserdata; adduserdata.dwData = WM_AddUser; adduserdata.cbData = sizeof(MessageStruct); adduserdata.lpData = addUser; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&adduserdata); m_wxid = ""; m_content = ""; UpdateData(FALSE); delete addUser; } ================================================ FILE: WeChatRobot/CAddUser.h ================================================ #pragma once // CAddUser 对话框 class CAddUser : public CDialogEx { DECLARE_DYNAMIC(CAddUser) public: CAddUser(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CAddUser(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ADD_USER }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_wxid; CString m_content; afx_msg void OnBnClickedAddUser(); }; ================================================ FILE: WeChatRobot/CChatRecords.cpp ================================================ // CChatRecords.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CChatRecords.h" #include "afxdialogex.h" #include "stdafx.h" #include "WeChatRobot.h" #include "CChatRecords.h" #include "afxdialogex.h" #include #include #include #include #include #include #include #include #include "Wininet.h" #pragma comment(lib,"Wininet.lib") #include #include //多媒体播放所需的头文件 #pragma comment(lib,"winmm.lib") //多媒体播放所需的库文件 DWORD g_index=0; //************************************************************ // 函数名称: string_To_UTF8 // 函数说明: string转UTF8 // 作 者: GuiShou // 时 间: 2019/11/7 // 参 数: str 需要转换的字符串 // 返 回 值: string 转换后的字符串 //*********************************************************** std::string string_To_UTF8(const std::string & str) { int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0); wchar_t * pwBuf = new wchar_t[nwLen + 1];//一定要加1,不然会出现尾巴 ZeroMemory(pwBuf, nwLen * 2 + 2); ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen); int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL); char * pBuf = new char[nLen + 1]; ZeroMemory(pBuf, nLen + 1); ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL); std::string retStr(pBuf); delete[]pwBuf; delete[]pBuf; pwBuf = NULL; pBuf = NULL; return retStr; } //************************************************************ // 函数名称: Wchar_tToString // 函数说明: wchar转string // 作 者: GuiShou // 时 间: 2019/11/7 // 参 数: wchar 需要转换的字符串 // 返 回 值: string 转换后的字符串 //*********************************************************** std::string Wchar_tToString(wchar_t *wchar) { std::string szDst; wchar_t * wText = wchar; DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, NULL, 0, NULL, FALSE);// WideCharToMultiByte的运用 char *psText; // psText为char*的临时数组,作为赋值给std::string的中间变量 psText = new char[dwNum]; WideCharToMultiByte(CP_OEMCP, NULL, wText, -1, psText, dwNum, NULL, FALSE);// WideCharToMultiByte的再次运用 szDst = psText;// std::string赋值 delete[]psText;// psText的清除 return szDst; } //************************************************************ // 函数名称: StringToWchar_t // 函数说明: string转wchar // 作 者: GuiShou // 时 间: 2019/11/7 // 参 数: str 需要转换的字符串 // 返 回 值: wchar_t* 转换后的字符串 //*********************************************************** wchar_t * StringToWchar_t(const std::string & str) { wchar_t * m_chatroommmsg = new wchar_t[str.size() * 2]; // memset(m_chatroommmsg, 0, str.size() * 2); setlocale(LC_ALL, "zh_CN.UTF-8"); swprintf(m_chatroommmsg, str.size() * 2, L"%S", str.c_str()); return m_chatroommmsg; } //************************************************************ // 函数名称: Log // 函数说明: 记录聊天记录到本地 // 作 者: GuiShou // 时 间: 2019/11/7 // 参 数: type 消息类型 wxid微信ID source消息来源 msgSender消息发送者 content消息内容 // 返 回 值: void //*********************************************************** void Log(const std::string & type, const std::string & wxid, const std::string & source, const std::string & msgSender, const std::string & content) { setlocale(LC_ALL, "zh_CN.UTF-8"); time_t t = time(0); char ch[64]; strftime(ch, sizeof(ch), "%Y-%m-%d %H-%M-%S", localtime(&t)); //年-月-日 时-分-秒 std::string times = ch; std::string log; if (strstr(msgSender.c_str(), "NULL") != NULL) { log = string_To_UTF8( "************************ " + times + " ************************" + "\n" + "消息类型:" + type + "\n" + "消息来源:" + source + "\n" + "微信昵称:" + wxid + "\n" + "消息内容:" + content + "\n" + "-------------------------------- 分割线 --------------------------------\n\n\n" ); } else { log = string_To_UTF8( "************************ " + times + " ************************" + "\n" + "消息类型:" + type + "\n" + "消息来源:" + source + "\n" + "群名称:" + wxid + "\n" + "群发送者:" + msgSender + "\n" + "消息内容:" + content + "\n" + "-------------------------------- 分割线 --------------------------------\n\n\n" ); } FILE * fp = fopen("log.txt", "ab+"); fwrite(log.c_str(), log.length(), 1, fp); fclose(fp); } IMPLEMENT_DYNAMIC(CChatRecords, CDialogEx) CChatRecords::CChatRecords(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_CHAT_RECORDS, pParent) { } CChatRecords::~CChatRecords() { } void CChatRecords::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST1, m_ChatRecord); } BEGIN_MESSAGE_MAP(CChatRecords, CDialogEx) ON_WM_COPYDATA() ON_MESSAGE(WM_ShowMessage, &CChatRecords::OnShowmessage) END_MESSAGE_MAP() // CChatRecords 消息处理程序 BOOL CChatRecords::OnInitDialog() { CDialogEx::OnInitDialog(); m_ChatRecord.InsertColumn(0, L"消息类型", 0, 100); m_ChatRecord.InsertColumn(1, L"消息来源", 0, 100); m_ChatRecord.InsertColumn(2, L"微信昵称/群名称", 0, 150); m_ChatRecord.InsertColumn(3, L"群发送者", 0, 150); m_ChatRecord.InsertColumn(4, L"消息内容", 0, 465); m_ChatRecord.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } //************************************************************ // 函数名称: OnShowmessage // 函数说明: 响应Showmessage消息 处理父窗口发过来的消息 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: WPARAM wParam, LPARAM lParam // 返 回 值: BOOL //*********************************************************** afx_msg LRESULT CChatRecords::OnShowmessage(WPARAM wParam, LPARAM lParam) { //取数据 ChatMessageData *msg = (ChatMessageData*)wParam; //显示到控件 m_ChatRecord.InsertItem(g_index, msg->sztype); m_ChatRecord.SetItemText(g_index, 1, msg->source); m_ChatRecord.SetItemText(g_index, 2, msg->wxname); m_ChatRecord.SetItemText(g_index, 3, msg->sendername); m_ChatRecord.SetItemText(g_index, 4, msg->content); //保存聊天记录到本地 std::string type = Wchar_tToString(msg->sztype); std::string wxid = Wchar_tToString(msg->wxname); std::string source = Wchar_tToString(msg->source); std::string msgSender = Wchar_tToString(msg->sendername); std::string content = Wchar_tToString(msg->content); Log(type.c_str(), wxid.c_str(), source.c_str(), msgSender.c_str(), content.c_str()); return 0; } ================================================ FILE: WeChatRobot/CChatRecords.h ================================================ #pragma once // CChatRecords 对话框 class CChatRecords : public CDialogEx { DECLARE_DYNAMIC(CChatRecords) public: CChatRecords(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CChatRecords(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_CHAT_RECORDS }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CListCtrl m_ChatRecord; virtual BOOL OnInitDialog(); protected: afx_msg LRESULT OnShowmessage(WPARAM wParam, LPARAM lParam); }; ================================================ FILE: WeChatRobot/CChatRoomMember.cpp ================================================ // CChatRoomMember.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CChatRoomMember.h" #include "afxdialogex.h" #include "CSendChatRoomAt.h" wchar_t memberwxid[50] = { 0 }; //群成员的微信ID wchar_t membernickname[50] = { 0 }; //群成员的微信昵称 int nSelected = 0; //选中行的行号 // CChatRoomMember 对话框 IMPLEMENT_DYNAMIC(CChatRoomMember, CDialogEx) CChatRoomMember::CChatRoomMember(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_CHATROOM_MEMBER, pParent), m_ChatRoomWxid(TempWxid) { } CChatRoomMember::~CChatRoomMember() { } void CChatRoomMember::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST1, m_ChatRoomMembers); } BEGIN_MESSAGE_MAP(CChatRoomMember, CDialogEx) ON_WM_COPYDATA() ON_NOTIFY(NM_CLICK, IDC_LIST1, &CChatRoomMember::OnClickList1) ON_NOTIFY(NM_RCLICK, IDC_LIST1, &CChatRoomMember::OnRclickList1) ON_COMMAND(ID_32795, &CChatRoomMember::OnSendChatRoomAt) ON_COMMAND(ID_32796, &CChatRoomMember::OnCopyWxid) ON_COMMAND(ID_32797, &CChatRoomMember::OnDelRoomMember) END_MESSAGE_MAP() // CChatRoomMember 消息处理程序 BOOL CChatRoomMember::OnInitDialog() { CDialogEx::OnInitDialog(); m_ChatRoomMembers.InsertColumn(0, L"序号", 0, 100); m_ChatRoomMembers.InsertColumn(1, L"微信ID", 0, 200); m_ChatRoomMembers.InsertColumn(2, L"微信号", 0, 200); m_ChatRoomMembers.InsertColumn(3, L"昵称", 0, 200); m_ChatRoomMembers.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); //拷贝群成员微信ID wchar_t memberwxid[50] = { 0 }; wcscpy_s(memberwxid, wcslen(m_ChatRoomWxid) + 1, m_ChatRoomWxid); //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT show_members; show_members.dwData = WM_ShowChatRoomMembers; show_members.cbData = (wcslen(memberwxid) + 1) * 2; show_members.lpData = memberwxid; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&show_members); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } BOOL CChatRoomMember::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { static DWORD dwIndex = 0; if (pCopyDataStruct->dwData == WM_ShowChatRoomMembers) { ChatRoomMemberInfo *user = (ChatRoomMemberInfo*)pCopyDataStruct->lpData; CString index; index.Format(L"%d", dwIndex+1); //显示序号 m_ChatRoomMembers.InsertItem(dwIndex, index); //显示微信ID m_ChatRoomMembers.SetItemText(dwIndex, 1, user->UserId); //显示微信号 m_ChatRoomMembers.SetItemText(dwIndex, 2, user->UserNumber); //显示微信昵称 m_ChatRoomMembers.SetItemText(dwIndex, 3, user->UserNickName); dwIndex++; } else if (pCopyDataStruct->dwData == WM_ShowChatRoomMembersDone) { //把序号清零 dwIndex = 0; } return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } //************************************************************ // 函数名称: OnRclickFriendlist // 函数说明: 响应List控件的左键点击消息 // 作 者: GuiShou // 时 间: 2019/7/23 // 参 数: pNMHDR pResult // 返 回 值: void //*********************************************************** void CChatRoomMember::OnClickList1(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); //拿到微信ID和微信昵称 memcpy(memberwxid, m_ChatRoomMembers.GetItemText(pNMItemActivate->iItem, 1), 40); memcpy(membernickname, m_ChatRoomMembers.GetItemText(pNMItemActivate->iItem, 3), 40); POSITION p = m_ChatRoomMembers.GetFirstSelectedItemPosition(); //获取选中行位置 nSelected = m_ChatRoomMembers.GetNextSelectedItem(p); //获取选中行的索引 *pResult = 0; } //************************************************************ // 函数名称: OnRclickList1 // 函数说明: 响应List控件的右键点击消息 // 作 者: GuiShou // 时 间: 2019/7/23 // 参 数: pNMHDR pResult // 返 回 值: void //*********************************************************** void CChatRoomMember::OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); //弹出好友相关的菜单 CMenu m_Menu, *tMenu; m_Menu.LoadMenu(IDR_MENU2); //拿到第0个下拉菜单(菜单可能有很多列 这个函数是拿到第几列) tMenu = m_Menu.GetSubMenu(2); //获取鼠标位置 CPoint pt; GetCursorPos(&pt); //弹出菜单 TrackPopupMenu(tMenu->m_hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, m_hWnd, 0); *pResult = 0; } //************************************************************ // 函数名称: OnSendChatRoomAt // 函数说明: 发送艾特消息 // 作 者: GuiShou // 时 间: 2019/7/23 // 参 数: void // 返 回 值: void //*********************************************************** void CChatRoomMember::OnSendChatRoomAt() { unique_ptr sendat(new CSendChatRoomAt(memberwxid, membernickname, m_ChatRoomWxid)); sendat->DoModal(); } //************************************************************ // 函数名称: OnCopyWxid // 函数说明: 复制微信ID // 作 者: GuiShou // 时 间: 2019/7/25 // 参 数: void // 返 回 值: void //*********************************************************** void CChatRoomMember::OnCopyWxid() { CString strText = memberwxid; //复制剪切板 if (!strText.IsEmpty()) { if (OpenClipboard()) { TCHAR* pszData; HGLOBAL hClipboardData = GlobalAlloc(GMEM_DDESHARE, (strText.GetLength() + 1) * sizeof(TCHAR)); if (hClipboardData) { pszData = (TCHAR*)GlobalLock(hClipboardData); _tcscpy_s(pszData, wcslen(strText) + 1, strText); GlobalUnlock(hClipboardData); SetClipboardData(CF_UNICODETEXT, hClipboardData);//根据相应的数据选择第一个参数,(CF_TEXT) } CloseClipboard(); } } } //************************************************************ // 函数名称: OnDelRoomMember // 函数说明: 删除群成员 // 作 者: GuiShou // 时 间: 2019/7/26 // 参 数: void // 返 回 值: void //*********************************************************** void CChatRoomMember::OnDelRoomMember() { if (MessageBoxA(NULL, "是否删除群成员", "Tip", MB_YESNO)) { MessageStruct* pMember = new MessageStruct(m_ChatRoomWxid, memberwxid); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT delmemberdata; delmemberdata.dwData = WM_DelRoomMember; delmemberdata.cbData = sizeof(MessageStruct); delmemberdata.lpData = pMember; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&delmemberdata); delete pMember; //删除选中行 m_ChatRoomMembers.DeleteItem(nSelected); //根据索引删除 } } ================================================ FILE: WeChatRobot/CChatRoomMember.h ================================================ #pragma once // CChatRoomMember 对话框 class CChatRoomMember : public CDialogEx { DECLARE_DYNAMIC(CChatRoomMember) public: CChatRoomMember(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CChatRoomMember(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_CHATROOM_MEMBER }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_ChatRoomWxid; //从好友列表窗口传过来的群ID CListCtrl m_ChatRoomMembers; virtual BOOL OnInitDialog(); afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); afx_msg void OnClickList1(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnRclickList1(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnSendChatRoomAt(); afx_msg void OnCopyWxid(); afx_msg void OnDelRoomMember(); }; ================================================ FILE: WeChatRobot/CCreateChatRoom.cpp ================================================ // CCreateChatRoom.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CCreateChatRoom.h" #include "afxdialogex.h" IMPLEMENT_DYNAMIC(CCreateChatRoom, CDialogEx) CCreateChatRoom::CCreateChatRoom(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_CreateChatRoom, pParent) , m_wxid1(_T("")) , m_wxid2(_T("")) { } CCreateChatRoom::~CCreateChatRoom() { } void CCreateChatRoom::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_wxid1); DDX_Text(pDX, IDC_EDIT2, m_wxid2); } BEGIN_MESSAGE_MAP(CCreateChatRoom, CDialogEx) ON_BN_CLICKED(IDC_CreateChatRoom, &CCreateChatRoom::OnBnClickedCreatechatroom) END_MESSAGE_MAP() // CCreateChatRoom 消息处理程序 //************************************************************ // 函数名称: OnBnClickedCreatechatroom // 函数说明: 创建群聊 // 作 者: GuiShou // 时 间: 2019/10/22 // 参 数: void // 返 回 值: void //*********************************************************** void CCreateChatRoom::OnBnClickedCreatechatroom() { } ================================================ FILE: WeChatRobot/CCreateChatRoom.h ================================================ #pragma once // CCreateChatRoom 对话框 class CCreateChatRoom : public CDialogEx { DECLARE_DYNAMIC(CCreateChatRoom) public: CCreateChatRoom(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CCreateChatRoom(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_CreateChatRoom }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_wxid1; CString m_wxid2; afx_msg void OnBnClickedCreatechatroom(); }; ================================================ FILE: WeChatRobot/CDecryptImage.cpp ================================================ // CDecryptImage.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CDecryptImage.h" #include "afxdialogex.h" #include #include #include // CDecryptImage 对话框 IMPLEMENT_DYNAMIC(CDecryptImage, CDialogEx) CDecryptImage::CDecryptImage(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_DECRYPT_IMAGE, pParent) , m_ImagePath(_T("")) , m_ImageDirectory(_T("C:\\Users\\XXX\\Documents\\WeChat Files\\微信ID\\FileStorage\\Image\\日期\\(只是个图片目录 告诉你在哪 别特么改!)")) , m_key(_T("")) { } CDecryptImage::~CDecryptImage() { } void CDecryptImage::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_ImagePath); DDX_Text(pDX, IDC_EDIT2, m_ImageDirectory); DDX_Text(pDX, IDC_EDIT6, m_key); } BEGIN_MESSAGE_MAP(CDecryptImage, CDialogEx) ON_BN_CLICKED(IDC_DecryptImage, &CDecryptImage::OnBnClickedDecryptimage) ON_WM_DROPFILES() END_MESSAGE_MAP() // CDecryptImage 消息处理程序 BOOL CDecryptImage::OnInitDialog() { CDialogEx::OnInitDialog(); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } //************************************************************ // 函数名称: OnBnClickedRadio1 // 函数说明: 响应点击解密按钮 // 作 者: GuiShou // 时 间: 2019/7/8 // 参 数: void // 返 回 值: void //*********************************************************** void CDecryptImage::OnBnClickedDecryptimage() { UpdateData(TRUE); //检查文件是否存在 if (GetFileAttributes(m_ImagePath) == INVALID_FILE_ATTRIBUTES) { MessageBox(L"图片不存在 请重试"); return; } //检测密钥是否存在 if (m_key == "") { MessageBox(L"密钥不能为空 请重试"); return; } //打开文件 HANDLE hFile = CreateFileW(m_ImagePath, GENERIC_ALL, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { MessageBoxA(NULL, "打开文件失败", "错误", 0); return; } //获取文件大小 DWORD dwSize = GetFileSize(hFile, NULL); //根据文件大小申请空间 char *lpBuff = new char[dwSize] {0}; //读取文件到内存 if (ReadFile(hFile, lpBuff, dwSize, NULL, NULL) == 0) { MessageBoxA(NULL, "读取文件失败", "错误", 0); return; } unsigned int hexkey = 0; USES_CONVERSION; sscanf_s(W2A(m_key), "%x", &hexkey); //循环异或 for (DWORD i = 0; i < dwSize; i++) { lpBuff[i] ^= hexkey; } //关闭句柄 CloseHandle(hFile); wchar_t NewFilePath[MAX_PATH] = { 0 }; wcscpy_s(NewFilePath, wcslen(m_ImagePath) + 1, m_ImagePath); for (DWORD i = wcslen(m_ImagePath); i > wcslen(m_ImagePath) - 4; i--) { NewFilePath[i] = 0; } wcscat_s(NewFilePath, L"png"); //打开文件 HANDLE hNewFile = CreateFileW(NewFilePath, GENERIC_ALL, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hNewFile == INVALID_HANDLE_VALUE) { MessageBoxA(NULL, "创建文件失败", "错误", 0); return; } WriteFile(hNewFile, lpBuff, dwSize, NULL, NULL); CloseHandle(hNewFile); MessageBoxA(NULL, "解密成功 请在同目录下查看", "Tip", MB_OK); m_ImagePath = ""; UpdateData(FALSE); } //************************************************************ // 函数名称: OnDropFiles // 函数说明: 响应拖拽文件 // 作 者: GuiShou // 时 间: 2019/7/8 // 参 数: HDROP hDropInfo 拖拽文件句柄 // 返 回 值: void //************************************************************ void CDecryptImage::OnDropFiles(HDROP hDropInfo) { //获取文件路径 TCHAR szPath[MAX_PATH] = { 0 }; DragQueryFile(hDropInfo, 0, szPath, MAX_PATH); //显示到控件 m_ImagePath = szPath; UpdateData(FALSE); CDialogEx::OnDropFiles(hDropInfo); } ================================================ FILE: WeChatRobot/CDecryptImage.h ================================================ #pragma once // CDecryptImage 对话框 class CDecryptImage : public CDialogEx { DECLARE_DYNAMIC(CDecryptImage) public: CDecryptImage(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CDecryptImage(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_DECRYPT_IMAGE }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedDecryptimage(); afx_msg void OnDropFiles(HDROP hDropInfo); CString m_ImagePath; CString m_ImageDirectory; virtual BOOL OnInitDialog(); CString m_key; }; ================================================ FILE: WeChatRobot/CFollowAccount.cpp ================================================ // CFollowAccount.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CFollowAccount.h" #include "afxdialogex.h" // CFollowAccount 对话框 IMPLEMENT_DYNAMIC(CFollowAccount, CDialogEx) CFollowAccount::CFollowAccount(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_FollowAccount, pParent) , m_accountid(_T("gh_f014862b32a9")) { } CFollowAccount::~CFollowAccount() { } void CFollowAccount::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_accountid); } BEGIN_MESSAGE_MAP(CFollowAccount, CDialogEx) ON_BN_CLICKED(IDC_FOLLOW, &CFollowAccount::OnBnClickedFollow) END_MESSAGE_MAP() // CFollowAccount 消息处理程序 //************************************************************ // 函数名称: OnBnClickedFollow // 函数说明: 关注公众号 // 作 者: GuiShou // 时 间: 2019/11/19 // 参 数: void // 返 回 值: void //*********************************************************** void CFollowAccount::OnBnClickedFollow() { } ================================================ FILE: WeChatRobot/CFollowAccount.h ================================================ #pragma once // CFollowAccount 对话框 class CFollowAccount : public CDialogEx { DECLARE_DYNAMIC(CFollowAccount) public: CFollowAccount(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CFollowAccount(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_FollowAccount }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_accountid; afx_msg void OnBnClickedFollow(); }; ================================================ FILE: WeChatRobot/CFriendInfo.cpp ================================================ // CFriendInfo.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CFriendInfo.h" #include "afxdialogex.h" // CFriendInfo 对话框 IMPLEMENT_DYNAMIC(CFriendInfo, CDialogEx) CFriendInfo::CFriendInfo(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_FRIENDINFO, pParent), m_Wxid(TempWxid) , m_wxid(_T("")) , m_wxnumber(_T("")) , m_wxv1(_T("")) , m_wxremark(_T("")) , m_wxnickname(_T("")) , wxsmallheader(_T("")) , wxbigheader(_T("")) { } CFriendInfo::~CFriendInfo() { } void CFriendInfo::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_wxid); DDX_Text(pDX, IDC_EDIT2, m_wxnumber); DDX_Text(pDX, IDC_EDIT6, m_wxv1); DDX_Text(pDX, IDC_EDIT7, m_wxremark); DDX_Text(pDX, IDC_EDIT8, m_wxnickname); DDX_Text(pDX, IDC_EDIT9, wxsmallheader); DDX_Text(pDX, IDC_EDIT10, wxbigheader); } BEGIN_MESSAGE_MAP(CFriendInfo, CDialogEx) ON_WM_COPYDATA() END_MESSAGE_MAP() // CFriendInfo 消息处理程序 BOOL CFriendInfo::OnInitDialog() { CDialogEx::OnInitDialog(); return TRUE; } //************************************************************ // 函数名称: OnCopyData // 函数说明: 响应CopyData消息 // 作 者: GuiShou // 时 间: 2019/10/9 // 参 数: CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct // 返 回 值: BOOL //*********************************************************** BOOL CFriendInfo::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } ================================================ FILE: WeChatRobot/CFriendInfo.h ================================================ #pragma once // CFriendInfo 对话框 class CFriendInfo : public CDialogEx { DECLARE_DYNAMIC(CFriendInfo) public: CFriendInfo(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CFriendInfo(); CString m_Wxid; //从好友列表窗口传过来的微信ID // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_FRIENDINFO }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); CString m_wxid; CString m_wxnumber; CString m_wxv1; CString m_wxremark; CString m_wxnickname; CString wxsmallheader; CString wxbigheader; afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); }; ================================================ FILE: WeChatRobot/CFriendList.cpp ================================================ // CFriendList.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CFriendList.h" #include "afxdialogex.h" #include "CSendMsg.h" #include "CRoomAnnouncement.h" #include "CAddChatRoomMember.h" #include "CSendXmlCard.h" #include "CChatRoomMember.h" #include "CSetRoomName.h" #include "CInviteGroupMember.h" #include "CFriendInfo.h" #include "CSetRemark.h" #include #include #include #include #include DWORD dwIndex = 0; wchar_t wxid[50]; //鼠标左键点击时拿到的微信ID vector g_wxidvector; //保存微信ID的容器 //是否关注聊天机器人 BOOL isAttentTuLing = FALSE; IMPLEMENT_DYNAMIC(CFriendList, CDialogEx) CFriendList::CFriendList(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_FRIEND_LIST, pParent) , m_GroupSendText(_T("")) { } CFriendList::~CFriendList() { } void CFriendList::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_FRIENDLIST, m_FriendList); DDX_Text(pDX, IDC_EDIT1, m_GroupSendText); } BEGIN_MESSAGE_MAP(CFriendList, CDialogEx) ON_WM_COPYDATA() ON_MESSAGE(WM_ShowFriendList, &CFriendList::OnShowfriendlist) ON_NOTIFY(NM_RCLICK, IDC_FRIENDLIST, &CFriendList::OnRclickFriendlist) ON_NOTIFY(NM_CLICK, IDC_FRIENDLIST, &CFriendList::OnClickFriendlist) ON_COMMAND(ID_32780, &CFriendList::OnSendMsg) ON_COMMAND(ID_32784, &CFriendList::OnSetRoomAnnouncement) ON_COMMAND(ID_32782, &CFriendList::OnCopyWxid) ON_COMMAND(ID_32785, &CFriendList::OnCopyWxid) ON_COMMAND(ID_32781, &CFriendList::OnDeleteUser) ON_COMMAND(ID_32786, &CFriendList::OnQuitChatRoom) ON_COMMAND(ID_32787, &CFriendList::OnAddGroupMember) ON_COMMAND(ID_32783, &CFriendList::OnSendMsg) ON_COMMAND(ID_32788, &CFriendList::OnSendXmlCard) ON_COMMAND(ID_32789, &CFriendList::OnShowChatRoomMember) ON_COMMAND(ID_32790, &CFriendList::OnSetRoomName) ON_COMMAND(ID_32799, &CFriendList::OnInviteGroupMember) ON_COMMAND(ID_32804, &CFriendList::OnGetFriendInfo) ON_BN_CLICKED(IDC_CheckAll, &CFriendList::OnBnClickedCheckall) ON_BN_CLICKED(IDC_ReverseChoose, &CFriendList::OnBnClickedReversechoose) ON_BN_CLICKED(IDC_CancelAll, &CFriendList::OnBnClickedCancelall) ON_BN_CLICKED(IDC_GroupSend, &CFriendList::OnBnClickedGroupsend) ON_COMMAND(ID_32805, &CFriendList::OnSetRemark) ON_COMMAND(ID_32808, &CFriendList::OnTopMsg) ON_COMMAND(ID_32810, &CFriendList::OnTopMsg) ON_COMMAND(ID_32809, &CFriendList::OnCancleTopMsg) ON_COMMAND(ID_32811, &CFriendList::OnCancleTopMsg) ON_COMMAND(ID_32812, &CFriendList::OnOpenNewMsgNotify) ON_COMMAND(ID_32814, &CFriendList::OnOpenNewMsgNotify) ON_COMMAND(ID_32813, &CFriendList::OnMsgNoDisturb) ON_COMMAND(ID_32815, &CFriendList::OnMsgNoDisturb) ON_MESSAGE(SaveFriendList, &CFriendList::OnSavefriendlist) END_MESSAGE_MAP() // CFriendList 消息处理程序 BOOL CFriendList::OnInitDialog() { CDialogEx::OnInitDialog(); m_FriendList.InsertColumn(0, L"序号", 0, 50); m_FriendList.InsertColumn(1, L"微信ID", 0, 200); m_FriendList.InsertColumn(2, L"微信号", 0, 200); m_FriendList.InsertColumn(3, L"昵称", 0, 250); m_FriendList.InsertColumn(4, L"备注", 0, 253); m_FriendList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES| LVS_EX_CHECKBOXES); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } //************************************************************ // 函数名称: OnShowfriendlist // 函数说明: 响应Showfriendlist消息 处理父窗口发过来的联系人 // 作 者: GuiShou // 时 间: 2019/7/5 // 参 数: WPARAM wParam, LPARAM lParam // 返 回 值: BOOL //*********************************************************** afx_msg LRESULT CFriendList::OnShowfriendlist(WPARAM wParam, LPARAM lParam) { //取数据 UserInfo* userinfo = (UserInfo*)wParam; CString index; index.Format(L"%d",dwIndex+1); //显示到List控件 //检测联系人列表中是否有聊天机器人 if (StrCmpW(userinfo->UserId,ChatRobotWxID)==0) { isAttentTuLing = TRUE; } m_FriendList.InsertItem(dwIndex, index); m_FriendList.SetItemText(dwIndex, 1, userinfo->UserId); m_FriendList.SetItemText(dwIndex, 2, userinfo->UserNumber); m_FriendList.SetItemText(dwIndex, 3, userinfo->UserNickName); m_FriendList.SetItemText(dwIndex, 4, userinfo->UserRemark); dwIndex++; return 0; } //************************************************************ // 函数名称: OnRclickFriendlist // 函数说明: 响应List控件的右键点击消息 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: WPARAM wParam, LPARAM lParam // 返 回 值: void //*********************************************************** void CFriendList::OnRclickFriendlist(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); //判断选中的是群ID还是个人微信ID if (StrStrW(wxid, L"chatroom") == NULL) { //弹出好友相关的菜单 CMenu m_Menu, *tMenu; m_Menu.LoadMenu(IDR_MENU2); //拿到第0个下拉菜单(菜单可能有很多列 这个函数是拿到第几列) tMenu = m_Menu.GetSubMenu(0); //获取鼠标位置 CPoint pt; GetCursorPos(&pt); //弹出菜单 TrackPopupMenu(tMenu->m_hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, m_hWnd, 0); } else { //弹出群相关的菜单 CMenu m_Menu, *tMenu; m_Menu.LoadMenu(IDR_MENU2); //拿到第0个下拉菜单(菜单可能有很多列 这个函数是拿到第几列) tMenu = m_Menu.GetSubMenu(1); //获取鼠标位置 CPoint pt; GetCursorPos(&pt); //弹出菜单 TrackPopupMenu(tMenu->m_hMenu, TPM_LEFTALIGN, pt.x, pt.y, 0, m_hWnd, 0); } *pResult = 0; } //************************************************************ // 函数名称: OnRclickFriendlist // 函数说明: 响应List控件的左键点击消息 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: pNMHDR pResult // 返 回 值: void //*********************************************************** void CFriendList::OnClickFriendlist(NMHDR *pNMHDR, LRESULT *pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); //拿到微信ID memcpy(wxid, m_FriendList.GetItemText(pNMItemActivate->iItem, 1), 40); *pResult = 0; } //************************************************************ // 函数名称: OnSendMsg // 函数说明: 响应发送消息菜单 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnSendMsg() { //利用构造函数把选中的微信ID传过去 unique_ptr pSendmsg(new CSendMsg(wxid)); pSendmsg->DoModal(); } //************************************************************ // 函数名称: OnSendMsg // 函数说明: 响应发送群公告菜单 // 作 者: GuiShou // 时 间: 2019/7/7 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnSetRoomAnnouncement() { //利用构造函数把选中的群ID传过去 unique_ptr pRoom(new CRoomAnnouncement(wxid)); pRoom->DoModal(); } //************************************************************ // 函数名称: OnCopyWxid // 函数说明: 响应复制微信ID菜单 // 作 者: GuiShou // 时 间: 2019/7/8 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnCopyWxid() { CString strText= wxid; //复制剪切板 if (!strText.IsEmpty()) { if (OpenClipboard()) { TCHAR* pszData; HGLOBAL hClipboardData = GlobalAlloc(GMEM_DDESHARE, (strText.GetLength() + 1) * sizeof(TCHAR)); if (hClipboardData) { pszData = (TCHAR*)GlobalLock(hClipboardData); _tcscpy_s(pszData, wcslen(strText) + 1, strText); GlobalUnlock(hClipboardData); SetClipboardData(CF_UNICODETEXT, hClipboardData);//根据相应的数据选择第一个参数,(CF_TEXT) } CloseClipboard(); } } } //************************************************************ // 函数名称: OnDeleteUser // 函数说明: 响应删除好友菜单 // 作 者: GuiShou // 时 间: 2019/7/9 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnDeleteUser() { if (MessageBoxA(NULL, "是否删除好友", "Tip", MB_YESNO)==IDYES) { if (wcscmp(wxid,L"filehelper")==0) { MessageBoxA(NULL, "无法删除filehelper", "Tip", MB_OK); return; } //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT deleteuser; deleteuser.dwData = WM_DeleteUser; deleteuser.cbData = (wcslen(wxid)+1)*2; deleteuser.lpData = wxid; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&deleteuser); //删除选中行 POSITION pos = m_FriendList.GetFirstSelectedItemPosition(); int nItem = m_FriendList.GetNextSelectedItem(pos); m_FriendList.DeleteItem(nItem); } } //************************************************************ // 函数名称: OnQuiteChatRoom // 函数说明: 响应退出群聊菜单 // 作 者: GuiShou // 时 间: 2019/7/9 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnQuitChatRoom() { if (MessageBoxA(NULL, "是否退出群聊", "Tip", MB_YESNO)) { //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT quitchatroom; quitchatroom.dwData = WM_QuitChatRoom; quitchatroom.cbData = (wcslen(wxid) + 1) * 2; quitchatroom.lpData = wxid; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&quitchatroom); //删除选中行 POSITION pos = m_FriendList.GetFirstSelectedItemPosition(); int nItem = m_FriendList.GetNextSelectedItem(pos); m_FriendList.DeleteItem(nItem); } } //************************************************************ // 函数名称: OnAddGroupMember // 函数说明: 响应邀请群成员(50人以下) // 作 者: GuiShou // 时 间: 2019/7/9 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnAddGroupMember() { unique_ptr addmember(new CAddChatRoomMember(wxid)); addmember->DoModal(); } //************************************************************ // 函数名称: OnSendRoomMessage // 函数说明: 响应发送xml名片菜单 // 作 者: GuiShou // 时 间: 2019/7/10 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnSendXmlCard() { unique_ptr sendcard(new CSendXmlCard(wxid)); sendcard->DoModal(); } //************************************************************ // 函数名称: OnShowChatRoomMember // 函数说明: 响应查看群成员菜单 // 作 者: GuiShou // 时 间: 2019/7/13 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnShowChatRoomMember() { unique_ptr chatroommember(new CChatRoomMember(wxid)); chatroommember->DoModal(); } //************************************************************ // 函数名称: OnSetRoomName // 函数说明: 响应修改群名称菜单 // 作 者: GuiShou // 时 间: 2019/7/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnSetRoomName() { unique_ptr pSetroomname(new CSetRoomName(wxid)); pSetroomname->DoModal(); } //************************************************************ // 函数名称: OnInviteGroupMember // 函数说明: 响应邀请群成员(50人以上) // 作 者: GuiShou // 时 间: 2019/9/19 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnInviteGroupMember() { unique_ptr Invitemember(new CInviteGroupMember(wxid)); Invitemember->DoModal(); } //************************************************************ // 函数名称: OnGetFriendInfo // 函数说明: 响应查看好友信息菜单 // 作 者: GuiShou // 时 间: 2019/10/9 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnGetFriendInfo() { } //************************************************************ // 函数名称: OnBnClickedCheckall // 函数说明: 全选 // 作 者: GuiShou // 时 间: 2019/10/18 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnBnClickedCheckall() { for (int i = 0; i < m_FriendList.GetItemCount(); i++) { m_FriendList.SetCheck(i, TRUE); } } //************************************************************ // 函数名称: OnBnClickedReversechoose // 函数说明: 反选 // 作 者: GuiShou // 时 间: 2019/10/18 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnBnClickedReversechoose() { for (int i = 0; i < m_FriendList.GetItemCount(); i++) { if (m_FriendList.GetCheck(i) == FALSE) //未被选中的 { m_FriendList.SetCheck(i, TRUE); } else //选中的 { m_FriendList.SetCheck(i, FALSE); } } } //************************************************************ // 函数名称: OnBnClickedCancelall // 函数说明: 取消 // 作 者: GuiShou // 时 间: 2019/10/18 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnBnClickedCancelall() { for (int i = 0; i < m_FriendList.GetItemCount(); i++) { m_FriendList.SetCheck(i, FALSE); } } //************************************************************ // 函数名称: OnBnClickedGroupsend // 函数说明: 群发 // 作 者: GuiShou // 时 间: 2019/10/18 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnBnClickedGroupsend() { } //************************************************************ // 函数名称: OnSetRemark // 函数说明: 响应修改备注菜单 // 作 者: GuiShou // 时 间: 2019/10/21 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnSetRemark() { } //************************************************************ // 函数名称: OnTopMsg // 函数说明: 响应置顶菜单 // 作 者: GuiShou // 时 间: 2019/11/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnTopMsg() { } //************************************************************ // 函数名称: OnCancleTopMsg // 函数说明: 响应取消置顶菜单 // 作 者: GuiShou // 时 间: 2019/11/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnCancleTopMsg() { } //************************************************************ // 函数名称: OnOpenNewMsgNotify // 函数说明: 响应开启新消息提醒菜单 // 作 者: GuiShou // 时 间: 2019/11/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnOpenNewMsgNotify() { } //************************************************************ // 函数名称: OnMsgNoDisturb // 函数说明: 响应消息免打扰菜单 // 作 者: GuiShou // 时 间: 2019/11/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFriendList::OnMsgNoDisturb() { } //************************************************************ // 函数名称: OnSavefriendlist // 函数说明: 响应保存好友列表消息 // 作 者: GuiShou // 时 间: 2020/02/19 // 参 数: void // 返 回 值: void //*********************************************************** afx_msg LRESULT CFriendList::OnSavefriendlist(WPARAM wParam, LPARAM lParam) { wstring wxUserFileName = L"UserLists.txt"; //作为输出文件打开 ofstream ofile; ofile.open(wxUserFileName, ios_base::trunc | ios_base::binary | ios_base::in); //获取所有行的数量 int nRow = m_FriendList.GetItemCount(); //获取所有列的数量 int nCol = m_FriendList.GetHeaderCtrl()->GetItemCount(); //开始循环行和列 for (int i = 0; i < nRow; i++) { for (int j = 0; j < nCol; j++) { USES_CONVERSION; CString csTemp = m_FriendList.GetItemText(i, j); string sTemp(CW2A(csTemp.GetString())); char const* pos = (char const*)sTemp.c_str(); //写入文件 ofile.write(pos, sTemp.length()); char const* cTab = "\t\t"; ofile.write(cTab, strlen(cTab)); } char const* cLine = "\r\n"; ofile.write(cLine, strlen(cLine)); } ofile.flush(); ofile.close(); return 0; } ================================================ FILE: WeChatRobot/CFriendList.h ================================================ #pragma once // CFriendList 对话框 class CFriendList : public CDialogEx { DECLARE_DYNAMIC(CFriendList) public: CFriendList(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CFriendList(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_FRIEND_LIST }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); CListCtrl m_FriendList; protected: afx_msg LRESULT OnShowfriendlist(WPARAM wParam, LPARAM lParam); public: afx_msg void OnRclickFriendlist(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnClickFriendlist(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnSendMsg(); afx_msg void OnSetRoomAnnouncement(); afx_msg void OnCopyWxid(); afx_msg void OnDeleteUser(); afx_msg void OnQuitChatRoom(); afx_msg void OnAddGroupMember(); afx_msg void OnSendXmlCard(); afx_msg void OnShowChatRoomMember(); afx_msg void OnSetRoomName(); afx_msg void OnInviteGroupMember(); afx_msg void OnGetFriendInfo(); afx_msg void OnBnClickedCheckall(); afx_msg void OnBnClickedReversechoose(); afx_msg void OnBnClickedCancelall(); CString m_GroupSendText; afx_msg void OnBnClickedGroupsend(); afx_msg void OnSetRemark(); afx_msg void OnTopMsg(); afx_msg void OnCancleTopMsg(); afx_msg void OnOpenNewMsgNotify(); afx_msg void OnMsgNoDisturb(); protected: afx_msg LRESULT OnSavefriendlist(WPARAM wParam, LPARAM lParam); }; ================================================ FILE: WeChatRobot/CFunctions.cpp ================================================ // CFunctions.cpp: 实现文件 // #include "stdafx.h" #include #include #include "WeChatRobot.h" #include "CFunctions.h" #include "afxdialogex.h" #include "CInformation.h" #include "CDecryptImage.h" #include "CMultiOpen.h" #include "CAddUser.h" #include "CFriendList.h" #include "COpenUrl.h" #include "CSendXmlAricle.h" #include "CCreateChatRoom.h" #include "CModifyVersion.h" #include "CFollowAccount.h" extern BOOL isAttentTuLing; //是否关注聊天机器人 BOOL bAutoChat = FALSE; //自动聊天 // CFunctions 对话框 IMPLEMENT_DYNAMIC(CFunctions, CDialogEx) CFunctions::CFunctions(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_FUNCTIONS, pParent) { } CFunctions::~CFunctions() { } void CFunctions::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CFunctions, CDialogEx) ON_BN_CLICKED(IDC_INFORMATION, &CFunctions::OnBnClickedInformation) ON_BN_CLICKED(IDC_DECRYPT_PIC, &CFunctions::OnBnClickedDecryptPic) ON_BN_CLICKED(IDC_MULTI_OPEN, &CFunctions::OnBnClickedMultiOpen) ON_BN_CLICKED(IDC_ADD_USER, &CFunctions::OnBnClickedAddUser) ON_BN_CLICKED(IDC_AUTO_CHAT, &CFunctions::OnBnClickedAutoChat) ON_BN_CLICKED(IDC_OPEN_URL, &CFunctions::OnBnClickedOpenUrl) ON_BN_CLICKED(IDC_SendXmlArticle, &CFunctions::OnBnClickedSendxmlarticle) ON_BN_CLICKED(IDC_SendMsgByTimer, &CFunctions::OnBnClickedSendmsgbytimer) ON_BN_CLICKED(IDC_CreateRoom, &CFunctions::OnBnClickedCreateroom) ON_BN_CLICKED(IDC_ModifyVersion, &CFunctions::OnBnClickedModifyversion) ON_BN_CLICKED(IDC_FollowAccount, &CFunctions::OnBnClickedFollowaccount) ON_BN_CLICKED(IDC_KeyWordsReply, &CFunctions::OnBnClickedKeywordsreply) END_MESSAGE_MAP() //************************************************************ // 函数名称: OnBnClickedInformation // 函数说明: 响应个人信息按钮 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedInformation() { unique_ptr info(new CInformation); info->DoModal(); } //************************************************************ // 函数名称: OnBnClickedDecryptPic // 函数说明: 响应解密图片按钮 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedDecryptPic() { CDecryptImage decryptimage; decryptimage.DoModal(); } //************************************************************ // 函数名称: OnBnClickedMultiOpen // 函数说明: 响应无限多开按钮 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedMultiOpen() { PatchWeChat(); OpenWeChat(); } //************************************************************ // 函数名称: OnBnClickedAddUser // 函数说明: 响应添加好友按钮 // 作 者: GuiShou // 时 间: 2019/7/13 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedAddUser() { CAddUser adduser; adduser.DoModal(); } //************************************************************ // 函数名称: OnBnClickedAutoChat // 函数说明: 响应自动聊天按钮 // 作 者: GuiShou // 时 间: 2019/7/16 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedAutoChat() { //检测是否关注聊天机器人 if (isAttentTuLing) { if (bAutoChat == FALSE) { MessageBoxW(L"自动聊天已开启"); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT autochat; autochat.dwData = WM_AutoChat; autochat.cbData = 0; autochat.lpData = NULL; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&autochat); bAutoChat = TRUE; } else { MessageBoxW(L"自动聊天已关闭"); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT autochat; autochat.dwData = WM_CancleAutoChat; autochat.cbData = 0; autochat.lpData = NULL; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&autochat); bAutoChat = FALSE; } } else { MessageBoxW(L"请先关注小冰的宇宙公众号", L"提示", 0); } } //************************************************************ // 函数名称: OnBnClickedOpenUrl // 函数说明: 打开微信浏览器 // 作 者: GuiShou // 时 间: 2019/9/10 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedOpenUrl() { COpenUrl openurl; openurl.DoModal(); } //************************************************************ // 函数名称: OnBnClickedSendxmlarticle // 函数说明: 发送xml文章 // 作 者: GuiShou // 时 间: 2019/9/30 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedSendxmlarticle() { } //************************************************************ // 函数名称: OnBnClickedSendmsgbytimer // 函数说明: 定时发送 // 作 者: GuiShou // 时 间: 2019/10/14 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedSendmsgbytimer() { } //************************************************************ // 函数名称: OnBnClickedCreateroom // 函数说明: 创建群聊 // 作 者: GuiShou // 时 间: 2019/10/22 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedCreateroom() { } //************************************************************ // 函数名称: OnBnClickedModifyversion // 函数说明: 修改版本号 // 作 者: GuiShou // 时 间: 2019/10/28 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedModifyversion() { } //************************************************************ // 函数名称: OnBnClickedFollowaccount // 函数说明: 关注公众号 // 作 者: GuiShou // 时 间: 2019/11/19 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedFollowaccount() { } //************************************************************ // 函数名称: OnBnClickedKeywordsreply // 函数说明: 开启或关闭关键词回复 // 作 者: GuiShou // 时 间: 2019/11/20 // 参 数: void // 返 回 值: void //*********************************************************** void CFunctions::OnBnClickedKeywordsreply() { } ================================================ FILE: WeChatRobot/CFunctions.h ================================================ #pragma once // CFunctions 对话框 class CFunctions : public CDialogEx { DECLARE_DYNAMIC(CFunctions) public: CFunctions(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CFunctions(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_FUNCTIONS }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedInformation(); afx_msg void OnBnClickedDecryptPic(); afx_msg void OnBnClickedMultiOpen(); afx_msg void OnBnClickedAddUser(); afx_msg void OnBnClickedAutoChat(); afx_msg void OnBnClickedOpenUrl(); afx_msg void OnBnClickedSendxmlarticle(); afx_msg void OnBnClickedSendmsgbytimer(); afx_msg void OnBnClickedCreateroom(); afx_msg void OnBnClickedModifyversion(); afx_msg void OnBnClickedFollowaccount(); afx_msg void OnBnClickedKeywordsreply(); }; ================================================ FILE: WeChatRobot/CInformation.cpp ================================================ #include "stdafx.h" #include "WeChatRobot.h" #include "CInformation.h" #include "afxdialogex.h" // CInformation 对话框 IMPLEMENT_DYNAMIC(CInformation, CDialogEx) CInformation::CInformation(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_INFORMATION, pParent) , m_header(_T("")) , m_city(_T("")) , m_province(_T("")) , m_nation(_T("")) , m_device(_T("")) , m_phone(_T("")) , m_nickname(_T("")) , m_count(_T("")) , m_wxid(_T("")) , m_sex(_T("")) , m_bigheader(_T("")) { } CInformation::~CInformation() { } void CInformation::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_HEADER, m_header); DDX_Text(pDX, IDC_CITY, m_city); DDX_Text(pDX, IDC_PROVINCE, m_province); DDX_Text(pDX, IDC_NATION, m_nation); DDX_Text(pDX, IDC_DEVICE, m_device); DDX_Text(pDX, IDC_PHONE, m_phone); DDX_Text(pDX, IDC_NICKNAME, m_nickname); DDX_Text(pDX, IDC_ACCOUNT, m_count); DDX_Text(pDX, IDC_WXID, m_wxid); DDX_Text(pDX, IDC_SEX, m_sex); DDX_Text(pDX, IDC_HEADER2, m_bigheader); } BEGIN_MESSAGE_MAP(CInformation, CDialogEx) ON_WM_COPYDATA() END_MESSAGE_MAP() // CInformation 消息处理程序 BOOL CInformation::OnInitDialog() { CDialogEx::OnInitDialog(); //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT GetInformation; //组装数据 GetInformation.dwData = WM_GetInformation; GetInformation.cbData = 0; GetInformation.lpData = NULL; //发送获取个人信息消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&GetInformation); return TRUE; } BOOL CInformation::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { //显示好友列表 if (pCopyDataStruct->dwData == WM_GetInformation) { //接收消息 PersonalInformation *info = (PersonalInformation*)pCopyDataStruct->lpData; //显示到控件 m_wxid = info->wxid; m_count = info->wxcount; m_nickname = info->nickname; m_phone = info->phonenumber; m_device = info->device; m_nation = info->nation; m_city = info->city; m_province = info->province; m_header = info->smallheader; m_bigheader = info->bigheader; m_sex = info->wxsex; UpdateData(FALSE); } return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } ================================================ FILE: WeChatRobot/CInformation.h ================================================ #pragma once // CInformation 对话框 class CInformation : public CDialogEx { DECLARE_DYNAMIC(CInformation) public: CInformation(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CInformation(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_INFORMATION }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); CString m_header; CString m_city; CString m_province; CString m_nation; CString m_device; CString m_phone; CString m_nickname; CString m_count; CString m_wxid; CString m_sex; CString m_bigheader; }; ================================================ FILE: WeChatRobot/CInjectTools.cpp ================================================ #include "stdafx.h" #include "CInjectTools.h" #include #include #include #include #pragma comment(lib,"advapi32") #define WECHAT_PROCESS_NAME "WeChat.exe" #define DLLNAME "WeChatHelper.dll" CString GetAppRegeditPath(CString strAppName) { //ر HKEY hKey; CString strAppRegeditPath(""); TCHAR szProductType[MAX_PATH]; memset(szProductType, 0, sizeof(szProductType)); DWORD dwBuflen = MAX_PATH; LONG lRet = 0; //Ǵע,ֻд򿪺 lRet = RegOpenKeyEx(HKEY_CURRENT_USER, //Ҫ򿪵ĸ LPCTSTR(strAppName), //Ҫ򿪵Ӽ 0, //һΪ0 KEY_QUERY_VALUE, //ָ򿪷ʽ,Ϊ &hKey); //ؾ if (lRet != ERROR_SUCCESS) //жǷ򿪳ɹ { return strAppRegeditPath; } else { //濪ʼѯ lRet = RegQueryValueEx(hKey, //עʱصľ TEXT("Wechat"), //Ҫѯ,ѯװĿ¼ NULL, //һΪNULL0 NULL, (LPBYTE)szProductType, //ҪĶ &dwBuflen); if (lRet != ERROR_SUCCESS) //жǷѯɹ { return strAppRegeditPath; } else { RegCloseKey(hKey); strAppRegeditPath = szProductType; int nPos = strAppRegeditPath.Find('-'); if (nPos >= 0) { CString sSubStr = strAppRegeditPath.Left(nPos - 1);//$,ʱnPos+1 strAppRegeditPath = sSubStr; } } } return strAppRegeditPath; } CString GetAppRegeditPath2(CString strAppName) { //ر HKEY hKey; CString strAppRegeditPath(""); TCHAR szProductType[MAX_PATH]; memset(szProductType, 0, sizeof(szProductType)); DWORD dwBuflen = MAX_PATH; LONG lRet = 0; //Ǵע,ֻд򿪺 lRet = RegOpenKeyEx(HKEY_CURRENT_USER, //Ҫ򿪵ĸ LPCTSTR(strAppName), //Ҫ򿪵Ӽ 0, //һΪ0 KEY_QUERY_VALUE, //ָ򿪷ʽ,Ϊ &hKey); //ؾ if (lRet != ERROR_SUCCESS) //жǷ򿪳ɹ { return strAppRegeditPath; } else { //濪ʼѯ lRet = RegQueryValueEx(hKey, //עʱصľ TEXT("InstallPath"), //Ҫѯ,ѯװĿ¼ NULL, //һΪNULL0 NULL, (LPBYTE)szProductType, //ҪĶ &dwBuflen); if (lRet != ERROR_SUCCESS) //жǷѯɹ { return strAppRegeditPath; } else { RegCloseKey(hKey); strAppRegeditPath = szProductType; } } return strAppRegeditPath; } //************************************************************ // : ProcessNameFindPID // ˵: ͨҵID // : GuiShou // ʱ : 2019/6/30 // : ProcessName // ֵ: DWORD PID //************************************************************ DWORD ProcessNameFindPID(const char* ProcessName) { PROCESSENTRY32 pe32 = { 0 }; pe32.dwSize = sizeof(PROCESSENTRY32); HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Process32First(hProcess, &pe32) == TRUE) { do { USES_CONVERSION; if (strcmp(ProcessName, W2A(pe32.szExeFile)) == 0) { return pe32.th32ProcessID; } } while (Process32Next(hProcess, &pe32)); } return 0; } //************************************************************ // : InjectDll // ˵: עDLL // : GuiShou // ʱ : 2019/6/30 // : void // ֵ: void //************************************************************ BOOL InjectDll(HANDLE& wxPid) { //ȡǰĿ¼µdll char szPath[MAX_PATH] = { 0 }; char* buffer = NULL; if ((buffer = _getcwd(NULL, 0)) == NULL) { MessageBoxA(NULL, "ȡǰĿ¼ʧ", "", 0); return FALSE; } sprintf_s(szPath, "%s\\%s", buffer, DLLNAME); //ȡ΢Pid DWORD dwPid = ProcessNameFindPID(WECHAT_PROCESS_NAME); if (dwPid == 0) { CString wxStrAppName = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); CString szProductType = GetAppRegeditPath(wxStrAppName); if (szProductType.GetLength()<5) { wxStrAppName = TEXT("Software\\Tencent\\WeChat"); szProductType = GetAppRegeditPath2(wxStrAppName); szProductType.Append(L"\\WeChat.exe"); } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); si.dwFlags = STARTF_USESHOWWINDOW;// ָwShowWindowԱЧ si.wShowWindow = TRUE; // ˳ԱΪTRUEĻʾ½̵ڣ // ΪFALSEĻʾ CreateProcess(szProductType, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); HWND hWechatMainForm = NULL; //WeChatLoginWndForPC while (NULL == hWechatMainForm) { hWechatMainForm = FindWindow(TEXT("WeChatLoginWndForPC"), NULL); Sleep(500); } if (NULL == hWechatMainForm) { return FALSE; } dwPid = pi.dwProcessId; wxPid = pi.hProcess; } //dllǷѾע if (CheckIsInject(dwPid)) { //򿪽 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (hProcess == NULL) { MessageBoxA(NULL, "̴ʧ", "", 0); return FALSE; } //΢Žڴ LPVOID pAddress = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (pAddress == NULL) { MessageBoxA(NULL, "ڴʧ", "", 0); return FALSE; } //дdll·΢Ž if (WriteProcessMemory(hProcess, pAddress, szPath, MAX_PATH, NULL) == 0) { MessageBoxA(NULL, "·дʧ", "", 0); return FALSE; } //ȡLoadLibraryAַ FARPROC pLoadLibraryAddress = GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"); if (pLoadLibraryAddress == NULL) { MessageBoxA(NULL, "ȡLoadLibraryAַʧ", "", 0); return FALSE; } //Զ߳עdll HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibraryAddress, pAddress, 0, NULL); if (hRemoteThread == NULL) { MessageBoxA(NULL, "Զ߳עʧ", "", 0); return FALSE; } CloseHandle(hRemoteThread); CloseHandle(hProcess); } else { MessageBoxA(NULL, "dllѾע룬ظע", "ʾ", 0); return FALSE; } return TRUE; } //************************************************************ // : CheckIsInject // ˵: ǷѾעdll // : GuiShou // ʱ : 2019/6/30 // : void // ֵ: BOOL //************************************************************ BOOL CheckIsInject(DWORD dwProcessid) { HANDLE hModuleSnap = INVALID_HANDLE_VALUE; //ʼģϢṹ MODULEENTRY32 me32 = { sizeof(MODULEENTRY32) }; //ģ 1 2 ID hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessid); //Чͷfalse if (hModuleSnap == INVALID_HANDLE_VALUE) { MessageBoxA(NULL, "ģʧ", "", MB_OK); return FALSE; } //ͨģվȡһģϢ if (!Module32First(hModuleSnap, &me32)) { MessageBoxA(NULL, "ȡһģϢʧ", "", MB_OK); //ȡʧرվ CloseHandle(hModuleSnap); return FALSE; } do { if (StrCmpW(me32.szModule, L"WeChatHelper.dll") == 0) { return FALSE; } } while (Module32Next(hModuleSnap, &me32)); return TRUE; } ================================================ FILE: WeChatRobot/CInjectTools.h ================================================ #pragma once DWORD ProcessNameFindPID(const char* ProcessName); //ͨȡID BOOL InjectDll(HANDLE& wxPid); //עdll BOOL CheckIsInject(DWORD dwProcessid); //DLLǷѾע ================================================ FILE: WeChatRobot/CInviteGroupMember.cpp ================================================ // CInviteGroupMember.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CInviteGroupMember.h" #include "afxdialogex.h" // CInviteGroupMember 对话框 IMPLEMENT_DYNAMIC(CInviteGroupMember, CDialogEx) CInviteGroupMember::CInviteGroupMember(LPCTSTR TempGroupId, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_InviteMember, pParent), m_ChatRoomWxid(TempGroupId) , m_wxid(_T("")) { } CInviteGroupMember::~CInviteGroupMember() { } void CInviteGroupMember::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_wxid); } BEGIN_MESSAGE_MAP(CInviteGroupMember, CDialogEx) ON_BN_CLICKED(IDC_INVITE, &CInviteGroupMember::OnBnClickedInvite) END_MESSAGE_MAP() //************************************************************ // 函数名称: OnBnClickedInvite // 函数说明: 响应确定按钮 // 作 者: GuiShou // 时 间: 2019/9/19 // 参 数: void // 返 回 值: void //*********************************************************** void CInviteGroupMember::OnBnClickedInvite() { } ================================================ FILE: WeChatRobot/CInviteGroupMember.h ================================================ #pragma once // CInviteGroupMember 对话框 class CInviteGroupMember : public CDialogEx { DECLARE_DYNAMIC(CInviteGroupMember) public: CInviteGroupMember(LPCTSTR TempGroupId, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CInviteGroupMember(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_InviteMember }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_ChatRoomWxid; //从好友列表窗口传过来的群ID CString m_wxid; afx_msg void OnBnClickedInvite(); }; ================================================ FILE: WeChatRobot/CMain.cpp ================================================ // CMain.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CMain.h" #include "afxdialogex.h" #include "CChatRecords.h" #include "CFriendList.h" #include "CFunctions.h" #include "CPay.h" #include "CAboutAuthor.h" IMPLEMENT_DYNAMIC(CMain, CDialogEx) CMain::CMain(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_MAIN, pParent) { } CMain::~CMain() { } void CMain::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_TAB1, m_MyTable); } BEGIN_MESSAGE_MAP(CMain, CDialogEx) ON_COMMAND(ID_32776, &CMain::OnWxLogout) ON_WM_COPYDATA() ON_COMMAND(ID_32779, &CMain::OnPayAuthor) ON_COMMAND(ID_32778, &CMain::OnAboutAuthor) ON_COMMAND(ID_32798, &CMain::OnSaveFriendList) ON_WM_CLOSE() ON_WM_DESTROY() END_MESSAGE_MAP() // CMain 消息处理程序 BOOL CMain::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: 在此添加额外的初始化 TCHAR Name[3][5] = { L"好友列表",L"聊天记录" , L"功能大全" }; for (int i = 0; i < 3; i++) { m_MyTable.InsertItem(i, Name[i]); } //给子窗口指针赋值 m_MyTable.m_Dia[0] = new CFriendList(); m_MyTable.m_Dia[1] = new CChatRecords(); m_MyTable.m_Dia[2] = new CFunctions(); //创建子窗口 UINT DiaIds[3] = { IDD_FRIEND_LIST, IDD_CHAT_RECORDS, IDD_FUNCTIONS}; for (int i = 0; i < 3; i++) { m_MyTable.m_Dia[i]->Create(DiaIds[i], &m_MyTable); } //控制两个窗口的大小 CRect rc; m_MyTable.GetClientRect(rc); rc.DeflateRect(2, 23, 2, 2); for (int i = 0; i < 3; i++) { m_MyTable.m_Dia[i]->MoveWindow(rc); } //显示第一个子窗口 m_MyTable.m_Dia[0]->ShowWindow(SW_SHOW); for (int i = 1; i < 3; i++) { m_MyTable.m_Dia[i]->ShowWindow(SW_HIDE); } return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } //************************************************************ // 函数名称: OnWxLogout // 函数说明: 响应退出微信菜单 // 作 者: GuiShou // 时 间: 2019/6/30 // 参 数: void // 返 回 值: void //*********************************************************** void CMain::OnWxLogout() { //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT logout; logout.dwData = WM_Logout; logout.cbData = 0; logout.lpData = NULL; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&logout); } //************************************************************ // 函数名称: OnCopyData // 函数说明: 响应CopyData消息 // 作 者: GuiShou // 时 间: 2019/7/5 // 参 数: CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct // 返 回 值: BOOL //*********************************************************** BOOL CMain::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { //显示好友列表 if (pCopyDataStruct->dwData == WM_GetFriendList) { UserInfo *user = (UserInfo*)pCopyDataStruct->lpData; //将消息发送给子窗口 m_MyTable.m_Dia[0]->SendMessage(WM_ShowFriendList, (WPARAM)user, NULL); } //显示聊天记录 else if (pCopyDataStruct->dwData == WM_ShowChatRecord) { ChatMessageData *msg = (ChatMessageData*)pCopyDataStruct->lpData; //将消息发送给子窗口 m_MyTable.m_Dia[1]->SendMessage(WM_ShowMessage, (WPARAM)msg, NULL); } return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } //************************************************************ // 函数名称: OnPayAuthor // 函数说明: 响应打赏作者菜单 // 作 者: GuiShou // 时 间: 2019/7/14 // 参 数: void // 返 回 值: void //*********************************************************** void CMain::OnPayAuthor() { CPay pay; pay.DoModal(); } //************************************************************ // 函数名称: OnAboutAuthor // 函数说明: 响应关于作者菜单 // 作 者: GuiShou // 时 间: 2019/7/14 // 参 数: void // 返 回 值: void //*********************************************************** void CMain::OnAboutAuthor() { CAboutAuthor about; about.DoModal(); } //************************************************************ // 函数名称: OnSaveFriendList // 函数说明: 响应保存联系人菜单 // 作 者: GuiShou // 时 间: 2019/9/17 // 参 数: void // 返 回 值: void //*********************************************************** void CMain::OnSaveFriendList() { m_MyTable.m_Dia[0]->SendMessage(SaveFriendList, NULL, NULL); } //************************************************************ // 函数名称: OnClose // 函数说明: 重载OnClose消息 // 作 者: GuiShou // 时 间: 2019/12/10 // 参 数: void // 返 回 值: void //*********************************************************** void CMain::OnClose() { if (MessageBoxA(NULL, "是否退出程序", "Tip", MB_YESNO) == IDYES) { EndDialog(0); } } ================================================ FILE: WeChatRobot/CMain.h ================================================ #pragma once #include "CMyTableCtrl.h" // CMain 对话框 class CMain : public CDialogEx { DECLARE_DYNAMIC(CMain) public: CMain(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CMain(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_MAIN }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CMyTableCtrl m_MyTable; virtual BOOL OnInitDialog(); afx_msg void OnWxLogout(); afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); afx_msg void OnPayAuthor(); afx_msg void OnAboutAuthor(); afx_msg void OnSaveFriendList(); afx_msg void OnClose(); }; ================================================ FILE: WeChatRobot/CModifyVersion.cpp ================================================ // CModifyVersion.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CModifyVersion.h" #include "afxdialogex.h" #include // CModifyVersion 对话框 IMPLEMENT_DYNAMIC(CModifyVersion, CDialogEx) CModifyVersion::CModifyVersion(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_ModifyVersion, pParent) , m_version(_T("2.7.1.85")) { } CModifyVersion::~CModifyVersion() { } void CModifyVersion::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_version); } BEGIN_MESSAGE_MAP(CModifyVersion, CDialogEx) ON_BN_CLICKED(IDC_Modify, &CModifyVersion::OnBnClickedModify) END_MESSAGE_MAP() // CModifyVersion 消息处理程序 void CModifyVersion::OnBnClickedModify() { } ================================================ FILE: WeChatRobot/CModifyVersion.h ================================================ #pragma once // CModifyVersion 对话框 class CModifyVersion : public CDialogEx { DECLARE_DYNAMIC(CModifyVersion) public: CModifyVersion(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CModifyVersion(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ModifyVersion }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_version; afx_msg void OnBnClickedModify(); }; ================================================ FILE: WeChatRobot/CMultiOpen.cpp ================================================ #include "stdafx.h" #include #include #pragma comment(lib, "shlwapi") #include "CMultiOpen.h" #include typedef NTSTATUS(NTAPI *NTQUERYOBJECT)( _In_opt_ HANDLE Handle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _Out_opt_ PVOID ObjectInformation, _In_ ULONG ObjectInformationLength, _Out_opt_ PULONG ReturnLength ); typedef NTSTATUS (NTAPI *ZWQUERYSYSTEMINFORMATION)( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation"); NTQUERYOBJECT NtQueryObject = (NTQUERYOBJECT)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryObject"); //************************************************************ // : ElevatePrivileges // ˵: Ȩ // : GuiShou // ʱ : 2019/7/13 // : void // ֵ: BOOL //*********************************************************** BOOL ElevatePrivileges() { HANDLE hToken; TOKEN_PRIVILEGES tkp; tkp.PrivilegeCount = 1; if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) return FALSE; LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid); tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),NULL,NULL)) { return FALSE; } return TRUE; } //************************************************************ // : DuplicateHandleEx // ˵: ƾ // : GuiShou // ʱ : 2019/7/13 // : void // ֵ: BOOL //*********************************************************** HANDLE DuplicateHandleEx(DWORD pid, HANDLE h, DWORD flags) { HANDLE hHandle = NULL; HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if(hProc) { if(!DuplicateHandle(hProc, (HANDLE)h, GetCurrentProcess(), &hHandle, 0, FALSE, /*DUPLICATE_SAME_ACCESS*/flags)) { hHandle = NULL; } } CloseHandle(hProc); return hHandle; } //************************************************************ // : GetProcIds // ˵: ȡPID // : GuiShou // ʱ : 2019/7/13 // : Name Pids // ֵ: int //*********************************************************** int GetProcIds(LPWSTR Name, DWORD* Pids) { PROCESSENTRY32 pe32 = {sizeof(pe32)}; int num = 0; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if(hSnap) { if(Process32First(hSnap, &pe32)) { do { if(!StrCmpW(Name, pe32.szExeFile)) { if(Pids) { Pids[num++] = pe32.th32ProcessID; } } } while(Process32Next(hSnap, &pe32)); } CloseHandle(hSnap); } return num; } //************************************************************ // : IsTargetPid // ˵: ǷĿPID // : GuiShou // ʱ : 2019/7/13 // : Pid Pids num // ֵ: BOOL //*********************************************************** BOOL IsTargetPid(DWORD Pid, DWORD* Pids, int num) { for(int i=0; i 0x4000000) // MAXSIZE { goto Exit0; } pbuffer = VirtualAlloc(NULL, dwSize*2, MEM_COMMIT, PAGE_READWRITE); if(!pbuffer) { goto Exit0; } Status = ZwQuerySystemInformation(SystemHandleInformation, pbuffer, dwSize*2, NULL); if(!NT_SUCCESS(Status)) { goto Exit0; } } } PSYSTEM_HANDLE_INFORMATION1 pHandleInfo = (PSYSTEM_HANDLE_INFORMATION1)pbuffer; int nCount = 0; //رվĴ for(nIndex = 0; nIndex < pHandleInfo->NumberOfHandles; nIndex++) { if(IsTargetPid(pHandleInfo->Handles[nIndex].UniqueProcessId, Pids, Num)) { // HANDLE hHandle = DuplicateHandleEx(pHandleInfo->Handles[nIndex].UniqueProcessId, (HANDLE)pHandleInfo->Handles[nIndex].HandleValue, DUPLICATE_SAME_ACCESS ); if(hHandle == NULL) continue; Status = NtQueryObject(hHandle, ObjectNameInformation, szName, 512, &dwFlags); if (!NT_SUCCESS(Status)) { CloseHandle(hHandle); continue; } Status = NtQueryObject(hHandle, ObjectTypeInformation, szType, 128, &dwFlags); if (!NT_SUCCESS(Status)) { CloseHandle(hHandle); continue; } pNameInfo = (POBJECT_NAME_INFORMATION)szName; pNameType = (POBJECT_NAME_INFORMATION)szType; WCHAR TypName[1024] = {0}; WCHAR Name[1024] = {0}; wcsncpy_s(TypName, (WCHAR*)pNameType->Name.Buffer, pNameType->Name.Length/2); wcsncpy_s(Name, (WCHAR*)pNameInfo->Name.Buffer, pNameInfo->Name.Length/2); // ƥǷΪҪرյľ if (0 == wcscmp(TypName, L"Mutant")) { if (wcsstr(Name, L"_WeChat_App_Instance_Identity_Mutex_Name")) { CloseHandle(hHandle); hHandle = DuplicateHandleEx(pHandleInfo->Handles[nIndex].UniqueProcessId, (HANDLE)pHandleInfo->Handles[nIndex].HandleValue, DUPLICATE_CLOSE_SOURCE ); if(hHandle) { OutputDebugStringA("+ Patch wechat success!\n"); CloseHandle(hHandle); } else { OutputDebugStringA("- Patch error"); } nCount++; if (nCount>=2) { goto Exit0; } } } CloseHandle(hHandle); } } Exit0: if (NULL != pbuffer) { VirtualFree(pbuffer, 0, MEM_RELEASE); } return 0; } //************************************************************ // : OpenWeChat // ˵: ΢ // : GuiShou // ʱ : 2019/7/13 // : void // ֵ: void //*********************************************************** void OpenWeChat() { HKEY hKey = NULL; if(ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, L"Software\\Tencent\\WeChat", &hKey)) { return; } DWORD Type = REG_SZ; WCHAR Path[MAX_PATH] = {0}; DWORD cbData = MAX_PATH*sizeof(WCHAR); if(ERROR_SUCCESS != RegQueryValueEx(hKey, L"InstallPath", 0, &Type, (LPBYTE)Path, &cbData)) { goto __exit; } PathAppend(Path, L"WeChat.exe"); ShellExecute(NULL, L"Open", Path, NULL, NULL, SW_SHOW); __exit: if(hKey) { RegCloseKey(hKey); } } ================================================ FILE: WeChatRobot/CMultiOpen.h ================================================ #pragma once #include /*ͷļ*/ typedef LONG NTSTATUS; #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, // 0 Y N SystemProcessorInformation, // 1 Y N SystemPerformanceInformation, // 2 Y N SystemTimeOfDayInformation, // 3 Y N SystemNotImplemented1, // 4 Y N SystemProcessesAndThreadsInformation, // 5 Y N SystemCallCounts, // 6 Y N SystemConfigurationInformation, // 7 Y N SystemProcessorTimes, // 8 Y N SystemGlobalFlag, // 9 Y Y SystemNotImplemented2, // 10 Y N SystemModuleInformation, // 11 Y N SystemLockInformation, // 12 Y N SystemNotImplemented3, // 13 Y N SystemNotImplemented4, // 14 Y N SystemNotImplemented5, // 15 Y N SystemHandleInformation, // 16 Y N SystemObjectInformation, // 17 Y N SystemPagefileInformation, // 18 Y N SystemInstructionEmulationCounts, // 19 Y N SystemInvalidInfoClass1, // 20 SystemCacheInformation, // 21 Y Y SystemPoolTagInformation, // 22 Y N SystemProcessorStatistics, // 23 Y N SystemDpcInformation, // 24 Y Y SystemNotImplemented6, // 25 Y N SystemLoadImage, // 26 N Y SystemUnloadImage, // 27 N Y SystemTimeAdjustment, // 28 Y Y SystemNotImplemented7, // 29 Y N SystemNotImplemented8, // 30 Y N SystemNotImplemented9, // 31 Y N SystemCrashDumpInformation, // 32 Y N SystemExceptionInformation, // 33 Y N SystemCrashDumpStateInformation, // 34 Y Y/N SystemKernelDebuggerInformation, // 35 Y N SystemContextSwitchInformation, // 36 Y N SystemRegistryQuotaInformation, // 37 Y Y SystemLoadAndCallImage, // 38 N Y SystemPrioritySeparation, // 39 N Y SystemNotImplemented10, // 40 Y N SystemNotImplemented11, // 41 Y N SystemInvalidInfoClass2, // 42 SystemInvalidInfoClass3, // 43 SystemTimeZoneInformation, // 44 Y N SystemLookasideInformation, // 45 Y N SystemSetTimeSlipEvent, // 46 N Y SystemCreateSession, // 47 N Y SystemDeleteSession, // 48 N Y SystemInvalidInfoClass4, // 49 SystemRangeStartInformation, // 50 Y N SystemVerifierInformation, // 51 Y Y SystemAddVerifier, // 52 N Y SystemSessionProcessesInformation // 53 Y N } SYSTEM_INFORMATION_CLASS; typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; }CLIENT_ID,*PCLIENT_ID; typedef struct { USHORT Length; USHORT MaxLen; USHORT *Buffer; }UNICODE_STRING, *PUNICODE_STRING; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; typedef struct _IO_COUNTERSEX { LARGE_INTEGER ReadOperationCount; LARGE_INTEGER WriteOperationCount; LARGE_INTEGER OtherOperationCount; LARGE_INTEGER ReadTransferCount; LARGE_INTEGER WriteTransferCount; LARGE_INTEGER OtherTransferCount; } IO_COUNTERSEX, *PIO_COUNTERSEX; typedef enum { StateInitialized, StateReady, StateRunning, StateStandby, StateTerminated, StateWait, StateTransition, StateUnknown } THREAD_STATE; typedef struct _VM_COUNTERS { SIZE_T PeakVirtualSize; SIZE_T VirtualSize; ULONG PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; } VM_COUNTERS; typedef VM_COUNTERS *PVM_COUNTERS; typedef struct _SYSTEM_THREADS { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; ULONG Priority; ULONG BasePriority; ULONG ContextSwitchCount; THREAD_STATE State; ULONG WaitReason; } SYSTEM_THREADS, *PSYSTEM_THREADS; typedef struct _SYSTEM_PROCESSES { // Information Class 5 ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; ULONG BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERSEX IoCounters; // Windows 2000 only SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES; typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; PVOID Object; ULONG GrantedAccess; } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO; typedef struct _SYSTEM_HANDLE_INFORMATION1 { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ]; } SYSTEM_HANDLE_INFORMATION1, *PSYSTEM_HANDLE_INFORMATION1; typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, ObjectNameInformation, ObjectTypeInformation, ObjectAllInformation, ObjectDataInformation } OBJECT_INFORMATION_CLASS; typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; void OpenWeChat(); int PatchWeChat(); BOOL IsTargetPid(DWORD Pid, DWORD* Pids, int num); int GetProcIds(LPWSTR Name, DWORD* Pids); HANDLE DuplicateHandleEx(DWORD pid, HANDLE h, DWORD flags); BOOL ElevatePrivileges(); ================================================ FILE: WeChatRobot/CMyTableCtrl.cpp ================================================ // CMyTableCtrl.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CMyTableCtrl.h" // CMyTableCtrl IMPLEMENT_DYNAMIC(CMyTableCtrl, CTabCtrl) CMyTableCtrl::CMyTableCtrl() { } CMyTableCtrl::~CMyTableCtrl() { } BEGIN_MESSAGE_MAP(CMyTableCtrl, CTabCtrl) ON_NOTIFY_REFLECT(TCN_SELCHANGE, &CMyTableCtrl::OnTcnSelchange) END_MESSAGE_MAP() // CMyTableCtrl 消息处理程序 void CMyTableCtrl::OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult) { int nNum = GetCurSel(); for (int i = 0; i < 3; i++) { if (i == nNum) { m_Dia[i]->ShowWindow(SW_SHOW); } else { m_Dia[i]->ShowWindow(SW_HIDE); } } *pResult = 0; } ================================================ FILE: WeChatRobot/CMyTableCtrl.h ================================================ #pragma once // CMyTableCtrl class CMyTableCtrl : public CTabCtrl { DECLARE_DYNAMIC(CMyTableCtrl) public: CMyTableCtrl(); virtual ~CMyTableCtrl(); CDialogEx* m_Dia[3]; protected: DECLARE_MESSAGE_MAP() public: afx_msg void OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult); }; ================================================ FILE: WeChatRobot/COpenUrl.cpp ================================================ // COpenUrl.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "COpenUrl.h" #include "afxdialogex.h" // COpenUrl 对话框 IMPLEMENT_DYNAMIC(COpenUrl, CDialogEx) COpenUrl::COpenUrl(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_OpenUrl, pParent) , m_urls(_T("www.baidu.com")) { } COpenUrl::~COpenUrl() { } void COpenUrl::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_urls); } BEGIN_MESSAGE_MAP(COpenUrl, CDialogEx) ON_BN_CLICKED(IDC_OPEN, &COpenUrl::OnBnClickedOpen) END_MESSAGE_MAP() // COpenUrl 消息处理程序 //************************************************************ // 函数名称: OnBnClickedOpen // 函数说明: 打开浏览器按钮 // 作 者: GuiShou // 时 间: 2019/9/10 // 参 数: void // 返 回 值: void //*********************************************************** void COpenUrl::OnBnClickedOpen() { UpdateData(TRUE); if (m_urls=="") { MessageBoxA(NULL,"url不能为空", "Tip", MB_OK); return; } wchar_t urls[500] = { 0 }; wcscpy_s(urls, wcslen(m_urls) + 1, m_urls); //点击按钮 拿到url 发送给控制端 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT openurl; openurl.dwData = WM_OpenUrl; openurl.cbData = (wcslen(urls) + 1) * 2; openurl.lpData = urls; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&openurl); } ================================================ FILE: WeChatRobot/COpenUrl.h ================================================ #pragma once // COpenUrl 对话框 class COpenUrl : public CDialogEx { DECLARE_DYNAMIC(COpenUrl) public: COpenUrl(CWnd* pParent = nullptr); // 标准构造函数 virtual ~COpenUrl(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_OpenUrl }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_urls; afx_msg void OnBnClickedOpen(); }; ================================================ FILE: WeChatRobot/CPay.cpp ================================================ // CPay.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CPay.h" #include "afxdialogex.h" // CPay 对话框 IMPLEMENT_DYNAMIC(CPay, CDialogEx) CPay::CPay(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_PAY, pParent) { } CPay::~CPay() { } void CPay::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CPay, CDialogEx) END_MESSAGE_MAP() // CPay 消息处理程序 ================================================ FILE: WeChatRobot/CPay.h ================================================ #pragma once // CPay 对话框 class CPay : public CDialogEx { DECLARE_DYNAMIC(CPay) public: CPay(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CPay(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_PAY }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() }; ================================================ FILE: WeChatRobot/CRoomAnnouncement.cpp ================================================ // CRoomAnnouncement.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CRoomAnnouncement.h" #include "afxdialogex.h" // CRoomAnnouncement 对话框 IMPLEMENT_DYNAMIC(CRoomAnnouncement, CDialogEx) CRoomAnnouncement::CRoomAnnouncement(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_ROOMANNOUNCE, pParent), m_ChatRoomWxid(TempWxid) , m_Announcement(_T("")) { } CRoomAnnouncement::~CRoomAnnouncement() { } void CRoomAnnouncement::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_Announcement); } BEGIN_MESSAGE_MAP(CRoomAnnouncement, CDialogEx) ON_BN_CLICKED(IDC_SendRoomAnnouncement, &CRoomAnnouncement::OnBnClickedSendroomannouncement) END_MESSAGE_MAP() // CRoomAnnouncement 消息处理程序 //************************************************************ // 函数名称: OnBnClickedSendroomannouncement // 函数说明: 响应发送群公告按钮 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CRoomAnnouncement::OnBnClickedSendroomannouncement() { //将控件的值更新到变量 UpdateData(TRUE); //构造发送的数据 MessageStruct* pMessage = new MessageStruct(m_ChatRoomWxid, m_Announcement); //发送到服务端 //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT chatroommsg; chatroommsg.dwData = WM_SetRoomAnnouncement; chatroommsg.cbData = sizeof(MessageStruct); chatroommsg.lpData = pMessage; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&chatroommsg); delete pMessage; m_Announcement = ""; UpdateData(FALSE); } ================================================ FILE: WeChatRobot/CRoomAnnouncement.h ================================================ #pragma once // CRoomAnnouncement 对话框 class CRoomAnnouncement : public CDialogEx { DECLARE_DYNAMIC(CRoomAnnouncement) public: CRoomAnnouncement(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CRoomAnnouncement(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ROOMANNOUNCE }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_Announcement; afx_msg void OnBnClickedSendroomannouncement(); CString m_ChatRoomWxid; //从好友列表窗口传过来的群ID }; ================================================ FILE: WeChatRobot/CSendChatRoomAt.cpp ================================================ // CSendChatRoomAt.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSendChatRoomAt.h" #include "afxdialogex.h" // CSendChatRoomAt 对话框 IMPLEMENT_DYNAMIC(CSendChatRoomAt, CDialogEx) CSendChatRoomAt::CSendChatRoomAt(LPCTSTR TempWxid, LPCTSTR TempNickName, LPCTSTR TempChatRoomid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SENDAT, pParent), m_MemberWxid(TempWxid), m_MemberNickName(TempNickName), m_ChatRoomid(TempChatRoomid) , m_msg(_T("")) { } CSendChatRoomAt::~CSendChatRoomAt() { } void CSendChatRoomAt::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_msg); } BEGIN_MESSAGE_MAP(CSendChatRoomAt, CDialogEx) ON_BN_CLICKED(IDC_SendAt, &CSendChatRoomAt::OnBnClickedSendat) END_MESSAGE_MAP() // CSendChatRoomAt 消息处理程序 //************************************************************ // 函数名称: OnBnClickedSendat // 函数说明: 响应发送按钮 // 作 者: GuiShou // 时 间: 2019/7/23 // 参 数: void // 返 回 值: void //*********************************************************** void CSendChatRoomAt::OnBnClickedSendat() { UpdateData(TRUE); unique_ptr msg(new AtMsg); wcscpy_s(msg->chatroomid, wcslen(m_ChatRoomid) + 1, m_ChatRoomid); wcscpy_s(msg->memberwxid, wcslen(m_MemberWxid) + 1, m_MemberWxid); wcscpy_s(msg->membernickname, wcslen(m_MemberNickName) + 1, m_MemberNickName); wcscpy_s(msg->msgcontent, wcslen(m_msg) + 1, m_msg); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT atmsgdata; atmsgdata.dwData = WM_SendAtMsg; atmsgdata.cbData = sizeof(AtMsg); atmsgdata.lpData = msg.get(); //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&atmsgdata); m_msg = ""; UpdateData(FALSE); } ================================================ FILE: WeChatRobot/CSendChatRoomAt.h ================================================ #pragma once // CSendChatRoomAt 对话框 class CSendChatRoomAt : public CDialogEx { DECLARE_DYNAMIC(CSendChatRoomAt) public: CSendChatRoomAt(LPCTSTR TempWxid, LPCTSTR TempNickName, LPCTSTR TempChatRoomid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSendChatRoomAt(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SENDAT }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_msg; afx_msg void OnBnClickedSendat(); CString m_MemberWxid; //从好友列表窗口传过来的微信ID CString m_MemberNickName; //从好友列表窗口传过来的微信昵称 CString m_ChatRoomid; //从好友列表窗口传过来的群ID }; ================================================ FILE: WeChatRobot/CSendMsg.cpp ================================================ // CSendMsg.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSendMsg.h" #include "afxdialogex.h" #define 文本 0 #define 文件 1 #define 图片 2 #define 视频 3 #define Gif 4 // CSendMsg 对话框 IMPLEMENT_DYNAMIC(CSendMsg, CDialogEx) CSendMsg::CSendMsg(LPCTSTR TempWxid,CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SendMsg, pParent), m_wxid(TempWxid) , m_Radio(0) , m_Content(_T("")) { } CSendMsg::~CSendMsg() { } void CSendMsg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Radio(pDX, IDC_RADIO1, m_Radio); DDX_Text(pDX, IDC_EDIT1, m_Content); } BEGIN_MESSAGE_MAP(CSendMsg, CDialogEx) ON_BN_CLICKED(IDC_Send, &CSendMsg::OnBnClickedSend) ON_BN_CLICKED(IDC_RADIO1, &CSendMsg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO2, &CSendMsg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO3, &CSendMsg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO4, &CSendMsg::OnBnClickedRadio1) ON_WM_DROPFILES() END_MESSAGE_MAP() // CSendMsg 消息处理程序 BOOL CSendMsg::OnInitDialog() { CDialogEx::OnInitDialog(); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } //************************************************************ // 函数名称: OnBnClickedSend // 函数说明: 响应发送按钮 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CSendMsg::OnBnClickedSend() { //同步控件数据到变量 UpdateData(TRUE); if (m_Content == "") { MessageBoxW(L"消息不能为空", L"Tip", 0); return; } //不是发送文本消息 检查文件是否存在 if (m_Radio!=文本) { if (GetFileAttributes(m_Content) == INVALID_FILE_ATTRIBUTES) { MessageBox(L"文件不存在 请重试"); return; } } //填充数据到结构体 MessageStruct* message = new MessageStruct(m_wxid, m_Content); //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT MessageData; //如果是文本就发送文本消息 如果是文件就发送文件消息 if (m_Radio == 文本) { MessageData.dwData = WM_SendTextMessage; } else if (m_Radio == 文件) { //发送文件消息 MessageData.dwData = WM_SendFileMessage; } else if (m_Radio == 图片) { //发送图片消息 MessageData.dwData = WM_SendImageMessage; } else if (m_Radio == 视频) { //发送视频消息 MessageData.dwData = WM_SendVideoMessage; } else if (m_Radio == Gif) { //发送Gif消息 MessageData.dwData = WM_SendGifMessage; } MessageData.cbData = sizeof(MessageStruct); MessageData.lpData = message; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&MessageData); //清空文本 m_Content = ""; delete message; UpdateData(FALSE); } //************************************************************ // 函数名称: OnBnClickedRadio1 // 函数说明: 响应点击单选框 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: void // 返 回 值: void //*********************************************************** void CSendMsg::OnBnClickedRadio1() { // TODO: 在此添加控件通知处理程序代码 } //************************************************************ // 函数名称: OnDropFiles // 函数说明: 响应拖拽文件 // 作 者: GuiShou // 时 间: 2019/7/6 // 参 数: HDROP hDropInfo 拖拽文件句柄 // 返 回 值: void //************************************************************ void CSendMsg::OnDropFiles(HDROP hDropInfo) { //获取文件路径 TCHAR szPath[MAX_PATH] = { 0 }; DragQueryFile(hDropInfo, 0, szPath, MAX_PATH); //显示到控件 m_Content = szPath; UpdateData(FALSE); CDialogEx::OnDropFiles(hDropInfo); } ================================================ FILE: WeChatRobot/CSendMsg.h ================================================ #pragma once // CSendMsg 对话框 class CSendMsg : public CDialogEx { DECLARE_DYNAMIC(CSendMsg) public: CSendMsg(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSendMsg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SendMsg }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_wxid; //从好友列表窗口传过来的微信ID virtual BOOL OnInitDialog(); afx_msg void OnBnClickedSend(); int m_Radio; afx_msg void OnBnClickedRadio1(); CString m_Content; afx_msg void OnDropFiles(HDROP hDropInfo); }; ================================================ FILE: WeChatRobot/CSendXmlAricle.cpp ================================================ // CSendXmlAricle.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSendXmlAricle.h" #include "afxdialogex.h" // CSendXmlAricle 对话框 IMPLEMENT_DYNAMIC(CSendXmlAricle, CDialogEx) CSendXmlAricle::CSendXmlAricle(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SendXmlArticle, pParent) , m_selfwxid(_T("")) , m_recverwxid(_T("")) , m_title(_T("")) , m_subtitle(_T("")) , m_linkurl(_T("")) , m_picpath(_T("")) { } CSendXmlAricle::~CSendXmlAricle() { } void CSendXmlAricle::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_selfwxid); DDX_Text(pDX, IDC_EDIT2, m_recverwxid); DDX_Text(pDX, IDC_EDIT6, m_title); DDX_Text(pDX, IDC_EDIT7, m_subtitle); DDX_Text(pDX, IDC_EDIT8, m_linkurl); DDX_Text(pDX, IDC_EDIT9, m_picpath); } BEGIN_MESSAGE_MAP(CSendXmlAricle, CDialogEx) ON_BN_CLICKED(IDC_SendXmlArticle, &CSendXmlAricle::OnBnClickedSendxmlarticle) END_MESSAGE_MAP() // CSendXmlAricle 消息处理程序 //************************************************************ // 函数名称: OnBnClickedSendxmlarticle // 函数说明: 发送xml文章按钮 // 作 者: GuiShou // 时 间: 2019/9/30 // 参 数: void // 返 回 值: void //*********************************************************** void CSendXmlAricle::OnBnClickedSendxmlarticle() { } ================================================ FILE: WeChatRobot/CSendXmlAricle.h ================================================ #pragma once // CSendXmlAricle 对话框 class CSendXmlAricle : public CDialogEx { DECLARE_DYNAMIC(CSendXmlAricle) public: CSendXmlAricle(CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSendXmlAricle(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SendXmlArticle }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_selfwxid; CString m_recverwxid; CString m_title; CString m_subtitle; CString m_linkurl; CString m_picpath; afx_msg void OnBnClickedSendxmlarticle(); }; ================================================ FILE: WeChatRobot/CSendXmlCard.cpp ================================================ // CSendXmlCard.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSendXmlCard.h" #include "afxdialogex.h" // CSendXmlCard 对话框 IMPLEMENT_DYNAMIC(CSendXmlCard, CDialogEx) CSendXmlCard::CSendXmlCard(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SendCard, pParent), m_Wxid(TempWxid) , m_SendWxid(_T("")) , m_SendNickName(_T("")) { } CSendXmlCard::~CSendXmlCard() { } void CSendXmlCard::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_SendWxid); DDX_Text(pDX, IDC_EDIT2, m_SendNickName); } BEGIN_MESSAGE_MAP(CSendXmlCard, CDialogEx) ON_BN_CLICKED(IDC_SendCard, &CSendXmlCard::OnBnClickedSendcard) END_MESSAGE_MAP() //************************************************************ // 函数名称: OnBnClickedSendcard // 函数说明: 响应发送按钮 // 作 者: GuiShou // 时 间: 2019/7/10 // 参 数: void // 返 回 值: void //*********************************************************** void CSendXmlCard::OnBnClickedSendcard() { UpdateData(TRUE); unique_ptr pCardMessage(new XmlCardMessage); wcscpy_s(pCardMessage->RecverWxid, wcslen(m_Wxid) + 1, m_Wxid); wcscpy_s(pCardMessage->SendWxid, wcslen(m_SendWxid) + 1, m_SendWxid); wcscpy_s(pCardMessage->NickName, wcslen(m_SendNickName) + 1, m_SendNickName); CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT sendcard; sendcard.dwData = WM_SendXmlCard; sendcard.cbData = sizeof(XmlCardMessage); sendcard.lpData = pCardMessage.get(); //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&sendcard); m_SendWxid = ""; m_SendNickName = ""; UpdateData(FALSE); } ================================================ FILE: WeChatRobot/CSendXmlCard.h ================================================ #pragma once // CSendXmlCard 对话框 class CSendXmlCard : public CDialogEx { DECLARE_DYNAMIC(CSendXmlCard) public: CSendXmlCard(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSendXmlCard(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SendCard }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() CString m_Wxid; //从好友列表窗口传过来的微信ID public: CString m_SendWxid; CString m_SendNickName; afx_msg void OnBnClickedSendcard(); }; ================================================ FILE: WeChatRobot/CSetRemark.cpp ================================================ // CSetRemark.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSetRemark.h" #include "afxdialogex.h" // CSetRemark 对话框 IMPLEMENT_DYNAMIC(CSetRemark, CDialogEx) CSetRemark::CSetRemark(LPCTSTR TempWxid, CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SetRemark, pParent), m_wxid(TempWxid) , m_remark(_T("")) { } CSetRemark::~CSetRemark() { } void CSetRemark::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_remark); } BEGIN_MESSAGE_MAP(CSetRemark, CDialogEx) ON_BN_CLICKED(IDC_SetRemark, &CSetRemark::OnBnClickedSetremark) END_MESSAGE_MAP() // CSetRemark 消息处理程序 void CSetRemark::OnBnClickedSetremark() { } ================================================ FILE: WeChatRobot/CSetRemark.h ================================================ #pragma once // CSetRemark 对话框 class CSetRemark : public CDialogEx { DECLARE_DYNAMIC(CSetRemark) public: CSetRemark(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSetRemark(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SetRemark }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_wxid; //从好友列表窗口传过来的微信ID CString m_remark; afx_msg void OnBnClickedSetremark(); }; ================================================ FILE: WeChatRobot/CSetRoomName.cpp ================================================ // CSetRoomName.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "CSetRoomName.h" #include "afxdialogex.h" // CSetRoomName 对话框 IMPLEMENT_DYNAMIC(CSetRoomName, CDialogEx) CSetRoomName::CSetRoomName(LPCTSTR TempWxid,CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SET_ROOM_NAME, pParent), m_ChatRoomWxid(TempWxid) , m_roomname(_T("")) { } CSetRoomName::~CSetRoomName() { } void CSetRoomName::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_roomname); } BEGIN_MESSAGE_MAP(CSetRoomName, CDialogEx) ON_BN_CLICKED(IDC_SetRoomName, &CSetRoomName::OnBnClickedSetroomname) END_MESSAGE_MAP() // CSetRoomName 消息处理程序 //************************************************************ // 函数名称: OnBnClickedSetroomname // 函数说明: 响应修改群名称按钮 // 作 者: GuiShou // 时 间: 2019/7/14 // 参 数: void // 返 回 值: void //*********************************************************** void CSetRoomName::OnBnClickedSetroomname() { UpdateData(TRUE); MessageStruct* roomname = new MessageStruct(m_ChatRoomWxid, m_roomname); //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT setroomnamedata; setroomnamedata.dwData = WM_SetRoomName; setroomnamedata.cbData = sizeof(MessageStruct); setroomnamedata.lpData = roomname; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&setroomnamedata); m_roomname = ""; delete roomname; UpdateData(FALSE); } ================================================ FILE: WeChatRobot/CSetRoomName.h ================================================ #pragma once // CSetRoomName 对话框 class CSetRoomName : public CDialogEx { DECLARE_DYNAMIC(CSetRoomName) public: CSetRoomName(LPCTSTR TempWxid, CWnd* pParent = nullptr); // 标准构造函数 virtual ~CSetRoomName(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_SET_ROOM_NAME }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: CString m_ChatRoomWxid; //从好友列表窗口传过来的群ID CString m_roomname; afx_msg void OnBnClickedSetroomname(); }; ================================================ FILE: WeChatRobot/WeChatRobot.cpp ================================================  // WeChatRobot.cpp: 定义应用程序的类行为。 // #include "stdafx.h" #include "WeChatRobot.h" #include "WeChatRobotDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CWeChatRobotApp BEGIN_MESSAGE_MAP(CWeChatRobotApp, CWinApp) ON_COMMAND(ID_HELP, &CWinApp::OnHelp) END_MESSAGE_MAP() // CWeChatRobotApp 构造 CWeChatRobotApp::CWeChatRobotApp() { // 支持重新启动管理器 m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART; // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 } // 唯一的 CWeChatRobotApp 对象 CWeChatRobotApp theApp; // CWeChatRobotApp 初始化 BOOL CWeChatRobotApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinApp::InitInstance(); AfxEnableControlContainer(); // 创建 shell 管理器,以防对话框包含 // 任何 shell 树视图控件或 shell 列表视图控件。 CShellManager *pShellManager = new CShellManager; // 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题 CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); CWeChatRobotDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: 在此放置处理何时用 // “确定”来关闭对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用 // “取消”来关闭对话框的代码 } else if (nResponse == -1) { TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n"); TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); } // 删除上面创建的 shell 管理器。 if (pShellManager != nullptr) { delete pShellManager; } #if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS) ControlBarCleanUp(); #endif // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; } ================================================ FILE: WeChatRobot/WeChatRobot.h ================================================  // WeChatRobot.h: PROJECT_NAME 应用程序的主头文件 // #pragma once #ifndef __AFXWIN_H__ #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件" #endif #include "resource.h" // 主符号 // CWeChatRobotApp: // 有关此类的实现,请参阅 WeChatRobot.cpp // class CWeChatRobotApp : public CWinApp { public: CWeChatRobotApp(); // 重写 public: virtual BOOL InitInstance(); // 实现 DECLARE_MESSAGE_MAP() }; extern CWeChatRobotApp theApp; ================================================ FILE: WeChatRobot/WeChatRobot.vcxproj ================================================ Debug Win32 Release Win32 Debug x64 Release x64 15.0 {155FAB13-5BFA-4845-A8B3-4CA5F9659347} MFCProj WeChatRobot 10.0.17763.0 Application true v141 Unicode Static Application false v141 false Unicode Static Application true v141 Unicode Dynamic Application false v141 true Unicode Dynamic true ..\openssl-1.0.2l-win32-msvc100\include;$(VC_IncludePath);$(WindowsSDK_IncludePath); true false false Use Level3 Disabled true WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) MultiThreadedDebug Windows false true _DEBUG;%(PreprocessorDefinitions) 0x0804 _DEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Use Level3 Disabled true _WINDOWS;_DEBUG;%(PreprocessorDefinitions) Windows false true _DEBUG;%(PreprocessorDefinitions) 0x0804 _DEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Use Level3 Disabled true true true WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) MultiThreaded Windows true true windowscodecs.lib false true NDEBUG;%(PreprocessorDefinitions) 0x0804 NDEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Use Level3 MaxSpeed true true true _WINDOWS;NDEBUG;%(PreprocessorDefinitions) Windows true true false true NDEBUG;%(PreprocessorDefinitions) 0x0804 NDEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) Create Create Create Create ================================================ FILE: WeChatRobot/WeChatRobot.vcxproj.filters ================================================  {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;ipp;xsd {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms {193408ff-e557-4e8f-a7f7-14adeb59a41c} {2a2cdfc5-e48a-46dc-a9d6-1c6a1c1da7a5} {e972c32d-5869-46fe-b699-7294185d45db} {4b8d265e-eb85-4bc0-b70b-94f16ada0131} {1434472e-7d72-4ace-9c79-2de3a3719841} {cf13cba3-0048-4828-9832-53b1fa18d624} {87653f1f-3e27-49a5-9f2c-91b13f46eb81} {ce3d11ea-50a8-4102-8fcc-c78b434c93e6} {1893610a-444d-43b3-9d38-ac949a886f2c} {57cae96b-b9d4-43d4-9876-e35d0bb96af6} {fff76411-4c4e-45e2-9f78-4f1415ed1b51} {1c2d0d7d-9764-4d79-b880-cb4516cb9b2c} {8e6a5c4b-f36e-4bfc-8bd8-dda5fa0613ab} {8a5c963d-2c38-41e6-9a59-03463cb86c13} {d73b7219-e423-4e13-b7d9-891557925620} {04f0e374-4481-4bc2-8bb2-1953a1f1081f} {744c6196-1c9e-4599-84a0-174a0cad9551} {6e5d0c2d-2b48-4085-973d-e23069646a4c} {77a5f69c-2e7d-48be-aeb9-17376dc0dafd} {e4db8bb4-32bd-4353-8af5-dacb3efea7cc} {e631ad46-5b2a-4b1b-a64a-89521bc01283} {c056225b-cdec-4635-b153-e64128b4878b} {e6129c08-a16f-4b2b-a5d6-6956224e905c} {f3300f15-5b33-45cd-9fda-d0ed9bd2efdd} {29b883c2-a143-4bbf-b2db-db10231b897e} {e6d57d6c-f891-4a43-a781-d47f3df64449} {539d852d-cee7-47be-9de2-a7b7af203d5b} {cda48e5c-30ae-4717-97cb-9a83ba6ccf5e} {d49002ed-e818-43d2-84a5-43ea14b4e447} {86d25358-824c-41fe-8532-395e15cd5e8c} {5e1adde2-8b7d-44e6-9338-a9b96af7784e} {30fd4e88-1105-4b17-bcd8-44367b7c946c} {4c32c906-f9de-4503-be4f-b64ad0614daf} {ab603aa1-5935-4fc4-af16-5720f654f8c6} {2645c386-2125-40da-9e8f-65c425dbc699} 头文件 头文件 头文件 头文件 登陆窗口 注入器 自定义数据\自定义消息 聊天记录 主窗口 选项卡 好友列表\发送消息 功能大全\个人信息 好友列表\好友列表 好友列表\群公告 功能大全\功能窗口 功能大全\解密图片 好友列表\添加群成员 好友列表\发送名片 功能大全\无限多开 菜单栏\打赏作者 菜单栏\关于作者 功能大全\添加好友 好友列表\修改群名称 好友列表\查看群成员\发送艾特消息 好友列表\查看群成员\查看群成员 功能大全\打开微信浏览器 好友列表\邀请群成员 功能大全\发送xml文章 好友列表\好友信息 好友列表\修改备注 功能大全\创建群聊 功能大全\修改版本号 自定义数据\结构体 功能大全\关注公众号 源文件 源文件 登陆窗口 注入器 聊天记录 主窗口 选项卡 好友列表\发送消息 功能大全\个人信息 好友列表\好友列表 好友列表\群公告 功能大全\功能窗口 功能大全\解密图片 好友列表\添加群成员 好友列表\发送名片 功能大全\无限多开 菜单栏\打赏作者 菜单栏\关于作者 功能大全\添加好友 好友列表\修改群名称 好友列表\查看群成员\发送艾特消息 好友列表\查看群成员\查看群成员 功能大全\打开微信浏览器 好友列表\邀请群成员 功能大全\发送xml文章 好友列表\好友信息 好友列表\修改备注 功能大全\创建群聊 功能大全\修改版本号 功能大全\关注公众号 资源文件 资源文件 资源文件 资源文件 ================================================ FILE: WeChatRobot/WeChatRobot.vcxproj.user ================================================  WeChatRobot.rc ================================================ FILE: WeChatRobot/WeChatRobotDlg.cpp ================================================  // WeChatRobotDlg.cpp: 实现文件 // #include "stdafx.h" #include "WeChatRobot.h" #include "WeChatRobotDlg.h" #include "afxdialogex.h" #include "CInjectTools.h" #include "CMain.h" HANDLE wxPid = NULL; //微信的PID #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_ABOUTBOX }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() public: }; CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CWeChatRobotDlg 对话框 CWeChatRobotDlg::CWeChatRobotDlg(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_WECHATROBOT_DIALOG, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CWeChatRobotDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CWeChatRobotDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_COPYDATA() ON_BN_CLICKED(IDC_SHOW_QRPIC, &CWeChatRobotDlg::OnBnClickedShowQrpic) END_MESSAGE_MAP() // CWeChatRobotDlg 消息处理程序 BOOL CWeChatRobotDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != nullptr) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 //防多开 RunSingle(); if (InjectDll(wxPid)==FALSE) { ExitProcess(-1); } return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CWeChatRobotDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else if ((nID & 0xFFF0) == SC_CLOSE)//对话框关闭 消息 { TerminateProcess(wxPid, 0); CDialogEx::OnSysCommand(nID, lParam); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CWeChatRobotDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CWeChatRobotDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } //************************************************************ // 函数名称: OnCopyData // 函数说明: 接收CopyData消息 // 作 者: GuiShou // 时 间: 2019/6/30 // 参 数: CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct // 返 回 值: BOOL //*********************************************************** BOOL CWeChatRobotDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { if (pCopyDataStruct->dwData==WM_Login) { EndDialog(0); CMain mainWindow; mainWindow.DoModal(); } else if (pCopyDataStruct->dwData == WM_AlreadyLogin) { MessageBoxA(NULL, "已经登陆微信 请重启微信 在未登录状态下运行程序", "Tip", 0); ExitProcess(-1); } return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); } //************************************************************ // 函数名称: OnBnClickedShowQrpic // 函数说明: 响应显示二维码按钮 // 作 者: GuiShou // 时 间: 2019/6/30 // 参 数: void // 返 回 值: void //*********************************************************** void CWeChatRobotDlg::OnBnClickedShowQrpic() { //查找窗口 CWnd *pWnd = CWnd::FindWindow(NULL, L"WeChatHelper"); COPYDATASTRUCT show_qrpic; show_qrpic.dwData = WM_ShowQrPicture; show_qrpic.cbData = 0; show_qrpic.lpData = NULL; //发送消息 pWnd->SendMessage(WM_COPYDATA, NULL, (LPARAM)&show_qrpic); Sleep(200); //显示图片 ShowPicture(); } //************************************************************ // 函数名称: ShowPicture // 函数说明: 显示二维码 // 作 者: GuiShou // 时 间: 2019/6/30 // 参 数: void // 返 回 值: void //*********************************************************** void CWeChatRobotDlg::ShowPicture() { char szTempPath[MAX_PATH] = { 0 }; char szPicturePath[MAX_PATH] = { 0 }; //获取Temp目录 GetTempPathA(MAX_PATH, szTempPath); //拼接图片完整路径 sprintf_s(szPicturePath, "%s%s", szTempPath, "qrcode.png"); USES_CONVERSION; CImage QrPic; QrPic.Load(A2W(szPicturePath)); CRect rect; CWnd *pWnd = GetDlgItem(IDC_QRPIC); CDC *pDC = pWnd->GetDC(); pWnd->GetClientRect(&rect); pDC->SetStretchBltMode(STRETCH_HALFTONE); QrPic.Draw(pDC->m_hDC, rect); ReleaseDC(pDC); QrPic.Destroy(); //删除临时文件夹下的图片 DeleteFileA(szPicturePath); } //************************************************************ // 函数名称: RunSingle // 函数说明: 防多开 // 作 者: GuiShou // 时 间: 2019/7/9 // 参 数: void // 返 回 值: void //*********************************************************** void CWeChatRobotDlg::RunSingle() { HANDLE hMutex = NULL; hMutex = CreateMutexA(NULL, FALSE, "GuiShou"); if (hMutex) { if (GetLastError() == ERROR_ALREADY_EXISTS) { ExitProcess(-1); } } } ================================================ FILE: WeChatRobot/WeChatRobotDlg.h ================================================  // WeChatRobotDlg.h: 头文件 // #pragma once // CWeChatRobotDlg 对话框 class CWeChatRobotDlg : public CDialogEx { // 构造 public: CWeChatRobotDlg(CWnd* pParent = nullptr); // 标准构造函数 // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_WECHATROBOT_DIALOG }; #endif protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: HICON m_hIcon; // 生成的消息映射函数 virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); afx_msg void OnBnClickedShowQrpic(); void ShowPicture(); //显示图片 void RunSingle(); //防多开 }; ================================================ FILE: WeChatRobot/data.h ================================================ #pragma once //ͨϢṹ struct MessageStruct { wchar_t msgdata1[MAX_PATH]; wchar_t msgdata2[MAX_PATH]; MessageStruct(wchar_t* pString1, wchar_t* pString2) { wcscpy_s(msgdata1, wcslen(pString1) + 1, pString1); wcscpy_s(msgdata2, wcslen(pString2) + 1, pString2); } MessageStruct(CString pString1, CString pString2) { wcscpy_s(msgdata1, wcslen(pString1) + 1, pString1); wcscpy_s(msgdata2, wcslen(pString2) + 1, pString2); } }; //¼Ϣṹ struct ChatMessageData { DWORD dwtype; //Ϣ wchar_t sztype[0x20]; //Ϣ wchar_t source[0x400]; //ϢԴ wchar_t wxid[0x40]; //΢ID/ȺID wchar_t wxname[0x200]; //΢/Ⱥ wchar_t sender[0x100]; //Ϣ wchar_t sendername[0x100]; //Ϣdz wchar_t content[0x5000]; //Ϣ }; //ƬϢṹ struct XmlCardMessage { wchar_t RecverWxid[50]; //ߵ΢ID wchar_t SendWxid[50]; //Ҫ͵΢ID wchar_t NickName[50]; //dz }; //ͰϢ struct AtMsg { wchar_t chatroomid[50] = { 0 }; wchar_t memberwxid[50] = { 0 }; wchar_t membernickname[50] = { 0 }; wchar_t msgcontent[100] = { 0 }; }; //XMLϢ struct SendXmlArticleStruct { wchar_t title[50]; wchar_t subtitle[50]; wchar_t urllink[200]; wchar_t picpath[260]; wchar_t selfwxid[50]; wchar_t recverwxid[50]; }; //ϢĽṹ struct PersonalInformation { wchar_t wxid[40]; //΢ID wchar_t wxcount[40]; //΢˺ wchar_t v1[150]; //V1 wchar_t nickname[50]; //΢dz wchar_t remark[50]; //ע wchar_t wxsex[10]; //Ա wchar_t phonenumber[30]; //ֻ wchar_t device[20]; //½豸 wchar_t nation[20]; // wchar_t province[20]; //ʡ wchar_t city[20]; // wchar_t area[20]; // wchar_t language[10]; // wchar_t bigheader[0x100]; //ͷ wchar_t smallheader[0x100]; //Сͷ wchar_t signature[50]; //ǩ wchar_t background[0x100]; //Ȧ wchar_t cachedir[MAX_PATH]; //Ŀ¼ wchar_t startdir[MAX_PATH]; //Ŀ¼ }; //бûϢ struct UserInfo { wchar_t UserId[80]; wchar_t UserNumber[80]; wchar_t UserRemark[80]; wchar_t UserNickName[80]; }; //ȺԱϢṹ struct ChatRoomMemberInfo { wchar_t UserId[0x100]; wchar_t UserNumber[0x100]; wchar_t UserNickName[0x100]; }; //ϸϢṹ struct UserInfoDetail { wchar_t UserId[50]; //΢ID wchar_t UserNumber[50]; //΢˺ wchar_t V1[200]; //V1 wchar_t Remark[50]; //ע wchar_t UserNickName[50]; //΢dz wchar_t smallHeader[1024]; //Сͷ wchar_t bigHeader[1024]; //ͷ }; ================================================ FILE: WeChatRobot/message.h ================================================ #pragma once //ͻ˺ͷͨѶϢ #define WM_Login 0 #define WM_ShowQrPicture 1 #define WM_Logout 2 #define WM_GetFriendList 3 #define WM_ShowChatRecord 4 #define WM_SendTextMessage 5 #define WM_SendFileMessage 6 #define WM_GetInformation 7 #define WM_SendImageMessage 8 #define WM_SetRoomAnnouncement 9 #define WM_DeleteUser 10 #define WM_QuitChatRoom 11 #define WM_AddGroupMember 12 #define WM_SendXmlCard 13 #define WM_ShowChatRoomMembers 14 #define WM_ShowChatRoomMembersDone 15 #define WM_DecryptDatabase 16 #define WM_AddUser 17 #define WM_SetRoomName 18 #define WM_AutoChat 19 #define WM_CancleAutoChat 20 #define WM_AlreadyLogin 21 #define WM_SendAtMsg 22 #define WM_DelRoomMember 23 #define WM_OpenUrl 24 #define WM_InviteGroupMember 26 #define WM_SendXmlArticle 27 #define WM_GetFriendInfomations 28 #define WM_TimerToSend 29 #define WM_CancelTimerToSend 30 #define WM_SetRemark 31 #define WM_CreateChatRoom 32 #define WM_ModifyVersion 33 #define WM_DecodeImage 34 #define WM_SendVideoMessage 35 #define WM_SendGifMessage 36 #define WM_TopMsg 37 #define WM_CancleTopMsg 38 #define WM_OpenNewMsgNotify 39 #define WM_MsgNoDisturb 40 #define WM_FollowPublicAccount 41 #define WM_KeywordsReplyOpen 43 #define WM_KeywordsReplyClose 44 //ͨѶԶϢ #define WM_ShowFriendList WM_USER+100 #define WM_ShowMessage WM_USER+101 #define SaveFriendList WM_USER+102 //΢ID #define ChatRobotWxID L"gh_f0e9306d8d03" ================================================ FILE: WeChatRobot/resource.h ================================================ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 WeChatRobot.rc 使用 // #define IDM_ABOUTBOX 0x0010 #define IDD_ABOUTBOX 100 #define IDS_ABOUTBOX 101 #define IDD_WECHATROBOT_DIALOG 102 #define IDR_MAINFRAME 128 #define IDI_ICON1 129 #define IDD_MAIN 131 #define IDD_FRIEND_LIST 133 #define IDD_CHAT_RECORDS 135 #define IDD_FUNCTIONS 137 #define IDR_MENU1 141 #define IDR_MENU2 142 #define IDD_SendMsg 143 #define IDI_ICON2 145 #define IDD_INFORMATION 146 #define IDD_ROOMANNOUNCE 148 #define IDD_DECRYPT_IMAGE 150 #define IDD_ADD_MEMBER 152 #define IDD_SEND_ROOM_MSG 154 #define IDD_SendCard 156 #define IDD_CHATROOM_MEMBER 158 #define IDD_PAY 162 #define IDB_BITMAP1 166 #define IDD_ABOUT_AUTHOR 167 #define IDD_ADD_USER 169 #define IDD_SET_ROOM_NAME 171 #define IDD_SENDAT 173 #define IDD_OpenUrl 175 #define IDD_InviteMember 177 #define IDD_SendXmlArticle 179 #define IDD_FRIENDINFO 181 #define IDD_SetRemark 183 #define IDD_CreateChatRoom 185 #define IDD_ModifyVersion 187 #define IDD_FollowAccount 189 #define IDC_INJECT_DLL 1000 #define IDC_UNLOAD_DLL 1001 #define IDC_SHOW_QRPIC 1003 #define IDC_QRPIC 1004 #define IDC_TAB1 1005 #define IDC_FRIENDLIST 1006 #define IDC_LIST1 1007 #define IDC_RADIO1 1008 #define IDC_RADIO2 1009 #define IDC_RADIO3 1010 #define IDC_EDIT1 1011 #define IDC_Send 1012 #define IDC_EDIT2 1012 #define IDC_INFORMATION 1013 #define IDC_ACCOUNT 1013 #define IDC_EDIT6 1013 #define IDC_DECRYPT_PIC 1014 #define IDC_NICKNAME 1014 #define IDC_EDIT3 1014 #define IDC_EDIT7 1014 #define IDC_PHONE 1015 #define IDC_EDIT4 1015 #define IDC_EDIT8 1015 #define IDC_DEVICE 1016 #define IDC_EDIT5 1016 #define IDC_EDIT9 1016 #define IDC_PROVINCE 1017 #define IDC_EDIT10 1017 #define IDC_CITY 1018 #define IDC_HEADER 1019 #define IDC_NATION 1020 #define IDC_WXID 1021 #define IDC_SEX 1022 #define IDC_HEADER2 1023 #define IDC_SendRoomAnnouncement 1024 #define IDC_HEADER3 1024 #define IDC_DecryptImage 1025 #define IDC_HEADER4 1025 #define IDC_MAKE_SURE 1026 #define IDC_HEADER5 1026 #define IDC_ChatRoomWXID 1027 #define IDC_SendChatRoomMsg 1029 #define IDC_SendCard 1030 #define IDC_MULTI_OPEN 1031 #define IDC_DECRYPT_DB 1032 #define IDC_ADD_USER 1033 #define IDC_AUTO_CHAT 1034 #define IDC_GET_EXPRESSION 1035 #define IDC_SetRoomName 1036 #define IDC_OPEN_URL 1036 #define IDC_SendAt 1037 #define IDC_SendXmlArticle 1037 #define IDC_OPEN 1038 #define IDC_SendMsgByTimer 1038 #define IDC_INVITE 1039 #define IDC_CreateRoom 1039 #define IDC_BUTTON1 1040 #define IDC_CheckAll 1040 #define IDC_SetRemark 1040 #define IDC_CreateChatRoom 1040 #define IDC_ModifyVersion 1040 #define IDC_Modify 1040 #define IDC_FOLLOW 1040 #define IDC_ReverseChoose 1041 #define IDC_FollowAccount 1041 #define IDC_CancelAll 1042 #define IDC_KeyWordsReply 1042 #define IDC_GroupSend 1044 #define IDC_RADIO4 1045 #define IDC_RADIO5 1046 #define ID_32775 32775 #define ID_32776 32776 #define ID_32777 32777 #define ID_32778 32778 #define ID_32779 32779 #define ID_32780 32780 #define ID_32781 32781 #define ID_32782 32782 #define ID_32783 32783 #define ID_32784 32784 #define ID_32785 32785 #define ID_32786 32786 #define ID_32787 32787 #define ID_32788 32788 #define ID_32789 32789 #define ID_32790 32790 #define ID_32791 32791 #define ID_32792 32792 #define ID_32793 32793 #define ID_32794 32794 #define ID_32795 32795 #define ID_32796 32796 #define ID_32797 32797 #define ID_32798 32798 #define ID_32799 32799 #define ID_32800 32800 #define ID_32801 32801 #define ID_32802 32802 #define ID_32803 32803 #define ID_32804 32804 #define ID_32805 32805 #define ID_32806 32806 #define ID_32807 32807 #define ID_32808 32808 #define ID_32809 32809 #define ID_32810 32810 #define ID_32811 32811 #define ID_32812 32812 #define ID_32813 32813 #define ID_32814 32814 #define ID_32815 32815 #define ID_32816 32816 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 191 #define _APS_NEXT_COMMAND_VALUE 32817 #define _APS_NEXT_CONTROL_VALUE 1047 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif ================================================ FILE: WeChatRobot/stdafx.cpp ================================================  // stdafx.cpp : 只包括标准包含文件的源文件 // WeChatRobot.pch 将作为预编译标头 // stdafx.obj 将包含预编译类型信息 #include "stdafx.h" ================================================ FILE: WeChatRobot/stdafx.h ================================================  // stdafx.h : 标准系统包含文件的包含文件, // 或是经常使用但不常更改的 // 特定于项目的包含文件 #pragma once #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料 #endif #include "targetver.h" #define _CRT_SECURE_NO_DEPRECATE 0 #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的 // 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏 #define _AFX_ALL_WARNINGS #include // MFC 核心组件和标准组件 #include // MFC 扩展 #include // MFC 自动化类 #ifndef _AFX_NO_OLE_SUPPORT #include // MFC 对 Internet Explorer 4 公共控件的支持 #endif #ifndef _AFX_NO_AFXCMN_SUPPORT #include // MFC 对 Windows 公共控件的支持 #endif // _AFX_NO_AFXCMN_SUPPORT #include // 功能区和控件条的 MFC 支持 #include #include #include using namespace std; #include "message.h" #include "data.h" #include #include #include #include #include #include #include #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") #elif defined _M_X64 #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") #else #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") #endif #endif ================================================ FILE: WeChatRobot/targetver.h ================================================ #pragma once // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将 // 将 _WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 #include ================================================ FILE: WeChatRobot.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.572 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeChatRobot", "WeChatRobot\WeChatRobot.vcxproj", "{155FAB13-5BFA-4845-A8B3-4CA5F9659347}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeChatHelper", "WeChatHelper\WeChatHelper.vcxproj", "{6B65B0BF-7949-4C08-904B-5F51D8D3988F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Debug|x64.ActiveCfg = Debug|x64 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Debug|x64.Build.0 = Debug|x64 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Debug|x86.ActiveCfg = Debug|Win32 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Debug|x86.Build.0 = Debug|Win32 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Release|x64.ActiveCfg = Release|x64 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Release|x64.Build.0 = Release|x64 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Release|x86.ActiveCfg = Release|Win32 {155FAB13-5BFA-4845-A8B3-4CA5F9659347}.Release|x86.Build.0 = Release|Win32 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Debug|x64.ActiveCfg = Debug|x64 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Debug|x64.Build.0 = Debug|x64 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Debug|x86.ActiveCfg = Debug|Win32 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Debug|x86.Build.0 = Debug|Win32 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Release|x64.ActiveCfg = Release|x64 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Release|x64.Build.0 = Release|x64 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Release|x86.ActiveCfg = Release|Win32 {6B65B0BF-7949-4C08-904B-5F51D8D3988F}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BC222587-D35B-45CC-9761-F3D1DD2B775A} EndGlobalSection EndGlobal