From efb5dba007ebeccd96ad280b082eea5416f3c8b0 Mon Sep 17 00:00:00 2001 From: ttttupup Date: Wed, 10 Apr 2024 21:26:40 +0800 Subject: [PATCH] feat:update --- app/wxhelper/src/chat_controller.cc | 156 ++++++++++++-- app/wxhelper/src/chat_controller.h | 4 + app/wxhelper/src/contacts_controller.cc | 72 ++++++- app/wxhelper/src/misc_controller.cc | 258 +++++++++++++++++++++++- app/wxhelper/src/offset.h | 32 +-- app/wxhelper/src/wechat_db.cc | 117 ++++++++++- app/wxhelper/src/wechat_db.h | 13 +- 7 files changed, 608 insertions(+), 44 deletions(-) diff --git a/app/wxhelper/src/chat_controller.cc b/app/wxhelper/src/chat_controller.cc index 242ee74..b5aa2d5 100644 --- a/app/wxhelper/src/chat_controller.cc +++ b/app/wxhelper/src/chat_controller.cc @@ -14,7 +14,20 @@ namespace func = wechat::function; namespace utils = base::utils; namespace jsonutils = wxhelper::jsonutils; namespace wxhelper { - +prototype::WeChatString* BuildWechatString(const std::wstring& ws) { + prototype::WeChatString* p = + base::utils::WxHeapAlloc( + sizeof(prototype::WeChatString)); + wchar_t* p_chat_room_id = + base::utils::WxHeapAlloc((ws.size() + 1) * 2); + wmemcpy(p_chat_room_id, ws.c_str(), ws.size() + 1); + p->ptr = p_chat_room_id; + p->length = static_cast(ws.size()); + p->max_length = static_cast(ws.size()); + p->c_len = 0; + p->c_ptr = 0; + return p; +} std::string ChatController::SendTextMsg(std::string params) { int64_t base_addr = wxutils::GetWeChatWinBase(); nlohmann::json jp = nlohmann::json::parse(params); @@ -35,11 +48,11 @@ std::string ChatController::SendTextMsg(std::string params) { func::__FreeChatMsg free; free = (func::__FreeChatMsg)free_chat_msg_addr; mgr(); - uint64_t success = send(reinterpret_cast(&chat_msg), - reinterpret_cast(&to_user), - reinterpret_cast(&text_msg), - reinterpret_cast(&temp), 1, 1, 0, 0); - free(reinterpret_cast(&chat_msg)); + uint64_t success = send(reinterpret_cast(&chat_msg), + reinterpret_cast(&to_user), + reinterpret_cast(&text_msg), + reinterpret_cast(&temp), 1, 1, 0, 0); + free(reinterpret_cast(&chat_msg)); nlohmann::json ret_data = { {"code", success}, {"data", {}}, {"msg", "success"}}; @@ -47,14 +60,114 @@ std::string ChatController::SendTextMsg(std::string params) { } std::string ChatController::SendImageMsg(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + nlohmann::json jp = nlohmann::json::parse(params); + std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid"); + std::wstring image_path = jsonutils::GetWStringParam(jp, "imagePath"); + prototype::WeChatString to_user(wxid); + prototype::WeChatString image_full_path(image_path); + uint64_t send_message_mgr_addr = base_addr + offset::kGetSendMessageMgr; + uint64_t send_img_addr = base_addr + offset::kSendImageMsg; + uint64_t new_chat_msg_addr = base_addr + offset::kChatMsgInstanceCounter; + uint64_t free_chat_msg_addr = base_addr + offset::kFreeChatMsg; + func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr; + func::__GetSendMessageMgr mgr = + (func::__GetSendMessageMgr)send_message_mgr_addr; + func::__SendImageMsg send_img = (func::__SendImageMsg)send_img_addr; + func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr; + + char chat_msg[0x460] = {0}; + char chat_msg_temp[0x460] = {0}; + + uint64_t p_chat_msg_temp = + new_chat_msg(reinterpret_cast(&chat_msg_temp)); + uint64_t temp1 = 0; + uint64_t temp2 = 0; + uint64_t* flag[10] = {}; + flag[8] = &temp1; + flag[9] = &temp2; + flag[1] = reinterpret_cast(p_chat_msg_temp); + + uint64_t p_chat_msg = new_chat_msg(reinterpret_cast(&chat_msg)); + uint64_t send_mgr = mgr(); + send_img(send_mgr, p_chat_msg, reinterpret_cast(&to_user), + reinterpret_cast(&image_full_path), + reinterpret_cast(&flag)); + free(p_chat_msg); + free(p_chat_msg_temp); + success = 1; + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; return ret.dump(); } std::string ChatController::SendFileMsg(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + nlohmann::json jp = nlohmann::json::parse(params); + std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid"); + std::wstring file_path = jsonutils::GetWStringParam(jp, "filePath"); + prototype::WeChatString* to_user = (prototype::WeChatString*)HeapAlloc( + GetProcessHeap(), 0, sizeof(prototype::WeChatString)); + wchar_t* ptr_wxid = + (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (wxid.length() + 1) * 2); + wmemcpy(ptr_wxid, wxid.c_str(), wxid.length() + 1); + to_user->ptr = ptr_wxid; + to_user->length = static_cast(wxid.length()); + to_user->max_length = static_cast(wxid.length()); + to_user->c_len = 0; + to_user->c_ptr = 0; + prototype::WeChatString* file_full_path = (prototype::WeChatString*)HeapAlloc( + GetProcessHeap(), 0, sizeof(prototype::WeChatString)); + wchar_t* ptr_path = + (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (file_path.length() + 1) * 2); + wmemcpy(ptr_path, file_path.c_str(), file_path.length() + 1); + file_full_path->ptr = ptr_path; + file_full_path->length = static_cast(file_path.length()); + file_full_path->max_length = static_cast(file_path.length()); + file_full_path->c_len = 0; + file_full_path->c_ptr = 0; + + uint64_t get_app_msg_mgr_addr = base_addr + offset::kGetAppMsgMgr; + uint64_t send_file_addr = base_addr + offset::kSendFileMsg; + uint64_t new_chat_msg_addr = base_addr + offset::kChatMsgInstanceCounter; + uint64_t free_chat_msg_addr = base_addr + offset::kFreeChatMsg; + func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr; + func::__GetAppMsgMgr get_app_mgr = (func::__GetAppMsgMgr)get_app_msg_mgr_addr; + func::__SendFile send_file = (func::__SendFile)send_file_addr; + func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr; + + char* chat_msg = (char*)HeapAlloc(GetProcessHeap(), 0, 0x460); + + uint64_t* temp1 = + (uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4); + uint64_t* temp2 = + (uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4); + uint64_t* temp3 = + (uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4); + uint64_t* temp4 = + (uint64_t*)HeapAlloc(GetProcessHeap(), 0, sizeof(uint64_t) * 4); + ZeroMemory(temp1, sizeof(uint64_t) * 4); + ZeroMemory(temp2, sizeof(uint64_t) * 4); + ZeroMemory(temp3, sizeof(uint64_t) * 4); + ZeroMemory(temp4, sizeof(uint64_t) * 4); + *temp4 = 0x1F; + uint64_t app_mgr = get_app_mgr(); + send_file(app_mgr, reinterpret_cast(chat_msg), + reinterpret_cast(to_user), + reinterpret_cast(file_full_path), 1, + reinterpret_cast(temp1), 0, + reinterpret_cast(temp2), 0, + reinterpret_cast(temp3), 0, 0); + free(reinterpret_cast(chat_msg)); + HeapFree(GetProcessHeap(), 0, to_user); + HeapFree(GetProcessHeap(), 0, file_full_path); + HeapFree(GetProcessHeap(), 0, temp1); + HeapFree(GetProcessHeap(), 0, temp2); + HeapFree(GetProcessHeap(), 0, temp3); + HeapFree(GetProcessHeap(), 0, temp4); + success = 1; + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; return ret.dump(); } @@ -83,9 +196,20 @@ std::string ChatController::SendApplet(std::string params) { } std::string ChatController::SendPatMsg(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; - return ret.dump(); + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + nlohmann::json jp = nlohmann::json::parse(params); + std::wstring room_id = jsonutils::GetWStringParam(jp, "receiver"); + std::wstring wxid = jsonutils::GetWStringParam(jp, "wxid"); + UINT64 send_pat_msg_addr = base_addr + offset::kSendPatMsg; + func::__SendPatMsg send_pat_msg = (func::__SendPatMsg)send_pat_msg_addr; + prototype::WeChatString chat_room(room_id); + prototype::WeChatString target(wxid); + success = send_pat_msg(reinterpret_cast(&chat_room), + reinterpret_cast(&target)); + nlohmann::json ret_data = { + {"code", success}, {"msg", "success"}, {"data", {}}}; + return ret_data.dump(); } std::string ChatController::ForwardMsg(std::string params) { @@ -106,5 +230,9 @@ std::string ChatController::ForwardPublicMsg(std::string params) { return ret.dump(); } - +std::string ChatController::GetContactOrChatRoomNickname(std::string params) { + nlohmann::json ret = { + {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + return ret.dump(); +} } // namespace wxhelper \ No newline at end of file diff --git a/app/wxhelper/src/chat_controller.h b/app/wxhelper/src/chat_controller.h index 50e359c..8111234 100644 --- a/app/wxhelper/src/chat_controller.h +++ b/app/wxhelper/src/chat_controller.h @@ -71,6 +71,10 @@ class ChatController : public http::HttpController { /// @param params json /// @return json static std::string ForwardPublicMsg(std::string params); + /// @brief 获取联系人昵称 + /// @param params json + /// @return json + static std::string GetContactOrChatRoomNickname(std::string params); }; } // namespace wxhelper diff --git a/app/wxhelper/src/contacts_controller.cc b/app/wxhelper/src/contacts_controller.cc index b5505a4..1c3926d 100644 --- a/app/wxhelper/src/contacts_controller.cc +++ b/app/wxhelper/src/contacts_controller.cc @@ -1,11 +1,77 @@ #include "contacts_controller.h" #include "nlohmann/json.hpp" +#include "offset.h" +#include "spdlog/spdlog.h" +#include "utils.h" +#include "wechat_interface.h" +#include "wxutils.h" +#include "json_utils.h" + +namespace offset = wechat::offset; +namespace prototype = wechat::prototype; +namespace func = wechat::function; +namespace utils = base::utils; +namespace jsonutils = wxhelper::jsonutils; std::string wxhelper::ContactsController::GetContactList(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; - return ret.dump(); + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t get_contact_mgr_addr = base_addr + offset::kGetContactMgr; + uint64_t get_contact_list_addr = base_addr + offset::kGetContactList; + func::__GetContactMgr get_contact_mgr = + (func::__GetContactMgr)get_contact_mgr_addr; + func::__GetContactList get_contact_list = + (func::__GetContactList)get_contact_list_addr; + uint64_t mgr = get_contact_mgr(); + uint64_t contact_vec[3] = {0, 0, 0}; + success = get_contact_list(mgr, reinterpret_cast(&contact_vec)); + + uint64_t start = contact_vec[0]; + uint64_t end = contact_vec[2]; + std::vector vec; + + while (start < end) { + wechat::ContactInner temp; + temp.wxid = wxutils::ReadWstringThenConvert(start + 0x10); + temp.custom_account = wxutils::ReadWstringThenConvert(start + 0x30); + temp.encrypt_name = wxutils::ReadWstringThenConvert(start + 0x50); + temp.remark = wxutils::ReadWstringThenConvert(start + 0x80); + temp.remark_pinyin = wxutils::ReadWstringThenConvert(start + 0x148); + temp.remark_pinyin_all = wxutils::ReadWstringThenConvert(start + 0x168); + temp.label_ids = wxutils::ReadWstringThenConvert(start + 0xc0); + temp.nickname = wxutils::ReadWstringThenConvert(start + 0xA0); + temp.pinyin = wxutils::ReadWstringThenConvert(start + 0x108); + temp.pinyin_all = wxutils::ReadWstringThenConvert(start + 0x128); + temp.verify_flag = *(int32_t *)(start + 0x70); + temp.type = *(int32_t *)(start + 0x74); + temp.reserved1 = *(int32_t *)(start + 0x1F0); + temp.reserved2 = *(int32_t *)(start + 0x1F4); + vec.push_back(temp); + start += 0x6A8; + } + nlohmann::json ret_data = { + {"code", success}, {"data", {}}, {"msg", "success"}}; + for (unsigned int i = 0; i < vec.size(); i++) { + nlohmann::json item = { + {"customAccount", vec[i].custom_account}, + {"encryptName", vec[i].encrypt_name}, + {"type", vec[i].type}, + {"verifyFlag", vec[i].verify_flag}, + {"wxid", vec[i].wxid}, + {"nickname", vec[i].nickname}, + {"pinyin", vec[i].pinyin}, + {"pinyinAll", vec[i].pinyin_all}, + {"reserved1", vec[i].reserved1}, + {"reserved2", vec[i].reserved2}, + {"remark", vec[i].remark}, + {"remarkPinyin", vec[i].remark_pinyin}, + {"remarkPinyinAll", vec[i].remark_pinyin_all}, + {"labelIds", vec[i].label_ids}, + }; + ret_data["data"].push_back(item); + } + return ret_data.dump(); } std::string wxhelper::ContactsController::GetContactProfile( diff --git a/app/wxhelper/src/misc_controller.cc b/app/wxhelper/src/misc_controller.cc index a7a19c3..6b80d99 100644 --- a/app/wxhelper/src/misc_controller.cc +++ b/app/wxhelper/src/misc_controller.cc @@ -1,15 +1,228 @@ #include "misc_controller.h" +#include "json_utils.h" +#include "memory.h" #include "nlohmann/json.hpp" +#include "offset.h" +#include "spdlog/spdlog.h" +#include "tinyxml2.h" +#include "utils.h" +#include "wechat_db.h" +#include "wechat_interface.h" +#include "wxutils.h" + +namespace offset = wechat::offset; +namespace prototype = wechat::prototype; +namespace func = wechat::function; +namespace utils = base::utils; +namespace jsonutils = wxhelper::jsonutils; namespace wxhelper { std::string MiscController::CheckLogin(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t accout_service_addr = base_addr + offset::kGetAccountServiceMgr; + func::__GetAccountService GetSevice = + (func::__GetAccountService)accout_service_addr; + uint64_t service_addr = GetSevice(); + if (service_addr) { + success = *(uint64_t *)(service_addr + 0x7F8); + } + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; return ret.dump(); } std::string MiscController::GetUserInfo(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t accout_service_addr = base_addr + offset::kGetAccountServiceMgr; + uint64_t get_app_data_save_path_addr = + base_addr + offset::kGetAppDataSavePath; + uint64_t get_current_data_path_addr = base_addr + offset::kGetCurrentDataPath; + func::__GetAccountService GetSevice = + (func::__GetAccountService)accout_service_addr; + func::__GetDataSavePath GetDataSavePath = + (func::__GetDataSavePath)get_app_data_save_path_addr; + func::__GetCurrentDataPath GetCurrentDataPath = + (func::__GetCurrentDataPath)get_current_data_path_addr; + wechat::SelfInfoInner out; + uint64_t service_addr = GetSevice(); + if (service_addr) { + if (*(int64_t *)(service_addr + 0x80) == 0 || + *(int64_t *)(service_addr + 0x80 + 0x10) == 0) { + out.wxid = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x80 + 0x18) == 0xF) { + out.wxid = std::string((char *)(service_addr + 0x80), + *(int64_t *)(service_addr + 0x80 + 0x10)); + } else { + out.wxid = std::string(*(char **)(service_addr + 0x80), + *(int64_t *)(service_addr + 0x80 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x108) == 0 || + *(int64_t *)(service_addr + 0x108 + 0x10) == 0) { + out.account = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x108 + 0x18) == 0xF) { + out.account = std::string((char *)(service_addr + 0x108), + *(int64_t *)(service_addr + 0x108 + 0x10)); + } else { + out.account = std::string(*(char **)(service_addr + 0x108), + *(int64_t *)(service_addr + 0x108 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x128) == 0 || + *(int64_t *)(service_addr + 0x128 + 0x10) == 0) { + out.mobile = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x128 + 0x18) == 0xF) { + out.mobile = std::string((char *)(service_addr + 0x128), + *(int64_t *)(service_addr + 0x128 + 0x10)); + } else { + out.mobile = std::string(*(char **)(service_addr + 0x128), + *(int64_t *)(service_addr + 0x128 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x148) == 0 || + *(int64_t *)(service_addr + 0x148 + 0x10) == 0) { + out.signature = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x148 + 0x18) == 0xF) { + out.signature = std::string((char *)(service_addr + 0x148), + *(int64_t *)(service_addr + 0x148 + 0x10)); + } else { + out.signature = std::string(*(char **)(service_addr + 0x148), + *(int64_t *)(service_addr + 0x148 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x168) == 0 || + *(int64_t *)(service_addr + 0x168 + 0x10) == 0) { + out.country = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x168 + 0x18) == 0xF) { + out.country = std::string((char *)(service_addr + 0x168), + *(int64_t *)(service_addr + 0x168 + 0x10)); + } else { + out.country = std::string(*(char **)(service_addr + 0x168), + *(int64_t *)(service_addr + 0x168 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x188) == 0 || + *(int64_t *)(service_addr + 0x188 + 0x10) == 0) { + out.province = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x188 + 0x18) == 0xF) { + out.province = std::string((char *)(service_addr + 0x188), + *(int64_t *)(service_addr + 0x188 + 0x10)); + } else { + out.province = std::string(*(char **)(service_addr + 0x188), + *(int64_t *)(service_addr + 0x188 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x1A8) == 0 || + *(int64_t *)(service_addr + 0x1A8 + 0x10) == 0) { + out.city = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x1A8 + 0x18) == 0xF) { + out.city = std::string((char *)(service_addr + 0x1A8), + *(int64_t *)(service_addr + 0x1A8 + 0x10)); + } else { + out.city = std::string(*(char **)(service_addr + 0x1A8), + *(int64_t *)(service_addr + 0x1A8 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x1E8) == 0 || + *(int64_t *)(service_addr + 0x1E8 + 0x10) == 0) { + out.name = std::string(); + } else { + if (*(int64_t *)(service_addr + 0x1E8 + 0x18) == 0xF) { + out.name = std::string((char *)(service_addr + 0x1E8), + *(int64_t *)(service_addr + 0x1E8 + 0x10)); + } else { + out.name = std::string(*(char **)(service_addr + 0x1E8), + *(int64_t *)(service_addr + 0x1E8 + 0x10)); + } + } + + if (*(int64_t *)(service_addr + 0x450) == 0 || + *(int64_t *)(service_addr + 0x450 + 0x10) == 0) { + out.head_img = std::string(); + } else { + out.head_img = std::string(*(char **)(service_addr + 0x450), + *(int64_t *)(service_addr + 0x450 + 0x10)); + } + + if (*(int64_t *)(service_addr + 0x7B8) == 0 || + *(int64_t *)(service_addr + 0x7B8 + 0x10) == 0) { + out.public_key = std::string(); + } else { + out.public_key = std::string(*(char **)(service_addr + 0x7B8), + *(int64_t *)(service_addr + 0x7B8 + 0x10)); + } + + if (*(int64_t *)(service_addr + 0x7D8) == 0 || + *(int64_t *)(service_addr + 0x7D8 + 0x10) == 0) { + out.private_key = std::string(); + } else { + out.private_key = std::string(*(char **)(service_addr + 0x7D8), + *(int64_t *)(service_addr + 0x7D8 + 0x10)); + } + + if (*(int64_t *)(service_addr + 0x6E0) == 0 || + *(int64_t *)(service_addr + 0x6E8) == 0) { + out.db_key = std::string(); + } else { + int64_t byte_addr = *(int64_t *)(service_addr + 0x6E0); + int64_t len = *(int64_t *)(service_addr + 0x6E8); + out.db_key = + base::utils::Bytes2Hex((BYTE *)byte_addr, static_cast(len)); + } + + uint64_t flag = *(uint64_t *)(service_addr + 0x7F8); + if (flag == 1) { + prototype::WeChatString current_data_path; + GetCurrentDataPath(reinterpret_cast(¤t_data_path)); + if (current_data_path.ptr) { + out.current_data_path = base::utils::WstringToUtf8( + std::wstring(current_data_path.ptr, current_data_path.length)); + } else { + out.current_data_path = std::string(); + } + } + } + prototype::WeChatString data_save_path; + GetCurrentDataPath(reinterpret_cast(&data_save_path)); + if (data_save_path.ptr) { + out.data_save_path = base::utils::WstringToUtf8( + std::wstring(data_save_path.ptr, data_save_path.length)); + } else { + out.data_save_path = std::string(); + } + success = 1; + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; + nlohmann::json j_info = { + {"name", out.name}, + {"city", out.city}, + {"province", out.province}, + {"country", out.country}, + {"account", out.account}, + {"wxid", out.wxid}, + {"mobile", out.mobile}, + {"headImage", out.head_img}, + {"signature", out.signature}, + {"dataSavePath", out.data_save_path}, + {"currentDataPath", out.current_data_path}, + {"dbKey", out.db_key}, + {"publicKey", out.public_key}, + {"privateKey", out.private_key}, + }; + ret["data"] = j_info; return ret.dump(); } std::string MiscController::GetSNSFirstPage(std::string params) { @@ -48,13 +261,31 @@ std::string MiscController::DoOcrTask(std::string params) { return ret.dump(); } std::string MiscController::LockWeChat(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t lock_mgr_addr = base_addr + offset::kGetLockWechatMgr; + uint64_t request_lock_addr = base_addr + offset::kRequestLockWechat; + func::__GetLockWechatMgr get_lock_mgr = + (func::__GetLockWechatMgr)lock_mgr_addr; + func::__RequestLockWechat request_lock = + (func::__RequestLockWechat)request_lock_addr; + uint64_t mgr = get_lock_mgr(); + success = request_lock(mgr); + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; return ret.dump(); } std::string MiscController::UnlockWeChat(std::string params) { - nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t lock_mgr_addr = base_addr + offset::kGetLockWechatMgr; + uint64_t request_unlock_addr = base_addr + offset::kRequestUnLockWechat; + func::__GetLockWechatMgr get_lock_mgr = + (func::__GetLockWechatMgr)lock_mgr_addr; + func::__RequestUnLockWechat request_unlock = + (func::__RequestUnLockWechat)request_unlock_addr; + uint64_t mgr = get_lock_mgr(); + success = request_unlock(mgr); + nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; return ret.dump(); } std::string MiscController::ClickEnterWeChat(std::string params) { @@ -63,8 +294,17 @@ std::string MiscController::ClickEnterWeChat(std::string params) { return ret.dump(); } std::string MiscController::GetLoginUrl(std::string params) { + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t login_mgr_addr = base_addr + offset::kGetQRCodeLoginMgr; + func::__GetQRCodeLoginMgr get = (func::__GetQRCodeLoginMgr)login_mgr_addr; + uint64_t addr = get(); + std::string login_url = wxutils::ReadWeChatStr(addr + 0x68); + success = 1; nlohmann::json ret = { - {"code", 200}, {"data", {}}, {"msg", "Not Implemented"}}; + {"code", success}, + {"data", {"loginUrl", "http://weixin.qq.com/x/" + login_url}}, + {"msg", "success"}}; return ret.dump(); } std::string MiscController::TranslateVoice(std::string params) { diff --git a/app/wxhelper/src/offset.h b/app/wxhelper/src/offset.h index 3b851c5..7d66796 100644 --- a/app/wxhelper/src/offset.h +++ b/app/wxhelper/src/offset.h @@ -125,22 +125,22 @@ const uint64_t kGetWebViewMgr = 0x9412d0; const uint64_t kShowWebView = 0x1d236b0; const uint64_t kSetUrl = 0x13dd410; #elif WECHAT_VERSION == V_3_9_9_43 -const uint64_t kGetAccountServiceMgr = 0x94e510; +const uint64_t kGetAccountServiceMgr = 0xa7df30; const uint64_t kSyncMsg = 0xc39680; const uint64_t kSyncMsgNext = 0xc39680; -const uint64_t kGetCurrentDataPath = 0x101a920; -const uint64_t kGetAppDataSavePath = 0x13a5b90; +const uint64_t kGetCurrentDataPath = 0x11664e0; +const uint64_t kGetAppDataSavePath = 0x14f29c0; const uint64_t kGetSendMessageMgr = 0xa7c730; const uint64_t kSendTextMsg = 0x11de090; const uint64_t kFreeChatMsg = 0xa7dfb0; const uint64_t kDoAddMsg = 0x1225a60; -const uint64_t kSendImageMsg = 0x1087950; -const uint64_t kChatMsgInstanceCounter = 0x956e00; -const uint64_t kSendFileMsg = 0xea0850; -const uint64_t kGetAppMsgMgr = 0x951cb0; -const uint64_t kGetContactMgr = 0x93a570; -const uint64_t kGetContactList = 0xf6cb70; +const uint64_t kSendImageMsg = 0x11d3a70; +const uint64_t kChatMsgInstanceCounter = 0xa86820; +const uint64_t kSendFileMsg = 0xfeb750; +const uint64_t kGetAppMsgMgr = 0xa816d0; +const uint64_t kGetContactMgr = 0xa69fd0; +const uint64_t kGetContactList = 0x10b8420; const uint64_t k_sqlite3_exec = 0x288ea10; const uint64_t k_sqlite3_prepare = 0x2896590; @@ -194,9 +194,9 @@ const uint64_t kSNSGetFirstPage = 0x1a51dd0; const uint64_t kSNSGetNextPageScene = 0x1a77240; const uint64_t kSNSDataMgr = 0xeebda0; const uint64_t kSNSTimeLineMgr = 0x19e83a0; -const uint64_t kGetMgrByPrefixLocalId = 0xf0ea60; +const uint64_t kGetMgrByPrefixLocalId = 0x105a010; const uint64_t kAddFavFromMsg = 0x1601520; -const uint64_t kGetChatMgr = 0x97e4d0; +const uint64_t kGetChatMgr = 0xaafd90; const uint64_t kGetFavoriteMgr = 0x8c69b0; const uint64_t kAddFavFromImage = 0x160b920; const uint64_t kGetContact = 0xf67060; @@ -224,13 +224,13 @@ const uint64_t kSendPatMsg = 0x195f340; const uint64_t kGetOCRManager = 0x999780; const uint64_t kDoOCRTask = 0x190b2a0; -const uint64_t kGetLockWechatMgr = 0xa727b0; -const uint64_t kRequestLockWechat = 0xa2cc70; -const uint64_t kRequestUnLockWechat = 0xa2cf10; +const uint64_t kGetLockWechatMgr = 0xbadb10; +const uint64_t kRequestLockWechat = 0xb63770; +const uint64_t kRequestUnLockWechat = 0xb63a10; -const uint64_t kOnLoginBtnClick = 0xe0cf70; +const uint64_t kOnLoginBtnClick = 0xf4d0f0; -const uint64_t kGetQRCodeLoginMgr = 0xdff6d0; +const uint64_t kGetQRCodeLoginMgr = 0xf3fa20; const uint64_t kUpdateMsg = 0xf15c40; const uint64_t kGetVoiceMgr = 0xbf78f0; diff --git a/app/wxhelper/src/wechat_db.cc b/app/wxhelper/src/wechat_db.cc index 71070bd..00f08d2 100644 --- a/app/wxhelper/src/wechat_db.cc +++ b/app/wxhelper/src/wechat_db.cc @@ -64,6 +64,7 @@ int GetDbInfoCallback(void *data, int argc, char **argv, char **name) { } void WeChatDb::Init() { + std::lock_guard lock(m); base_addr_ = wxhelper::wxutils::GetWeChatWinBase(); func_ = sqlite3::SqliteFunction(base_addr_); dbmap_ = {}; @@ -75,8 +76,18 @@ int WeChatDb::ExecuteSQL(uint64_t db, const char *sql, return func_.sqlite3_exec(db, sql, callback, data, 0); } +int64_t WeChatDb::GetDbHandleByDbName(wchar_t *dbname) { + if (dbmap_.size() == 0) { + GetWeChatDbHandles(); + } + if (dbmap_.find(dbname) != dbmap_.end()) { + return dbmap_[dbname].handle; + } + return 0; +} + std::vector WeChatDb::GetWeChatDbHandles() { - std::lock_guard lock(m); + std::lock_guard lock(m); dbs_.clear(); dbmap_.clear(); uint64_t p_contact_addr = *(uint64_t *)(base_addr_ + offset::kGPInstance); @@ -217,7 +228,111 @@ int WeChatDb::Select(uint64_t db_hanle, const std::string &sql, return 1; } +int64_t WeChatDb::GetLocalIdByMsgId(uint64_t msgid, int64_t &dbIndex) { + char sql[260] = {0}; + sprintf_s(sql, "select localId from MSG where MsgSvrID=%llu;", msgid); + wchar_t dbname[20] = {0}; + for (int i = 0;; i++) { + swprintf_s(dbname, L"MSG%d.db", i); + uint64_t handle = GetDbHandleByDbName(dbname); + if (handle == 0) { + SPDLOG_INFO("MSG db handle is null"); + return 0; + } + std::vector> result; + int ret = Select(handle, (const char *)sql, result); + if (result.size() == 0) continue; + dbIndex = dbmap_[dbname].extrainfo; + return stoi(result[1][0]); + } + return 0; +} + +std::vector WeChatDb::GetChatMsgByMsgId(uint64_t msgid) { + char sql[260] = {0}; + sprintf_s(sql, + "select " + "localId,TalkerId,MsgSvrID,Type,SubType,IsSender,CreateTime," + "Sequence,StatusEx,FlagEx,Status,MsgServerSeq,MsgSequence," + "StrTalker,StrContent,BytesExtra from MSG where MsgSvrID=%llu;", + msgid); + wchar_t dbname[20] = {0}; + for (int i = 0;; i++) { + swprintf_s(dbname, L"MSG%d.db", i); + UINT64 handle = GetDbHandleByDbName(dbname); + if (handle == 0) { + SPDLOG_INFO("MSG db handle is null"); + return {}; + } + std::vector> result; + int ret = Select(handle, (const char *)sql, result); + if (result.size() == 0) continue; + return result[1]; + } + return {}; +} + +std::string WeChatDb::GetVoiceBuffByMsgId(uint64_t msgid) { + char sql[260] = {0}; + sprintf_s(sql, "SELECT Buf from Media WHERE Reserved0=%llu;", msgid); + wchar_t dbname[20] = {0}; + for (int i = 0;; i++) { + swprintf_s(dbname, L"MediaMSG%d.db", i); + UINT64 handle = GetDbHandleByDbName(dbname); + if (handle == 0) { + SPDLOG_INFO("Media db handle is null"); + return ""; + } + std::vector> result; + int ret = Select(handle, (const char *)sql, result); + if (result.size() == 0) continue; + return result[1][0]; + } + return ""; +} + +std::string WeChatDb::GetPublicMsgCompressContentByMsgId(uint64_t msgid) { + char sql[260] = {0}; + sprintf_s(sql, "SELECT CompressContent from PublicMsg WHERE MsgSvrID=%llu;", + msgid); + wchar_t dbname[20] = {0}; + swprintf_s(dbname, 20, L"%s", L"PublicMsg.db"); + UINT64 handle = GetDbHandleByDbName(dbname); + if (handle == 0) { + SPDLOG_INFO("db handle not found,check msgid"); + return ""; + } + std::vector> result; + int ret = Select(handle, (const char *)sql, result); + if (result.size() == 0) { + SPDLOG_INFO( + "this SQL statement executed normally, but the result was empty"); + return ""; + } + return result[1][0]; +} + +std::string WeChatDb::GetChatMsgStrContentByMsgId(uint64_t msgid) { + char sql[260] = {0}; + sprintf_s(sql, "select StrContent from MSG where MsgSvrID=%llu;", msgid); + wchar_t dbname[20] = {0}; + for (int i = 0;; i++) { + swprintf_s(dbname, L"MSG%d.db", i); + UINT64 handle = GetDbHandleByDbName(dbname); + if (handle == 0) { + SPDLOG_INFO("MSG db handle is null"); + return {}; + } + std::vector> result; + int ret = Select(handle, (const char *)sql, result); + if (result.size() == 0) continue; + return result[1][0]; + } + return {}; +} + void WeChatDb::AddDatebaseInfo(uint64_t storage) { + std::lock_guard lock(m); uint64_t storage_addr = *(uint64_t *)(storage + 0x50); std::wstring name = std::wstring((wchar_t *)(*(uint64_t *)(storage + 0x78)), *(int32_t *)(storage + 0x80)); diff --git a/app/wxhelper/src/wechat_db.h b/app/wxhelper/src/wechat_db.h index d3eabb4..30e9914 100644 --- a/app/wxhelper/src/wechat_db.h +++ b/app/wxhelper/src/wechat_db.h @@ -18,6 +18,17 @@ class WeChatDb : public base::Singleton { int Select(uint64_t db_hanle, const std::string &sql, std::vector> &query_result); + int64_t GetLocalIdByMsgId(uint64_t msgid, int64_t &dbIndex); + std::vector GetChatMsgByMsgId(uint64_t msgid); + + std::string GetVoiceBuffByMsgId(uint64_t msgid); + + std::string GetPublicMsgCompressContentByMsgId(uint64_t msgid); + + std::string GetChatMsgStrContentByMsgId(uint64_t msgid); + + int64_t GetDbHandleByDbName(wchar_t *dbname); + private: void AddDatebaseInfo(uint64_t storage); int ExecSelect(uint64_t db, const std::string &sql, @@ -30,7 +41,7 @@ class WeChatDb : public base::Singleton { std::vector dbs_; sqlite3::SqliteFunction func_; uint64_t base_addr_; - mutable std::mutex m; + mutable std::recursive_mutex m; }; } // namespace wechat