From 51985777f7e0affbc184b1a9e3d5e4b9d048c207 Mon Sep 17 00:00:00 2001 From: Changhua Date: Sat, 28 Aug 2021 08:33:24 +0800 Subject: [PATCH] Impl GetContacts --- App/App.cpp | 17 +++++++++++- App/App.py | 18 ++++++++++--- SDK/sdk.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ SDK/sdk.def | 1 + SDK/sdk.h | 12 +++++++++ SDKpy/sdkpy.cpp | 10 +++++++ 6 files changed, 123 insertions(+), 4 deletions(-) diff --git a/App/App.cpp b/App/App.cpp index bfef993..91e12c3 100644 --- a/App/App.cpp +++ b/App/App.cpp @@ -10,6 +10,16 @@ 等效为在属性,链接,输入中添加该依赖 */ +void printContacts(ContactMap_t contacts) +{ + wcout << L"contacts number: " << contacts.size() << endl; + for (auto it = contacts.begin(); it != contacts.end(); ++it) { + wcout << it->second.wxId << L"\t" << it->second.wxCode << L"\t" << it->second.wxName << L"\t" + << it->second.wxGender << L"\t" << it->second.wxCountry << L"\t" << it->second.wxProvince << L"\t" + << it->second.wxCity << endl; + } +} + int onTextMsg(WxMessage_t msg) { try { @@ -32,7 +42,7 @@ int main() wstring content = L"这里填写消息内容"; wstring img_path = L"test.jpg"; - //_setmode(_fileno(stdout), _O_WTEXT); // 没有这个wcout遇到一些字符会导致console卡死,用了会导致脱离控制台 + _setmode(_fileno(stdout), _O_WTEXT); // 没有这个wcout遇到一些字符会导致console卡死,用了会导致脱离控制台 _wsetlocale(LC_ALL, L"chs"); // 这是个大坑,不设置中文直接不见了。。。 // 获取消息类型 @@ -55,6 +65,11 @@ int main() // 发送照片 WxSendImageMsg(wxid, img_path); + Sleep(10000); // 等待10秒 + // 测试联系人获取 + auto mContact = WxGetContacts(); + printContacts(mContact); + while (1) { Sleep(10000); // 休眠,释放CPU } diff --git a/App/App.py b/App/App.py index b8da948..7c1634d 100644 --- a/App/App.py +++ b/App/App.py @@ -9,6 +9,7 @@ def main(): print(dir(sdk)) # 查看SDK支持的方法和属性 help(sdk.WxSetTextMsgCb) # 查看某方法的情况 help(sdk.WxMessage) # 查看消息结构 + help(sdk.WxContact) # 查看通讯录结构 WxMsgTypes = sdk.WxGetMsgTypes() # 获取消息类型 print(WxMsgTypes) # 查看消息类型 @@ -20,6 +21,12 @@ def main(): print("初始化成功") + time.sleep(2) + print("打印通讯录......") + contacts = sdk.WxGetContacts() + for k, v in contacts.items(): + print(k, v.wxCode, v.wxName, v.wxCountry, v.wxProvince, v.wxCity, v.wxGender) + time.sleep(2) print("发送文本消息......") sdk.WxSendTextMsg("filehelper", "", "message from WeChatFerry...") @@ -30,15 +37,20 @@ def main(): # 接收消息。先定义消息处理回调 def OnTextMsg(msg: sdk.WxMessage): + s = "收到" if msg.self == 1: # 忽略自己发的消息 + s += f"来自自己的消息" + print(f"\n{s}") + return 0 - s = "" msgType = WxMsgTypes.get(msg.type, '未知消息类型') + nickName = contacts.get(msg.wxId, {'wxName': 'NoBody'}).wxName if msg.source == 0: - s += f"收到来自好友[{msg.wxId}]的{msgType}消息:" + s += f"来自好友[{nickName}]的{msgType}消息:" else: - s += f"收到来自群[{msg.roomId}]的[{msg.wxId}]的{msgType}消息:" + groupName = contacts.get(msg.roomId, {'wxName': 'Unknown'}).wxName + s += f"来自群[{groupName}]的[{nickName}]的{msgType}消息:" s += f"\r\n{msg.content}" if msg.type != 0x01: diff --git a/SDK/sdk.cpp b/SDK/sdk.cpp index 337a77f..6a48509 100644 --- a/SDK/sdk.cpp +++ b/SDK/sdk.cpp @@ -297,4 +297,73 @@ static int getAddrHandle(DWORD *addr, HANDLE *handle) return 0; } +ContactMap_t WxGetContacts() +{ + ContactMap_t mContact; + DWORD moduleBaseAddress; + HANDLE hProcess; + + if (getAddrHandle(&moduleBaseAddress, &hProcess) != 0) { + return mContact; + } + + DWORD Address1 = moduleBaseAddress + 0x1DB9728; + DWORD Address2 = GetMemoryIntByAddress(hProcess, Address1); + DWORD Address3 = GetMemoryIntByAddress(hProcess, Address2 + 0x28 + 0xBC); + + vector nodeAddressList; + nodeAddressList.push_back(Address3); + + DWORD nodeAddress1 = GetMemoryIntByAddress(hProcess, Address3 + 0x0); + DWORD nodeAddress2 = GetMemoryIntByAddress(hProcess, Address3 + 0x4); + DWORD nodeAddress3 = GetMemoryIntByAddress(hProcess, Address3 + 0x8); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress1) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress1); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress2) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress2); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress3) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress3); + + unsigned int index = 1; + while (index < nodeAddressList.size()) { + WxContact_t contactItem; + DWORD nodeAddress = nodeAddressList[index++]; + DWORD checkNullResult = GetMemoryIntByAddress(hProcess, nodeAddress + 0xD); + if (checkNullResult == 0) { + index++; + continue; + } + contactItem.wxId = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x38); + contactItem.wxCode = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x4C); + contactItem.wxName = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x94); + contactItem.wxCountry = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x1D8); + contactItem.wxProvince = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x1EC); + contactItem.wxCity = GetUnicodeInfoByAddress(hProcess, nodeAddress + 0x200); + DWORD gender = GetMemoryIntByAddress(hProcess, nodeAddress + 0x18C); + + if (gender == 1) + contactItem.wxGender = L"男"; + else if (gender == 2) + contactItem.wxGender = L"女"; + else + contactItem.wxGender = L"未知"; + + mContact.insert(make_pair(contactItem.wxId, contactItem)); + + DWORD nodeAddress1 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x0); + DWORD nodeAddress2 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x4); + DWORD nodeAddress3 = GetMemoryIntByAddress(hProcess, nodeAddress + 0x8); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress1) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress1); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress2) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress2); + if (find(nodeAddressList.begin(), nodeAddressList.end(), nodeAddress3) == nodeAddressList.end()) + nodeAddressList.push_back(nodeAddress3); + } + + CloseHandle(hProcess); + + return mContact; +} + MsgTypesMap_t WxGetMsgTypes() { return WxMsgTypes; } diff --git a/SDK/sdk.def b/SDK/sdk.def index a9fa19b..5e4375c 100644 --- a/SDK/sdk.def +++ b/SDK/sdk.def @@ -4,3 +4,4 @@ EXPORTS WxSendTextMsg WxGetMsgTypes WxSendImageMsg + WxGetContacts diff --git a/SDK/sdk.h b/SDK/sdk.h index 7e03e90..1e28520 100644 --- a/SDK/sdk.h +++ b/SDK/sdk.h @@ -17,10 +17,22 @@ typedef struct WxMessage { wstring content; // 消息内容,MAC版最大:16384,即16KB } WxMessage_t; +typedef struct WxContact { + wstring wxId; + wstring wxCode; + wstring wxName; + wstring wxCountry; + wstring wxProvince; + wstring wxCity; + wstring wxGender; +} WxContact_t; + typedef map MsgTypesMap_t; +typedef map ContactMap_t; int WxInitSDK(); int WxSetTextMsgCb(const std::function &onMsg); int WxSendTextMsg(wstring wxid, wstring at_wxid, wstring msg); int WxSendImageMsg(wstring wxid, wstring path); +ContactMap_t WxGetContacts(); MsgTypesMap_t WxGetMsgTypes(); diff --git a/SDKpy/sdkpy.cpp b/SDKpy/sdkpy.cpp index 2e55bf9..d8b2fac 100644 --- a/SDKpy/sdkpy.cpp +++ b/SDKpy/sdkpy.cpp @@ -22,10 +22,20 @@ PYBIND11_MODULE(wcferry, m) .def_readonly("roomId", &WxMessage::roomId) .def_readonly("content", &WxMessage::content); + py::class_(m, "WxContact") + .def_readonly("wxId", &WxContact::wxId) + .def_readonly("wxCode", &WxContact::wxCode) + .def_readonly("wxName", &WxContact::wxName) + .def_readonly("wxCountry", &WxContact::wxCountry) + .def_readonly("wxProvince", &WxContact::wxProvince) + .def_readonly("wxCity", &WxContact::wxCity) + .def_readonly("wxGender", &WxContact::wxGender); + m.def("WxInitSDK", &WxInitSDK); m.def("WxSetTextMsgCb", &WxSetTextMsgCbPy); m.def("WxSendTextMsg", &WxSendTextMsg); m.def("WxSendImageMsg", &WxSendImageMsg); + m.def("WxGetContacts", &WxGetContacts, py::return_value_policy::reference); m.def("WxGetMsgTypes", &WxGetMsgTypes, py::return_value_policy::reference); #ifdef VERSION_INFO