From b9c1370bfe2f375f44d88e0176dfe2186c889538 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 8 Aug 2024 17:48:20 +0800 Subject: [PATCH] up --- .../wechat_service.cc | 1598 +++++++++++++++++ inc/wechat_service.h | 2 +- src/misc_controller.cc | 9 +- src/wechat_service.cc | 73 +- wxhelper.vcxproj | 2 +- 5 files changed, 1646 insertions(+), 38 deletions(-) create mode 100644 enc_temp_folder/bd4455ec16623a51f931c98552ba1e28/wechat_service.cc diff --git a/enc_temp_folder/bd4455ec16623a51f931c98552ba1e28/wechat_service.cc b/enc_temp_folder/bd4455ec16623a51f931c98552ba1e28/wechat_service.cc new file mode 100644 index 0000000..087e2b0 --- /dev/null +++ b/enc_temp_folder/bd4455ec16623a51f931c98552ba1e28/wechat_service.cc @@ -0,0 +1,1598 @@ +#include "wechat_service.h" + +#include "json_utils.h" +#include "memory.h" +#include "spdlog/spdlog.h" +#include "tinyxml2.h" +#include "utils.h" +#include "wechat_db.h" +#include "wxutils.h" + +#define BUFSIZE 1024 +#define JPEG0 0xFF +#define JPEG1 0xD8 +#define JPEG2 0xFF +#define PNG0 0x89 +#define PNG1 0x50 +#define PNG2 0x4E +#define BMP0 0x42 +#define BMP1 0x4D +#define GIF0 0x47 +#define GIF1 0x49 +#define GIF2 0x46 + +namespace offset = wechat::offset; +namespace prototype = wechat::prototype; +namespace func = wechat::function; +namespace utils = base::utils; +namespace jsonutils = wxhelper::jsonutils; +namespace wxutils = wxhelper::wxutils; +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; +} +wechat::WeChatService::~WeChatService() {} + +void wechat::WeChatService::Init() { base_addr_ = wxutils::GetWeChatWinBase(); } + +int64_t wechat::WeChatService::CheckLogin() { + int64_t success = -1; + + 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); + } + return success; +} + +int64_t wechat::WeChatService::GetSelfInfo(SelfInfoInner& out) { + int64_t success = -1; + 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; + 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; + return success; +} + +int64_t wechat::WeChatService::SendTextMsg(const std::wstring& wxid, + const std::wstring& msg) { + prototype::WeChatString to_user(wxid); + prototype::WeChatString text_msg(msg); + uint64_t send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr; + uint64_t send_text_msg_addr = base_addr_ + offset::kSendTextMsg; + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + char chat_msg[0x460] = {0}; + uint64_t temp[3] = {0}; + func::__GetSendMessageMgr mgr; + mgr = (func::__GetSendMessageMgr)send_message_mgr_addr; + func::__SendTextMsg send; + send = (func::__SendTextMsg)send_text_msg_addr; + 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)); + return 0; +} + +int64_t wechat::WeChatService::SendImageMsg(const std::wstring& wxid, + const std::wstring& image_path) { + int64_t success = -1; + 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 temp3 = 1; + uint64_t* flag[10] = {}; + flag[0] = reinterpret_cast(temp3); + 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(); + success = 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); + return success; +} + +int64_t wechat::WeChatService::SendFileMsg(const std::wstring& wxid, + const std::wstring& file_path) { + int64_t success = -1; + 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); + + ZeroMemory(temp1, sizeof(uint64_t) * 4); + ZeroMemory(temp2, sizeof(uint64_t) * 4); + ZeroMemory(temp3, sizeof(uint64_t) * 4); + + uint64_t app_mgr = get_app_mgr(); + success = 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, 0xC); + 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); + return success; +} + +int64_t wechat::WeChatService::GetContacts(std::vector& vec) { + 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]; + 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; + } + return success; +} + +int64_t wechat::WeChatService::GetChatRoomDetailInfo( + const std::wstring& room_id, ChatRoomInfoInner& room_info) { + int64_t success = -1; + prototype::WeChatString chat_room_id(room_id); + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t get_chat_room_mgr_addr = base_addr + offset::kChatRoomMgr; + uint64_t get_chat_room_detail_addr = + base_addr + offset::kGetChatRoomDetailInfo; + uint64_t create_chat_room_info_addr = base_addr + offset::kNewChatRoomInfo; + uint64_t free_chat_room_info_addr = base_addr + offset::kFreeChatRoomInfo; + + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__NewChatRoomInfo new_chat_room_info = + (func::__NewChatRoomInfo)create_chat_room_info_addr; + func::__FreeChatRoomInfo free_chat_room_info = + (func::__FreeChatRoomInfo)free_chat_room_info_addr; + func::__GetChatRoomDetailInfo get_chat_room_detail = + (func::__GetChatRoomDetailInfo)get_chat_room_detail_addr; + + char chat_room_info[0x144] = {0}; + + uint64_t new_room_info = + new_chat_room_info(reinterpret_cast(&chat_room_info)); + + uint64_t mgr = get_chat_room_mgr(); + success = get_chat_room_detail(mgr, reinterpret_cast(&chat_room_id), + new_room_info, 1); + + room_info.chat_room_id = wxutils::ReadWstringThenConvert(new_room_info + 0x8); + room_info.notice = wxutils::ReadWstringThenConvert(new_room_info + 0x28); + room_info.admin = wxutils::ReadWstringThenConvert(new_room_info + 0x48); + room_info.xml = wxutils::ReadWstringThenConvert(new_room_info + 0x78); + free_chat_room_info(new_room_info); + + return success; +} + +int64_t wechat::WeChatService::AddMemberToChatRoom( + const std::wstring& room_id, const std::vector& members) { + int64_t success = -1; + uint64_t get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr; + uint64_t add_members_addr = base_addr_ + offset::kDoAddMemberToChatRoom; + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__DoAddMemberToChatRoom add_members = + (func::__DoAddMemberToChatRoom)add_members_addr; + + prototype::WeChatString* chat_room_id = (prototype::WeChatString*)HeapAlloc( + GetProcessHeap(), 0, sizeof(prototype::WeChatString)); + wchar_t* p_chat_room_id = + (wchar_t*)HeapAlloc(GetProcessHeap(), 0, (room_id.size() + 1) * 2); + wmemcpy(p_chat_room_id, room_id.c_str(), room_id.size() + 1); + chat_room_id->ptr = p_chat_room_id; + chat_room_id->length = static_cast(room_id.size()); + chat_room_id->max_length = static_cast(room_id.size()); + chat_room_id->c_len = 0; + chat_room_id->c_ptr = 0; + + std::vector member_list; + uint64_t temp[2] = {0}; + wechat::VectorInner* list = (wechat::VectorInner*)&member_list; + int64_t members_ptr = (int64_t)&list->start; + for (int i = 0; i < members.size(); i++) { + prototype::WeChatString member(members[i]); + member_list.push_back(member); + } + uint64_t mgr = get_chat_room_mgr(); + success = + add_members(mgr, members_ptr, reinterpret_cast(chat_room_id), + reinterpret_cast(&temp)); + return success; +} + +int64_t wechat::WeChatService::ModChatRoomMemberNickName( + const std::wstring& room_id, const std::wstring& wxid, + const std::wstring& nickname) { + int64_t success = -1; + uint64_t mod_addr = base_addr_ + offset::kDoModChatRoomMemberNickName; + func::__DoModChatRoomMemberNickName modify = + (func::__DoModChatRoomMemberNickName)mod_addr; + const wchar_t* p = room_id.c_str(); + prototype::WeChatString* chat_room_id = BuildWechatString(room_id); + prototype::WeChatString* self_id = BuildWechatString(wxid); + prototype::WeChatString* name = BuildWechatString(nickname); + success = modify( + reinterpret_cast(p), reinterpret_cast(chat_room_id), + reinterpret_cast(self_id), reinterpret_cast(name)); + return success; +} + +int64_t wechat::WeChatService::DelMemberFromChatRoom( + const std::wstring& room_id, const std::vector& members) { + int64_t success = -1; + uint64_t get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr; + uint64_t del_members_addr = base_addr_ + offset::kDelMemberFromChatRoom; + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__DoDelMemberFromChatRoom del_members = + (func::__DoDelMemberFromChatRoom)del_members_addr; + + prototype::WeChatString* chat_room_id = BuildWechatString(room_id); + std::vector member_list; + uint64_t temp[2] = {0}; + wechat::VectorInner* list = (wechat::VectorInner*)&member_list; + int64_t members_ptr = (int64_t)&list->start; + for (int i = 0; i < members.size(); i++) { + prototype::WeChatString member(members[i]); + member_list.push_back(member); + } + uint64_t mgr = get_chat_room_mgr(); + success = + del_members(mgr, members_ptr, reinterpret_cast(chat_room_id)); + return success; +} + +int64_t wechat::WeChatService::GetMemberFromChatRoom( + const std::wstring& room_id, ChatRoomMemberInner& member) { + int64_t success = -1; + uint64_t get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr; + uint64_t get_members_addr = base_addr_ + offset::kGetMemberFromChatRoom; + uint64_t new_chat_room_addr = base_addr_ + offset::kNewChatRoom; + uint64_t free_chat_room_addr = base_addr_ + offset::kFreeChatRoom; + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__GetMemberFromChatRoom get_members = + (func::__GetMemberFromChatRoom)get_members_addr; + func::__NewChatRoom new_chat_room = (func::__NewChatRoom)new_chat_room_addr; + func::__FreeChatRoom free_chat_room = + (func::__FreeChatRoom)free_chat_room_addr; + + prototype::WeChatString chat_room_id(room_id); + char chat_room_info[0x308] = {0}; + uint64_t addr = new_chat_room(reinterpret_cast(&chat_room_info)); + uint64_t mgr = get_chat_room_mgr(); + success = get_members(mgr, reinterpret_cast(&chat_room_id), addr); + member.chat_room_id = wxutils::ReadWstringThenConvert(addr + 0x10); + member.admin = wxutils::ReadWstringThenConvert(addr + 0x78); + member.member_nickname = wxutils::ReadWstringThenConvert(addr + 0x50); + member.admin_nickname = wxutils::ReadWstringThenConvert(addr + 0xA0); + member.member = wxutils::ReadWeChatStr(addr + 0x30); + free_chat_room(addr); + return success; +} + +int64_t wechat::WeChatService::SetTopMsg(uint64_t msg_id) { + int64_t success = -1; + uint64_t top_addr = base_addr_ + offset::kTopMsg; + func::__DoTopMsg top_msg = (func::__DoTopMsg)top_addr; + int64_t index = 0; + int64_t local_id = + wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); + if (local_id <= 0 || index >> 32 == 0) { + success = -2; + return success; + } + LARGE_INTEGER l; + l.HighPart = index >> 32; + l.LowPart = (DWORD)local_id; + uint64_t ptr = reinterpret_cast(&l); + success = top_msg(ptr, 1); + + return success; +} + +int64_t wechat::WeChatService::RemoveTopMsg(const std::wstring& room_id, + uint64_t msg_id) { + int64_t success = -1; + uint64_t remove_addr = base_addr_ + offset::kRemoveTopMsg; + func::__RemoveTopMsg remove_top_msg = (func::__RemoveTopMsg)remove_addr; + prototype::WeChatString* chat_room_id = BuildWechatString(room_id); + const wchar_t* w_room = room_id.c_str(); + success = remove_top_msg(reinterpret_cast(w_room), msg_id, + reinterpret_cast(chat_room_id)); + return success; +} +TODO("InviteMemberToChatRoom") +int64_t wechat::WeChatService::InviteMemberToChatRoom( + const std::wstring& room_id, const std::vector& wxids) { + int64_t success = -1; + uint64_t invite_addr = base_addr_ + offset::kInviteMember; + func::__InviteMemberToChatRoom invite = + (func::__InviteMemberToChatRoom)invite_addr; + const wchar_t* w_room = room_id.c_str(); + prototype::WeChatString* chat_room_id = BuildWechatString(room_id); + std::vector wxid_list; + wechat::VectorInner* list = (wechat::VectorInner*)&wxid_list; + int64_t head = (int64_t)&list->start; + for (int i = 0; i < wxids.size(); i++) { + prototype::WeChatString id(wxids[i]); + wxid_list.push_back(id); + } + uint64_t temp[2] = {0}; + success = invite(reinterpret_cast(w_room), head, + reinterpret_cast(chat_room_id), + reinterpret_cast(&temp)); + return success; +} + +TODO("CreateChatRoom") +int64_t wechat::WeChatService::CreateChatRoom( + const std::vector& wxids) { + int64_t success = -1; + uint64_t get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr; + uint64_t create_chat_room_addr = base_addr_ + offset::kCreateChatRoom; + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__CreateChatRoom create_chat_room = + (func::__CreateChatRoom)create_chat_room_addr; + std::vector wxid_list; + wechat::VectorInner* list = (wechat::VectorInner*)&wxid_list; + int64_t head = (int64_t)&list->start; + for (int i = 0; i < wxids.size(); i++) { + prototype::WeChatString id(wxids[i]); + wxid_list.push_back(id); + } + int64_t end = list->end; + uint64_t mgr = get_chat_room_mgr(); + success = create_chat_room(mgr, head, end); + return success; +} + +TODO("QuitChatRoom") +int64_t wechat::WeChatService::QuitChatRoom(const std::wstring& room_id) { + int64_t success = -1; + uint64_t get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr; + uint64_t quit_chat_room_addr = base_addr_ + offset::kQuitChatRoom; + func::__GetChatRoomMgr get_chat_room_mgr = + (func::__GetChatRoomMgr)get_chat_room_mgr_addr; + func::__QuitChatRoom quit_chat_room = + (func::__QuitChatRoom)quit_chat_room_addr; + uint64_t mgr = get_chat_room_mgr(); + prototype::WeChatString chat_room_id(room_id); + success = quit_chat_room(mgr, reinterpret_cast(&chat_room_id), 0); + return success; +} + +int64_t wechat::WeChatService::ForwardMsg(uint64_t msg_id, + const std::wstring& wxid) { + int64_t success = -1; + uint64_t forward_addr = base_addr_ + offset::kForwardMsg; + func::__ForwardMsg forward_msg = (func::__ForwardMsg)forward_addr; + int64_t index = 0; + int64_t local_id = + wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); + if (local_id <= 0 || index >> 32 == 0) { + success = -2; + + return success; + } + LARGE_INTEGER l; + l.HighPart = index >> 32; + l.LowPart = (DWORD)local_id; + prototype::WeChatString* recv = BuildWechatString(wxid); + success = forward_msg(reinterpret_cast(recv), l.QuadPart, 0x4, 0x0); + return success; +} + +TODO("GetSNSFirstPage") +int64_t wechat::WeChatService::GetSNSFirstPage() { + int64_t success = -1; + uint64_t sns_data_mgr_addr = base_addr_ + offset::kSNSDataMgr; + uint64_t sns_first_page_addr = base_addr_ + offset::kSNSGetFirstPage; + func::__GetSNSDataMgr sns_data_mgr = (func::__GetSNSDataMgr)sns_data_mgr_addr; + func::__GetSNSFirstPage sns_first_page = + (func::__GetSNSFirstPage)sns_first_page_addr; + uint64_t mgr = sns_data_mgr(); + int64_t buff[16] = {0}; + success = sns_first_page(mgr, reinterpret_cast(&buff), 1); + return success; +} + +TODO("GetSNSNextPage") +int64_t wechat::WeChatService::GetSNSNextPage(uint64_t sns_id) { + int64_t success = -1; + uint64_t time_line_mgr_addr = base_addr_ + offset::kSNSTimeLineMgr; + uint64_t sns_next_page_addr = base_addr_ + offset::kSNSGetNextPageScene; + func::__GetSnsTimeLineMgr time_line_mgr = + (func::__GetSnsTimeLineMgr)time_line_mgr_addr; + func::__GetSNSNextPageScene sns_next_page = + (func::__GetSNSNextPageScene)sns_next_page_addr; + uint64_t mgr = time_line_mgr(); + success = sns_next_page(mgr, sns_id); + return success; +} + + +int64_t wechat::WeChatService::AddFavFromMsg(uint64_t msg_id) { + int64_t success = -1; + uint64_t get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr; + uint64_t get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId; + uint64_t add_fav_addr = base_addr_ + offset::kAddFavFromMsg; + uint64_t get_favorite_mgr_addr = base_addr_ + offset::kGetFavoriteMgr; + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + func::__GetMgrByPrefixLocalId get_by_local_id = + (func::__GetMgrByPrefixLocalId)get_by_local_id_addr; + uint64_t new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter; + + func::__AddFavFromMsg add_fav = (func::__AddFavFromMsg)add_fav_addr; + func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr; + func::__GetFavoriteMgr get_favorite_mgr = + (func::__GetFavoriteMgr)get_favorite_mgr_addr; + func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr; + func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr; + + int64_t index = 0; + int64_t local_id = + wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); + if (local_id <= 0 || index >> 32 == 0) { + success = -2; + return success; + } + char chat_msg[0x460] = {0}; + LARGE_INTEGER l; + l.HighPart = index >> 32; + l.LowPart = (DWORD)local_id; + uint64_t p_chat_msg = new_chat_msg(reinterpret_cast(&chat_msg)); + + get_chat_mgr(); + get_by_local_id(l.QuadPart, p_chat_msg); + uint64_t mgr = get_favorite_mgr(); + success = add_fav(mgr, p_chat_msg); + free_chat_msg(p_chat_msg); + return success; +} + + +int64_t wechat::WeChatService::AddFavFromImage(const std::wstring& wxid, + const std::wstring& image_path) { + int64_t success = -1; + uint64_t get_favorite_mgr_addr = base_addr_ + offset::kGetFavoriteMgr; + uint64_t add_fav_from_image_addr = base_addr_ + offset::kAddFavFromImage; + prototype::WeChatString* send_id = BuildWechatString(wxid); + prototype::WeChatString* path = BuildWechatString(image_path); + func::__GetFavoriteMgr get_favorite_mgr = + (func::__GetFavoriteMgr)get_favorite_mgr_addr; + func::__AddFavFromImage add_fav_from_image = + (func::__AddFavFromImage)add_fav_from_image_addr; + uint64_t mgr = get_favorite_mgr(); + success = add_fav_from_image(mgr, reinterpret_cast(path), + reinterpret_cast(send_id)); + return success; +} +int64_t wechat::WeChatService::SendAtText( + const std::wstring& room_id, const std::vector& wxids, + const std::wstring& msg) { + int64_t success = -1; + std::vector wxid_list; + wechat::VectorInner* list = (wechat::VectorInner*)&wxid_list; + std::wstring at_msg = L""; + int number = 0; + for (unsigned int i = 0; i < wxids.size(); i++) { + std::wstring nickname; + std::wstring at_all = L"notify@all"; + if (at_all.compare(wxids[i]) == 0) { + nickname = L"\u6240\u6709\u4eba"; + } else { + nickname = GetContactOrChatRoomNickname(wxids[i]); + } + if (nickname.length() == 0) { + continue; + } + prototype::WeChatString id(wxids[i]); + wxid_list.push_back(id); + at_msg = at_msg + L"@" + nickname + L" "; + number++; + } + if (number < 1) { + success = -2; + return success; + } + at_msg += msg; + + INT64 head = (INT64)&list->start; + prototype::WeChatString to_user(room_id); + prototype::WeChatString text_msg(at_msg); + uint64_t send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr; + uint64_t send_text_msg_addr = base_addr_ + offset::kSendTextMsg; + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + char chat_msg[0x460] = {0}; + func::__GetSendMessageMgr mgr = + (func::__GetSendMessageMgr)send_message_mgr_addr; + func::__SendTextMsg send = (func::__SendTextMsg)send_text_msg_addr; + func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr; + mgr(); + success = send(reinterpret_cast(&chat_msg), + reinterpret_cast(&to_user), + reinterpret_cast(&text_msg), head, 1, 1, 0, 0); + free(reinterpret_cast(&chat_msg)); + return 0; +} +TODO("GetContactOrChatRoomNickname") +std::wstring wechat::WeChatService::GetContactOrChatRoomNickname( + const std::wstring& wxid) { + int64_t success = -1; + prototype::WeChatString to_user(wxid); + uint64_t get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr; + uint64_t new_contact_addr = base_addr_ + offset::kNewContact; + uint64_t get_contact_addr = base_addr_ + offset::kGetContact; + uint64_t free_contact_addr = base_addr_ + offset::kFreeContact; + func::__GetContactMgr get_contact_mgr = + (func::__GetContactMgr)get_contact_mgr_addr; + func::__GetContact get_contact = (func::__GetContact)get_contact_addr; + func::__NewContact new_contact = (func::__NewContact)new_contact_addr; + func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr; + char buff[0x6A9] = {0}; + uint64_t contact = new_contact(reinterpret_cast(&buff)); + uint64_t mgr = get_contact_mgr(); + success = get_contact(mgr, reinterpret_cast(&to_user), contact); + + if (success == 1) { + std::wstring nickname = wxutils::ReadWstring(contact + 0xA0); + free_contact(contact); + return nickname; + } else { + free_contact(contact); + return L""; + } +} + + +int64_t wechat::WeChatService::GetContactByWxid(const std::wstring& wxid, + ContactProfileInner& profile) { + int64_t success = -1; + prototype::WeChatString to_user(wxid); + uint64_t get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr; + uint64_t new_contact_addr = base_addr_ + offset::kNewContact; + uint64_t get_contact_addr = base_addr_ + offset::kGetContact; + uint64_t free_contact_addr = base_addr_ + offset::kFreeContact; + func::__GetContactMgr get_contact_mgr = + (func::__GetContactMgr)get_contact_mgr_addr; + func::__GetContact get_contact = (func::__GetContact)get_contact_addr; + func::__NewContact new_contact = (func::__NewContact)new_contact_addr; + func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr; + char buff[0x6A9] = {0}; + uint64_t contact = new_contact(reinterpret_cast(&buff)); + uint64_t mgr = get_contact_mgr(); + success = get_contact(mgr, reinterpret_cast(&to_user), contact); + profile.wxid = wxutils::ReadWstringThenConvert(contact + 0x10); + profile.account = wxutils::ReadWstringThenConvert(contact + 0x30); + profile.v3 = wxutils::ReadWstringThenConvert(contact + 0x50); + profile.nickname = wxutils::ReadWstringThenConvert(contact + 0xA0); + profile.head_image = wxutils::ReadWstringThenConvert(contact + 0x188); + free_contact(contact); + return success; +} + +std::wstring combineAndRemoveDuplicate(const std::wstring& basePath, const std::wstring& resultPath) { + std::wstring cleanedBasePath = basePath; + if (cleanedBasePath.back() == L'\\') { + cleanedBasePath.pop_back(); + } + size_t pos = resultPath.find(cleanedBasePath); + if (pos != std::wstring::npos) { + std::wstring adjustedResultPath = resultPath.substr(pos + cleanedBasePath.length()); + return cleanedBasePath + L'\\' + adjustedResultPath; + } + + return basePath + L'\\' + resultPath; +} +TODO("DoDownloadTask") +std::wstring getBasePath(const std::wstring& path) { + size_t pos = path.find_last_of(L'\\'); + if (pos != std::wstring::npos) { + return path.substr(0, pos + 1); + } + return path; // 如果没有找到反斜杠,则返回原路径 +} +std::wstring wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { + + uint64_t get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId; + func::__GetMgrByPrefixLocalId get_by_local_id = + (func::__GetMgrByPrefixLocalId)get_by_local_id_addr; + + uint64_t get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr; + func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr; + + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr; + + uint64_t new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter; + func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr; + + uint64_t get_current_data_path_addr = + base_addr_ + offset::kGetCurrentDataPath; + func::__GetCurrentDataPath GetCurrentDataPath = + (func::__GetCurrentDataPath)get_current_data_path_addr; + + uint64_t new_app_msg_info_addr = base_addr_ + offset::kNewAppMsgInfo; + func::__NewAppMsgInfo new_app_msg_info = + (func::__NewAppMsgInfo)new_app_msg_info_addr; + + uint64_t free_app_msg_info_addr = base_addr_ + offset::kFreeAppMsgInfo; + func::__FreeAppMsgInfo free_app_msg_info = + (func::__NewAppMsgInfo)free_app_msg_info_addr; + + uint64_t xml_to_app_info_addr = base_addr_ + offset::kParseAppMsgXml; + func::__ParseAppMsgXml xml_to_app_info = + (func::__ParseAppMsgXml)xml_to_app_info_addr; + + uint64_t get_pre_download_mgr_addr = base_addr_ + offset::kGetPreDownLoadMgr; + func::__GetPreDownLoadMgr get_pre_download_mgr = + (func::__GetPreDownLoadMgr)get_pre_download_mgr_addr; + + uint64_t push_attach_task_addr = base_addr_ + offset::kPushAttachTask; + func::__PushAttachTask push_attach_task = + (func::__PushAttachTask)push_attach_task_addr; + + int64_t index = 0; + int64_t local_id = + wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); + if (local_id <= 0 || index >> 32 == 0) { + return L"-2"; + } + char* chat_msg = base::utils::WxHeapAlloc(0x460); + LARGE_INTEGER l; + l.HighPart = index >> 32; + l.LowPart = (DWORD)local_id; + uint64_t p_chat_msg = new_chat_msg(reinterpret_cast(chat_msg)); + + get_chat_mgr(); + get_by_local_id(l.QuadPart, p_chat_msg); + + std::wstring save_path = L""; + std::wstring thumb_path = L""; + + prototype::WeChatString current_data_path; + GetCurrentDataPath(reinterpret_cast(¤t_data_path)); + + if (current_data_path.length > 0) { + save_path += current_data_path.ptr; + } else { + return L"-1"; + } + + int64_t type = *(int64_t*)(chat_msg + 0x38); + wchar_t* content = *(wchar_t**)(chat_msg + 0x88); + DWORD len = *(DWORD*)(chat_msg + 0x94); + std::wstring tmp_content(content, len); + prototype::WeChatString* we_content = BuildWechatString(tmp_content); + + switch (type) { + case 0x3: { + std::wstring basePath = getBasePath(save_path); + save_path = basePath; + break; + } + case 0x3E: + case 0x2B: { + save_path += L"\\video"; + if (!wxutils::FindOrCreateDirectory(save_path)) { + return L"-3" ; + } + thumb_path = save_path + L"\\" + std::to_wstring(msg_id) + L".jpg"; + save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".mp4"; + + break; + } + case 0x31: { + save_path += L"\\file"; + if (!wxutils::FindOrCreateDirectory(save_path)) { + return L"-3"; + } + char* p_xml_app_msg = base::utils::WxHeapAlloc(0x3000); + uint64_t xml_msg = + new_app_msg_info(reinterpret_cast(p_xml_app_msg)); + uint64_t result = + xml_to_app_info(xml_msg, reinterpret_cast(we_content), 1); + if (result != 1) { + return L"-4"; + } + std::wstring file_name = wxutils::ReadWstring(xml_msg + 0x70); + save_path = + save_path + L"\\" + std::to_wstring(msg_id) + L"_" + file_name; + free_app_msg_info(xml_msg); + break; + } + default: + break; + } + + int temp = 1; + memcpy(chat_msg + 0x40C, &temp, sizeof(temp)); + UINT64 mgr = get_pre_download_mgr(); + INT64 success = push_attach_task(mgr, p_chat_msg, 0, 1); + std::wstring result = *(wchar_t**)(chat_msg + 0x2A0); + free_chat_msg(p_chat_msg); + return save_path + result; +} + +TODO("ForwardPublicMsg") +int64_t wechat::WeChatService::ForwardPublicMsg(const std::wstring& wxid, + const std::wstring& title, + const std::wstring& url, + const std::wstring& thumb_url, + const std::wstring& sender_id, + const std::wstring& sender_name, + const std::wstring& digest) { + return 0; +} + +TODO("ForwardPublicMsgByMsgId") +int64_t wechat::WeChatService::ForwardPublicMsgByMsgId(const std::wstring& wxid, + uint64_t msg_id) { + return 0; +} +TODO("DecodeImage") +int64_t wechat::WeChatService::DecodeImage(const std::wstring& file_path, + const std::wstring& save_dir) { + if (!wxutils::FindOrCreateDirectory(save_dir)) { + return 0; + } + + int64_t pos_begin = file_path.find_last_of(L"\\") + 1; + int64_t pos_end = file_path.find_last_of(L"."); + std::wstring file_name = file_path.substr(pos_begin, pos_end - pos_begin); + HANDLE h_origin_file = + CreateFileW(file_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + char buffer[BUFSIZE] = {0}; + DWORD bytes_read = 0; + DWORD bytes_write = 0; + unsigned char magic_head[4] = {0}; + std::wstring suffix; + short key = 0; + if (ReadFile(h_origin_file, buffer, BUFSIZE, &bytes_read, NULL)) { + memcpy(magic_head, buffer, 3); + } else { + CloseHandle(h_origin_file); + return 0; + } + if ((magic_head[0] ^ JPEG0) == (magic_head[1] ^ JPEG1)) { + key = magic_head[0] ^ JPEG0; + suffix = L".jpg"; + } else if ((magic_head[0] ^ PNG1) == (magic_head[1] ^ PNG2)) { + key = magic_head[0] ^ PNG1; + suffix = L".png"; + } else if ((magic_head[0] ^ GIF0) == (magic_head[1] ^ GIF1)) { + key = magic_head[0] ^ GIF0; + suffix = L".gif"; + } else if ((magic_head[0] ^ BMP0) == (magic_head[1] ^ BMP1)) { + key = magic_head[0] ^ BMP0; + suffix = L".bmp"; + } else { + key = -1; + suffix = L".dat"; + } + std::wstring save_img_path = save_dir + L"\\" + file_name + suffix; + HANDLE save_img = CreateFileW(save_img_path.c_str(), GENERIC_ALL, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (save_img == INVALID_HANDLE_VALUE) { + return 0; + } + if (key > 0) { + for (unsigned int i = 0; i < bytes_read; i++) { + buffer[i] ^= key; + } + } + if (!WriteFile(save_img, (LPCVOID)buffer, bytes_read, &bytes_write, 0)) { + CloseHandle(h_origin_file); + CloseHandle(save_img); + return 0; + } + + do { + if (ReadFile(h_origin_file, buffer, BUFSIZE, &bytes_read, NULL)) { + if (key > 0) { + for (unsigned int i = 0; i < bytes_read; i++) { + buffer[i] ^= key; + } + } + if (!WriteFile(save_img, (LPCVOID)buffer, bytes_read, &bytes_write, 0)) { + CloseHandle(h_origin_file); + CloseHandle(save_img); + return 0; + } + } + } while (bytes_read == BUFSIZE); + CloseHandle(h_origin_file); + CloseHandle(save_img); + return 1; +} +TODO("GetVoiceByDB") +int64_t wechat::WeChatService::GetVoiceByDB(ULONG64 msg_id, + const std::wstring& dir) { + return 0; +} +TODO("SendCustomEmotion") +int64_t wechat::WeChatService::SendCustomEmotion(const std::wstring& file_path, + const std::wstring& wxid) { + int64_t success = -1; + uint64_t get_custom_smiley_mgr_addr = + base_addr_ + offset::kGetCustomSmileyMgr; + func::__GetCustomSmileyMgr get_custom_smiley_mgr = + (func::__GetCustomSmileyMgr)get_custom_smiley_mgr_addr; + uint64_t send_custom_emotion_addr = base_addr_ + offset::kSendCustomEmotion; + func::__SendCustomEmotion send_custom_emotion = + (func::__SendCustomEmotion)send_custom_emotion_addr; + prototype::WeChatString* path = BuildWechatString(file_path); + prototype::WeChatString* recv = BuildWechatString(wxid); + int64_t* temp = base::utils::WxHeapAlloc(0x20); + memset(temp, 0, 0x20); + uint64_t mgr = get_custom_smiley_mgr(); + success = send_custom_emotion( + mgr, reinterpret_cast(path), reinterpret_cast(temp), + reinterpret_cast(recv), 2, reinterpret_cast(temp), 0, + reinterpret_cast(temp)); + return success; +} + +TODO("SendApplet") +int64_t wechat::WeChatService::SendApplet( + const std::wstring& recv_wxid, const std::wstring& waid_suff, + const std::wstring& waid_w, const std::wstring& waid_s, + const std::wstring& wa_wxid, const std::wstring& json_param, + const std::wstring& head_image, const std::wstring& big_image, + const std::wstring& index_page) { + int64_t success = -1; + if (js_api_addr_ == 0) { + auto vec2 = + base::memory::ScanAndMatchValue(base_addr_ + 0x32D1318, 0x1000, 0x8); + for (int i = 0; i < vec2.size(); i++) { + int64_t ptr = vec2.at(i); + if (*(int64_t*)ptr == base_addr_ + 0x32D1318) { + js_api_addr_ = ptr; + break; + } + } + } + if (js_api_addr_ == 0) { + success = -2; + return success; + } + + uint64_t share_app_msg_addr = base_addr_ + offset::kNewJsApiShareAppMessage; + func::__JsApiShareAppMessage share_app_msg = + (func::__JsApiShareAppMessage)share_app_msg_addr; + + uint64_t init_addr = base_addr_ + offset::kInitJsConfig; + func::__InitJsConfig init = (func::__InitJsConfig)init_addr; + + uint64_t send_applet_addr = base_addr_ + offset::kSendApplet; + func::__SendApplet send_applet = (func::__SendApplet)send_applet_addr; + + uint64_t get_by_waid_addr = base_addr_ + offset::kGetAppInfoByWaid; + func::__GetAppInfoByWaid get_app_info = + (func::__GetAppInfoByWaid)get_by_waid_addr; + + uint64_t copy_app_req_addr = base_addr_ + offset::kCopyShareAppMessageRequest; + func::__CopyShareAppMessageRequest copy_app_req = + (func::__CopyShareAppMessageRequest)copy_app_req_addr; + + uint64_t new_wa_msg_addr = base_addr_ + offset::kNewWAUpdatableMsgInfo; + func::__NewWAUpdatableMsgInfo new_wa_msg = + (func::__NewWAUpdatableMsgInfo)new_wa_msg_addr; + + uint64_t free_wa_msg_addr = base_addr_ + offset::kFreeWAUpdatableMsgInfo; + func::__FreeWAUpdatableMsgInfo free_wa_msg = + (func::__FreeWAUpdatableMsgInfo)free_wa_msg_addr; + + std::vector* temp = + base::utils::WxHeapAlloc>(0x20); + // std::vector* temp = new + // std::vector(); + wechat::VectorInner* list = (wechat::VectorInner*)temp; + + prototype::WeChatString* member = BuildWechatString(recv_wxid); +#ifdef _DEBUG + list->head = reinterpret_cast(member); +#endif + list->start = reinterpret_cast(member); + list->finsh = reinterpret_cast(member) + 0x20; + list->end = reinterpret_cast(member) + 0x20; + + uint64_t head = reinterpret_cast(&(list->start)); + + prototype::WeChatString* waid_cat = BuildWechatString(waid_suff); + prototype::WeChatString* waid = BuildWechatString(waid_w); + + prototype::WeChatString* waid_2 = BuildWechatString(waid_suff); + + prototype::WeChatString* waid_str = BuildWechatString(waid_s); + prototype::WeChatString* app_wxid = BuildWechatString(wa_wxid); + prototype::WeChatString* json_str = BuildWechatString(json_param); + prototype::WeChatString* head_image_url = BuildWechatString(head_image); + prototype::WeChatString* image = BuildWechatString(big_image); + prototype::WeChatString* index = BuildWechatString(index_page); + + uint64_t app_msg = js_api_addr_; + + uint64_t data = *(uint64_t*)(app_msg + 0x8); + char* share_req = base::utils::WxHeapAlloc(0x2000); + + char* mid_ptr = base::utils::WxHeapAlloc(0x18); + memcpy(mid_ptr, &share_req, sizeof(INT64)); + memcpy(mid_ptr + 0x8, &share_req, sizeof(INT64)); + memcpy(mid_ptr + 0x10, &share_req, sizeof(INT64)); + + memcpy((void*)data, mid_ptr, 0x18); + + memcpy(share_req, (void*)(app_msg + 0x8), sizeof(uint64_t)); + memcpy(share_req + 0x8, (void*)(app_msg + 0x8), sizeof(uint64_t)); + memcpy(share_req + 0x10, (void*)(app_msg + 0x8), sizeof(uint64_t)); + memcpy(share_req + 0x20, waid_2, sizeof(prototype::WeChatString)); + memcpy(share_req + 0x48, waid_str, sizeof(prototype::WeChatStr)); + memcpy(share_req + 0x98, app_wxid, sizeof(prototype::WeChatStr)); + memcpy(share_req + 0xF8, json_str, sizeof(prototype::WeChatStr)); + memcpy(share_req + 0x178, head_image_url, sizeof(prototype::WeChatStr)); + memcpy(share_req + 0x198, image, sizeof(prototype::WeChatStr)); + memcpy(share_req + 0x1c0, index, sizeof(prototype::WeChatStr)); + + success = send_applet(app_msg, reinterpret_cast(waid_cat), head, 0); + return success; +} + +int64_t wechat::WeChatService::SendPatMsg(const std::wstring& room_id, + const std::wstring& wxid) { + int64_t success = -1; + uint64_t 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)); + return success; +} + +TODO("DoOCRTask") +int64_t wechat::WeChatService::DoOCRTask(const std::wstring& img_path, + std::string& result) { + int64_t success = -1; + uint64_t ocr_manager_addr = base_addr_ + offset::kGetOCRManager; + func::__GetOCRManager ocr_manager = (func::__GetOCRManager)ocr_manager_addr; + + uint64_t do_ocr_task_addr = base_addr_ + offset::kDoOCRTask; + func::__DoOCRTask do_ocr_task = (func::__DoOCRTask)do_ocr_task_addr; + + prototype::WeChatString img(img_path); + std::vector* temp = + base::utils::WxHeapAlloc>(0x20); + int64_t unkonwn = 0; + wechat::VectorInner* list = (wechat::VectorInner*)temp; + list->start = reinterpret_cast(&list->start); + list->finsh = list->start; + char buff[0x28] = {0}; + memcpy(buff, &list->start, sizeof(INT64)); + uint64_t mgr = ocr_manager(); + success = do_ocr_task(mgr, reinterpret_cast(&img), 1, + reinterpret_cast(buff), + reinterpret_cast(&unkonwn)); + int64_t number = *(int64_t*)(buff + 0x8); + if (number > 0) { + int64_t header = *(int64_t*)(buff); + for (unsigned int i = 0; i < number; i++) { + int64_t content = *(int64_t*)header; + result += wxutils::ReadWstringThenConvert(content + 0x28); + result += "\r\n"; + header = content; + } + } + return success; +} + +int64_t wechat::WeChatService::LockWeChat() { + int64_t success = -1; + 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); + return success; +} + +int64_t wechat::WeChatService::UnlockWeChat() { + int64_t success = -1; + 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); + + return success; +} + +int64_t wechat::WeChatService::EnterWeChat() { + int64_t success = -1; + int64_t base_addr = wxutils::GetWeChatWinBase(); + uint64_t click_cb_addr = base_addr + offset::kOnLoginBtnClick; + func::__OnLoginBtnClick cb = (func::__OnLoginBtnClick)click_cb_addr; + auto vec = + base::memory::ScanAndMatchValue(base_addr + 0x4ecedf8, 0x1000, 0x8); + for (int i = 0; i < vec.size(); i++) { + int64_t ptr = vec.at(i); + if (*(int64_t*)ptr == base_addr + 0x4ecedf8) { + int64_t login_wnd = ptr; + success = cb(ptr); + break; + } + } + return success; +} + +TODO("SendMultiAtText") +int64_t wechat::WeChatService::SendMultiAtText( + const std::wstring& room_id, + const std::vector>& at) { + int64_t success = -1; + std::vector wxid_list; + wechat::VectorInner* list = (wechat::VectorInner*)&wxid_list; + std::wstring at_msg = L""; + int number = 0; + for (unsigned int i = 0; i < at.size(); i++) { + std::wstring nickname; + std::wstring at_all = L"notify@all"; + if (at_all.compare(at[i].first) == 0) { + nickname = L"\u6240\u6709\u4eba"; + } else { + // nickname = GetContactOrChatRoomNickname(at[i].first); + nickname = L""; + } + if (nickname.length() == 0) { + continue; + } + prototype::WeChatString id(at[i].first); + wxid_list.push_back(id); + at_msg = at_msg + L"@" + nickname + L" " + at[i].second + L" "; + number++; + } + if (number < 1) { + success = -2; + return success; + } + int64_t head = (int64_t)&list->start; + prototype::WeChatString to_user(room_id); + prototype::WeChatString text_msg(at_msg); + uint64_t send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr; + uint64_t send_text_msg_addr = base_addr_ + offset::kSendTextMsg; + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + char chat_msg[0x460] = {0}; + func::__GetSendMessageMgr mgr = + (func::__GetSendMessageMgr)send_message_mgr_addr; + func::__SendTextMsg send = (func::__SendTextMsg)send_text_msg_addr; + func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr; + mgr(); + success = send(reinterpret_cast(&chat_msg), + reinterpret_cast(&to_user), + reinterpret_cast(&text_msg), head, 1, 1, 0, 0); + free(reinterpret_cast(&chat_msg)); + return success; +} + +std::string wechat::WeChatService::GetLoginUrl() { + 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); + return "http://weixin.qq.com/x/" + login_url; +} + +void wechat::WeChatService::SetBaseAddr(uint64_t addr) { + this->base_addr_ = addr; +} + +void wechat::WeChatService::SetJsApiAddr(uint64_t addr) { + this->js_api_addr_ = addr; +} + +TODO("TranslateVoice") +int64_t wechat::WeChatService::TranslateVoice(uint64_t msg_id) { + int64_t success = -1; + uint64_t get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId; + func::__GetMgrByPrefixLocalId get_by_local_id = + (func::__GetMgrByPrefixLocalId)get_by_local_id_addr; + + uint64_t get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr; + func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr; + + uint64_t free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg; + func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr; + + uint64_t new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter; + func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr; + + uint64_t update_addr = base_addr_ + offset::kUpdateMsg; + func::__UpdateMsg update = (func::__UpdateMsg)update_addr; + + uint64_t get_voice_mgr_addr = base_addr_ + offset::kGetVoiceMgr; + func::__GetVoiceMgr get_voice_mgr = (func::__GetVoiceMgr)get_voice_mgr_addr; + + uint64_t to_msg_addr = base_addr_ + offset::kChatMsg2NetSceneSendMsg; + func::__ChatMsg2NetSceneSendMsg to_msg = + (func::__ChatMsg2NetSceneSendMsg)to_msg_addr; + + uint64_t trans_addr = base_addr_ + offset::kTranslateVoice; + func::__TranslateVoice translate_voice = (func::__TranslateVoice)trans_addr; + + char temp_msg[0x460] = {0}; + + char* chat_msg = base::utils::WxHeapAlloc(0x460); + int64_t index = 0; + int64_t local_id = + wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); + if (local_id <= 0 || index >> 32 == 0) { + success = -2; + + return success; + } + LARGE_INTEGER l; + l.HighPart = index >> 32; + l.LowPart = (DWORD)local_id; + uint64_t p_chat_msg = new_chat_msg(reinterpret_cast(chat_msg)); + get_chat_mgr(); + get_by_local_id(l.QuadPart, p_chat_msg); + uint64_t mgr = get_chat_mgr(); + update(mgr, p_chat_msg, 0); + + uint64_t voice_mgr = get_voice_mgr(); + uint64_t msg = to_msg(reinterpret_cast(&temp_msg), p_chat_msg); + + success = translate_voice(voice_mgr, msg, 0); + + return success; +} + +TODO("GetTranslateVoiceText") +std::string wechat::WeChatService::GetTranslateVoiceText(uint64_t msg_id) { + std::string content = + wechat::WeChatDb::GetInstance().GetChatMsgStrContentByMsgId(msg_id); + if (content.empty()) { + return {}; + } + tinyxml2::XMLDocument doc; + if (doc.Parse(content.c_str(), content.size()) != 0) { + SPDLOG_INFO("tinyxml2 parse error"); + return {}; + } + tinyxml2::XMLElement* msg = doc.FirstChildElement("msg"); + if (msg != nullptr) { + tinyxml2::XMLElement* voicetrans = msg->FirstChildElement("voicetrans"); + if (voicetrans != nullptr) { + const char* value = voicetrans->Attribute("transtext", nullptr); + return value; + } + } + return ""; +} + +TODO("OpenUrlByWeChatBrowser") +int64_t wechat::WeChatService::OpenUrlByWeChatBrowser(const std::wstring& url, + int flag) { + int64_t success = -1; + uint64_t config_addr = base_addr_ + offset::kNewWebViewPageConfig; + func::__NewWebViewPageConfig config = + (func::__NewWebViewPageConfig)config_addr; + + uint64_t free_config_addr = base_addr_ + offset::kFreeWebViewPageConfig; + func::__FreeWebViewPageConfig free_config = + (func::__FreeWebViewPageConfig)free_config_addr; + + uint64_t web_view_mgr_addr = base_addr_ + offset::kGetWebViewMgr; + func::__GetWebViewMgr web_view_mgr = (func::__GetWebViewMgr)web_view_mgr_addr; + + uint64_t show_addr = base_addr_ + offset::kShowWebView; + func::__ShowWebView show_web_view = (func::__ShowWebView)show_addr; + + uint64_t set_url_addr = base_addr_ + offset::kSetUrl; + func::__SetUrl set_url = (func::__SetUrl)set_url_addr; + + int a = flag >> 4; + int b = flag & 0x1; + int c = flag & 0x2; + int d = flag & 0x4; + int e = flag & 0x8; + char* web_config = (char*)HeapAlloc(GetProcessHeap(), 0, 0xA20); + + uint64_t ptr = config(reinterpret_cast(web_config)); + set_url(ptr + 0x868, reinterpret_cast(url.c_str()), url.size()); + web_view_mgr(); + success = show_web_view(ptr, a, b, c, d, e); + free_config(ptr); + return success; +} + +TODO("GetChatRoomMemberNickname") +std::wstring wechat::WeChatService::GetChatRoomMemberNickname( + const std::wstring& room_id, const std::wstring& member_id) { + + return std::wstring(); +} + +TODO("DelContact") +int64_t wechat::WeChatService::DelContact(const std::wstring& wxid) { + int64_t success = -1; + uint64_t del_contcat_addr = base_addr_ + offset::kDoDelContact; + func::__DelContact del_contcat = (func::__DelContact)del_contcat_addr; + + return success; +} + +TODO("SearchContact") +int64_t wechat::WeChatService::SearchContact( + const std::wstring& keyword, wechat::SearchContactInner& contact) { + int64_t success = -1; + prototype::WeChatString key(keyword); + uint64_t search_mgr_addr = base_addr_ + offset::kGetSearchContactMgr; + uint64_t search_addr = base_addr_ + offset::kStartSearch; + + func::__GetSearchContactMgr get_mgr = + (func::__GetSearchContactMgr)search_mgr_addr; + func::__StartSearch search = (func::__StartSearch)search_addr; + uint64_t mgr = get_mgr(); + // success = search(mgr,&key); + + return success; +} + +TODO("AddFriendByWxid") +int64_t wechat::WeChatService::AddFriendByWxid(const std::wstring& wxid, + const std::wstring& msg) { + uint64_t add_friend_addr = base_addr_ + offset::kAddFriend; + func::__AddFriend add_friend = (func::__AddFriend)add_friend_addr; + return 0; +} + +TODO("VerifyApply") +int64_t wechat::WeChatService::VerifyApply(const std::wstring& v3, + const std::wstring& v4, + int32_t permission) { + uint64_t verify_addr = base_addr_ + offset::kVerifyApply; + func::__Verify add_friend = (func::__Verify)verify_addr; + return 0; +} + +TODO("DoConfirmReceipt") +int64_t wechat::WeChatService::DoConfirmReceipt( + const std::wstring& wxid, const std::wstring& transcationid, + const std::wstring& transferid) { + int success = -1; + prototype::WeChatString recv_id(wxid); + prototype::WeChatString transcation_id(transcationid); + prototype::WeChatString transfer_id(transferid); + + char pay_info[0x224] = {0}; + uint64_t new_pay_info_addr = base_addr_ + offset::kNewPayInfo; + uint64_t free_pay_info_addr = base_addr_ + offset::kFreePayInfo; + uint64_t do_confirm_addr = base_addr_ + offset::kTransferConfirm; + + func::__NewWCPayInfo new_pay_info = (func::__NewWCPayInfo)new_pay_info_addr; + func::__FreeWCPayInfo free_pay_info = + (func::__FreeWCPayInfo)free_pay_info_addr; + func::__PayTransferConfirm do_confirm = + (func::__PayTransferConfirm)do_confirm_addr; + + new_pay_info(reinterpret_cast(&pay_info)); + memcpy(&pay_info[0x30], &transcation_id, sizeof(transcation_id)); + memcpy(&pay_info[0x58], &transfer_id, sizeof(transfer_id)); + // memcpy(&pay_info[0xA0], &recv_id, sizeof(recv_id)); + success = do_confirm(reinterpret_cast(&pay_info), reinterpret_cast(&recv_id)); + + free_pay_info(reinterpret_cast(&pay_info)); + + return success; +} + +TODO("DoRefuseReceipt") +int64_t wechat::WeChatService::DoRefuseReceipt( + const std::wstring& wxid, const std::wstring& transcationid, + const std::wstring& transferid) { + int success = -1; + prototype::WeChatString recv_id(wxid); + prototype::WeChatString transcation_id(transcationid); + prototype::WeChatString transfer_id(transferid); + + char pay_info[0x224] = {0}; + uint64_t new_pay_info_addr = base_addr_ + offset::kNewPayInfo; + uint64_t free_pay_info_addr = base_addr_ + offset::kFreePayInfo; + uint64_t do_refuse_addr = base_addr_ + offset::kTransferRefuse; + + func::__NewWCPayInfo new_pay_info = (func::__NewWCPayInfo)new_pay_info_addr; + func::__FreeWCPayInfo free_pay_info = + (func::__FreeWCPayInfo)free_pay_info_addr; + func::__PayTransferRefuse do_refuse = + (func::__PayTransferRefuse)do_refuse_addr; + + new_pay_info(reinterpret_cast(&pay_info)); + memcpy(&pay_info[0x30], &transcation_id, sizeof(transcation_id)); + memcpy(&pay_info[0x58], &transfer_id, sizeof(transfer_id)); + // memcpy(&pay_info[0xA0], &recv_id, sizeof(recv_id)); + success = do_refuse(reinterpret_cast(&pay_info), reinterpret_cast(&recv_id)); + + free_pay_info(reinterpret_cast(&pay_info)); + return success; +} diff --git a/inc/wechat_service.h b/inc/wechat_service.h index 3a677fc..9f4474d 100644 --- a/inc/wechat_service.h +++ b/inc/wechat_service.h @@ -54,7 +54,7 @@ class WeChatService : public base::Singleton { std::wstring GetContactOrChatRoomNickname(const std::wstring& wxid); int64_t GetContactByWxid(const std::wstring& wxid, ContactProfileInner& profile); - int64_t DoDownloadTask(uint64_t msg_id); + std::wstring DoDownloadTask(uint64_t msg_id); int64_t ForwardPublicMsg(const std::wstring& wxid, const std::wstring& title, const std::wstring& url, const std::wstring& thumb_url, diff --git a/src/misc_controller.cc b/src/misc_controller.cc index 7e049d8..37527ee 100644 --- a/src/misc_controller.cc +++ b/src/misc_controller.cc @@ -1,5 +1,6 @@ #include "misc_controller.h" - +#include +#include #include "json_utils.h" #include "nlohmann/json.hpp" #include "spdlog/spdlog.h" @@ -162,8 +163,10 @@ std::string MiscController::DownloadAttach(std::string params) { SPDLOG_INFO("DownloadAttach params:{}", params); nlohmann::json jp = nlohmann::json::parse(params); int64_t msg_id = jsonutils::GetInt64Param(jp, "msgId"); - int64_t success = wechat::WeChatService::GetInstance().DoDownloadTask(msg_id); - nlohmann::json ret = {{"code", success}, {"data", {}}, {"msg", "success"}}; + std::wstring result = wechat::WeChatService::GetInstance().DoDownloadTask(msg_id); + std::string result_str = std::wstring_convert>().to_bytes(result); + nlohmann::json ret = { + {"code", 1}, {"data", {"result", result_str}}, {"msg", "success"} }; return ret.dump(); } } // namespace wxhelper diff --git a/src/wechat_service.cc b/src/wechat_service.cc index e659605..47f5ce2 100644 --- a/src/wechat_service.cc +++ b/src/wechat_service.cc @@ -844,9 +844,23 @@ int64_t wechat::WeChatService::GetContactByWxid(const std::wstring& wxid, return success; } +std::wstring combineAndRemoveDuplicate(const std::wstring& basePath, const std::wstring& resultPath) { + std::wstring cleanedBasePath = basePath; + if (cleanedBasePath.back() == L'\\') { + cleanedBasePath.pop_back(); + } + size_t pos = resultPath.find(cleanedBasePath); + if (pos != std::wstring::npos) { + std::wstring adjustedResultPath = resultPath.substr(pos + cleanedBasePath.length()); + return cleanedBasePath + L'\\' + adjustedResultPath; + } + + return basePath + L'\\' + resultPath; +} TODO("DoDownloadTask") -int64_t wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { - int64_t success = -1; + +std::wstring wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { + uint64_t get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId; func::__GetMgrByPrefixLocalId get_by_local_id = (func::__GetMgrByPrefixLocalId)get_by_local_id_addr; @@ -889,8 +903,7 @@ int64_t wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { int64_t local_id = wechat::WeChatDb::GetInstance().GetLocalIdByMsgId(msg_id, index); if (local_id <= 0 || index >> 32 == 0) { - success = -2; - return success; + return L"-2"; } char* chat_msg = base::utils::WxHeapAlloc(0x460); LARGE_INTEGER l; @@ -909,45 +922,42 @@ int64_t wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { if (current_data_path.length > 0) { save_path += current_data_path.ptr; - save_path += L"wxhelper"; } else { - return -1; + return L"-1"; } - if (!wxutils::FindOrCreateDirectory(save_path)) { - return -3; - } - int64_t type = *(int64_t*)(chat_msg + 0x38); + int64_t type = *(int64_t*)(chat_msg + 0x38); wchar_t* content = *(wchar_t**)(chat_msg + 0x88); DWORD len = *(DWORD*)(chat_msg + 0x94); std::wstring tmp_content(content, len); prototype::WeChatString* we_content = BuildWechatString(tmp_content); switch (type) { - case 0x3: { - save_path += L"\\image"; - if (!wxutils::FindOrCreateDirectory(save_path)) { - return -3; + case 0x3: { + if (!save_path.empty() && save_path.back() == L'\\') { + save_path.pop_back(); + } + size_t pos = save_path.find_last_of(L'\\'); + if (pos != std::wstring::npos) { + save_path = save_path.substr(0, pos + 1); // 保留最后一个反斜杠 } - thumb_path = save_path + L"\\" + std::to_wstring(msg_id) + L"_t.dat"; - save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".dat"; break; - } - case 0x3E: - case 0x2B: { + } + case 0x3E: + case 0x2B: { save_path += L"\\video"; if (!wxutils::FindOrCreateDirectory(save_path)) { - return -3; + return L"-3" ; } thumb_path = save_path + L"\\" + std::to_wstring(msg_id) + L".jpg"; save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".mp4"; break; - } - case 0x31: { + } + case 0x31: { save_path += L"\\file"; if (!wxutils::FindOrCreateDirectory(save_path)) { - return -3; + return L"-3"; } char* p_xml_app_msg = base::utils::WxHeapAlloc(0x3000); uint64_t xml_msg = @@ -955,28 +965,25 @@ int64_t wechat::WeChatService::DoDownloadTask(uint64_t msg_id) { uint64_t result = xml_to_app_info(xml_msg, reinterpret_cast(we_content), 1); if (result != 1) { - return -4; + return L"-4"; } std::wstring file_name = wxutils::ReadWstring(xml_msg + 0x70); save_path = save_path + L"\\" + std::to_wstring(msg_id) + L"_" + file_name; free_app_msg_info(xml_msg); break; - } - default: + } + default: break; } - prototype::WeChatString* we_save_path = BuildWechatString(save_path); - prototype::WeChatString* we_thumb_path = BuildWechatString(thumb_path); + int temp = 1; - memcpy(chat_msg + 0x280, we_thumb_path, sizeof(prototype::WeChatString)); - memcpy(chat_msg + 0x2A0, we_save_path, sizeof(prototype::WeChatString)); memcpy(chat_msg + 0x40C, &temp, sizeof(temp)); UINT64 mgr = get_pre_download_mgr(); - success = push_attach_task(mgr, p_chat_msg, 0, 1); + INT64 success = push_attach_task(mgr, p_chat_msg, 0, 1); + std::wstring result = *(wchar_t**)(chat_msg + 0x2A0); free_chat_msg(p_chat_msg); - - return success; + return save_path + result; } TODO("ForwardPublicMsg") diff --git a/wxhelper.vcxproj b/wxhelper.vcxproj index d050655..af5a5c9 100644 --- a/wxhelper.vcxproj +++ b/wxhelper.vcxproj @@ -118,7 +118,7 @@ Level3 - ProgramDatabase + EditAndContinue Disabled stdcpp17 inc\nlohmann;inc\tinyxml2;inc\mongoose;inc\lz4;inc\Detours;inc\include;inc\base64;inc;inc\spdlog;%(AdditionalIncludeDirectories)