diff --git a/App/App.cpp b/App/App.cpp index c27655f..cc815aa 100644 --- a/App/App.cpp +++ b/App/App.cpp @@ -71,7 +71,7 @@ int main() Sleep(1000); // 等待1秒 wprintf(L"Message: 接收通知中......\n"); - WxSetTextMsgCb(onTextMsg); + WxEnableRecvMsg(onTextMsg); Sleep(1000); // 等待1秒 // 测试发送消息 diff --git a/App/App.py b/App/App.py index 7c1634d..bf28580 100644 --- a/App/App.py +++ b/App/App.py @@ -7,11 +7,9 @@ import wcferry as sdk def main(): print(dir(sdk)) # 查看SDK支持的方法和属性 - help(sdk.WxSetTextMsgCb) # 查看某方法的情况 + help(sdk.WxEnableRecvMsg) # 查看某方法的情况 help(sdk.WxMessage) # 查看消息结构 help(sdk.WxContact) # 查看通讯录结构 - WxMsgTypes = sdk.WxGetMsgTypes() # 获取消息类型 - print(WxMsgTypes) # 查看消息类型 # 初始化SDK,如果成功,返回0;否则失败 status = sdk.WxInitSDK() @@ -20,6 +18,8 @@ def main(): exit(-1) print("初始化成功") + WxMsgTypes = sdk.WxGetMsgTypes() # 获取消息类型 + print(WxMsgTypes) # 查看消息类型 time.sleep(2) print("打印通讯录......") @@ -61,7 +61,7 @@ def main(): return 0 print("Message: 接收通知中......") - sdk.WxSetTextMsgCb(OnTextMsg) # 设置回调,接收消息 + sdk.WxEnableRecvMsg(OnTextMsg) # 设置回调,接收消息 while True: time.sleep(1) diff --git a/Rpc/rpc.idl b/Rpc/rpc.idl index cafe7cf..8c07bb4 100644 --- a/Rpc/rpc.idl +++ b/Rpc/rpc.idl @@ -56,5 +56,6 @@ interface ISpy int GetDbTables([ in, string ] const wchar_t *db, [out] int *pNum, [ out, size_is(, *pNum) ] PPRpcTables *tbls); void EnableReceiveMsg(); + void DisableReceiveMsg(); [callback] int ReceiveMsg([in] RpcMessage_t rpcMsg); }; diff --git a/SDK/rpc_client.cpp b/SDK/rpc_client.cpp index ea3b1f2..2737df8 100644 --- a/SDK/rpc_client.cpp +++ b/SDK/rpc_client.cpp @@ -33,8 +33,6 @@ RPC_STATUS RpcDisconnectServer() RPC_STATUS status; // Free the memory allocated by a string status = RpcStringFree(&pszStringBinding); - if (status) - return status; // Releases binding handle resources and disconnects from the server status = RpcBindingFree(&hSpyBinding); @@ -42,7 +40,7 @@ RPC_STATUS RpcDisconnectServer() return status; } -unsigned int __stdcall RpcSetTextMsgCb(void *p) +int RpcEnableReceiveMsg() { unsigned long ulCode = 0; RpcTryExcept @@ -53,7 +51,25 @@ unsigned int __stdcall RpcSetTextMsgCb(void *p) RpcExcept(1) { ulCode = RpcExceptionCode(); - printf("rpcWxSetTextMsgCb exception 0x%lx = %ld\n", ulCode, ulCode); + printf("RpcEnableReceiveMsg exception 0x%lx = %ld\n", ulCode, ulCode); + } + RpcEndExcept; + + return 0; +} + +int RpcDisableReceiveMsg() +{ + unsigned long ulCode = 0; + RpcTryExcept + { + // UnHook Message receiving + client_DisableReceiveMsg(); + } + RpcExcept(1) + { + ulCode = RpcExceptionCode(); + printf("RpcDisableReceiveMsg exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept; @@ -72,7 +88,8 @@ int RpcIsLogin() RpcExcept(1) { ulCode = RpcExceptionCode(); - printf("rpcIsLogin exception 0x%lx = %ld\n", ulCode, ulCode); + printf("RpcIsLogin exception 0x%lx = %ld\n", ulCode, ulCode); + return -1; } RpcEndExcept; @@ -88,7 +105,7 @@ int RpcSendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *m RpcExcept(1) { ulCode = RpcExceptionCode(); - printf("rpcWxSendTextMsg exception 0x%lx = %ld\n", ulCode, ulCode); + printf("RpcSendTextMsg exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept; @@ -104,7 +121,7 @@ int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path) RpcExcept(1) { ulCode = RpcExceptionCode(); - printf("rpcWxSendImageMsg exception 0x%lx = %ld\n", ulCode, ulCode); + printf("RpcSendImageMsg exception 0x%lx = %ld\n", ulCode, ulCode); } RpcEndExcept; diff --git a/SDK/rpc_client.h b/SDK/rpc_client.h index 0f3b5f8..4d41ed0 100644 --- a/SDK/rpc_client.h +++ b/SDK/rpc_client.h @@ -5,7 +5,8 @@ RPC_STATUS RpcConnectServer(); RPC_STATUS RpcDisconnectServer(); -unsigned int __stdcall RpcSetTextMsgCb(void *p); +int RpcEnableReceiveMsg(); +int RpcDisableReceiveMsg(); int RpcIsLogin(); int RpcSendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *msg); int RpcSendImageMsg(const wchar_t *wxid, const wchar_t *path); diff --git a/SDK/sdk.cpp b/SDK/sdk.cpp index 95b7f08..9e99d5c 100644 --- a/SDK/sdk.cpp +++ b/SDK/sdk.cpp @@ -19,7 +19,7 @@ static WCHAR SpyDllPath[MAX_PATH] = { 0 }; int WxInitSDK() { - DWORD status = 0; + int status = 0; unsigned long ulCode = 0; GetModuleFileName(GetModuleHandle(WECHATSDKDLL), SpyDllPath, MAX_PATH); @@ -34,35 +34,49 @@ int WxInitSDK() if (status != 0) { return status; } + Sleep(2000); // 等待微信打开 if (InjectDll(WeChatPID, SpyDllPath)) { return -1; } - RpcConnectServer(); - - while (!RpcIsLogin()) { - Sleep(1000); + Sleep(1000); // 等待SPY就绪 + status = RpcConnectServer(); + if (status != 0) { + printf("RpcConnectServer: %d\n", status); + return -1; } + do { + status = RpcIsLogin(); + if (status == -1) { + return status; + } + else if (status == 1) { + break; + } + Sleep(1000); + } while (1); + return ERROR_SUCCESS; } int WxDestroySDK() { + WxDisableRecvMsg(); RpcDisconnectServer(); - EjectDll(WeChatPID, SpyDllPath); + // 关闭 RPC,但不卸载 DLL,方便下次使用。 + //EjectDll(WeChatPID, SpyDllPath); return ERROR_SUCCESS; } -int WxSetTextMsgCb(const std::function &onMsg) +int WxEnableRecvMsg(const std::function &onMsg) { if (onMsg) { HANDLE msgThread; g_cbReceiveTextMsg = onMsg; - - msgThread = (HANDLE)_beginthreadex(NULL, 0, RpcSetTextMsgCb, NULL, 0, NULL); + msgThread = (HANDLE)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RpcEnableReceiveMsg, NULL, 0, NULL); if (msgThread == NULL) { printf("Failed to create innerWxRecvTextMsg.\n"); return -2; @@ -76,6 +90,12 @@ int WxSetTextMsgCb(const std::function &onMsg) return -1; } +int WxDisableRecvMsg() +{ + RpcDisableReceiveMsg(); + return -1; +} + int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg) { return RpcSendTextMsg(wxid.c_str(), at_wxid.c_str(), msg.c_str()); diff --git a/SDK/sdk.def b/SDK/sdk.def index 3456ef4..8678b85 100644 --- a/SDK/sdk.def +++ b/SDK/sdk.def @@ -1,7 +1,8 @@ EXPORTS WxInitSDK WxDestroySDK - WxSetTextMsgCb + WxEnableRecvMsg + WxDisableRecvMsg WxSendTextMsg WxGetMsgTypes WxSendImageMsg diff --git a/SDK/sdk.h b/SDK/sdk.h index 7f798ba..f8274d6 100644 --- a/SDK/sdk.h +++ b/SDK/sdk.h @@ -39,7 +39,8 @@ typedef vector DbTableVector_t; int WxInitSDK(); int WxDestroySDK(); -int WxSetTextMsgCb(const std::function &onMsg); +int WxEnableRecvMsg(const std::function &onMsg); +int WxDisableRecvMsg(); int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg); int WxSendImageMsg(wstring wxid, wstring path); ContactMap_t WxGetContacts(); diff --git a/SDKpy/sdkpy.cpp b/SDKpy/sdkpy.cpp index d8b2fac..f03c114 100644 --- a/SDKpy/sdkpy.cpp +++ b/SDKpy/sdkpy.cpp @@ -6,7 +6,7 @@ namespace py = pybind11; -int WxSetTextMsgCbPy(const std::function &onMsg) { return WxSetTextMsgCb(onMsg); } +int WxEnableRecvMsgPy(const std::function &onMsg) { return WxEnableRecvMsg(onMsg); } PYBIND11_MODULE(wcferry, m) { @@ -32,7 +32,8 @@ PYBIND11_MODULE(wcferry, m) .def_readonly("wxGender", &WxContact::wxGender); m.def("WxInitSDK", &WxInitSDK); - m.def("WxSetTextMsgCb", &WxSetTextMsgCbPy); + m.def("WxEnableRecvMsg", &WxEnableRecvMsgPy); + m.def("WxDisableRecvMsg", &WxDisableRecvMsg); m.def("WxSendTextMsg", &WxSendTextMsg); m.def("WxSendImageMsg", &WxSendImageMsg); m.def("WxGetContacts", &WxGetContacts, py::return_value_policy::reference); diff --git a/Spy/dllmain.cpp b/Spy/dllmain.cpp index b1fce62..1d1cf21 100644 --- a/Spy/dllmain.cpp +++ b/Spy/dllmain.cpp @@ -7,7 +7,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { //MessageBox(NULL, L"InitSpy", L"DllMain", 0); - InitSpy(hModule); + InitSpy(); break; } case DLL_THREAD_ATTACH: @@ -15,7 +15,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv break; case DLL_PROCESS_DETACH: { //MessageBox(NULL, L"DestroySpy", L"DllMain", 0); - DestroySpy(); + DestroySpy(hModule); break; } } diff --git a/Spy/rpc_server.cpp b/Spy/rpc_server.cpp index 78bc09b..063b6d5 100644 --- a/Spy/rpc_server.cpp +++ b/Spy/rpc_server.cpp @@ -28,6 +28,7 @@ void server_EnableReceiveMsg() { unsigned long ulCode = 0; ListenMessage(); + listenMsgFlag = true; RpcTryExcept { // 调用客户端的回调函数 @@ -49,6 +50,12 @@ void server_EnableReceiveMsg() RpcEndExcept } +void server_DisableReceiveMsg() +{ + UnListenMessage(); + listenMsgFlag = false; +} + int server_SendTextMsg(const wchar_t *wxid, const wchar_t *at_wxid, const wchar_t *msg) { SendTextMessage(wxid, at_wxid, msg); @@ -177,7 +184,7 @@ RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void * /*pBin return RPC_S_OK; // Always allow anyone. } -int RpcStartServer(HMODULE hModule) +int RpcStartServer() { RPC_STATUS status; // Uses the protocol combined with the endpoint for receiving @@ -201,7 +208,6 @@ int RpcStartServer(HMODULE hModule) (unsigned)-1, // Infinite max size of incoming data blocks. SecurityCallback); // Naive security callback. - listenMsgFlag = true; while (g_rpcKeepAlive) { Sleep(1000); // 休眠,释放CPU } @@ -209,17 +215,18 @@ int RpcStartServer(HMODULE hModule) return 0; } -int RpcStopServer(void) +int RpcStopServer() { RPC_STATUS status; UnListenMessage(); listenMsgFlag = false; + g_rpcKeepAlive = false; status = RpcMgmtStopServerListening(NULL); if (status) return status; - status = RpcServerUnregisterIf(NULL, NULL, FALSE); + status = RpcServerUnregisterIf(server_ISpy_v1_0_s_ifspec, NULL, 0); return status; } diff --git a/Spy/rpc_server.h b/Spy/rpc_server.h index c0a24aa..cc1e9bb 100644 --- a/Spy/rpc_server.h +++ b/Spy/rpc_server.h @@ -1,5 +1,4 @@ #pragma once -#include "framework.h" -int RpcStartServer(HMODULE hModule); -int RpcStopServer(void); +int RpcStartServer(); +int RpcStopServer(); diff --git a/Spy/spy.cpp b/Spy/spy.cpp index a331cf2..5c3eff1 100644 --- a/Spy/spy.cpp +++ b/Spy/spy.cpp @@ -8,37 +8,37 @@ BOOL g_rpcKeepAlive = false; WxCalls_t g_WxCalls = { 0 }; DWORD g_WeChatWinDllAddr = 0; -void InitSpy(HMODULE hModule) +void InitSpy() { wchar_t version[16] = { 0 }; - g_WeChatWinDllAddr = (DWORD)LoadLibrary(L"WeChatWin.dll"); //获取wechatWin模块地址 + g_WeChatWinDllAddr = (DWORD)GetModuleHandle(L"WeChatWin.dll"); //获取wechatWin模块地址 if (g_WeChatWinDllAddr == 0) { MessageBox(NULL, L"获取wechatWin.dll模块地址失败", L"错误", 0); - FreeLibraryAndExitThread(hModule, 0); + return; } if (!GetWeChatVersion(version)) { //获取微信版本 MessageBox(NULL, L"获取微信版本失败", L"错误", 0); - FreeLibraryAndExitThread(hModule, 0); + return; } if (LoadCalls(version, &g_WxCalls) != 0) { //加载微信版本对应的Call地址 MessageBox(NULL, L"不支持当前版本", L"错误", 0); - FreeLibraryAndExitThread(hModule, 0); + return; } g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - HANDLE rpcThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RpcStartServer, hModule, NULL, 0); + HANDLE rpcThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RpcStartServer, NULL, NULL, 0); if (rpcThread != 0) { CloseHandle(rpcThread); } } -void DestroySpy() +void DestroySpy(HMODULE hModule) { RpcStopServer(); - FreeLibrary((HMODULE)g_WeChatWinDllAddr); + FreeLibraryAndExitThread(hModule, 0); } int IsLogin(void) { return (int)GET_DWORD(g_WeChatWinDllAddr + g_WxCalls.login); } diff --git a/Spy/spy.h b/Spy/spy.h index 59d669e..09ae7ef 100644 --- a/Spy/spy.h +++ b/Spy/spy.h @@ -2,5 +2,5 @@ #include "framework.h" -void InitSpy(HMODULE hModule); -void DestroySpy(); +void InitSpy(); +void DestroySpy(HMODULE hModule);