提交 27b8d2f4 编写于 作者: L ljc545w

完善http接口

上级 be0260eb
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
vector<DbInfoStruct> dbs; vector<DbInfoStruct> dbs;
/* /*
* 根据数据库名从`dbs`中检索数据库句柄 * 根据数据库名从`dbs`中检索数据库句柄
* dbname:数据库名 * dbname:数据库名
* return:DWORD,如果检索成功,返回数据库句柄,否则返回`0` * return:DWORD,如果检索成功,返回数据库句柄,否则返回`0`
*/ */
DWORD GetDbHandleByDbName(wchar_t *dbname) DWORD GetDbHandleByDbName(wchar_t *dbname)
{ {
if (dbs.size() == 0) if (dbs.size() == 0)
...@@ -28,9 +28,9 @@ DWORD GetDbHandleByDbName(wchar_t *dbname) ...@@ -28,9 +28,9 @@ DWORD GetDbHandleByDbName(wchar_t *dbname)
} }
/* /*
* 供外部调用的获取数据库信息接口 * 供外部调用的获取数据库信息接口
* return:DWORD,`dbs`首个成员地址 * return:DWORD,`dbs`首个成员地址
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
DWORD GetDbHandlesRemote() DWORD GetDbHandlesRemote()
{ {
...@@ -41,9 +41,9 @@ DWORD GetDbHandlesRemote() ...@@ -41,9 +41,9 @@ DWORD GetDbHandlesRemote()
#endif #endif
/* /*
* 获取数据库信息的具体实现 * 获取数据库信息的具体实现
* return:void * return:void
*/ */
vector<void *> GetDbHandles() vector<void *> GetDbHandles()
{ {
dbs.clear(); dbs.clear();
...@@ -134,7 +134,7 @@ vector<void *> GetDbHandles() ...@@ -134,7 +134,7 @@ vector<void *> GetDbHandles()
} }
#endif #endif
vector<void *> ret_array; vector<void *> ret_array;
for (auto it : dbs) for (unsigned int i = 0; i < dbs.size() - 1; i++)
ret_array.push_back(&it); ret_array.push_back(&dbs[i]);
return ret_array; return ret_array;
} }
...@@ -9,54 +9,58 @@ static DWORD WeChatWinBase = GetWeChatWinBase(); ...@@ -9,54 +9,58 @@ static DWORD WeChatWinBase = GetWeChatWinBase();
static DWORD HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset; static DWORD HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset;
static DWORD HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset; static DWORD HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset;
static DWORD HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5; static DWORD HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5;
static char ImageMsgOldAsm[5] = { 0 }; static char ImageMsgOldAsm[5] = {0};
static wstring savepath = L""; static wstring savepath = L"";
void SaveImageMsg(unsigned char* buffer, int length, DWORD msgHandle) { void SaveImageMsg(unsigned char *buffer, int length, DWORD msgHandle)
int l_datpath = *(int*)(msgHandle + 0x4) + 1; {
wchar_t* datpath = new wchar_t[l_datpath]; int l_datpath = *(int *)(msgHandle + 0x4) + 1;
memcpy(datpath, (void*)(*(DWORD*)msgHandle), l_datpath * 2); wchar_t *datpath = new wchar_t[l_datpath];
wstring wdatpath(datpath); memcpy(datpath, (void *)(*(DWORD *)msgHandle), l_datpath * 2);
delete[] datpath; wstring wdatpath(datpath);
datpath = NULL; delete[] datpath;
if (wdatpath.find(L"_t.dat") != wstring::npos) { datpath = NULL;
return; if (wdatpath.find(L"_t.dat") != wstring::npos)
} {
int pos_begin = wdatpath.find_last_of(L"\\") + 1; return;
int pos_end = wdatpath.find_last_of(L"."); }
wstring filename = wdatpath.substr(pos_begin, pos_end - pos_begin); int pos_begin = wdatpath.find_last_of(L"\\") + 1;
int pos_end = wdatpath.find_last_of(L".");
wstring filename = wdatpath.substr(pos_begin, pos_end - pos_begin);
unsigned char magic_head[4] = { 0 }; unsigned char magic_head[4] = {0};
wchar_t postfix[5] = { 0 }; wchar_t postfix[5] = {0};
memcpy(magic_head, buffer, 3); memcpy(magic_head, buffer, 3);
if (magic_head[0] == 137 && magic_head[1] == 80 && magic_head[2] == 78) if (magic_head[0] == 137 && magic_head[1] == 80 && magic_head[2] == 78)
{ {
lstrcpy(postfix,L".png"); lstrcpy(postfix, L".png");
} }
else if (magic_head[0] == 71 && magic_head[1] == 73 && magic_head[2] == 70) else if (magic_head[0] == 71 && magic_head[1] == 73 && magic_head[2] == 70)
{ {
lstrcpy(postfix, L".gif"); lstrcpy(postfix, L".gif");
} }
else if (magic_head[0] == 255 && magic_head[1] == 216 && magic_head[2] == 255) else if (magic_head[0] == 255 && magic_head[1] == 216 && magic_head[2] == 255)
{ {
lstrcpy(postfix, L".jpg"); lstrcpy(postfix, L".jpg");
} }
else { else
lstrcpy(postfix, L""); {
} lstrcpy(postfix, L"");
wstring filepath = savepath + filename + postfix; }
HANDLE hFile = CreateFile(filepath.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); wstring filepath = savepath + filename + postfix;
if (hFile == INVALID_HANDLE_VALUE) HANDLE hFile = CreateFile(filepath.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
{ if (hFile == INVALID_HANDLE_VALUE)
return; {
} return;
DWORD dwWrite = 0; }
WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0); DWORD dwWrite = 0;
CloseHandle(hFile); WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0);
CloseHandle(hFile);
} }
__declspec(naked) void dealImageMsg() { __declspec(naked) void dealImageMsg()
__asm { {
__asm {
pushad; pushad;
pushfd; pushfd;
push esi; push esi;
...@@ -68,41 +72,61 @@ __declspec(naked) void dealImageMsg() { ...@@ -68,41 +72,61 @@ __declspec(naked) void dealImageMsg() {
popad; popad;
call HookImageMsgNextCall; call HookImageMsgNextCall;
jmp HookImageMsgJmpBackAddr; jmp HookImageMsgJmpBackAddr;
} }
} }
void __stdcall HookImageMsg() { void __stdcall HookImageMsg()
WeChatWinBase = GetWeChatWinBase(); {
if (ImageMsgHooked || !WeChatWinBase) WeChatWinBase = GetWeChatWinBase();
return; if (ImageMsgHooked || !WeChatWinBase)
HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset; return;
HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset; HookImageMsgAddr = WeChatWinBase + HookImageMsgAddrOffset;
HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5; HookImageMsgNextCall = WeChatWinBase + HookImageMsgNextCallOffset;
HookAnyAddress(HookImageMsgAddr, dealImageMsg, ImageMsgOldAsm); HookImageMsgJmpBackAddr = HookImageMsgAddr + 0x5;
char settime[] = "00:00-00:00"; HookAnyAddress(HookImageMsgAddr, dealImageMsg, ImageMsgOldAsm);
DWORD AutoDownloadTimeSettingAddr = GetWeChatWinBase() + AutoDownloadTimeSettingOffset; char settime[] = "00:00-00:00";
WriteProcessMemory(GetCurrentProcess(), (LPVOID)AutoDownloadTimeSettingAddr, settime, strlen(settime) + 1, 0); DWORD AutoDownloadTimeSettingAddr = GetWeChatWinBase() + AutoDownloadTimeSettingOffset;
ImageMsgHooked = true; WriteProcessMemory(GetCurrentProcess(), (LPVOID)AutoDownloadTimeSettingAddr, settime, strlen(settime) + 1, 0);
ImageMsgHooked = true;
} }
void UnHookImageMsg() { void UnHookImageMsg()
if (!ImageMsgHooked) {
return; if (!ImageMsgHooked)
UnHookAnyAddress(HookImageMsgAddr, ImageMsgOldAsm); return;
ImageMsgHooked = false; UnHookAnyAddress(HookImageMsgAddr, ImageMsgOldAsm);
ImageMsgHooked = false;
} }
#ifndef USE_SOCKET #ifndef USE_SOCKET
BOOL HookImageMsgRemote(LPVOID lpParameter) { BOOL HookImageMsgRemote(LPVOID lpParameter)
savepath = (wstring)(wchar_t*)lpParameter; {
if (savepath.back() != '\\') { savepath = (wstring)(wchar_t *)lpParameter;
savepath += L"\\"; if (savepath.back() != '\\')
} {
wstring createpath = savepath.substr(0, savepath.length() - 1); savepath += L"\\";
if (!FindOrCreateDirectory(createpath.c_str())) { }
return false; wstring createpath = savepath.substr(0, savepath.length() - 1);
} if (!FindOrCreateDirectory(createpath.c_str()))
HookImageMsg(); {
return true; return false;
}
HookImageMsg();
return true;
} }
#endif #else
\ No newline at end of file BOOL __stdcall HookImageMsg(wstring savepath)
{
if (savepath.back() != '\\')
{
savepath += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
}
HookImageMsg();
return true;
}
#endif
...@@ -8,40 +8,42 @@ static DWORD WeChatWinBase = GetWeChatWinBase(); ...@@ -8,40 +8,42 @@ static DWORD WeChatWinBase = GetWeChatWinBase();
static DWORD HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset; static DWORD HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset;
static DWORD HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset; static DWORD HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset;
static DWORD HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5; static DWORD HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5;
static char VoiceMsgOldAsm[5] = { 0 }; static char VoiceMsgOldAsm[5] = {0};
static wstring savepath = L""; static wstring savepath = L"";
void SaveVoiceMsg(unsigned char* buffer, int length, DWORD msgHandle) { void SaveVoiceMsg(unsigned char *buffer, int length, DWORD msgHandle)
/*time_t curtime = time(0); {
wchar_t timestamp[32] = { 0 }; /*time_t curtime = time(0);
_itow_s((int)curtime, timestamp, 10);*/ wchar_t timestamp[32] = { 0 };
wchar_t* temp; _itow_s((int)curtime, timestamp, 10);*/
int wxid_length = *(DWORD*)(msgHandle + 0x174); wchar_t *temp;
temp = new wchar_t[wxid_length + 1]; int wxid_length = *(DWORD *)(msgHandle + 0x174);
memcpy(temp, (void*)(*(DWORD*)(msgHandle + 0x170)), (wxid_length + 1) * 2); temp = new wchar_t[wxid_length + 1];
wstring sender(temp); memcpy(temp, (void *)(*(DWORD *)(msgHandle + 0x170)), (wxid_length + 1) * 2);
delete[] temp; wstring sender(temp);
temp = NULL; delete[] temp;
temp = NULL;
int clientmsg_length = *(DWORD*)(msgHandle + 0x188);
temp = new wchar_t[clientmsg_length + 1]; int clientmsg_length = *(DWORD *)(msgHandle + 0x188);
memcpy(temp, (void*)(*(DWORD*)(msgHandle + 0x184)), (clientmsg_length + 1) * 2); temp = new wchar_t[clientmsg_length + 1];
wstring clientmsgid(temp); memcpy(temp, (void *)(*(DWORD *)(msgHandle + 0x184)), (clientmsg_length + 1) * 2);
delete[] temp; wstring clientmsgid(temp);
temp = NULL; delete[] temp;
wstring filename = savepath + sender + L"-" + clientmsgid + L".amr"; temp = NULL;
HANDLE hFile = CreateFile(filename.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); wstring filename = savepath + sender + L"-" + clientmsgid + L".amr";
if (hFile == INVALID_HANDLE_VALUE) HANDLE hFile = CreateFile(filename.c_str(), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
{ if (hFile == INVALID_HANDLE_VALUE)
return; {
} return;
DWORD dwWrite = 0; }
WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0); DWORD dwWrite = 0;
CloseHandle(hFile); WriteFile(hFile, (LPCVOID)buffer, length, &dwWrite, 0);
CloseHandle(hFile);
} }
__declspec(naked) void dealVoiceMsg() { __declspec(naked) void dealVoiceMsg()
__asm { {
__asm {
pushad; pushad;
pushfd; pushfd;
push edi; push edi;
...@@ -53,38 +55,58 @@ __declspec(naked) void dealVoiceMsg() { ...@@ -53,38 +55,58 @@ __declspec(naked) void dealVoiceMsg() {
popad; popad;
call HookVoiceMsgNextCall; call HookVoiceMsgNextCall;
jmp HookVoiceMsgJmpBackAddr; jmp HookVoiceMsgJmpBackAddr;
} }
} }
void __stdcall HookVoiceMsg() { void __stdcall HookVoiceMsg()
WeChatWinBase = GetWeChatWinBase(); {
if (VoiceMsgHooked || !WeChatWinBase) WeChatWinBase = GetWeChatWinBase();
return; if (VoiceMsgHooked || !WeChatWinBase)
HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset; return;
HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset; HookVoiceMsgAddr = WeChatWinBase + HookVoiceMsgAddrOffset;
HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5; HookVoiceMsgNextCall = WeChatWinBase + HookVoiceMsgNextCallOffset;
HookAnyAddress(HookVoiceMsgAddr, dealVoiceMsg, VoiceMsgOldAsm); HookVoiceMsgJmpBackAddr = HookVoiceMsgAddr + 0x5;
VoiceMsgHooked = true; HookAnyAddress(HookVoiceMsgAddr, dealVoiceMsg, VoiceMsgOldAsm);
VoiceMsgHooked = true;
} }
void UnHookVoiceMsg() { void UnHookVoiceMsg()
if (!VoiceMsgHooked) {
return; if (!VoiceMsgHooked)
UnHookAnyAddress(HookVoiceMsgAddr, VoiceMsgOldAsm); return;
VoiceMsgHooked = false; UnHookAnyAddress(HookVoiceMsgAddr, VoiceMsgOldAsm);
VoiceMsgHooked = false;
} }
#ifndef USE_SOCKET #ifndef USE_SOCKET
BOOL HookVoiceMsgRemote(LPVOID lpParameter) { BOOL HookVoiceMsgRemote(LPVOID lpParameter)
savepath = (wstring)(wchar_t*)lpParameter; {
if (savepath.back() != '\\') { savepath = (wstring)(wchar_t *)lpParameter;
savepath += L"\\"; if (savepath.back() != '\\')
} {
wstring createpath = savepath.substr(0, savepath.length() - 1); savepath += L"\\";
if (!FindOrCreateDirectory(createpath.c_str())) { }
return false; wstring createpath = savepath.substr(0, savepath.length() - 1);
} if (!FindOrCreateDirectory(createpath.c_str()))
HookVoiceMsg(); {
return true; return false;
}
HookVoiceMsg();
return true;
}
#else
BOOL __stdcall HookVoiceMsg(wstring savepath)
{
if (savepath.back() != '\\')
{
savepath += L"\\";
}
wstring createpath = savepath.substr(0, savepath.length() - 1);
if (!FindOrCreateDirectory(createpath.c_str()))
{
return false;
}
HookVoiceMsg();
return true;
} }
#endif #endif
\ No newline at end of file
#pragma once #pragma once
#include<windows.h> #include <windows.h>
#ifndef USE_SOCKET #ifndef USE_SOCKET
extern "C" __declspec(dllexport) VOID HookReceiveMessage(int port); extern "C" __declspec(dllexport) VOID HookReceiveMessage(int port);
extern "C" __declspec(dllexport) VOID UnHookReceiveMessage(); extern "C" __declspec(dllexport) VOID UnHookReceiveMessage();
...@@ -12,7 +12,9 @@ VOID HookReceiveMessage(int port); ...@@ -12,7 +12,9 @@ VOID HookReceiveMessage(int port);
VOID UnHookReceiveMessage(); VOID UnHookReceiveMessage();
void UnHookImageMsg(); void UnHookImageMsg();
void UnHookVoiceMsg(); void UnHookVoiceMsg();
BOOL __stdcall HookVoiceMsg(wstring savepath);
BOOL __stdcall HookImageMsg(wstring savepath);
#endif #endif
void __stdcall HookVoiceMsg(); void __stdcall HookVoiceMsg();
void __stdcall HookImageMsg(); void __stdcall HookImageMsg();
\ No newline at end of file
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
#define DeleteAtTextCacheCallOffset 0x78757780 - 0x786A0000 #define DeleteAtTextCacheCallOffset 0x78757780 - 0x786A0000
/* /*
* 外部调用时传递的参数结构 * 外部调用时传递的参数结构
* chatroomid:群聊ID的保存地址 * chatroomid:群聊ID的保存地址
* wxidlist:艾特列表的保存地址,真实类型应当是`wchar_t**` * wxidlist:艾特列表的保存地址,真实类型应当是`wchar_t**`
* wxmsg:发送的内容保存地址 * wxmsg:发送的内容保存地址
* length:艾特的人数量,用于指示wxidlist长度 * length:艾特的人数量,用于指示wxidlist长度
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
struct SendAtTextStruct struct SendAtTextStruct
{ {
...@@ -24,13 +24,13 @@ struct SendAtTextStruct ...@@ -24,13 +24,13 @@ struct SendAtTextStruct
#endif #endif
/* /*
* 内存中使用的参数结构 * 内存中使用的参数结构
* 构造与Release版本vector动态数组相仿 * 构造与Release版本vector动态数组相仿
* 成员类型:`WxString` * 成员类型:`WxString`
* AtUser:类似`vector`的`data`方法,保存数组首个成员的地址 * AtUser:类似`vector`的`data`方法,保存数组首个成员的地址
* addr_end1:数组尾地址 * addr_end1:数组尾地址
* addr_end2:数组尾地址 * addr_end2:数组尾地址
*/ */
struct AtStruct struct AtStruct
{ {
DWORD AtUser; DWORD AtUser;
...@@ -39,10 +39,10 @@ struct AtStruct ...@@ -39,10 +39,10 @@ struct AtStruct
}; };
/* /*
* 供外部调用的发送艾特消息接口 * 供外部调用的发送艾特消息接口
* lpParameter:SendAtTextStruct类型结构体指针 * lpParameter:SendAtTextStruct类型结构体指针
* return:void * return:void
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
void SendAtTextRemote(LPVOID lpParameter) void SendAtTextRemote(LPVOID lpParameter)
{ {
...@@ -59,15 +59,15 @@ void SendAtTextRemote(LPVOID lpParameter) ...@@ -59,15 +59,15 @@ void SendAtTextRemote(LPVOID lpParameter)
#endif #endif
/* /*
* 发送艾特消息的具体实现 * 发送艾特消息的具体实现
* wsChatRoomId:群聊ID * wsChatRoomId:群聊ID
* wsWxId:艾特的人列表 * wsWxId:艾特的人列表
* wsTextMsg:发送的消息内容 * wsTextMsg:发送的消息内容
* length:艾特的人数量 * length:艾特的人数量
* AutoNickName:是否自动填充被艾特人昵称 * AutoNickName:是否自动填充被艾特人昵称
* return:void * return:BOOL,发送成功返回`1`,发送失败返回`0`
*/ */
void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsTextMsg, int length, BOOL AutoNickName) BOOL __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsTextMsg, int length, BOOL AutoNickName)
{ {
// +1的作用是补充一个空结构体,将`AtStruct`尾地址设定为空结构的首地址即可 // +1的作用是补充一个空结构体,将`AtStruct`尾地址设定为空结构的首地址即可
WxString *AtUsers = new WxString[length + 1]; WxString *AtUsers = new WxString[length + 1];
...@@ -97,7 +97,7 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText ...@@ -97,7 +97,7 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText
} }
AtMessage += wsTextMsg; AtMessage += wsTextMsg;
if (!querySuccess) if (!querySuccess)
return; return FALSE;
WxString wxChatRoomId(wsChatRoomId); WxString wxChatRoomId(wsChatRoomId);
WxString wxTextMsg((wchar_t *)AtMessage.c_str()); WxString wxTextMsg((wchar_t *)AtMessage.c_str());
AtStruct at = {0}; AtStruct at = {0};
...@@ -111,7 +111,7 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText ...@@ -111,7 +111,7 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText
DWORD dllBaseAddress = GetWeChatWinBase(); DWORD dllBaseAddress = GetWeChatWinBase();
DWORD callAddress = dllBaseAddress + SendAtTextCallOffset; DWORD callAddress = dllBaseAddress + SendAtTextCallOffset;
DWORD DeleteTextCacheCall = dllBaseAddress + DeleteAtTextCacheCallOffset; DWORD DeleteTextCacheCall = dllBaseAddress + DeleteAtTextCacheCallOffset;
int isSuccess = 0;
__asm { __asm {
lea eax, at; lea eax, at;
push 0x1; push 0x1;
...@@ -121,10 +121,12 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText ...@@ -121,10 +121,12 @@ void __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsText
lea edx, wxChatRoomId; lea edx, wxChatRoomId;
lea ecx, buffer; lea ecx, buffer;
call callAddress; call callAddress;
mov isSuccess,eax;
add esp, 0xC; add esp, 0xC;
lea ecx, buffer; lea ecx, buffer;
call DeleteTextCacheCall; call DeleteTextCacheCall;
} }
delete[] AtUsers; delete[] AtUsers;
AtUsers = NULL; AtUsers = NULL;
return isSuccess == 1;
} }
#pragma once #pragma once
#include<windows.h> #include <windows.h>
void __stdcall SendAtText(wchar_t* wsChatRoomId, DWORD wsWxId[], wchar_t* wsTextMsg, int length, BOOL AutoNickName); BOOL __stdcall SendAtText(wchar_t *wsChatRoomId, DWORD wsWxId[], wchar_t *wsTextMsg, int length, BOOL AutoNickName);
#ifndef USE_SOCKET #ifndef USE_SOCKET
extern "C" __declspec(dllexport) void SendAtTextRemote(LPVOID lpParameter); extern "C" __declspec(dllexport) void SendAtTextRemote(LPVOID lpParameter);
#endif #endif
\ No newline at end of file
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
#define DeleteCardCacheCallOffset 0x78757780 - 0x786A0000 #define DeleteCardCacheCallOffset 0x78757780 - 0x786A0000
/* /*
* 外部调用时提供的参数结构 * 外部调用时提供的参数结构
* receiver:名片消息接收人wxid保存地址 * receiver:名片消息接收人wxid保存地址
* sharedwxid:被推荐人的wxid保存地址 * sharedwxid:被推荐人的wxid保存地址
* nickname:名片显示的昵称保存地址 * nickname:名片显示的昵称保存地址
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
struct SendCardStruct struct SendCardStruct
{ {
...@@ -21,10 +21,10 @@ struct SendCardStruct ...@@ -21,10 +21,10 @@ struct SendCardStruct
#endif #endif
/* /*
* 供外部调用的发送名片接口 * 供外部调用的发送名片接口
* lparameter:SendCardStruct类型结构体指针 * lparameter:SendCardStruct类型结构体指针
* return:void * return:void
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
VOID SendCardRemote(LPVOID lparameter) VOID SendCardRemote(LPVOID lparameter)
{ {
...@@ -37,12 +37,12 @@ VOID SendCardRemote(LPVOID lparameter) ...@@ -37,12 +37,12 @@ VOID SendCardRemote(LPVOID lparameter)
#endif #endif
/* /*
* 发送名片消息的具体实现 * 发送名片消息的具体实现
* receiver:消息接收人wxid * receiver:消息接收人wxid
* sharedwxid:被推荐人wxid * sharedwxid:被推荐人wxid
* nickname:名片显示的昵称 * nickname:名片显示的昵称
* return:BOOL,发送成功返回`0`,发送失败返回`1` * return:BOOL,发送成功返回`1`,发送失败返回`0`
*/ */
BOOL __stdcall SendCard(wchar_t *receiver, wchar_t *sharedwxid, wchar_t *nickname) BOOL __stdcall SendCard(wchar_t *receiver, wchar_t *sharedwxid, wchar_t *nickname)
{ {
DWORD WeChatWinBase = GetWeChatWinBase(); DWORD WeChatWinBase = GetWeChatWinBase();
...@@ -69,10 +69,10 @@ BOOL __stdcall SendCard(wchar_t *receiver, wchar_t *sharedwxid, wchar_t *nicknam ...@@ -69,10 +69,10 @@ BOOL __stdcall SendCard(wchar_t *receiver, wchar_t *sharedwxid, wchar_t *nicknam
add esp, 0xC; add esp, 0xC;
lea ecx, buffer; lea ecx, buffer;
call DeleteCardCacheCall; call DeleteCardCacheCall;
mov isSuccess, eax; mov isSuccess, eax;
popad; popad;
} }
delete[] xml; delete[] xml;
xml = NULL; xml = NULL;
return isSuccess; return isSuccess == 0;
} }
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
#define DeleteSendFileCacheCallOffset (0x78757780 - 0x786A0000) #define DeleteSendFileCacheCallOffset (0x78757780 - 0x786A0000)
/* /*
* 外部调用时传递的参数结构 * 外部调用时传递的参数结构
* wxid:wxid的保存地址 * wxid:wxid的保存地址
* filepath:文件绝对路径的保存地址 * filepath:文件绝对路径的保存地址
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
struct FileParamStruct struct FileParamStruct
{ {
...@@ -23,14 +23,14 @@ struct FileParamStruct ...@@ -23,14 +23,14 @@ struct FileParamStruct
#endif #endif
/* /*
* 内存中使用的参数结构 * 内存中使用的参数结构
* type:消息类型,文件消息为3 * type:消息类型,文件消息为3
* buffer:文件绝对路径 * buffer:文件绝对路径
* length:绝对路径字符数 * length:绝对路径字符数
* maxLength:绝对路径最大字节数 * maxLength:绝对路径最大字节数
* fill:占位用空缓冲区 * fill:占位用空缓冲区
* WxFileStruct:默认构造函数 * WxFileStruct:默认构造函数
*/ */
struct WxFileStruct struct WxFileStruct
{ {
int type = 3; int type = 3;
...@@ -48,10 +48,10 @@ struct WxFileStruct ...@@ -48,10 +48,10 @@ struct WxFileStruct
}; };
/* /*
* 供外部调用的发送文件消息接口 * 供外部调用的发送文件消息接口
* lpParamStruct:FileParamStruct类型结构体指针 * lpParamStruct:FileParamStruct类型结构体指针
* return:void * return:void
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
void SendFileRemote(LPVOID lpParamStruct) void SendFileRemote(LPVOID lpParamStruct)
{ {
...@@ -61,12 +61,12 @@ void SendFileRemote(LPVOID lpParamStruct) ...@@ -61,12 +61,12 @@ void SendFileRemote(LPVOID lpParamStruct)
#endif #endif
/* /*
* 发送文件消息的具体实现 * 发送文件消息的具体实现
* receiver:接收人wxid * receiver:接收人wxid
* FilePath:文件绝对路径 * FilePath:文件绝对路径
* return:void * return:BOOL,发送成功返回`1`,发送失败返回`0`
*/ */
void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath) BOOL __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath)
{ {
WxString pReceiver(receiver); WxString pReceiver(receiver);
WxString pFilePath(FilePath); WxString pFilePath(FilePath);
...@@ -85,7 +85,7 @@ void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath) ...@@ -85,7 +85,7 @@ void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath)
DWORD edi_ = pReceiver.length; DWORD edi_ = pReceiver.length;
DWORD ptrReceiver = (DWORD)pReceiver.buffer; DWORD ptrReceiver = (DWORD)pReceiver.buffer;
int isSuccess = 0;
__asm { __asm {
pushad; pushad;
pushfd; pushfd;
...@@ -118,9 +118,11 @@ void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath) ...@@ -118,9 +118,11 @@ void __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath)
lea eax, buffer; lea eax, buffer;
push eax; push eax;
call WxSendFileCall3; call WxSendFileCall3;
mov isSuccess,eax;
lea ecx, buffer; lea ecx, buffer;
call DeleteSendFileCacheCall; call DeleteSendFileCacheCall;
popfd; popfd;
popad; popad;
} }
return isSuccess == 1;
} }
#pragma once #pragma once
#include<windows.h> #include <windows.h>
void __stdcall SendFile(wchar_t* receiver, wchar_t* FilePath); BOOL __stdcall SendFile(wchar_t *receiver, wchar_t *FilePath);
#ifndef USE_SOCKET #ifndef USE_SOCKET
extern "C" __declspec(dllexport) void SendFileRemote(LPVOID lpParamStruct); extern "C" __declspec(dllexport) void SendFileRemote(LPVOID lpParamStruct);
#endif #endif
\ No newline at end of file
...@@ -10,10 +10,10 @@ ...@@ -10,10 +10,10 @@
#define DeleteSendImageCacheCallOffset (0x78757780 - 0x786A0000) #define DeleteSendImageCacheCallOffset (0x78757780 - 0x786A0000)
/* /*
* 外部调用时传递的参数结构 * 外部调用时传递的参数结构
* wxid:保存wxid的地址 * wxid:保存wxid的地址
* imagepath:保存图片绝对路径的地址 * imagepath:保存图片绝对路径的地址
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
struct ImageParamStruct struct ImageParamStruct
{ {
...@@ -23,10 +23,10 @@ struct ImageParamStruct ...@@ -23,10 +23,10 @@ struct ImageParamStruct
#endif #endif
/* /*
* 供外部调用的发送图片消息接口 * 供外部调用的发送图片消息接口
* lpParamStruct:ImageParamStruct类型结构体指针 * lpParamStruct:ImageParamStruct类型结构体指针
* return:void * return:void
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
void SendImageRemote(LPVOID lpParamStruct) void SendImageRemote(LPVOID lpParamStruct)
{ {
...@@ -36,12 +36,12 @@ void SendImageRemote(LPVOID lpParamStruct) ...@@ -36,12 +36,12 @@ void SendImageRemote(LPVOID lpParamStruct)
#endif #endif
/* /*
* 发送图片消息的具体实现 * 发送图片消息的具体实现
* receiver:接收人wxid * receiver:接收人wxid
* ImagePath:图片绝对路径 * ImagePath:图片绝对路径
* return:void * return:BOOL,发送成功返回`1`,发送失败返回`0`
*/ */
void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath) BOOL __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath)
{ {
DWORD WeChatWinBase = GetWeChatWinBase(); DWORD WeChatWinBase = GetWeChatWinBase();
DWORD SendImageCall1 = WeChatWinBase + SendImageCall1Offset; DWORD SendImageCall1 = WeChatWinBase + SendImageCall1Offset;
...@@ -54,7 +54,7 @@ void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath) ...@@ -54,7 +54,7 @@ void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath)
WxString pImagePath(ImagePath); WxString pImagePath(ImagePath);
WxString nullStruct = {0}; WxString nullStruct = {0};
DWORD tempeax = 0; DWORD tempeax = 0;
int isSuccess = 0;
__asm { __asm {
pushad; pushad;
call SendImageCall1; call SendImageCall1;
...@@ -72,8 +72,10 @@ void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath) ...@@ -72,8 +72,10 @@ void __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath)
lea eax, buffer; lea eax, buffer;
push eax; push eax;
call SendImageCall3; call SendImageCall3;
mov isSuccess,eax;
lea ecx, buffer; lea ecx, buffer;
call DeleteSendImageCacheCall; call DeleteSendImageCacheCall;
popad; popad;
} }
return isSuccess == 1;
} }
#pragma once #pragma once
#include<windows.h> #include <windows.h>
void __stdcall SendImage(wchar_t* receiver, wchar_t* ImagePath); BOOL __stdcall SendImage(wchar_t *receiver, wchar_t *ImagePath);
#ifndef USE_SOCKET #ifndef USE_SOCKET
extern "C" __declspec(dllexport) void SendImageRemote(LPVOID lpParamStruct); extern "C" __declspec(dllexport) void SendImageRemote(LPVOID lpParamStruct);
#endif #endif
\ No newline at end of file
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
#define DeleteTextCacheCallOffset 0x78757780 - 0x786A0000 #define DeleteTextCacheCallOffset 0x78757780 - 0x786A0000
/* /*
* 外部调用时传递的参数结构 * 外部调用时传递的参数结构
* wxid:wxid保存地址 * wxid:wxid保存地址
* wxmsg:发送的内容保存地址 * wxmsg:发送的内容保存地址
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
struct SendTextStruct struct SendTextStruct
{ {
...@@ -19,10 +19,10 @@ struct SendTextStruct ...@@ -19,10 +19,10 @@ struct SendTextStruct
#endif #endif
/* /*
* 供外部调用的发送文本消息接口 * 供外部调用的发送文本消息接口
* lpParameter:SendTextStruct类型结构体指针 * lpParameter:SendTextStruct类型结构体指针
* return:void * return:void
*/ */
#ifndef USE_SOCKET #ifndef USE_SOCKET
void SendTextRemote(LPVOID lpParameter) void SendTextRemote(LPVOID lpParameter)
{ {
...@@ -34,12 +34,12 @@ void SendTextRemote(LPVOID lpParameter) ...@@ -34,12 +34,12 @@ void SendTextRemote(LPVOID lpParameter)
#endif #endif
/* /*
* 发送文本消息的具体实现 * 发送文本消息的具体实现
* wsWxId:接收人wxid * wsWxId:接收人wxid
* wsTextMsg:发送的消息内容 * wsTextMsg:发送的消息内容
* return:void * return:BOOL,发送成功返回`1`,发送失败返回`0`
*/ */
void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg) BOOL __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg)
{ {
WxString wxWxid(wsWxId); WxString wxWxid(wsWxId);
WxString wxTextMsg(wsTextMsg); WxString wxTextMsg(wsTextMsg);
...@@ -50,7 +50,7 @@ void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg) ...@@ -50,7 +50,7 @@ void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg)
DWORD dllBaseAddress = GetWeChatWinBase(); DWORD dllBaseAddress = GetWeChatWinBase();
DWORD callAddress = dllBaseAddress + SendTextCallOffset; DWORD callAddress = dllBaseAddress + SendTextCallOffset;
DWORD DeleteTextCacheCall = dllBaseAddress + DeleteTextCacheCallOffset; DWORD DeleteTextCacheCall = dllBaseAddress + DeleteTextCacheCallOffset;
int isSuccess = 0;
__asm { __asm {
pushad; pushad;
lea eax, wxNull; lea eax, wxNull;
...@@ -61,9 +61,11 @@ void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg) ...@@ -61,9 +61,11 @@ void __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg)
lea edx, wxWxid; lea edx, wxWxid;
lea ecx, buffer; lea ecx, buffer;
call callAddress; call callAddress;
mov isSuccess,eax;
add esp, 0xC; add esp, 0xC;
lea ecx, buffer; lea ecx, buffer;
call DeleteTextCacheCall; call DeleteTextCacheCall;
popad; popad;
} }
return isSuccess == 1;
} }
#pragma once #pragma once
#include<windows.h> #include <windows.h>
void __stdcall SendText(wchar_t* wsWxId, wchar_t* wsTextMsg); BOOL __stdcall SendText(wchar_t *wsWxId, wchar_t *wsTextMsg);
#ifndef USE_SOCKET #ifndef USE_SOCKET
extern "C" __declspec(dllexport) void SendTextRemote(LPVOID lpParameter); extern "C" __declspec(dllexport) void SendTextRemote(LPVOID lpParameter);
#endif #endif
\ No newline at end of file
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
#ifdef USE_SOCKET #ifdef USE_SOCKET
#define WS2LW(wstr) (LPWSTR) wstr.c_str() #define WS2LW(wstr) (LPWSTR) wstr.c_str()
void __stdcall SendText(wstring wxid, wstring msg) BOOL __stdcall SendText(wstring wxid, wstring msg)
{ {
return SendText(WS2LW(wxid), WS2LW(msg)); return SendText(WS2LW(wxid), WS2LW(msg));
} }
void __stdcall SendAtText(wstring wsChatRoomId, vector<wstring> wxids, wstring wsTextMsg, BOOL AutoNickName) BOOL __stdcall SendAtText(wstring wsChatRoomId, vector<wstring> wxids, wstring wsTextMsg, BOOL AutoNickName)
{ {
vector<DWORD> wxid_list; vector<DWORD> wxid_list;
for (auto wxid : wxids) for (unsigned int i = 0; i < wxids.size(); i++)
wxid_list.push_back((DWORD)wxid.c_str()); wxid_list.push_back((DWORD)wxids[i].c_str());
return SendAtText(WS2LW(wsChatRoomId), wxid_list.data(), WS2LW(wsTextMsg), wxid_list.size(), AutoNickName); return SendAtText(WS2LW(wsChatRoomId), wxid_list.data(), WS2LW(wsTextMsg), wxid_list.size(), AutoNickName);
} }
...@@ -22,12 +22,12 @@ BOOL __stdcall SendCard(wstring receiver, wstring sharedwxid, wstring nickname) ...@@ -22,12 +22,12 @@ BOOL __stdcall SendCard(wstring receiver, wstring sharedwxid, wstring nickname)
return SendCard(WS2LW(receiver), WS2LW(sharedwxid), WS2LW(nickname)); return SendCard(WS2LW(receiver), WS2LW(sharedwxid), WS2LW(nickname));
} }
void __stdcall SendImage(wstring receiver, wstring ImagePath) BOOL __stdcall SendImage(wstring receiver, wstring ImagePath)
{ {
return SendImage(WS2LW(receiver), WS2LW(ImagePath)); return SendImage(WS2LW(receiver), WS2LW(ImagePath));
} }
void __stdcall SendFile(wstring receiver, wstring FilePath) BOOL __stdcall SendFile(wstring receiver, wstring FilePath)
{ {
return SendFile(WS2LW(receiver), WS2LW(FilePath)); return SendFile(WS2LW(receiver), WS2LW(FilePath));
} }
...@@ -90,16 +90,16 @@ wstring __stdcall GetChatRoomMemberNickname(wstring chatroomid, wstring wxid) ...@@ -90,16 +90,16 @@ wstring __stdcall GetChatRoomMemberNickname(wstring chatroomid, wstring wxid)
BOOL __stdcall DelChatRoomMember(wstring chatroomid, vector<wstring> wxids) BOOL __stdcall DelChatRoomMember(wstring chatroomid, vector<wstring> wxids)
{ {
vector<wchar_t *> wxid_list; vector<wchar_t *> wxid_list;
for (auto wxid : wxids) for (unsigned int i = 0; i < wxids.size(); i++)
wxid_list.push_back((wchar_t *)wxid.c_str()); wxid_list.push_back(WS2LW(wxids[i]));
return DelChatRoomMember(WS2LW(chatroomid), wxid_list.data(), wxid_list.size()); return DelChatRoomMember(WS2LW(chatroomid), wxid_list.data(), wxid_list.size());
} }
BOOL __stdcall AddChatRoomMember(wstring chatroomid, vector<wstring> wxids) BOOL __stdcall AddChatRoomMember(wstring chatroomid, vector<wstring> wxids)
{ {
vector<wchar_t *> wxid_list; vector<wchar_t *> wxid_list;
for (auto wxid : wxids) for (unsigned int i = 0; i < wxids.size(); i++)
wxid_list.push_back((wchar_t *)wxid.c_str()); wxid_list.push_back(WS2LW(wxids[i]));
return AddChatRoomMember(WS2LW(chatroomid), wxid_list.data(), wxid_list.size()); return AddChatRoomMember(WS2LW(chatroomid), wxid_list.data(), wxid_list.size());
} }
...@@ -123,9 +123,9 @@ BOOL __stdcall ChangeWeChatVersion(wstring verStr) ...@@ -123,9 +123,9 @@ BOOL __stdcall ChangeWeChatVersion(wstring verStr)
return ChangeWeChatVer(WS2LW(verStr)); return ChangeWeChatVer(WS2LW(verStr));
} }
int __stdcall BackupSQLiteDB(DWORD DbHandle, wstring BackupFile) BOOL __stdcall BackupSQLiteDB(DWORD DbHandle, wstring BackupFile)
{ {
string filepath = unicode_to_utf8(WS2LW(BackupFile)); string filepath = unicode_to_utf8(WS2LW(BackupFile));
return BackupSQLiteDB(DbHandle, filepath.c_str()); return BackupSQLiteDB(DbHandle, filepath.c_str()) == SQLITE_OK;
} }
#endif #endif
// pch.cpp: 与预编译标头对应的源文件 // pch.cpp: 与预编译标头对应的源文件
#include "pch.h" #include "pch.h"
#include <functional>
// 当使用预编译的头时,需要使用此源文件,编译才能成功。 // 当使用预编译的头时,需要使用此源文件,编译才能成功。
/* /*
* 创建一个控制台窗口 * 创建一个控制台窗口
* return:BOOL,成功返回`0`,失败返回`1` * return:BOOL,成功返回`0`,失败返回`1`
*/ */
BOOL CreateConsole(void) BOOL CreateConsole(void)
{ {
if (AllocConsole()) if (AllocConsole())
...@@ -26,9 +27,9 @@ BOOL CreateConsole(void) ...@@ -26,9 +27,9 @@ BOOL CreateConsole(void)
} }
/* /*
* 获取`WeChatWin.dll`基址 * 获取`WeChatWin.dll`基址
* return:DWORD,`WeChatWin.dll`模块基址 * return:DWORD,`WeChatWin.dll`模块基址
*/ */
DWORD GetWeChatWinBase() DWORD GetWeChatWinBase()
{ {
return (DWORD)GetModuleHandleA("WeChatWin.dll"); return (DWORD)GetModuleHandleA("WeChatWin.dll");
...@@ -52,8 +53,8 @@ BOOL FindOrCreateDirectory(const wchar_t *pszPath) ...@@ -52,8 +53,8 @@ BOOL FindOrCreateDirectory(const wchar_t *pszPath)
} }
/* /*
* 将宽字节字符串转换成`std::string` * 将宽字节字符串转换成`std::string`
*/ */
string unicode_to_gb2312(wchar_t *wchar) string unicode_to_gb2312(wchar_t *wchar)
{ {
wchar_t *wText = wchar; wchar_t *wText = wchar;
...@@ -67,8 +68,8 @@ string unicode_to_gb2312(wchar_t *wchar) ...@@ -67,8 +68,8 @@ string unicode_to_gb2312(wchar_t *wchar)
} }
/* /*
* 将UTF8编码数据转换为GBK编码 * 将UTF8编码数据转换为GBK编码
*/ */
string utf8_to_gb2312(const char *strUTF8) string utf8_to_gb2312(const char *strUTF8)
{ {
int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0); int len = MultiByteToWideChar(CP_UTF8, 0, strUTF8, -1, NULL, 0);
...@@ -87,8 +88,8 @@ string utf8_to_gb2312(const char *strUTF8) ...@@ -87,8 +88,8 @@ string utf8_to_gb2312(const char *strUTF8)
} }
/* /*
* 将UTF8编码数据转换为GBK编码 * 将UTF8编码数据转换为GBK编码
*/ */
wstring utf8_to_unicode(const char *buffer) wstring utf8_to_unicode(const char *buffer)
{ {
int c_size = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, 0, 0); int c_size = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, 0, 0);
...@@ -114,12 +115,12 @@ string unicode_to_utf8(wchar_t *wstr) ...@@ -114,12 +115,12 @@ string unicode_to_utf8(wchar_t *wstr)
} }
/* /*
* 对任意地址添加HOOK * 对任意地址添加HOOK
* dwHookAddr:HOOK的目标地址 * dwHookAddr:HOOK的目标地址
* dwJmpAddress:跳转到的地址 * dwJmpAddress:跳转到的地址
* originalRecieveCode:保存旧指令的数组 * originalRecieveCode:保存旧指令的数组
* return:void * return:void
*/ */
void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieveCode) void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieveCode)
{ {
//组装跳转数据 //组装跳转数据
...@@ -144,11 +145,11 @@ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieve ...@@ -144,11 +145,11 @@ void HookAnyAddress(DWORD dwHookAddr, LPVOID dwJmpAddress, char *originalRecieve
} }
/* /*
* 对任意地址取消HOOK * 对任意地址取消HOOK
* dwHookAddr:HOOK的目标地址 * dwHookAddr:HOOK的目标地址
* originalRecieveCode:保存旧指令的数组 * originalRecieveCode:保存旧指令的数组
* return:void * return:void
*/ */
void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode) void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode)
{ {
DWORD OldProtext = 0; DWORD OldProtext = 0;
...@@ -158,9 +159,9 @@ void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode) ...@@ -158,9 +159,9 @@ void UnHookAnyAddress(DWORD dwHookAddr, char *originalRecieveCode)
} }
/* /*
* 取消所有HOOK * 取消所有HOOK
* return:void * return:void
*/ */
void UnHookAll() void UnHookAll()
{ {
UnHookLogMsgInfo(); UnHookLogMsgInfo();
...@@ -173,12 +174,12 @@ void UnHookAll() ...@@ -173,12 +174,12 @@ void UnHookAll()
} }
/* /*
* 将单字符替换为指定的字符串 * 将单字符替换为指定的字符串
* source:源字符串 * source:源字符串
* replaced:被替换的单字符 * replaced:被替换的单字符
* replaceto:替换成的字符串 * replaceto:替换成的字符串
* return:std::wstring,替换后的字符串 * return:std::wstring,替换后的字符串
*/ */
wstring wreplace(wstring source, wchar_t replaced, wstring replaceto) wstring wreplace(wstring source, wchar_t replaced, wstring replaceto)
{ {
wstring temp = L""; wstring temp = L"";
...@@ -196,8 +197,8 @@ wstring wreplace(wstring source, wchar_t replaced, wstring replaceto) ...@@ -196,8 +197,8 @@ wstring wreplace(wstring source, wchar_t replaced, wstring replaceto)
} }
/* /*
* 获取当前时间 * 获取当前时间
*/ */
wstring GetTimeW(long long timestamp) wstring GetTimeW(long long timestamp)
{ {
wchar_t *wstr = new wchar_t[20]; wchar_t *wstr = new wchar_t[20];
...@@ -217,7 +218,6 @@ void PrintProcAddr() ...@@ -217,7 +218,6 @@ void PrintProcAddr()
{ {
CreateConsole(); CreateConsole();
printf("WeChatVersion %s\n", GetWeChatVerStr().c_str()); printf("WeChatVersion %s\n", GetWeChatVerStr().c_str());
#ifndef USE_SOCKET
printf("SendImage 0x%08X\n", (DWORD)SendImage); printf("SendImage 0x%08X\n", (DWORD)SendImage);
printf("SendText 0x%08X\n", (DWORD)SendText); printf("SendText 0x%08X\n", (DWORD)SendText);
printf("SendFile 0x%08X\n", (DWORD)SendFile); printf("SendFile 0x%08X\n", (DWORD)SendFile);
...@@ -226,8 +226,11 @@ void PrintProcAddr() ...@@ -226,8 +226,11 @@ void PrintProcAddr()
printf("GetUserInfoByWxId 0x%08X\n", (DWORD)GetUserInfoByWxId); printf("GetUserInfoByWxId 0x%08X\n", (DWORD)GetUserInfoByWxId);
printf("SendArticle 0x%08X\n", (DWORD)SendArticle); printf("SendArticle 0x%08X\n", (DWORD)SendArticle);
printf("SendCard 0x%08X\n", (DWORD)SendCard); printf("SendCard 0x%08X\n", (DWORD)SendCard);
printf("CheckFriendStatus 0x%08X\n", (DWORD)CheckFriendStatus); void(__stdcall * check_friend_status)(wchar_t *) = CheckFriendStatus;
printf("GetChatRoomMembers 0x%08X\n", (DWORD)GetChatRoomMembers); printf("CheckFriendStatus 0x%08X\n", (DWORD)check_friend_status);
BOOL(__stdcall * get_chatroom_members)
(wchar_t *) = GetChatRoomMembers;
printf("GetChatRoomMembers 0x%08X\n", (DWORD)get_chatroom_members);
printf("ExecuteSql 0x%08X\n", (DWORD)ExecuteSQL); printf("ExecuteSql 0x%08X\n", (DWORD)ExecuteSQL);
printf("BackupSQLiteDB 0x%08X\n", (DWORD)BackupSQLiteDB); printf("BackupSQLiteDB 0x%08X\n", (DWORD)BackupSQLiteDB);
printf("VerifyFriendApply 0x%08X\n", (DWORD)VerifyFriendApply); printf("VerifyFriendApply 0x%08X\n", (DWORD)VerifyFriendApply);
...@@ -235,13 +238,13 @@ void PrintProcAddr() ...@@ -235,13 +238,13 @@ void PrintProcAddr()
printf("AddFriendByWxid 0x%08X\n", (DWORD)AddFriendByWxid); printf("AddFriendByWxid 0x%08X\n", (DWORD)AddFriendByWxid);
printf("AddBrandContact 0x%08X\n", (DWORD)AddBrandContact); printf("AddBrandContact 0x%08X\n", (DWORD)AddBrandContact);
printf("SelectData 0x%08X\n", (DWORD)SelectData); printf("SelectData 0x%08X\n", (DWORD)SelectData);
printf("SearchContactByNet 0x%08X\n", (DWORD)SearchContactByNet); void *(__stdcall * search_contact_by_net)(wchar_t *) = SearchContactByNet;
printf("SearchContactByNet 0x%08X\n", (DWORD)search_contact_by_net);
printf("AddChatRoomMember 0x%08X\n", (DWORD)AddChatRoomMember); printf("AddChatRoomMember 0x%08X\n", (DWORD)AddChatRoomMember);
printf("DelChatRoomMember 0x%08X\n", (DWORD)DelChatRoomMember); printf("DelChatRoomMember 0x%08X\n", (DWORD)DelChatRoomMember);
printf("SetChatRoomAnnouncement 0x%08X\n", (DWORD)SetChatRoomAnnouncement); printf("SetChatRoomAnnouncement 0x%08X\n", (DWORD)SetChatRoomAnnouncement);
printf("SetChatRoomSelfNickname 0x%08X\n", (DWORD)SetChatRoomSelfNickname); printf("SetChatRoomSelfNickname 0x%08X\n", (DWORD)SetChatRoomSelfNickname);
printf("SetChatRoomName 0x%08X\n", (DWORD)SetChatRoomName); printf("SetChatRoomName 0x%08X\n", (DWORD)SetChatRoomName);
#endif
} }
BOOL ProcessIsWeChat() BOOL ProcessIsWeChat()
......
...@@ -92,7 +92,14 @@ static int get_http_param_int(mg_http_message *hm, json jData, string key, int m ...@@ -92,7 +92,14 @@ static int get_http_param_int(mg_http_message *hm, json jData, string key, int m
} }
case HTTP_METHOD_POST: case HTTP_METHOD_POST:
{ {
result = STOI_S((string)jData[key]); try
{
result = jData[key];
}
catch (json::exception)
{
result = STOI_S((string)jData[key]);
}
break; break;
} }
default: default:
...@@ -122,21 +129,42 @@ static vector<wstring> get_http_param_array(mg_http_message *hm, json jData, str ...@@ -122,21 +129,42 @@ static vector<wstring> get_http_param_array(mg_http_message *hm, json jData, str
return result; return result;
} }
void request_event(mg_http_message *hm) void request_event(mg_http_message *hm, string &ret)
{ {
int method = I_METHOD(getMgStrA(hm->method)); int method = I_METHOD(getMgStrA(hm->method));
// 第四个参数设置为false,不抛出异常 // 第四个参数设置为false,不抛出异常
json jData = json::parse(hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false); json jData = json::parse(hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
if (jData.is_discarded() == true && method == HTTP_METHOD_POST) if (jData.is_discarded() == true && method == HTTP_METHOD_POST)
{
json ret_data = {{"result", "ERROR"},
{"err_msg", "json string is invalid."}};
ret = ret_data.dump();
return; return;
int num = STOI_S(getMgVarA(hm, "type")); }
switch (num) int api_number = STOI_S(getMgVarA(hm, "type"));
switch (api_number)
{
case WECHAT_IS_LOGIN:
{
BOOL logined = isWxLogin();
json ret_data = {{"is_login", logined}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_GET_SELF_INFO:
{ {
wstring self_info = GetSelfInfo();
json ret_data = {{"self_info", unicode_to_utf8(WS2LW(self_info))}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_MSG_SEND_TEXT: case WECHAT_MSG_SEND_TEXT:
{ {
wstring wxid = get_http_param_str(hm, jData, "wxid", method); wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring msg = get_http_param_str(hm, jData, "msg", method); wstring msg = get_http_param_str(hm, jData, "msg", method);
SendText(wxid, msg); BOOL status = SendText(wxid, msg);
json ret_data = {{"msg", 1}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_AT: case WECHAT_MSG_SEND_AT:
...@@ -145,7 +173,9 @@ void request_event(mg_http_message *hm) ...@@ -145,7 +173,9 @@ void request_event(mg_http_message *hm)
vector<wstring> wxids = get_http_param_array(hm, jData, "wxids", method); vector<wstring> wxids = get_http_param_array(hm, jData, "wxids", method);
wstring msg = get_http_param_str(hm, jData, "msg", method); wstring msg = get_http_param_str(hm, jData, "msg", method);
int auto_nickname = get_http_param_int(hm, jData, "auto_nickname", method); int auto_nickname = get_http_param_int(hm, jData, "auto_nickname", method);
SendAtText(chatroom, wxids, msg, auto_nickname); BOOL status = SendAtText(chatroom, wxids, msg, auto_nickname);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_CARD: case WECHAT_MSG_SEND_CARD:
...@@ -153,21 +183,27 @@ void request_event(mg_http_message *hm) ...@@ -153,21 +183,27 @@ void request_event(mg_http_message *hm)
wstring receiver = get_http_param_str(hm, jData, "receiver", method); wstring receiver = get_http_param_str(hm, jData, "receiver", method);
wstring shared_wxid = get_http_param_str(hm, jData, "shared_wxid", method); wstring shared_wxid = get_http_param_str(hm, jData, "shared_wxid", method);
wstring nickname = get_http_param_str(hm, jData, "nickname", method); wstring nickname = get_http_param_str(hm, jData, "nickname", method);
SendCard(receiver, shared_wxid, nickname); BOOL status = SendCard(receiver, shared_wxid, nickname);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_IMAGE: case WECHAT_MSG_SEND_IMAGE:
{ {
wstring receiver = get_http_param_str(hm, jData, "receiver", method); wstring receiver = get_http_param_str(hm, jData, "receiver", method);
wstring img_path = get_http_param_str(hm, jData, "img_path", method); wstring img_path = get_http_param_str(hm, jData, "img_path", method);
SendImage(receiver, img_path); BOOL status = SendImage(receiver, img_path);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_FILE: case WECHAT_MSG_SEND_FILE:
{ {
wstring receiver = get_http_param_str(hm, jData, "receiver", method); wstring receiver = get_http_param_str(hm, jData, "receiver", method);
wstring file_path = get_http_param_str(hm, jData, "file_path", method); wstring file_path = get_http_param_str(hm, jData, "file_path", method);
SendFile(receiver, file_path); BOOL status = SendFile(receiver, file_path);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_ARTICLE: case WECHAT_MSG_SEND_ARTICLE:
...@@ -177,14 +213,287 @@ void request_event(mg_http_message *hm) ...@@ -177,14 +213,287 @@ void request_event(mg_http_message *hm)
wstring abstract = get_http_param_str(hm, jData, "abstract", method); wstring abstract = get_http_param_str(hm, jData, "abstract", method);
wstring url = get_http_param_str(hm, jData, "url", method); wstring url = get_http_param_str(hm, jData, "url", method);
wstring img_path = get_http_param_str(hm, jData, "img_path", method); wstring img_path = get_http_param_str(hm, jData, "img_path", method);
SendArticle(wxid, title, abstract, url, img_path); BOOL status = SendArticle(wxid, title, abstract, url, img_path);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break; break;
} }
case WECHAT_MSG_SEND_APP: case WECHAT_MSG_SEND_APP:
{ {
wstring wxid = get_http_param_str(hm, jData, "wxid", method); wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring appid = get_http_param_str(hm, jData, "appid", method); wstring appid = get_http_param_str(hm, jData, "appid", method);
SendAppMsg(wxid, appid); BOOL status = SendAppMsg(wxid, appid);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_MSG_START_HOOK:
{
int port = get_http_param_int(hm, jData, "port", method);
HookReceiveMessage(port);
break;
}
case WECHAT_MSG_STOP_HOOK:
{
UnHookReceiveMessage();
break;
}
case WECHAT_MSG_START_IMAGE_HOOK:
{
wstring savepath = get_http_param_str(hm, jData, "save_path", method);
BOOL status = HookImageMsg(savepath);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_MSG_STOP_IMAGE_HOOK:
{
UnHookImageMsg();
break;
}
case WECHAT_MSG_START_VOICE_HOOK:
{
wstring savepath = get_http_param_str(hm, jData, "save_path", method);
BOOL status = HookVoiceMsg(savepath);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_MSG_STOP_VOICE_HOOK:
{
UnHookVoiceMsg();
break;
}
case WECHAT_CONTACT_GET_LIST:
{
vector<WxFriendStruct> friend_list = GetWxContact();
json ret_data = {{"data", json::array()}, {"result", "OK"}};
for (unsigned int i = 0; i < friend_list.size() - 1; i++)
{
json f_j;
WxFriendStruct f = friend_list[i];
DWORD buffer_addr = *(DWORD *)f.wxIdAddr;
wstring wxid = buffer_addr != 0 ? wstring((wchar_t *)buffer_addr) : L"";
buffer_addr = *(DWORD *)f.wxNumberAddr;
wstring wxNumber = buffer_addr != 0 ? wstring((wchar_t *)buffer_addr) : L"";
buffer_addr = *(DWORD *)f.wxNickNameAddr;
wstring wxNickName = buffer_addr != 0 ? wstring((wchar_t *)buffer_addr) : L"";
buffer_addr = *(DWORD *)f.wxRemarkAddr;
wstring wxRemark = buffer_addr != 0 ? wstring((wchar_t *)buffer_addr) : L"";
f_j["wxid"] = unicode_to_utf8(WS2LW(wxid));
f_j["wxNumber"] = unicode_to_utf8(WS2LW(wxNumber));
f_j["wxNickName"] = unicode_to_utf8(WS2LW(wxNickName));
f_j["wxRemark"] = unicode_to_utf8(WS2LW(wxRemark));
ret_data["data"].push_back(f_j);
}
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_CHECK_STATUS:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
int status_code = CheckFriendStatus(wxid);
json ret_data = {{"status", status_code}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_DEL:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
BOOL status = DeleteUser(wxid);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_SEARCH_BY_CACHE:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring userinfo = GetUserInfoByWxId(wxid);
json ret_data = {{"userinfo", unicode_to_utf8(WS2LW(userinfo))}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_SEARCH_BY_NET:
{
wstring keyword = get_http_param_str(hm, jData, "keyword", method);
map<wstring, wstring> userinfo = SearchContactByNet(keyword);
json ret_data;
for (auto it : userinfo)
{
string key = unicode_to_utf8(WS2LW(it.first));
ret_data[key] = unicode_to_utf8(WS2LW(it.second));
}
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_ADD_BY_WXID:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring msg = get_http_param_str(hm, jData, "msg", method);
BOOL status = AddFriendByWxid(wxid, msg);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_ADD_BY_V3:
{
wstring v3 = get_http_param_str(hm, jData, "v3", method);
wstring msg = get_http_param_str(hm, jData, "msg", method);
int add_type = get_http_param_int(hm, jData, "add_type", method);
BOOL status = AddFriendByV3(v3, msg, add_type);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_ADD_BY_PUBLIC_ID:
{
wstring public_id = get_http_param_str(hm, jData, "public_id", method);
BOOL status = AddBrandContact(public_id);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_VERIFY_APPLY:
{
wstring v3 = get_http_param_str(hm, jData, "v3", method);
wstring v4 = get_http_param_str(hm, jData, "v4", method);
BOOL status = VerifyFriendApply(v3, v4);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CONTACT_EDIT_REMARK:
{
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring remark = get_http_param_str(hm, jData, "remark", method);
BOOL status = EditRemark(wxid, remark);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_GET_MEMBER_LIST:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
wstring members = GetChatRoomMembers(chatroom_id);
json ret_data = {{"members", unicode_to_utf8(WS2LW(members))}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_GET_MEMBER_NICKNAME:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
wstring wxid = get_http_param_str(hm, jData, "wxid", method);
wstring nickname = GetChatRoomMemberNickname(chatroom_id, wxid);
json ret_data = {{"nickname", unicode_to_utf8(WS2LW(nickname))}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_DEL_MEMBER:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
vector<wstring> wxids = get_http_param_array(hm, jData, "wxids", method);
BOOL status = DelChatRoomMember(chatroom_id, wxids);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_ADD_MEMBER:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
vector<wstring> wxids = get_http_param_array(hm, jData, "wxids", method);
BOOL status = AddChatRoomMember(chatroom_id, wxids);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_SET_ANNOUNCEMENT:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
wstring announcement = get_http_param_str(hm, jData, "announcement", method);
BOOL status = SetChatRoomAnnouncement(chatroom_id, announcement);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_SET_CHATROOM_NAME:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
wstring new_name = get_http_param_str(hm, jData, "chatroom_name", method);
BOOL status = SetChatRoomName(chatroom_id, new_name);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_CHATROOM_SET_SELF_NICKNAME:
{
wstring chatroom_id = get_http_param_str(hm, jData, "chatroom_id", method);
wstring nickname = get_http_param_str(hm, jData, "nickname", method);
BOOL status = SetChatRoomSelfNickname(chatroom_id, nickname);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_DATABASE_GET_HANDLES:
{
vector<void *> v_ptr = GetDbHandles();
json ret_data = {{"data", json::array()}, {"result", "OK"}};
for (unsigned int i = 0; i < v_ptr.size(); i++)
{
json db_info;
db_info["tables"] = json::array();
DbInfoStruct *db = reinterpret_cast<DbInfoStruct *>(v_ptr[i]);
db_info["handle"] = db->handle;
db_info["db_name"] = unicode_to_utf8(db->dbname);
for (auto table : db->tables)
{
json table_info = {{"name", table.name}, {"tbl_name", table.tbl_name}, {"sql", table.sql}, {"rootpage", table.rootpage}};
db_info["tables"].push_back(table_info);
}
ret_data["data"].push_back(db_info);
}
ret = ret_data.dump();
break;
}
case WECHAT_DATABASE_BACKUP:
{
DWORD db_handle = get_http_param_int(hm, jData, "db_handle", method);
wstring savepath = get_http_param_str(hm, jData, "save_path", method);
BOOL status = BackupSQLiteDB(db_handle, savepath);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_DATABASE_QUERY:
{
DWORD db_handle = get_http_param_int(hm, jData, "db_handle", method);
wstring sql = get_http_param_str(hm, jData, "sql", method);
string a_sql = unicode_to_utf8(WS2LW(sql));
// TODO: 数据库查询目前不可用
// SelectData(db_handle, a_sql.c_str(), NULL);
break;
}
case WECHAT_SET_VERSION:
{
wstring versionStr = get_http_param_str(hm, jData, "version", method);
BOOL status = ChangeWeChatVersion(versionStr);
json ret_data = {{"msg", status}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_LOG_START_HOOK:
{
#ifndef _DEBUG
CreateConsole();
#endif
HookLogMsgInfo();
break;
}
case WECHAT_LOG_STOP_HOOK:
{
#ifndef _DEBUG
FreeConsole();
#endif
UnHookLogMsgInfo();
break; break;
} }
default: default:
...@@ -197,7 +506,9 @@ void request_event(mg_http_message *hm) ...@@ -197,7 +506,9 @@ void request_event(mg_http_message *hm)
// Simply serve static files from `s_root_dir` // Simply serve static files from `s_root_dir`
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{ {
#ifdef _DEBUG
wcout.imbue(locale("chs")); wcout.imbue(locale("chs"));
#endif
switch (ev) switch (ev)
{ {
case MG_EV_HTTP_MSG: case MG_EV_HTTP_MSG:
...@@ -213,17 +524,19 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) ...@@ -213,17 +524,19 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
(int)hm->uri.len, hm->uri.ptr, (int)tmp.uri.len, tmp.uri.ptr, (int)hm->uri.len, hm->uri.ptr, (int)tmp.uri.len, tmp.uri.ptr,
(int)cl->len, cl->ptr)); (int)cl->len, cl->ptr));
#endif #endif
string ret = R"({"result":"OK"})";
if (mg_http_match_uri(hm, "/api/")) if (mg_http_match_uri(hm, "/api/"))
{ {
try try
{ {
request_event(hm); request_event(hm, ret);
mg_http_reply(c, 200, "", "{\"result\": \"OK\"}", 0, 0);
} }
catch (json::exception) catch (json::exception &e)
{ {
mg_http_reply(c, 200, "", "{\"result\": \"ERROR\"}", 0, 0); json res = {{"result", "ERROR"}, {"err_msg", e.what()}};
ret = res.dump();
} }
mg_http_reply(c, 200, "", ret.c_str(), 0, 0);
} }
else if (mg_http_match_uri(hm, "/api/f2/*")) else if (mg_http_match_uri(hm, "/api/f2/*"))
{ {
......
...@@ -20,7 +20,10 @@ typedef enum HTTP_METHODSTag ...@@ -20,7 +20,10 @@ typedef enum HTTP_METHODSTag
typedef enum WECHAT_HTTP_APISTag typedef enum WECHAT_HTTP_APISTag
{ {
WECHAT_GET_SELF_INFO = 1, // login check
WECHAT_IS_LOGIN = 0,
// self info
WECHAT_GET_SELF_INFO,
// send message // send message
WECHAT_MSG_SEND_TEXT, WECHAT_MSG_SEND_TEXT,
WECHAT_MSG_SEND_AT, WECHAT_MSG_SEND_AT,
......
...@@ -62,7 +62,7 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler): ...@@ -62,7 +62,7 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler):
_fields_ = [("pid", ctypes.wintypes.DWORD), _fields_ = [("pid", ctypes.wintypes.DWORD),
("type", ctypes.wintypes.DWORD), ("type", ctypes.wintypes.DWORD),
("isSendMsg", ctypes.wintypes.DWORD), ("isSendMsg", ctypes.wintypes.DWORD),
("msgid",ctypes.c_ulonglong), ("msgid", ctypes.c_ulonglong),
("sender", ctypes.c_wchar * 80), ("sender", ctypes.c_wchar * 80),
("wxid", ctypes.c_wchar * 80), ("wxid", ctypes.c_wchar * 80),
("message", ctypes.c_wchar * 0x1000B), ("message", ctypes.c_wchar * 0x1000B),
...@@ -102,10 +102,10 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler): ...@@ -102,10 +102,10 @@ class ReceiveMsgBaseServer(socketserver.BaseRequestHandler):
@staticmethod @staticmethod
def msg_callback(data): def msg_callback(data):
# 主线程中已经注入,此处禁止调用StartService和StopService # 主线程中已经注入,此处禁止调用StartService和StopService
msg = {'pid': data.pid, 'time': data.time, 'type': data.type, msg = {'pid': data.pid, 'time': data.time, 'type': data.type,
'isSendMsg': data.isSendMsg, 'msgid': data.msgid, 'isSendMsg': data.isSendMsg, 'msgid': data.msgid,
'wxid': data.wxid, 'wxid': data.wxid,
'sendto' if data.isSendMsg else 'from': data.sender, 'sendto' if data.isSendMsg else 'from': data.sender,
'message': data.message} 'message': data.message}
robot = comtypes.client.CreateObject("WeChatRobot.CWeChatRobot") robot = comtypes.client.CreateObject("WeChatRobot.CWeChatRobot")
event = comtypes.client.CreateObject("WeChatRobot.RobotEvent") event = comtypes.client.CreateObject("WeChatRobot.RobotEvent")
...@@ -1047,7 +1047,7 @@ def get_wechat_pid_list() -> list: ...@@ -1047,7 +1047,7 @@ def get_wechat_pid_list() -> list:
if psutil.Process(pid).name() == 'WeChat.exe': if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid) pid_list.append(pid)
except psutil.NoSuchProcess: except psutil.NoSuchProcess:
pass pass
return pid_list return pid_list
...@@ -1108,10 +1108,10 @@ def start_socket_server(port: int = 10808, ...@@ -1108,10 +1108,10 @@ def start_socket_server(port: int = 10808,
---------- ----------
port : int port : int
socket的监听端口号. socket的监听端口号.
request_handler : ReceiveMsgBaseServer request_handler : ReceiveMsgBaseServer
用于处理消息的类,需要继承自socketserver.BaseRequestHandler或ReceiveMsgBaseServer 用于处理消息的类,需要继承自socketserver.BaseRequestHandler或ReceiveMsgBaseServer
main_thread : bool main_thread : bool
是否在主线程中启动server 是否在主线程中启动server
......
import ctypes
import json
import copy
import requests
if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong):
driver = ctypes.cdll.LoadLibrary('./wxDriver64.dll')
else:
driver = ctypes.cdll.LoadLibrary('./wxDriver.dll')
new_wechat = driver.new_wechat
new_wechat.argtypes = None
new_wechat.restype = ctypes.c_bool
start_listen = driver.start_listen
start_listen.argtypes = [ctypes.c_int,ctypes.c_int]
start_listen.restype = ctypes.c_int
stop_listen = driver.stop_listen
stop_listen.argtypes = [ctypes.c_int]
stop_listen.restype = ctypes.c_int
class WECHAT_HTTP_APIS:
# login check
WECHAT_IS_LOGIN = 0 # 登录检查
# self info
WECHAT_GET_SELF_INFO = 1 # 获取个人信息
# send message
WECHAT_MSG_SEND_TEXT = 2 # 发送文本
WECHAT_MSG_SEND_AT = 3 # 发送群艾特
WECHAT_MSG_SEND_CARD = 4 # 分享好友名片
WECHAT_MSG_SEND_IMAGE = 5 # 发送图片
WECHAT_MSG_SEND_FILE = 6 # 发送文件
WECHAT_MSG_SEND_ARTICLE = 7 # 发送xml文章
WECHAT_MSG_SEND_APP = 8 # 发送小程序
# receive message
WECHAT_MSG_START_HOOK = 9 # 开启接收消息HOOK,只支持socket监听
WECHAT_MSG_STOP_HOOK = 10 # 关闭接收消息HOOK
WECHAT_MSG_START_IMAGE_HOOK = 11 # 开启图片消息HOOK
WECHAT_MSG_STOP_IMAGE_HOOK = 12 # 关闭图片消息HOOK
WECHAT_MSG_START_VOICE_HOOK = 13 # 开启语音消息HOOK
WECHAT_MSG_STOP_VOICE_HOOK = 14 # 关闭语音消息HOOK
# contact
WECHAT_CONTACT_GET_LIST = 15 # 获取联系人列表
WECHAT_CONTACT_CHECK_STATUS = 16 # 检查是否被好友删除
WECHAT_CONTACT_DEL = 17 # 删除好友
WECHAT_CONTACT_SEARCH_BY_CACHE = 18 # 从内存中获取好友信息
WECHAT_CONTACT_SEARCH_BY_NET = 19 # 网络搜索用户信息
WECHAT_CONTACT_ADD_BY_WXID = 20 # wxid加好友
WECHAT_CONTACT_ADD_BY_V3 = 21 # v3数据加好友
WECHAT_CONTACT_ADD_BY_PUBLIC_ID = 22 # 关注公众号
WECHAT_CONTACT_VERIFY_APPLY = 23 # 通过好友请求
WECHAT_CONTACT_EDIT_REMARK = 24 # 修改备注
# chatroom
WECHAT_CHATROOM_GET_MEMBER_LIST = 25 # 获取群成员列表
WECHAT_CHATROOM_GET_MEMBER_NICKNAME = 26 # 获取指定群成员昵称
WECHAT_CHATROOM_DEL_MEMBER = 27 # 删除群成员
WECHAT_CHATROOM_ADD_MEMBER = 28 # 添加群成员
WECHAT_CHATROOM_SET_ANNOUNCEMENT = 29 # 设置群公告
WECHAT_CHATROOM_SET_CHATROOM_NAME = 30 # 设置群聊名称
WECHAT_CHATROOM_SET_SELF_NICKNAME = 31 # 设置群内个人昵称
# database
WECHAT_DATABASE_GET_HANDLES = 32 # 获取数据库句柄
WECHAT_DATABASE_BACKUP = 33 # 备份数据库
# TODO: 数据库查询目前不可用
WECHAT_DATABASE_QUERY = 34 # 数据库查询
# version
WECHAT_SET_VERSION = 35 # 修改微信版本号
# log
WECHAT_LOG_START_HOOK = 36 # 开启日志信息HOOK
WECHAT_LOG_STOP_HOOK = 37 # 关闭日志信息HOOK
APIS = WECHAT_HTTP_APIS
# http api 参数模板
class WECHAT_HTTP_API_PARAM_TEMPLATES:
__HTTP_API_PARAM_TEMPLATE = {
# login check
APIS.WECHAT_IS_LOGIN: {},
# self info
APIS.WECHAT_GET_SELF_INFO: {},
# send message
APIS.WECHAT_MSG_SEND_TEXT: {"wxid": "",
"msg": ""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_MSG_SEND_AT: {"chatroom_id":"",
"wxids": "",
"msg": "",
"auto_nickname": 1},
APIS.WECHAT_MSG_SEND_CARD: {"receiver":'',
"shared_wxid":"",
"nickname":""},
APIS.WECHAT_MSG_SEND_IMAGE: {"receiver":"",
"img_path":""},
APIS.WECHAT_MSG_SEND_FILE: {"receiver":"",
"file_path":""},
APIS.WECHAT_MSG_SEND_ARTICLE: {"wxid":"",
"title":"",
"abstract":"",
"url":"",
"img_path":""},
APIS.WECHAT_MSG_SEND_APP: {"wxid":"",
"appid":""},
# receive message
APIS.WECHAT_MSG_START_HOOK: {"port": 10808},
APIS.WECHAT_MSG_STOP_HOOK: {},
APIS.WECHAT_MSG_START_IMAGE_HOOK: {"save_path":""},
APIS.WECHAT_MSG_STOP_IMAGE_HOOK: {},
APIS.WECHAT_MSG_START_VOICE_HOOK: {"save_path":""},
APIS.WECHAT_MSG_STOP_VOICE_HOOK: {},
# contact
APIS.WECHAT_CONTACT_GET_LIST: {},
APIS.WECHAT_CONTACT_CHECK_STATUS: {"wxid":""},
APIS.WECHAT_CONTACT_DEL: {"wxid":""},
APIS.WECHAT_CONTACT_SEARCH_BY_CACHE: {"wxid":""},
APIS.WECHAT_CONTACT_SEARCH_BY_NET: {"keyword":""},
APIS.WECHAT_CONTACT_ADD_BY_WXID: {"wxid":"",
"msg":""},
APIS.WECHAT_CONTACT_ADD_BY_V3: {"v3":"",
"msg":"",
"add_type": 0x6},
APIS.WECHAT_CONTACT_ADD_BY_PUBLIC_ID: {"public_id":""},
APIS.WECHAT_CONTACT_VERIFY_APPLY: {"v3":"",
"v4":""},
APIS.WECHAT_CONTACT_EDIT_REMARK: {"wxid":"",
"remark":""},
# chatroom
APIS.WECHAT_CHATROOM_GET_MEMBER_LIST: {"chatroom_id":""},
APIS.WECHAT_CHATROOM_GET_MEMBER_NICKNAME: {"chatroom_id":"",
"wxid":""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_CHATROOM_DEL_MEMBER: {"chatroom_id":"",
"wxids":""},
# wxids需要以`,`分隔,例如`wxid1,wxid2,wxid3`
APIS.WECHAT_CHATROOM_ADD_MEMBER: {"chatroom_id":"",
"wxids":""},
APIS.WECHAT_CHATROOM_SET_ANNOUNCEMENT: {"chatroom_id":"",
"announcement":""},
APIS.WECHAT_CHATROOM_SET_CHATROOM_NAME: {"chatroom_id":"",
"chatroom_name":""},
APIS.WECHAT_CHATROOM_SET_SELF_NICKNAME: {"chatroom_id":"",
"nickname":""},
# database
APIS.WECHAT_DATABASE_GET_HANDLES: {},
APIS.WECHAT_DATABASE_BACKUP: {"db_handle":0,
"save_path":""},
APIS.WECHAT_DATABASE_QUERY: {"db_handle":0,
"sql":""},
# version
APIS.WECHAT_SET_VERSION: {"version": "3.7.0.30"},
# log
APIS.WECHAT_LOG_START_HOOK: {},
APIS.WECHAT_LOG_STOP_HOOK: {},
}
def get_http_template(self, api_number):
try:
return copy.deepcopy(self.__HTTP_API_PARAM_TEMPLATE[api_number])
except KeyError:
raise ValueError("There is no interface numbered %s." % api_number)
get_http_template = WECHAT_HTTP_API_PARAM_TEMPLATES().get_http_template
def post_wechat_http_api(api,port,data = {}):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.post(url = url,data = json.dumps(data))
return resp.json()
def get_wechat_http_api(api,port,data = {}):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.get(url = url,params = data)
return resp.json()
def get_wechat_pid_list() -> list:
import psutil
pid_list = []
process_list = psutil.pids()
for pid in process_list:
try:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
except psutil.NoSuchProcess:
pass
return pid_list
def test():
test_port = 8000
pids = get_wechat_pid_list()
if len(pids) == 0:
pids.append(new_wechat())
start_listen(pids[0],test_port)
if post_wechat_http_api(APIS.WECHAT_IS_LOGIN,port = test_port)["is_login"] == 1:
print(post_wechat_http_api(APIS.WECHAT_GET_SELF_INFO,port = test_port))
data = {"wxid":"filehelper","msg":"hello http"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_TEXT,data = data,port = test_port)
data = {"receiver":'filehelper',"shared_wxid":"filehelper","nickname":"文件传输助手"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_CARD,data = data,port = test_port)
data = {"receiver":'filehelper',"img_path":r"D:\VS2019C++\MyWeChatRobot\test\测试图片.png"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_IMAGE,data = data,port = test_port)
data = {"receiver":'filehelper',"file_path":r"D:\VS2019C++\MyWeChatRobot\test\测试文件"}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_FILE,data = data,port = test_port)
data = {"wxid":'filehelper',
"title":"百度",
"abstract":"百度一下,你就知道",
"url":"https://www.baidu.com/",
"img_path":""}
post_wechat_http_api(APIS.WECHAT_MSG_SEND_ARTICLE,data = data,port = test_port)
print(post_wechat_http_api(APIS.WECHAT_CONTACT_GET_LIST,port = test_port))
data = {"wxid":"filehelper"}
print(post_wechat_http_api(APIS.WECHAT_CONTACT_CHECK_STATUS,data = data,port = test_port))
stop_listen(pids[0])
if __name__ == '__main__':
test()
import ctypes
import json
import requests
PORT = 8000
def call_http_api(api,data,port = PORT):
url = "http://127.0.0.1:{}/api/?type={}".format(port,api)
resp = requests.post(url = url,data = json.dumps(data))
print("POST",resp.json())
def get_wechat_pid_list() -> list:
import psutil
pid_list = []
process_list = psutil.pids()
for pid in process_list:
try:
if psutil.Process(pid).name() == 'WeChat.exe':
pid_list.append(pid)
except psutil.NoSuchProcess:
pass
return pid_list
def test():
data = {"wxid":"filehelper","msg":"hello http"}
call_http_api(2,data)
data = {"receiver":'filehelper',"shared_wxid":"filehelper","nickname":"文件传输助手"}
call_http_api(4,data)
data = {"receiver":'filehelper',"img_path":r"D:\C++\ComWeChatRobot\test\测试图片.png"}
call_http_api(5,data)
data = {"receiver":'filehelper',"file_path":r"D:\C++\ComWeChatRobot\test\测试文件"}
call_http_api(6,data)
data = {"wxid":'filehelper',
"title":"百度",
"abstract":"百度一下,你就知道",
"url":"https://www.baidu.com/",
"img_path":""}
call_http_api(7,data)
wx = ctypes.cdll.LoadLibrary('./wxDriver64.dll')
pids = get_wechat_pid_list()
if len(pids) == 0:
pids.append(wx.new_wechat())
wx.start_listen(pids[0],PORT)
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册