Merge pull request #263 from lich0821/3.9.11.25

Adatp 3.9.11.25
This commit is contained in:
Changhua 2024-10-31 23:18:31 +08:00 committed by GitHub
commit da07270461
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 132 additions and 142 deletions

View File

@ -38,6 +38,7 @@
* 发送图片消息
* 发送文件消息
* 发送卡片消息
* 发送 XML 消息
* 发送 GIF 消息
* 拍一拍群友
* 转发消息
@ -61,6 +62,10 @@
</details>
## 感谢大佬们贡献代码
<a href="https://github.com/lich0821/WeChatFerry/graphs/contributors">![](https://contrib.rocks/image?repo=lich0821/WeChatFerry)</a>
## 快速开始
### Python
[![PyPi](https://img.shields.io/pypi/v/wcferry.svg)](https://pypi.python.org/pypi/wcferry) [![Downloads](https://static.pepy.tech/badge/wcferry)](https://pypi.python.org/pypi/wcferry) [![Documentation Status](https://readthedocs.org/projects/wechatferry/badge/?version=latest)](https://wechatferry.readthedocs.io/zh/latest/?badge=latest)
@ -97,6 +102,7 @@ pip install --upgrade wcferry
## 一起开发
> 🚫 非开发用户不需要往下看。
>
> **开发用户**:可以根据文档和错误提示,自行解决编译错误的人员。
### 安装开发环境
@ -202,9 +208,9 @@ WeChatFerry
## 版本更新
### v39.2.4
### v39.3.0
* 修复 wxid 问题
* 适配 `3.9.11.25`
<details><summary>点击查看更多</summary>
@ -216,6 +222,10 @@ WeChatFerry
* `y` 是 `WeChatFerry` 的版本,从 0 开始
* `z` 是各客户端的版本,从 0 开始
### v39.2.4
* 修复 wxid 问题
### v39.2.3
* 实现发送 GIF

View File

@ -14,7 +14,11 @@ void InitLogger(std::string path)
if (logger != nullptr) {
return;
}
// check and create logs folder
std::filesystem::path logDir = std::filesystem::path(path) / "logs";
if (!std::filesystem::exists(logDir)) {
std::filesystem::create_directory(logDir);
}
auto filename = std::filesystem::path(path + LOGGER_FILE_NAME).make_preferred().string();
try {
logger = spdlog::rotating_logger_mt(LOGGER_NAME, filename, LOGGER_MAX_SIZE, LOGGER_MAX_FILES);

View File

@ -117,7 +117,7 @@ message XmlMsg
string receiver = 1; //
string content = 2; // xml
string path = 3; //
int32 type = 4; //
uint64 type = 4; //
}
message MsgTypes { map<int32, string> types = 1; }

View File

@ -117,6 +117,7 @@
<PrecompiledHeaderOutputFile />
<SupportJustMyCode>true</SupportJustMyCode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -192,7 +192,7 @@ xcopy /y $(OutDir)$(TargetFileName) $(SolutionDir)..\clients\python\wcferry</Com
<OmitFramePointers>false</OmitFramePointers>
<PrecompiledHeaderOutputFile />
<DisableSpecificWarnings>4251;4731;4819</DisableSpecificWarnings>
<AdditionalOptions>/EHa %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/EHa /utf-8 %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>

View File

@ -9,10 +9,10 @@
using namespace std;
extern QWORD g_WeChatWinDllAddr;
#define OS_GET_CHATROOM_MGR 0x1C4E200
#define OS_ADD_MEMBERS 0x221B8A0
#define OS_DELETE_MEMBERS 0x221BEE0
#define OS_INVITE_MEMBERS 0x221B280
#define OS_GET_CHATROOM_MGR 0x1B83BD0
#define OS_ADD_MEMBERS 0x2155100
#define OS_DELETE_MEMBERS 0x2155740
#define OS_INVITE_MEMBERS 0x2154AE0
typedef QWORD (*GetChatRoomMgr_t)();
typedef QWORD (*AddMemberToChatRoom_t)(QWORD, QWORD, QWORD, QWORD);

View File

@ -7,8 +7,8 @@
using namespace std;
extern QWORD g_WeChatWinDllAddr;
#define OS_GET_CONTACT_MGR 0x1C0BDE0
#define OS_GET_CONTACT_LIST 0x2265540
#define OS_GET_CONTACT_MGR 0x1B417A0
#define OS_GET_CONTACT_LIST 0x219ED10
#define OS_CONTACT_BIN 0x200
#define OS_CONTACT_BIN_LEN 0x208
#define OS_CONTACT_WXID 0x10

View File

@ -5,16 +5,16 @@
#include "sqlite3.h"
#include "util.h"
#define OFFSET_DB_INSTANCE 0x5A40598
#define OFFSET_DB_MICROMSG 0xb8
#define OFFSET_DB_CHAT_MSG 0x2c8
#define OFFSET_DB_MISC 0x5f0
#define OFFSET_DB_EMOTION 0x15f0
#define OFFSET_DB_INSTANCE 0x5902000
#define OFFSET_DB_MICROMSG 0xB8
#define OFFSET_DB_CHAT_MSG 0x2C8
#define OFFSET_DB_MISC 0x5F0
#define OFFSET_DB_EMOTION 0x15F0
#define OFFSET_DB_MEDIA 0xF48
#define OFFSET_DB_BIZCHAT_MSG 0x1A70
#define OFFSET_DB_FUNCTION_MSG 0x1b98
#define OFFSET_DB_FUNCTION_MSG 0x1B98
#define OFFSET_DB_NAME 0x28
#define OFFSET_DB_MSG_MGR 0x5ABB5D8
#define OFFSET_DB_MSG_MGR 0x595F900
extern UINT64 g_WeChatWinDllAddr;

View File

@ -24,17 +24,17 @@ extern QWORD g_WeChatWinDllAddr;
#define HEADER_GIF1 0x47
#define HEADER_GIF2 0x49
#define OS_LOGIN_STATUS 0x5AB86A8
#define OS_GET_SNS_DATA_MGR 0x22A91C0
#define OS_GET_SNS_FIRST_PAGE 0x2ED9080
#define OS_GET_SNS_TIMELINE_MGR 0x2E6B110
#define OS_GET_SNS_NEXT_PAGE 0x2EFEC00
#define OS_NEW_CHAT_MSG 0x1C28800
#define OS_FREE_CHAT_MSG 0x1C1FF10
#define OS_GET_CHAT_MGR 0x1C51CF0
#define OS_GET_MGR_BY_PREFIX_LOCAL_ID 0x2206280
#define OS_GET_PRE_DOWNLOAD_MGR 0x1CD87E0
#define OS_PUSH_ATTACH_TASK 0x1DA69C0
#define OS_LOGIN_STATUS 0x595C9E8
#define OS_GET_SNS_DATA_MGR 0x21E2200
#define OS_GET_SNS_FIRST_PAGE 0x2E212d0
#define OS_GET_SNS_TIMELINE_MGR 0x2DB3390
#define OS_GET_SNS_NEXT_PAGE 0x2EC8970
#define OS_NEW_CHAT_MSG 0x1B5E140
#define OS_FREE_CHAT_MSG 0x1B55850
#define OS_GET_CHAT_MGR 0x1B876C0
#define OS_GET_MGR_BY_PREFIX_LOCAL_ID 0x213FB00
#define OS_GET_PRE_DOWNLOAD_MGR 0x1C0EE70
#define OS_PUSH_ATTACH_TASK 0x1CDF4E0
typedef QWORD (*GetSNSDataMgr_t)();
typedef QWORD (*GetSnsTimeLineMgr_t)();

View File

@ -31,15 +31,15 @@ extern QWORD g_WeChatWinDllAddr;
#define OS_RECV_MSG_THUMB 0x280
#define OS_RECV_MSG_EXTRA 0x2A0
#define OS_RECV_MSG_XML 0x308
#define OS_RECV_MSG_CALL 0x2205510
#define OS_RECV_MSG_CALL 0x2147680
#define OS_PYQ_MSG_START 0x30
#define OS_PYQ_MSG_END 0x38
#define OS_PYQ_MSG_TS 0x38
#define OS_PYQ_MSG_XML 0x9B8
#define OS_PYQ_MSG_SENDER 0x18
#define OS_PYQ_MSG_CONTENT 0x48
#define OS_PYQ_MSG_CALL 0x2EFAA10
#define OS_WXLOG 0x26DA2D0
#define OS_PYQ_MSG_CALL 0x2E42C90
#define OS_WXLOG 0x2613D20
typedef QWORD (*RecvMsg_t)(QWORD, QWORD);
typedef QWORD (*WxLog_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD);

View File

@ -321,7 +321,6 @@ bool func_send_emotion(char *path, char *receiver, uint8_t *out, size_t *len)
return true;
}
#if 0
bool func_send_xml(XmlMsg xml, uint8_t *out, size_t *len)
{
Response rsp = Response_init_default;
@ -335,7 +334,7 @@ bool func_send_xml(XmlMsg xml, uint8_t *out, size_t *len)
string receiver(xml.receiver);
string content(xml.content);
string path(xml.path ? xml.path : "");
uint32_t type = (uint32_t)xml.type;
uint64_t type = (uint64_t)xml.type;
SendXmlMessage(receiver, content, path, type);
rsp.msg.status = 0;
}
@ -349,7 +348,6 @@ bool func_send_xml(XmlMsg xml, uint8_t *out, size_t *len)
return true;
}
#endif
bool func_send_rich_txt(RichText rt, uint8_t *out, size_t *len)
{

View File

@ -14,20 +14,22 @@ extern string GetSelfWxid(); // Defined in spy.cpp
#define SRTM_SIZE 0x3F0
#define OS_NEW 0x1C28800
#define OS_FREE 0x1C1FF10
#define OS_SEND_MSG_MGR 0x1C1E690
#define OS_SEND_TEXT 0x238DDD0
#define OS_SEND_IMAGE 0x2383560
#define OS_GET_APP_MSG_MGR 0x1C23630
#define OS_SEND_FILE 0x21969E0
#define OS_RTM_NEW 0x1C27D50
#define OS_RTM_FREE 0x1C27120
#define OS_SEND_RICH_TEXT 0x21A09C0
#define OS_SEND_PAT_MSG 0x2D669B0
#define OS_FORWARD_MSG 0x238D350
#define OS_GET_EMOTION_MGR 0x1C988D0
#define OS_SEND_EMOTION 0x227B9E0
#define OS_NEW 0x1B5E140
#define OS_FREE 0x1B55850
#define OS_SEND_MSG_MGR 0x1CA4F70
#define OS_SEND_TEXT 0x22C6B60
#define OS_SEND_IMAGE 0x22BC2F0
#define OS_GET_APP_MSG_MGR 0x1B557D0
#define OS_SEND_FILE 0x20D0230
#define OS_RTM_NEW 0x1B5D690
#define OS_RTM_FREE 0x1B5CA60
#define OS_SEND_RICH_TEXT 0x20DA210
#define OS_SEND_PAT_MSG 0x2CAEC00
#define OS_FORWARD_MSG 0x22C60E0
#define OS_GET_EMOTION_MGR 0x1BCEF10
#define OS_SEND_EMOTION 0x21B52D5
#define OS_XML_BUGSIGN 0x24F0D70
#define OS_SEND_XML 0x20CF360
typedef QWORD (*New_t)(QWORD);
typedef QWORD (*Free_t)(QWORD);
@ -43,6 +45,9 @@ typedef QWORD (*ForwardMsg_t)(QWORD, QWORD, QWORD, QWORD);
typedef QWORD (*GetEmotionMgr_t)();
typedef QWORD (*SendEmotion_t)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD);
typedef QWORD (*__XmlBufSignFunc)(QWORD, QWORD, QWORD);
typedef QWORD (*__SendXmlMsgFunc)(QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD, QWORD);
void SendTextMessage(string wxid, string msg, string atWxids)
{
QWORD success = 0;
@ -228,70 +233,42 @@ void SendEmotionMessage(string wxid, string path)
SendEmotion(mgr, (QWORD)pWxPath, (QWORD)buff, (QWORD)pWxWxid, 2, (QWORD)buff, 0, (QWORD)buff);
}
#if 0
void SendXmlMessage(string receiver, string xml, string path, int type)
void SendXmlMessage(string receiver, string xml, string path, QWORD type)
{
if (g_WeChatWinDllAddr == 0) {
return;
}
// 发送消息Call地址 = 微信基址 + 偏移
DWORD sendXmlCall1 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call1;
DWORD sendXmlCall2 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call2;
DWORD sendXmlCall3 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call3;
DWORD sendXmlCall4 = g_WeChatWinDllAddr + g_WxCalls.sendXml.call4;
DWORD sendXmlParam = g_WeChatWinDllAddr + g_WxCalls.sendXml.param;
New_t funcNew = (New_t)(g_WeChatWinDllAddr + OS_NEW);
Free_t funcFree = (Free_t)(g_WeChatWinDllAddr + OS_FREE);
char buffer[0xFF0] = { 0 };
DWORD xmlBufSign = g_WeChatWinDllAddr + OS_XML_BUGSIGN;
DWORD sendXmlMsg = g_WeChatWinDllAddr + OS_SEND_XML;
__XmlBufSignFunc xmlBufSignFunc = (__XmlBufSignFunc)xmlBufSign;
__SendXmlMsgFunc sendXmlMsgFunc = (__SendXmlMsgFunc)sendXmlMsg;
char buff[0x500] = { 0 };
char buff2[0x500] = { 0 };
char nullBuf[0x1C] = { 0 };
wstring wsSender = String2Wstring(GetSelfWxid());
wstring wsReceiver = String2Wstring(receiver);
wstring wsXml = String2Wstring(xml);
DWORD pBuf = (DWORD)(&buff);
DWORD pBuf2 = (DWORD)(&buff2);
WxString wxPath;
WxString wxNull;
WxString wxXml(wsXml);
WxString wxSender(wsSender);
WxString wxReceiver(wsReceiver);
funcNew(pBuf);
funcNew(pBuf2);
if (!path.empty()) {
wstring wsPath = String2Wstring(path);
wxPath = WxString(wsPath);
}
DWORD sbuf[4] = { 0, 0, 0, 0 };
DWORD sendtype = type;
__asm {
pushad;
pushfd;
lea ecx, buffer;
call sendXmlCall1;
mov eax, [sendtype];
push eax;
lea eax, nullBuf;
lea edx, wxSender;
push eax;
lea eax, wxPath;
push eax;
lea eax, wxXml;
push eax;
lea edi, wxReceiver;
push edi;
lea ecx, buffer;
call sendXmlCall2;
add esp, 0x14;
lea eax, wxNull;
push eax;
lea ecx, buffer;
call sendXmlCall3;
mov dl, 0x0;
lea ecx, buffer;
push sendXmlParam;
push sendXmlParam;
call sendXmlCall4;
add esp, 0x8;
popfd;
popad;
}
DWORD sign = xmlBufSignFunc(pBuf2, (DWORD)(&sbuf), 0x1);
WxString *pReceiver = NewWxStringFromStr(receiver);
WxString *pXml = NewWxStringFromStr(xml);
WxString *pPath = NewWxStringFromStr(path);
WxString *pSender = NewWxStringFromStr(GetSelfWxid());
sendXmlMsgFunc(pBuf, (QWORD)pSender, (QWORD)pReceiver, (QWORD)pXml, (QWORD)pPath, (QWORD)(&nullBuf), type, 0x4,
sign, pBuf2);
funcFree((QWORD)&buff));
funcFree((QWORD)&buff2));
}
#endif

View File

@ -17,7 +17,7 @@ typedef struct {
void SendTextMessage(string wxid, string msg, string atWxids);
void SendImageMessage(string wxid, string path);
void SendFileMessage(string wxid, string path);
void SendXmlMessage(string receiver, string xml, string path, int type);
void SendXmlMessage(string receiver, string xml, string path, uint64_t type);
void SendEmotionMessage(string wxid, string path);
int SendRichTextMessage(RichText_t &rt);
int SendPatMessage(string roomid, string wxid);

Binary file not shown.

View File

@ -2,7 +2,7 @@
#include "framework.h"
#define SUPPORT_VERSION L"3.9.10.27"
#define SUPPORT_VERSION L"3.9.11.25"
void InitSpy(int port);
void CleanupSpy();

View File

@ -51,8 +51,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 39,2,4,0
PRODUCTVERSION 3,9,10,27
FILEVERSION 39,3,0,0
PRODUCTVERSION 3,9,11,25
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "WeChatFerry"
VALUE "FileDescription", "WeChatFerry"
VALUE "FileVersion", "39.2.4.0"
VALUE "FileVersion", "39.3.0.0"
VALUE "InternalName", "spy.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "spy.dll"
VALUE "ProductName", "WeChatFerry"
VALUE "ProductVersion", "3.9.10.27"
VALUE "ProductVersion", "3.9.11.25"
END
END
BLOCK "VarFileInfo"

View File

@ -138,43 +138,43 @@
#define SQLITE_NULL 5
#define SQLITE_TEXT 3
#define SQLITE3_EXEC_OFFSET 0x3AFBCE0
#define SQLITE3_BACKUP_INIT_OFFSET 0x1DEA900
#define SQLITE3_PREPARE_OFFSET 0x3B03990
#define SQLITE3_OPEN_OFFSET 0x1E598B0
#define SQLITE3_BACKUP_STEP_OFFSET 0x1DEAD00
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DEB440
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1DEB450
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1DEB340
#define SQLITE3_SLEEP_OFFSET 0x1E5A0F0
#define SQLITE3_ERRCODE_OFFSET 0x1E58550
#define SQLITE3_CLOSE_OFFSET 0x1E56CD0
#define SQLITE3_STEP_OFFSET 0x3ABFCE0
#define SQLITE3_COLUMN_COUNT_OFFSET 0x3AC0500
#define SQLITE3_COLUMN_NAME_OFFSET 0x3AC0F00
#define SQLITE3_COLUMN_TYPE_OFFSET 0x3AC0D50
#define SQLITE3_COLUMN_BLOB_OFFSET 0x3AC0530
#define SQLITE3_COLUMN_BYTES_OFFSET 0x3AC0620
#define SQLITE3_FINALIZE_OFFSET 0x3ABED90
#define SQLITE3_EXEC_OFFSET 0x3A5EDA0
#define SQLITE3_BACKUP_INIT_OFFSET 0x3A18EA0
#define SQLITE3_PREPARE_OFFSET 0x3A66A20
#define SQLITE3_OPEN_OFFSET 0x3A9E210
#define SQLITE3_BACKUP_STEP_OFFSET 0x3A193F0
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1B26EB0
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1B26EE0
#define SQLITE3_BACKUP_FINISH_OFFSET 0x3A19AF0
#define SQLITE3_SLEEP_OFFSET 0x3A9EE70
#define SQLITE3_ERRCODE_OFFSET 0x3A9CB10
#define SQLITE3_CLOSE_OFFSET 0x3A9AC70
#define SQLITE3_STEP_OFFSET 0x3A22DA0
#define SQLITE3_COLUMN_COUNT_OFFSET 0x3A235C0
#define SQLITE3_COLUMN_NAME_OFFSET 0x3A23FC0
#define SQLITE3_COLUMN_TYPE_OFFSET 0x3A23E10
#define SQLITE3_COLUMN_BLOB_OFFSET 0x3A235F0
#define SQLITE3_COLUMN_BYTES_OFFSET 0x3A236E0
#define SQLITE3_FINALIZE_OFFSET 0x3A21E50
typedef int (*Sqlite3_callback)(void *, int, char **, char **);
typedef int(__cdecl *Sqlite3_exec)(QWORD, /* An open database */
const char *sql, /* SQL to be evaluated */
Sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
typedef int(__cdecl *Sqlite3_exec)(QWORD, /* An open database */
const char *sql, /* SQL to be evaluated */
Sqlite3_callback, /* Callback function */
void *, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
typedef QWORD(__cdecl *Sqlite3_backup_init)(QWORD *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
QWORD *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
typedef int(__cdecl *Sqlite3_prepare)(QWORD db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
QWORD **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
typedef int(__cdecl *Sqlite3_prepare)(QWORD db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
QWORD **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
typedef int(__cdecl *Sqlite3_open)(const char *filename, QWORD **ppDb);
typedef int(__cdecl *Sqlite3_backup_step)(QWORD *p, int nPage);

View File

@ -4,10 +4,10 @@
extern UINT64 g_WeChatWinDllAddr;
#define OS_USER_HOME 0x5A7E190
#define OS_USER_WXID 0x5AB7F30
#define OS_USER_NAME 0x5AB8098
#define OS_USER_MOBILE 0x5AB7FD8
#define OS_USER_HOME 0x5932770
#define OS_USER_WXID 0x595C270
#define OS_USER_NAME 0x595C3D8
#define OS_USER_MOBILE 0x595C318
static char home[MAX_PATH] = { 0 };