diff --git a/App/App.cpp b/App/App.cpp index c0ae879..bfef993 100644 --- a/App/App.cpp +++ b/App/App.cpp @@ -26,10 +26,11 @@ int onTextMsg(WxMessage_t msg) int main() { - DWORD status = 0; - wstring wxid = L"filehelper"; // 微信ID - wstring at_wxid = L""; - wstring content = L"这里填写消息内容"; + DWORD status = 0; + wstring wxid = L"filehelper"; // 微信ID + wstring at_wxid = L""; + wstring content = L"这里填写消息内容"; + wstring img_path = L"test.jpg"; //_setmode(_fileno(stdout), _O_WTEXT); // 没有这个wcout遇到一些字符会导致console卡死,用了会导致脱离控制台 _wsetlocale(LC_ALL, L"chs"); // 这是个大坑,不设置中文直接不见了。。。 @@ -51,6 +52,8 @@ int main() // 测试消息发送 WxSendTextMsg(wxid, at_wxid, content); + // 发送照片 + WxSendImageMsg(wxid, img_path); while (1) { Sleep(10000); // 休眠,释放CPU diff --git a/App/App.py b/App/App.py index 0fa695d..b8da948 100644 --- a/App/App.py +++ b/App/App.py @@ -24,6 +24,10 @@ def main(): print("发送文本消息......") sdk.WxSendTextMsg("filehelper", "", "message from WeChatFerry...") + time.sleep(2) + print("发送图片消息......") + sdk.WxSendImageMsg("filehelper", "test.jpg") + # 接收消息。先定义消息处理回调 def OnTextMsg(msg: sdk.WxMessage): if msg.self == 1: # 忽略自己发的消息 diff --git a/App/App.vcxproj b/App/App.vcxproj index 49b955a..21802c7 100644 --- a/App/App.vcxproj +++ b/App/App.vcxproj @@ -123,7 +123,8 @@ xcopy /y $(OutDir)Spy.dll $(OutDir)wx\ xcopy /y $(OutDir)SDK.dll $(OutDir)wx\ xcopy /y $(OutDir)wcferry.pyd $(OutDir)wx\ xcopy /y $(OutDir)App.exe $(OutDir)wx\ -xcopy /y $(SolutionDir)App\App.py $(OutDir)wx\ +xcopy /y $(SolutionDir)App\App.py $(OutDir)wx\ +xcopy /y $(SolutionDir)App\test.jpg $(OutDir)wx\ Copy output diff --git a/App/test.jpg b/App/test.jpg new file mode 100644 index 0000000..14aa7a7 Binary files /dev/null and b/App/test.jpg differ diff --git a/Rpc/rpc.idl b/Rpc/rpc.idl index d18fb71..50d0893 100644 --- a/Rpc/rpc.idl +++ b/Rpc/rpc.idl @@ -9,7 +9,8 @@ interface ISpy import "rpc_types.h"; int IsLogin(); - int SendTextMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *at_wxid, [ in, string ] const wchar_t *msg); + int SendTextMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *at_wxid, [ in, string ] const wchar_t *msg); + int SendImageMsg([ in, string ] const wchar_t *wxid, [ in, string ] const wchar_t *path); void EnableReceiveMsg(); [callback] int ReceiveMsg([ in ] RpcMessage_t *msg); diff --git a/SDK/sdk.cpp b/SDK/sdk.cpp index b21f61f..337a77f 100644 --- a/SDK/sdk.cpp +++ b/SDK/sdk.cpp @@ -225,6 +225,24 @@ int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg) return innerWxSendTextMsg(wxid.c_str(), at_wxid.c_str(), msg.c_str()); } +static int innerWxSendImageMsg(const wchar_t *wxid, const wchar_t *path) +{ + int ret = 0; + unsigned long ulCode = 0; + + RpcTryExcept { ret = client_SendImageMsg(wxid, path); } + RpcExcept(1) + { + ulCode = RpcExceptionCode(); + printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode); + } + RpcEndExcept + + return ret; +} + +int WxSendImageMsg(wstring wxid, wstring path) { return innerWxSendImageMsg(wxid.c_str(), path.c_str()); } + static int getAddrHandle(DWORD *addr, HANDLE *handle) { DWORD processID = 0; diff --git a/SDK/sdk.def b/SDK/sdk.def index c73f152..a9fa19b 100644 --- a/SDK/sdk.def +++ b/SDK/sdk.def @@ -3,3 +3,4 @@ EXPORTS WxSetTextMsgCb WxSendTextMsg WxGetMsgTypes + WxSendImageMsg diff --git a/SDK/sdk.h b/SDK/sdk.h index 268485f..7e03e90 100644 --- a/SDK/sdk.h +++ b/SDK/sdk.h @@ -22,4 +22,5 @@ typedef map MsgTypesMap_t; int WxInitSDK(); int WxSetTextMsgCb(const std::function &onMsg); int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg); +int WxSendImageMsg(wstring wxid, wstring path); MsgTypesMap_t WxGetMsgTypes(); diff --git a/SDKpy/sdkpy.cpp b/SDKpy/sdkpy.cpp index 598697d..2e55bf9 100644 --- a/SDKpy/sdkpy.cpp +++ b/SDKpy/sdkpy.cpp @@ -25,6 +25,7 @@ PYBIND11_MODULE(wcferry, m) m.def("WxInitSDK", &WxInitSDK); m.def("WxSetTextMsgCb", &WxSetTextMsgCbPy); m.def("WxSendTextMsg", &WxSendTextMsg); + m.def("WxSendImageMsg", &WxSendImageMsg); m.def("WxGetMsgTypes", &WxGetMsgTypes, py::return_value_policy::reference); #ifdef VERSION_INFO diff --git a/Spy/load_calls.cpp b/Spy/load_calls.cpp index b07594e..2ca986a 100644 --- a/Spy/load_calls.cpp +++ b/Spy/load_calls.cpp @@ -4,14 +4,17 @@ #include "load_calls.h" #define SUPPORT_VERSION L"3.3.0.115" -WxCalls_t wxCalls = { 0x1DDF60C, // Login Status - { 0x1DDF4BC, 0x1DDF534, 0x1DDF568 }, // User Info: wxid, nickname, mobile - 0x3E3B80, // Send Message - /* Receive Message: - Hook, call, type, self, id, msgXml, roomId, wxId, content */ - { 0x3C0D70, 0x3C0FA0, 0x38, 0x3C, 0x184, 0x1D8, 0x48, 0x170, 0x70 } }; +WxCalls_t wxCalls = { + 0x1DDF60C, // Login Status + { 0x1DDF4BC, 0x1DDF534, 0x1DDF568 }, // User Info: wxid, nickname, mobile + 0x3E3B80, // Send Message + /* Receive Message: + Hook, call, type, self, id, msgXml, roomId, wxId, content */ + { 0x3C0D70, 0x3C0FA0, 0x38, 0x3C, 0x184, 0x1D8, 0x48, 0x170, 0x70 }, + { 0x5CCB50, 0x6F5C0, 0x3E3490 } // Send Image Message +}; -int LoadCalls(const wchar_t *version, WxCalls_t *calls) +int LoadCalls(const wchar_t* version, WxCalls_t* calls) { if (wcscmp(version, SUPPORT_VERSION) != 0) { return -1; diff --git a/Spy/rpc_server.cpp b/Spy/rpc_server.cpp index 3ba12e4..932a155 100644 --- a/Spy/rpc_server.cpp +++ b/Spy/rpc_server.cpp @@ -46,6 +46,13 @@ int server_SendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_ return 0; } +int server_SendImageMsg(const wchar_t *wxid, const wchar_t *path) +{ + SendImageMessage(wxid, path); + + return 0; +} + RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBindingHandle*/) { return RPC_S_OK; // Always allow anyone. diff --git a/Spy/send_msg.cpp b/Spy/send_msg.cpp index fbbc6ee..82d0437 100644 --- a/Spy/send_msg.cpp +++ b/Spy/send_msg.cpp @@ -47,3 +47,48 @@ void SendTextMessage(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t add esp, 0xC } } + +void SendImageMessage(const wchar_t *wxid, const wchar_t *path) +{ + if (g_WeChatWinDllAddr == 0) { + return; + } + char buf1[0x20] = { 0 }; + char buf2[0x378] = { 0 }; + TextStruct_t imgWxid = { 0 }; + TextStruct_t imgPath = { 0 }; + + wstring wsWxid = wxid; + wstring wsPath = path; + + imgWxid.text = (wchar_t *)wsWxid.c_str(); + imgWxid.size = wsWxid.size(); + imgWxid.capacity = wsWxid.capacity(); + + imgPath.text = (wchar_t *)wsPath.c_str(); + imgPath.size = wsPath.size(); + imgPath.capacity = wsPath.capacity(); + + // 发送图片Call地址 = 微信基址 + 偏移 + DWORD sendCall1 = g_WeChatWinDllAddr + g_WxCalls.sendImg.call1; + DWORD sendCall2 = g_WeChatWinDllAddr + g_WxCalls.sendImg.call2; + DWORD sendCall3 = g_WeChatWinDllAddr + g_WxCalls.sendImg.call3; + + __asm { + pushad + sub esp, 0x14 + lea eax, buf1 + mov ecx, esp + push eax + call sendCall1 + lea ebx, imgPath + push ebx + lea eax, imgWxid + push eax + lea eax, buf2 + push eax + call sendCall2 + mov ecx, eax + call sendCall3 + } +} diff --git a/Spy/send_msg.h b/Spy/send_msg.h index 408c13e..9853676 100644 --- a/Spy/send_msg.h +++ b/Spy/send_msg.h @@ -1,3 +1,4 @@ #pragma once -void SendTextMessage(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *msg); +void SendTextMessage(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *msg); +void SendImageMessage(const wchar_t *wxid, const wchar_t *path); diff --git a/Spy/spy_types.h b/Spy/spy_types.h index a103470..3b2ee29 100644 --- a/Spy/spy_types.h +++ b/Spy/spy_types.h @@ -34,7 +34,8 @@ typedef struct WxCalls { UserInfoCall_t ui; // 用户信息 DWORD sendTextMsg; // 发送消息 RecvMsg_t recvMsg; // 接收消息 -} WxCalls_t; + SendImg_t sendImg; // 发送图片 +} WxCalls_t; typedef struct TextStruct { wchar_t *text;