From 055adf5eab6ffff12633aa81fd56ec50de7c2be9 Mon Sep 17 00:00:00 2001 From: hugy <504650082@qq.com> Date: Tue, 21 Mar 2023 12:34:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Ehook=E8=AF=AD=E9=9F=B3?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +- src/api.cc | 599 ------------------------------------------- src/api.h | 71 ----- src/base64.cpp | 312 ---------------------- src/base64.h | 35 --- src/chat_room.cc | 184 ------------- src/chat_room.h | 10 - src/common.cc | 138 ---------- src/common.h | 83 ------ src/contact.cc | 106 -------- src/contact.h | 11 - src/db_operation.cc | 155 ----------- src/db_operation.h | 23 -- src/dllMain.cc | 23 -- src/forward.cc | 41 --- src/forward.h | 5 - src/framework.h | 7 - src/get_db_handle.cc | 299 --------------------- src/get_db_handle.h | 9 - src/hook_img.cc | 231 ----------------- src/hook_img.h | 10 - src/hook_recv_msg.cc | 220 ---------------- src/hook_recv_msg.h | 10 - src/new_sqlite3.h | 195 -------------- src/pch.h | 18 -- src/self_info.cc | 139 ---------- src/self_info.h | 7 - src/send_file.cc | 67 ----- src/send_file.h | 5 - src/send_image.cc | 47 ---- src/send_image.h | 5 - src/send_text.cc | 45 ---- src/send_text.h | 6 - src/wechat_data.h | 140 ---------- 34 files changed, 6 insertions(+), 3258 deletions(-) delete mode 100644 src/api.cc delete mode 100644 src/api.h delete mode 100644 src/base64.cpp delete mode 100644 src/base64.h delete mode 100644 src/chat_room.cc delete mode 100644 src/chat_room.h delete mode 100644 src/common.cc delete mode 100644 src/common.h delete mode 100644 src/contact.cc delete mode 100644 src/contact.h delete mode 100644 src/db_operation.cc delete mode 100644 src/db_operation.h delete mode 100644 src/dllMain.cc delete mode 100644 src/forward.cc delete mode 100644 src/forward.h delete mode 100644 src/framework.h delete mode 100644 src/get_db_handle.cc delete mode 100644 src/get_db_handle.h delete mode 100644 src/hook_img.cc delete mode 100644 src/hook_img.h delete mode 100644 src/hook_recv_msg.cc delete mode 100644 src/hook_recv_msg.h delete mode 100644 src/new_sqlite3.h delete mode 100644 src/pch.h delete mode 100644 src/self_info.cc delete mode 100644 src/self_info.h delete mode 100644 src/send_file.cc delete mode 100644 src/send_file.h delete mode 100644 src/send_image.cc delete mode 100644 src/send_image.h delete mode 100644 src/send_text.cc delete mode 100644 src/send_text.h delete mode 100644 src/wechat_data.h diff --git a/README.md b/README.md index a798bce..7327b7a 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,9 @@ vcpkg 2023-03-02 : 新增发送@消息 -2023-03-04 : 新增消息附件下载 +2023-03-04 : 新增消息附件下载 + +2023-03-21 : 新增hook语音 #### 功能预览: 0.检查是否登录 @@ -136,7 +138,9 @@ vcpkg 9.hook消息 10.取消hook消息 11.hook图片 -12.取消hook图片 +12.取消hook图片 +13.hook语音 +14.取消hook语音 17.删除好友 19.通过手机或qq查找微信 20.通过wxid添加好友 diff --git a/src/api.cc b/src/api.cc deleted file mode 100644 index 10f5d5b..0000000 --- a/src/api.cc +++ /dev/null @@ -1,599 +0,0 @@ -#include "pch.h" -#include "api.h" -#include - -#include - - -#include "send_text.h" -#include "common.h" -#include "send_image.h" -#include "send_file.h" -#include "hook_recv_msg.h" -#include "get_db_handle.h" -#include "wechat_data.h" -#include "forward.h" -#include "db_operation.h" -#include "contact.h" -#include "chat_room.h" -#include "self_info.h" -#include "hook_img.h" - -#pragma comment(lib, "ws2_32.lib") -using namespace std; -using namespace nlohmann; - -#define STR2INT(str) (is_digit(str) ? stoi(str) : 0) -#define WS2LW(wstr) (LPWSTR) wstr.c_str() - -static bool kHttpRuning = false; -static HANDLE kHttpThread = NULL; - -bool is_digit(string str) { - if (str.length() == 0) { - return false; - } - - for (auto it : str) { - if (it < '0' || it > '9') { - return false; - } - } - return true; -} - -string get_var(mg_http_message *hm, string name) { - string ret; - char *buffer = new char[hm->query.len + 1]; - ZeroMemory(buffer, hm->query.len + 1); - int len = mg_http_get_var(&hm->query, name.c_str(), buffer, hm->query.len); - if (len > 0) ret = string(buffer, len); - delete[] buffer; - buffer = NULL; - return ret; -} -/// @brief 获取request中的请求参数int类型 -/// @param hm 消息 -/// @param data json数据 -/// @param key key -/// @param method 是否是post,暂时全部用post -/// @return int -static int get_http_req_param_int(mg_http_message *hm, json data, string key, int method){ - int result; - switch (method) { - case 0: { - result = STR2INT(get_var(hm,key).c_str()); - break; - } - case 1: { - try { - result = data[key].get(); - } catch (json::exception) { - result = STR2INT(data[key].get()); - } - break; - } - default: - break; - } - return result; -} - -/// @brief 获取request中的请求参数 -/// @param hm 消息 -/// @param data json数据 -/// @param key key -/// @param method 是否是post,暂时全部用post -/// @return -static wstring get_http_req_param(mg_http_message *hm, json data, string key, int method){ - wstring result; - switch (method) { - case 0: { - result = utf8_to_unicode(get_var(hm,key).c_str()); - break; - } - case 1: { - result = utf8_to_unicode(data[key].get().c_str()); - break; - } - default: - break; - } - return result; -} - -static unsigned long long get_http_param_ulong64(mg_http_message *hm, - json j_data, string key, - int method) { - unsigned long long result = 0; - switch (method) { - case 0: { - string value = get_var(hm, key); - istringstream is(value); - is >> result; - break; - } - case 1: { - try { - result = j_data[key].get(); - } catch (json::exception) { - string value = j_data[key].get(); - istringstream is(value); - is >> result; - } - break; - } - default: - break; - } - return result; -} - -static int get_http_param_int(mg_http_message *hm, json j_data, string key, - int method) { - int result = 0; - switch (method) { - case 0: { - result = STR2INT(get_var(hm, key)); - break; - } - case 1: { - try { - result = j_data[key].get(); - } catch (json::exception) { - result = STR2INT(j_data[key].get()); - } - break; - } - default: - break; - } - return result; -} - -static vector get_http_param_array(mg_http_message *hm, json j_data, - string key, int method) { - vector result; - switch (method) { - case 0: { - result = split(utf8_to_unicode(get_var(hm, key).c_str()), L','); - break; - } - case 1: { - result = split(utf8_to_unicode(j_data[key].get().c_str()), L','); - break; - } - default: - break; - } - return result; -} - -/// @brief api接口入口解析 -/// @param hm mg_http_message -/// @param c connection -/// @param ret json数据 -void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) { - int is_post = 0; - - if (mg_vcasecmp(&hm->method, "POST") == 0) { - is_post = 1; - } - #ifdef _DEBUG - printf("method:%s body: %s", hm->method.ptr,hm->body.ptr); - #endif - if (is_post == 0){ - json ret_data = {{"result", "ERROR"}, {"msg", "not support method"}}; - ret = ret_data.dump(); - return; - } - - json j_param = - json::parse(hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false); - if (hm->body.len != 0 && j_param.is_discarded() == true) { - json ret_data = {{"result", "ERROR"}, {"msg", "json string is invalid."}}; - ret = ret_data.dump(); - return; - } - int api_number = STR2INT(get_var(hm, "type")); - switch (api_number) { - case WECHAT_IS_LOGIN: { - int success = CheckLogin(); - json ret_data = {{"result", "OK"}, {"code", success}}; - ret = ret_data.dump(); - break; - } - case WECHAT_GET_SELF_INFO: { - SelfInfoInner self_info; - int success = GetSelfInfo(self_info); - json ret_data = {{"result", "OK"}, {"code", success}}; - if (success) { - json j_info = { - {"name", self_info.name}, - {"city", self_info.city}, - {"province", self_info.province}, - {"country", self_info.country}, - {"account", self_info.account}, - {"wxid", self_info.wxid}, - {"mobile", self_info.mobile}, - {"smallImage", self_info.small_img}, - {"bigImage", self_info.big_img}, - {"dataRootPath",self_info.data_root_path}, - {"dataSavePath",self_info.data_save_path}, - {"currentDataPath",self_info.current_data_path}, - }; - ret_data["data"] = j_info; - } - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_SEND_TEXT: { - wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post); - wstring msg = get_http_req_param(hm, j_param, "msg", is_post); - int success = SendText(WS2LW(wxid), WS2LW(msg)); - json ret_data = {{"result", "OK"}, {"code", success}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_SEND_AT: { - break; - } - case WECHAT_MSG_SEND_CARD: { - break; - } - case WECHAT_MSG_SEND_IMAGE: { - wstring receiver = get_http_req_param(hm, j_param, "wxid", is_post); - wstring img_path = get_http_req_param(hm, j_param, "imagePath", is_post); - int success = SendImage(WS2LW(receiver), WS2LW(img_path)); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_SEND_FILE: { - wstring receiver = get_http_req_param(hm, j_param, "wxid", is_post); - wstring file_path = get_http_req_param(hm, j_param, "filePath", is_post); - int success = SendFile(WS2LW(receiver), WS2LW(file_path)); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_SEND_ARTICLE: { - break; - } - case WECHAT_MSG_SEND_APP: { - break; - } - case WECHAT_MSG_START_HOOK: { - int port = get_http_req_param_int(hm, j_param, "port", is_post); - int success = HookRecvMsg(port); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_STOP_HOOK: { - int success = UnHookRecvMsg(); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_START_IMAGE_HOOK: { - wstring img_dir = get_http_req_param(hm, j_param, "imgDir", is_post); - int success = HookImg(img_dir); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_STOP_IMAGE_HOOK: { - int success = UnHookImg(); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_MSG_START_VOICE_HOOK: { - break; - } - case WECHAT_MSG_STOP_VOICE_HOOK: { - break; - } - case WECHAT_CONTACT_GET_LIST: { - - break; - } - case WECHAT_CONTACT_CHECK_STATUS: { - break; - } - case WECHAT_CONTACT_DEL: { - wstring user_id = get_http_req_param(hm, j_param, "wxid", is_post); - int success = DelContact(WS2LW(user_id)); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_CONTACT_SEARCH_BY_CACHE: { - break; - } - case WECHAT_CONTACT_SEARCH_BY_NET: { - break; - } - case WECHAT_CONTACT_ADD_BY_WXID: { - break; - } - case WECHAT_CONTACT_ADD_BY_V3: { - break; - } - case WECHAT_CONTACT_ADD_BY_PUBLIC_ID: { - break; - } - case WECHAT_CONTACT_VERIFY_APPLY: { - break; - } - case WECHAT_CONTACT_EDIT_REMARK: { - break; - } - case WECHAT_CHATROOM_GET_MEMBER_LIST: { - wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post); - ChatRoomInner out{0}; - int success = GetMemberFromChatRoom(WS2LW(room_id),out); - json ret_data = {{"code", success}, {"result", "OK"}}; - if (success){ - json member_info ={ - {"admin",unicode_to_utf8(out.admin)}, - {"chatRoomId",unicode_to_utf8(out.chat_room)}, - {"members",out.members}, - }; - ret_data["data"] = member_info; - } - ret = ret_data.dump(); - break; - } - case WECHAT_CHATROOM_GET_MEMBER_NICKNAME: { - break; - } - case WECHAT_CHATROOM_DEL_MEMBER: { - wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post); - vector wxids = get_http_param_array(hm, j_param, "memberIds", is_post); - vector wxid_list; - for (unsigned int i = 0; i < wxids.size(); i++){ - wxid_list.push_back(WS2LW(wxids[i])); - } - int success = DelMemberFromChatRoom(WS2LW(room_id), wxid_list.data(),wxid_list.size()); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_CHATROOM_ADD_MEMBER: { - wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post); - vector wxids = get_http_param_array(hm, j_param, "memberIds", is_post); - vector wxid_list; - for (unsigned int i = 0; i < wxids.size(); i++){ - wxid_list.push_back(WS2LW(wxids[i])); - } - int success = AddMemberToChatRoom(WS2LW(room_id), wxid_list.data(),wxid_list.size()); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_CHATROOM_SET_ANNOUNCEMENT: { - break; - } - case WECHAT_CHATROOM_SET_CHATROOM_NAME: { - break; - } - case WECHAT_CHATROOM_SET_SELF_NICKNAME: { - break; - } - case WECHAT_DATABASE_GET_HANDLES: { - vector v_ptr = GetDbHandles(); - json ret_data = {{"data", json::array()}, {"result", "OK"}}; - for (unsigned int i = 0; i < v_ptr.size(); i++) { - json db_info; - db_info["tables"] = json::array(); - DatabaseInfo *db = reinterpret_cast(v_ptr[i]); - db_info["handle"] = db->handle; - db_info["databaseName"] = unicode_to_utf8(db->db_name); - for (auto table : db->tables) { - json table_info = {{"name", table.name}, - {"tableName", table.table_name}, - {"sql", table.sql}, - {"rootpage", table.rootpage}}; - db_info["tables"].push_back(table_info); - } - ret_data["data"].push_back(db_info); - } - ret = ret_data.dump(); - break; - } - case WECHAT_DATABASE_BACKUP: { - break; - } - case WECHAT_DATABASE_QUERY: { - DWORD db_handle = get_http_param_int(hm, j_param, "dbHandle", is_post); - wstring sql = get_http_req_param(hm, j_param, "sql", is_post); - string sql_str = unicode_to_utf8(WS2LW(sql)); - vector> items; - int success = Select(db_handle, sql_str.c_str(),items); - json ret_data = {{"data", json::array()}, {"code",success},{"result", "OK"}}; - if(success == 0){ - ret = ret_data.dump(); - break; - } - for (auto it : items) { - json temp_arr = json::array(); - for (size_t i = 0; i < it.size(); i++) { - temp_arr.push_back(it[i]); - } - ret_data["data"].push_back(temp_arr); - } - ret = ret_data.dump(); - break; - } - case WECHAT_SET_VERSION: { - break; - } - case WECHAT_LOG_START_HOOK: { - break; - } - case WECHAT_LOG_STOP_HOOK: { - break; - } - case WECHAT_BROWSER_OPEN_WITH_URL: { - break; - } - case WECHAT_GET_PUBLIC_MSG: { - break; - } - case WECHAT_MSG_FORWARD_MESSAGE: { - wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post); - ULONG64 msgid = get_http_param_ulong64(hm, j_param, "msgid", is_post); - int success = ForwardMsg(WS2LW(wxid), msgid); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - break; - } - case WECHAT_GET_QRCODE_IMAGE: { - break; - } - case WECHAT_GET_A8KEY: { - break; - } - case WECHAT_MSG_SEND_XML: { - break; - } - case WECHAT_LOGOUT: { - break; - } - case WECHAT_GET_TRANSFER: { - break; - } - case WECHAT_GET_CONTACT_ALL: { - vector vec; - int success = GetAllContact(vec); - json ret_data = { - {"data", json::array()}, {"code", success}, {"result", "OK"}}; - - for (unsigned int i = 0; i < vec.size(); i++) { - #ifdef _DEBUG - cout << "vector :" < 0 - ? vec[i].custom_account.ptr != nullptr - ? unicode_to_utf8(vec[i].custom_account.ptr) - : string() - : string()}, - {"delFlag", vec[i].del_flag}, - {"userName", vec[i].encrypt_name.length > 0 - ? vec[i].encrypt_name.ptr != nullptr - ? unicode_to_utf8(vec[i].encrypt_name.ptr) - : string() - : string()}, - {"type", vec[i].type}, - {"verifyFlag", vec[i].verify_flag}, - {"verifyFlag", vec[i].verify_flag}, - {"wxid", vec[i].wxid.length > 0 ? unicode_to_utf8(vec[i].wxid.ptr) - : string()}, - }; - ret_data["data"].push_back(item); - } - ret = ret_data.dump(); - break; - } - case WECHAT_GET_CHATROOM_INFO: { - wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post); - ChatRoomInfoInner chat_room_detail{0}; - int success = GetChatRoomDetailInfo(WS2LW(room_id), chat_room_detail); - json ret_data = {{"code", success}, {"result", "OK"}}; - if(!success){ - break; - } - json detail = { - {"chatRoomId", - chat_room_detail.chat_room_id.length > 0 - ? unicode_to_utf8(chat_room_detail.chat_room_id.ptr) - : string()}, - {"notice", chat_room_detail.notice.length > 0 - ? unicode_to_utf8(chat_room_detail.notice.ptr) - : string()}, - {"admin", chat_room_detail.admin.length > 0 - ? unicode_to_utf8(chat_room_detail.admin.ptr) - : string()}, - {"xml", chat_room_detail.xml.length > 0 - ? unicode_to_utf8(chat_room_detail.xml.ptr) - : string()}, - }; - ret_data["data"]=detail; - ret = ret_data.dump(); - break; - } - case WECHAT_GET_IMG_BY_NAME: { - wstring image_path = get_http_req_param(hm, j_param, "imagePath", is_post); - wstring save_path = get_http_req_param(hm, j_param, "savePath", is_post); - int success = GetImgByName(WS2LW(image_path),WS2LW(save_path)); - json ret_data = {{"code", success}, {"result", "OK"}}; - ret = ret_data.dump(); - } - default: - break; - } -} - -/// @brief 事件回调函数 -/// @param c 链接 -/// @param ev 事件 -/// @param ev_data 事件数据 -/// @param fn_data 回调数据 -static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { - struct mg_http_serve_opts opts = {0}; - if (ev == MG_EV_HTTP_MSG) { - struct mg_http_message *hm = (struct mg_http_message *)ev_data; - string ret = R"({"result":"OK"})"; - if (mg_http_match_uri(hm, "/api/")) { - try { - api_handle(hm, c, ret); - } catch (json::exception &e) { - json res = {{"result", "ERROR"}, {"msg", e.what()}}; - ret = res.dump(); - } - if (ret != "") { - mg_http_reply(c, 200, "", ret.c_str(), 0, 0); - } - } else { - mg_http_reply(c, 500, NULL, "%s", "Invalid URI"); - } - } - (void)fn_data; -} -/// @brief http server -/// @param port 端口 -void http_server(int port) { - string lsten_addr = "http://0.0.0.0:" + to_string(port); - struct mg_mgr mgr; - // Init manager - mg_mgr_init(&mgr); - // Setup listener - mg_http_listen(&mgr, lsten_addr.c_str(), fn, &mgr); - // Event loop - for (;;) mg_mgr_poll(&mgr, 1000); - // Cleanup - mg_mgr_free(&mgr); -} - -/// @brief 启动http服务 -/// @param port 端口 -/// @return 成功返回0 -int http_start(int port) { - if (kHttpRuning) { - return 1; - } - #ifdef _DEBUG - CreateConsole(); - #endif - kHttpRuning = true; - kHttpThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)http_server, - (LPVOID)port, NULL, 0); - return 0; -} \ No newline at end of file diff --git a/src/api.h b/src/api.h deleted file mode 100644 index 4ecd6e3..0000000 --- a/src/api.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef API_H_ -#define API_H_ - - -typedef enum WECHAT_HTTP_APISTag -{ - // login check - WECHAT_IS_LOGIN = 0, - // self info - WECHAT_GET_SELF_INFO, - // send message - WECHAT_MSG_SEND_TEXT, - WECHAT_MSG_SEND_AT, - WECHAT_MSG_SEND_CARD, - WECHAT_MSG_SEND_IMAGE, - WECHAT_MSG_SEND_FILE, - WECHAT_MSG_SEND_ARTICLE, - WECHAT_MSG_SEND_APP, - // receive message - WECHAT_MSG_START_HOOK, - WECHAT_MSG_STOP_HOOK, - WECHAT_MSG_START_IMAGE_HOOK, - WECHAT_MSG_STOP_IMAGE_HOOK, - WECHAT_MSG_START_VOICE_HOOK, - WECHAT_MSG_STOP_VOICE_HOOK, - // contact - WECHAT_CONTACT_GET_LIST, - WECHAT_CONTACT_CHECK_STATUS, - WECHAT_CONTACT_DEL, - WECHAT_CONTACT_SEARCH_BY_CACHE, - WECHAT_CONTACT_SEARCH_BY_NET, - WECHAT_CONTACT_ADD_BY_WXID, - WECHAT_CONTACT_ADD_BY_V3, - WECHAT_CONTACT_ADD_BY_PUBLIC_ID, - WECHAT_CONTACT_VERIFY_APPLY, - WECHAT_CONTACT_EDIT_REMARK, - // chatroom - WECHAT_CHATROOM_GET_MEMBER_LIST, - WECHAT_CHATROOM_GET_MEMBER_NICKNAME, - WECHAT_CHATROOM_DEL_MEMBER, - WECHAT_CHATROOM_ADD_MEMBER, - WECHAT_CHATROOM_SET_ANNOUNCEMENT, - WECHAT_CHATROOM_SET_CHATROOM_NAME, - WECHAT_CHATROOM_SET_SELF_NICKNAME, - // database - WECHAT_DATABASE_GET_HANDLES, - WECHAT_DATABASE_BACKUP, - WECHAT_DATABASE_QUERY, - // version - WECHAT_SET_VERSION, - // log - WECHAT_LOG_START_HOOK, - WECHAT_LOG_STOP_HOOK, - // browser - WECHAT_BROWSER_OPEN_WITH_URL, - WECHAT_GET_PUBLIC_MSG, - WECHAT_MSG_FORWARD_MESSAGE, - WECHAT_GET_QRCODE_IMAGE, - WECHAT_GET_A8KEY, - WECHAT_MSG_SEND_XML, - WECHAT_LOGOUT, - WECHAT_GET_TRANSFER, - WECHAT_GET_CONTACT_ALL, - WECHAT_GET_CHATROOM_INFO, - WECHAT_GET_IMG_BY_NAME, -} WECHAT_HTTP_APIS, - *PWECHAT_HTTP_APIS; - - -int http_start(int port); -#endif \ No newline at end of file diff --git a/src/base64.cpp b/src/base64.cpp deleted file mode 100644 index f81394e..0000000 --- a/src/base64.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "pch.h" -/* - base64.cpp and base64.h - - base64 encoding and decoding with C++. - More information at - https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp - - Version: 2.rc.08 (release candidate) - - Copyright (C) 2004-2017, 2020, 2021 Ren Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - Ren Nyffenegger rene.nyffenegger@adp-gmbh.ch - -*/ - -#include "base64.h" - -#include -#include - -// -// Depending on the url parameter in base64_chars, one of -// two sets of base64 characters needs to be chosen. -// They differ in their last two characters. -// -static const char *base64_chars[2] = { - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "+/", - - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "-_"}; - -static unsigned int pos_of_char(const unsigned char chr) -{ - // - // Return the position of chr within base64_encode() - // - - if (chr >= 'A' && chr <= 'Z') - return chr - 'A'; - else if (chr >= 'a' && chr <= 'z') - return chr - 'a' + ('Z' - 'A') + 1; - else if (chr >= '0' && chr <= '9') - return chr - '0' + ('Z' - 'A') + ('z' - 'a') + 2; - else if (chr == '+' || chr == '-') - return 62; // Be liberal with input and accept both url ('-') and non-url ('+') base 64 characters ( - else if (chr == '/' || chr == '_') - return 63; // Ditto for '/' and '_' - else - // - // 2020-10-23: Throw std::exception rather than const char* - //(Pablo Martin-Gomez, https://github.com/Bouska) - // - throw std::runtime_error("Input is not valid base64-encoded data."); -} - -static std::string insert_linebreaks(std::string str, size_t distance) -{ - // - // Provided by https://github.com/JomaCorpFX, adapted by me. - // - if (!str.length()) - { - return ""; - } - - size_t pos = distance; - - while (pos < str.size()) - { - str.insert(pos, "\n"); - pos += distance + 1; - } - - return str; -} - -template -static std::string encode_with_line_breaks(String s) -{ - return insert_linebreaks(base64_encode(s, false), line_length); -} - -template -static std::string encode_pem(String s) -{ - return encode_with_line_breaks(s); -} - -template -static std::string encode_mime(String s) -{ - return encode_with_line_breaks(s); -} - -template -static std::string encode(String s, bool url) -{ - return base64_encode(reinterpret_cast(s.data()), s.length(), url); -} - -std::string base64_encode(unsigned char const *bytes_to_encode, size_t in_len, bool url) -{ - - size_t len_encoded = (in_len + 2) / 3 * 4; - - unsigned char trailing_char = url ? '.' : '='; - - // - // Choose set of base64 characters. They differ - // for the last two positions, depending on the url - // parameter. - // A bool (as is the parameter url) is guaranteed - // to evaluate to either 0 or 1 in C++ therefore, - // the correct character set is chosen by subscripting - // base64_chars with url. - // - const char *base64_chars_ = base64_chars[url]; - - std::string ret; - ret.reserve(len_encoded); - - unsigned int pos = 0; - - while (pos < in_len) - { - ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0xfc) >> 2]); - - if (pos + 1 < in_len) - { - ret.push_back(base64_chars_[((bytes_to_encode[pos + 0] & 0x03) << 4) + ((bytes_to_encode[pos + 1] & 0xf0) >> 4)]); - - if (pos + 2 < in_len) - { - ret.push_back(base64_chars_[((bytes_to_encode[pos + 1] & 0x0f) << 2) + ((bytes_to_encode[pos + 2] & 0xc0) >> 6)]); - ret.push_back(base64_chars_[bytes_to_encode[pos + 2] & 0x3f]); - } - else - { - ret.push_back(base64_chars_[(bytes_to_encode[pos + 1] & 0x0f) << 2]); - ret.push_back(trailing_char); - } - } - else - { - - ret.push_back(base64_chars_[(bytes_to_encode[pos + 0] & 0x03) << 4]); - ret.push_back(trailing_char); - ret.push_back(trailing_char); - } - - pos += 3; - } - - return ret; -} - -template -static std::string decode(String encoded_string, bool remove_linebreaks) -{ - // - // decode() is templated so that it can be used with String = const std::string& - // or std::string_view (requires at least C++17) - // - - if (encoded_string.empty()) - return std::string(); - - if (remove_linebreaks) - { - - std::string copy(encoded_string); - - copy.erase(std::remove(copy.begin(), copy.end(), '\n'), copy.end()); - - return base64_decode(copy, false); - } - - size_t length_of_string = encoded_string.length(); - size_t pos = 0; - - // - // The approximate length (bytes) of the decoded string might be one or - // two bytes smaller, depending on the amount of trailing equal signs - // in the encoded string. This approximation is needed to reserve - // enough space in the string to be returned. - // - size_t approx_length_of_decoded_string = length_of_string / 4 * 3; - std::string ret; - ret.reserve(approx_length_of_decoded_string); - - while (pos < length_of_string) - { - // - // Iterate over encoded input string in chunks. The size of all - // chunks except the last one is 4 bytes. - // - // The last chunk might be padded with equal signs or dots - // in order to make it 4 bytes in size as well, but this - // is not required as per RFC 2045. - // - // All chunks except the last one produce three output bytes. - // - // The last chunk produces at least one and up to three bytes. - // - - size_t pos_of_char_1 = pos_of_char(encoded_string[pos + 1]); - - // - // Emit the first output byte that is produced in each chunk: - // - ret.push_back(static_cast(((pos_of_char(encoded_string[pos + 0])) << 2) + ((pos_of_char_1 & 0x30) >> 4))); - - if ((pos + 2 < length_of_string) && // Check for data that is not padded with equal signs (which is allowed by RFC 2045) - encoded_string[pos + 2] != '=' && - encoded_string[pos + 2] != '.' // accept URL-safe base 64 strings, too, so check for '.' also. - ) - { - // - // Emit a chunk's second byte (which might not be produced in the last chunk). - // - unsigned int pos_of_char_2 = pos_of_char(encoded_string[pos + 2]); - ret.push_back(static_cast(((pos_of_char_1 & 0x0f) << 4) + ((pos_of_char_2 & 0x3c) >> 2))); - - if ((pos + 3 < length_of_string) && - encoded_string[pos + 3] != '=' && - encoded_string[pos + 3] != '.') - { - // - // Emit a chunk's third byte (which might not be produced in the last chunk). - // - ret.push_back(static_cast(((pos_of_char_2 & 0x03) << 6) + pos_of_char(encoded_string[pos + 3]))); - } - } - - pos += 4; - } - - return ret; -} - -std::string base64_decode(std::string const &s, bool remove_linebreaks) -{ - return decode(s, remove_linebreaks); -} - -std::string base64_encode(std::string const &s, bool url) -{ - return encode(s, url); -} - -std::string base64_encode_pem(std::string const &s) -{ - return encode_pem(s); -} - -std::string base64_encode_mime(std::string const &s) -{ - return encode_mime(s); -} - -#if __cplusplus >= 201703L -// -// Interface with std::string_view rather than const std::string& -// Requires C++17 -// Provided by Yannic Bonenberger (https://github.com/Yannic) -// - -std::string base64_encode(std::string_view s, bool url) -{ - return encode(s, url); -} - -std::string base64_encode_pem(std::string_view s) -{ - return encode_pem(s); -} - -std::string base64_encode_mime(std::string_view s) -{ - return encode_mime(s); -} - -std::string base64_decode(std::string_view s, bool remove_linebreaks) -{ - return decode(s, remove_linebreaks); -} - -#endif // __cplusplus >= 201703L diff --git a/src/base64.h b/src/base64.h deleted file mode 100644 index 3d2bab7..0000000 --- a/src/base64.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// base64 encoding and decoding with C++. -// Version: 2.rc.08 (release candidate) -// -#pragma once -#ifndef BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A -#define BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A - -#include - -#if __cplusplus >= 201703L -#include -#endif // __cplusplus >= 201703L - -std::string base64_encode(std::string const &s, bool url = false); -std::string base64_encode_pem(std::string const &s); -std::string base64_encode_mime(std::string const &s); - -std::string base64_decode(std::string const &s, bool remove_linebreaks = false); -std::string base64_encode(unsigned char const *, size_t len, bool url = false); - -#if __cplusplus >= 201703L -// -// Interface with std::string_view rather than const std::string& -// Requires C++17 -// Provided by Yannic Bonenberger (https://github.com/Yannic) -// -std::string base64_encode(std::string_view s, bool url = false); -std::string base64_encode_pem(std::string_view s); -std::string base64_encode_mime(std::string_view s); - -std::string base64_decode(std::string_view s, bool remove_linebreaks = false); -#endif // __cplusplus >= 201703L - -#endif /* BASE64_H_C0CE2A47_D10E_42C9_A27C_C883944E704A */ diff --git a/src/chat_room.cc b/src/chat_room.cc deleted file mode 100644 index b07e2f8..0000000 --- a/src/chat_room.cc +++ /dev/null @@ -1,184 +0,0 @@ -#include "pch.h" -#include "chat_room.h" - -#include "common.h" - -#include "wechat_data.h" -#define WX_CHAT_ROOM_MGR_OFFSET 0x686e40 -#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xa70920 -#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xd03ec0 -#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0x7226e0 -#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xa668f0 -#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40 -#define WX_FREE_CHAT_MSG_OFFSET 0x651c40 -#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xa66400 -#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xa71650 -#define WX_INIT_CHAT_ROOM_OFFSET 0xd01c30 -#define WX_FREE_CHAT_ROOM_OFFSET 0xa79310 - -int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info) { - int success = 0; - WeChatString chat_room(chat_room_id); - DWORD base = GetWeChatWinBase(); - DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET; - DWORD get_chat_room_detail_addr = base + WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET; - DWORD create_chat_room_info_addr = base + WX_NEW_CHAT_ROOM_INFO_OFFSET; - DWORD free_chat_room_info_addr = base + WX_FREE_CHAT_ROOM_INFO_OFFSET; - char chat_room_info[0xA4] = {0}; - __asm { - PUSHAD - LEA ECX,chat_room_info - CALL create_chat_room_info_addr - CALL get_chat_room_mgr_addr - PUSH 0x0 - LEA ECX,chat_room_info - PUSH ECX - LEA ECX,chat_room - PUSH ECX - MOV ECX,EAX - CALL get_chat_room_detail_addr - MOV success,EAX - POPAD - } - room_info.chat_room_id.ptr = *(wchar_t**)(chat_room_info + 0x4); - room_info.chat_room_id.length = *(DWORD*)(chat_room_info + 0x8); - room_info.chat_room_id.max_length = *(DWORD*)(chat_room_info + 0xC); - - room_info.notice.ptr = *(wchar_t**)(chat_room_info + 0x18); - room_info.notice.length = *(DWORD*)(chat_room_info + 0x1C); - room_info.notice.max_length = *(DWORD*)(chat_room_info + 0x20); - - room_info.admin.ptr = *(wchar_t**)(chat_room_info + 0x2C); - room_info.admin.length = *(DWORD*)(chat_room_info + 0x30); - room_info.admin.max_length = *(DWORD*)(chat_room_info + 0x34); - - room_info.xml.ptr = *(wchar_t**)(chat_room_info + 0x50); - room_info.xml.length = *(DWORD*)(chat_room_info + 0x54); - room_info.xml.max_length = *(DWORD*)(chat_room_info + 0x58); - __asm { - PUSHAD - LEA ECX,chat_room_info - CALL free_chat_room_info_addr - POPAD - } - return success; -} - -int DelMemberFromChatRoom(wchar_t* chat_room_id, wchar_t** wxids,int len) { - int success = 0; - WeChatString chat_room(chat_room_id); - vector members; - VectorInner *list = (VectorInner *)&members; - DWORD members_ptr = (DWORD)&list->start; - for (int i = 0; i < len; i++) { - WeChatString pwxid(wxids[i]); - members.push_back(pwxid); - } - DWORD base = GetWeChatWinBase(); - DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET; - DWORD del_member_addr = base + WX_DEL_CHAT_ROOM_MEMBER_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - __asm { - PUSHAD - CALL get_chat_room_mgr_addr - SUB ESP,0x14 - MOV ESI,EAX - MOV ECX,ESP - LEA EDI,chat_room - PUSH EDI - CALL init_chat_msg_addr - MOV ECX,ESI - MOV EAX,dword ptr[members_ptr] - PUSH EAX - CALL del_member_addr - MOV success,EAX - POPAD - } - return success; -} - - -int AddMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids,int len){ - int success = 0; - WeChatString chat_room(chat_room_id); - vector members; - VectorInner *list = (VectorInner *)&members; - DWORD members_ptr = (DWORD)&list->start; - for (int i = 0; i < len; i++) { - WeChatString pwxid(wxids[i]); - members.push_back(pwxid); - } - DWORD base = GetWeChatWinBase(); - DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET; - DWORD add_member_addr = base + WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - DWORD temp=0; - __asm { - PUSHAD - PUSHFD - CALL get_chat_room_mgr_addr - SUB ESP,0x8 - MOV temp,EAX - MOV ECX,ESP - MOV dword ptr [ECX],0x0 - MOV dword ptr [ECX + 4],0x0 - TEST ESI,ESI - SUB ESP,0x14 - MOV ECX,ESP - LEA EAX,chat_room - PUSH EAX - CALL init_chat_msg_addr - MOV ECX,temp - MOV EAX,dword ptr[members_ptr] - PUSH EAX - CALL add_member_addr - MOV success,EAX - POPFD - POPAD - } - return success; -} - - -int GetMemberFromChatRoom(wchar_t* chat_room_id,ChatRoomInner & out){ - int success = 0; - WeChatString chat_room(chat_room_id); - DWORD chat_room_ptr = (DWORD) &chat_room; - char buffer[0x1A0] = {0}; - DWORD base = GetWeChatWinBase(); - DWORD get_member_addr = base + WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET; - DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET; - DWORD create_chat_room_addr = base + WX_INIT_CHAT_ROOM_OFFSET; - DWORD free_chat_room_addr = base + WX_FREE_CHAT_ROOM_OFFSET; - __asm { - PUSHAD - LEA ECX,buffer - CALL create_chat_room_addr - CALL get_chat_room_mgr_addr - LEA EAX, buffer - PUSH EAX - PUSH chat_room_ptr - CALL get_member_addr - MOVZX EAX,AL - MOV success,EAX - POPAD - } - char* members = *(char **)(buffer +0x1c); - wchar_t* room = *(wchar_t **)(buffer +0x8); - wchar_t* admin = *(wchar_t **)(buffer +0x4c); - - out.members = new char[strlen(members) + 1]; - memcpy(out.members, members, strlen(members) + 1); - - out.chat_room = new wchar_t[wcslen(room)+1]; - wmemcpy(out.chat_room ,room,wcslen(room)+1); - - out.admin = new wchar_t[wcslen(admin)+1]; - wmemcpy(out.admin ,admin,wcslen(admin)+1); - - __asm{ - LEA ECX,buffer - CALL free_chat_room_addr - } - return success; -} diff --git a/src/chat_room.h b/src/chat_room.h deleted file mode 100644 index 9ac930a..0000000 --- a/src/chat_room.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef CHAT_ROOM_H_ -#define CHAT_ROOM_H_ -#include "wechat_data.h" - -int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info); -int DelMemberFromChatRoom(wchar_t* chat_room_id,wchar_t** wxids,int len); -int AddMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids,int len); - -int GetMemberFromChatRoom(wchar_t* chat_room_id,ChatRoomInner & out); -#endif \ No newline at end of file diff --git a/src/common.cc b/src/common.cc deleted file mode 100644 index 264188e..0000000 --- a/src/common.cc +++ /dev/null @@ -1,138 +0,0 @@ -#include "pch.h" -#include "common.h" - - -using namespace std; - -/// @brief utf8 转换成unicode -/// @param buffer utf8 -/// @return unicode -wstring utf8_to_unicode(const char *buffer) { - int c_size = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0); - if (c_size > 0) { - wchar_t *temp = new wchar_t[c_size + 1]; - MultiByteToWideChar(CP_UTF8, 0, buffer, -1, temp, c_size); - temp[c_size] = L'\0'; - wstring ret(temp); - delete[] temp; - temp = NULL; - return ret; - } - return wstring(); -} - -/// @brief unicode转换utf8 -/// @param wstr unicode -/// @return string utf8 -string unicode_to_utf8(wchar_t *wstr) { - int c_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, FALSE); - if (c_size > 0) { - char *buffer = new char[c_size + 1]; - WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, c_size, NULL, FALSE); - buffer[c_size] = '\0'; - string str(buffer); - delete[] buffer; - buffer = NULL; - return str; - } - return string(); -} - -/// @brief 获取WeChatWin.dll基址 -/// @return 基址 -DWORD GetWeChatWinBase() { return (DWORD)GetModuleHandleA("WeChatWin.dll"); } - -/// @brief 创建窗口 -/// @param void -/// @return 创建结果 -BOOL CreateConsole(void) { - if (AllocConsole()) { - AttachConsole(GetCurrentProcessId()); - FILE *retStream; - freopen_s(&retStream, "CONOUT$", "w", stdout); - if (!retStream) throw std::runtime_error("Stdout redirection failed."); - freopen_s(&retStream, "CONOUT$", "w", stderr); - if (!retStream) throw std::runtime_error("Stderr redirection failed."); - return 0; - } - return 1; -} - -/// @brief hook any addr -/// @param hook_addr need hook of addr -/// @param jmp_addr hook function addr -/// @param origin origin code -void HookAnyAddress(DWORD hook_addr, LPVOID jmp_addr, char *origin) { - BYTE jmp_code[5] = {0}; - jmp_code[0] = 0xE9; - *(DWORD *)&jmp_code[1] = (DWORD)jmp_addr - hook_addr - 5; - DWORD old_protext = 0; - VirtualProtect((LPVOID)hook_addr, 5, PAGE_EXECUTE_READWRITE, &old_protext); - ReadProcessMemory(GetCurrentProcess(), (LPVOID)hook_addr, origin, 5, 0); - memcpy((void *)hook_addr, jmp_code, 5); - VirtualProtect((LPVOID)hook_addr, 5, old_protext, &old_protext); -} - -/// @brief unhook -/// @param hook_addr hook addr -/// @param origin origin addr code -void UnHookAnyAddress(DWORD hook_addr, char *origin) { - DWORD old_protext = 0; - VirtualProtect((LPVOID)hook_addr, 5, PAGE_EXECUTE_READWRITE, &old_protext); - WriteProcessMemory(GetCurrentProcess(), (LPVOID)hook_addr, origin, 5, 0); - VirtualProtect((LPVOID)hook_addr, 5, old_protext, &old_protext); -} - -/// @brief get timeW -/// @param timestamp timestamp -/// @return str -wstring GetTimeW(long long timestamp) { - wchar_t *wstr = new wchar_t[20]; - memset(wstr, 0, 20 * 2); - tm tm_out; - localtime_s(&tm_out, ×tamp); - swprintf_s(wstr, 20, L"%04d-%02d-%02d %02d:%02d:%02d", 1900 + tm_out.tm_year, - tm_out.tm_mon + 1, tm_out.tm_mday, tm_out.tm_hour, tm_out.tm_min, - tm_out.tm_sec); - wstring strTimeW(wstr); - delete[] wstr; - return strTimeW; -} - -wstring String2Wstring(string str) { - wstring result; - int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0); - wchar_t *buffer = new wchar_t[len + 1]; - MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len); - buffer[len] = '\0'; - result.append(buffer); - delete[] buffer; - return result; -} - -string Wstring2String(wstring wstr) { - string result; - int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, - NULL, NULL); - char *buffer = new char[len + 1]; - WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, - NULL); - buffer[len] = '\0'; - result.append(buffer); - delete[] buffer; - return result; -} - -BOOL FindOrCreateDirectoryW(const wchar_t *path) { - WIN32_FIND_DATAW fd; - HANDLE hFind = ::FindFirstFileW(path, &fd); - if (hFind != INVALID_HANDLE_VALUE) { - FindClose(hFind); - return true; - } - - if (!::CreateDirectoryW(path, NULL)) { - return false; - } - return true; -} \ No newline at end of file diff --git a/src/common.h b/src/common.h deleted file mode 100644 index af9bb7e..0000000 --- a/src/common.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef COMMON_H_ -#define COMMON_H_ -#include -using namespace std; -#define READ_WSTRING(addr, offset) ((*(DWORD *)(addr + offset + 0x4) == 0) ? wstring(L"") : wstring((wchar_t *)(*(DWORD *)(addr + offset)), *(DWORD *)(addr + offset + 0x4))) - -/// @brief utf8 转换成unicode -/// @param buffer utf8 -/// @return unicode -wstring utf8_to_unicode(const char *buffer); - -/// @brief unicode转换utf8 -/// @param wstr unicode -/// @return utf8 -string unicode_to_utf8(wchar_t *wstr); - -/// @brief 获取WeChatWin.dll基址 -/// @return 基址 -DWORD GetWeChatWinBase(); -/// @brief 创建窗口 -/// @param void -/// @return 创建结果 -BOOL CreateConsole(void); -/// @brief hook任意地址 -/// @param hook_addr 被hook的地址 -/// @param jmp_addr 被hook的函数的地址 -/// @param origin 原始code -void HookAnyAddress(DWORD hook_addr, LPVOID jmp_addr, char *origin); - -/// @brief 取消hook -/// @param hook_addr 被hook的地址 -/// @param origin 原始code -void UnHookAnyAddress(DWORD hook_addr, char *origin); - -/// @brief get timeW -/// @param timestamp timestamp -/// @return str -wstring GetTimeW(long long timestamp); -/// @brief unicode trans utf8 -/// @param str unicode str -/// @return utf8 str -std::string UnicodeToUtf8(const wchar_t *str); -/// @brief string convert wstring -/// @param str -/// @return -wstring String2Wstring(string str); -/// @brief wstring convert string -/// @param str -/// @return -string Wstring2String(wstring wstr); - -/// @brief create dir -/// @param path -/// @return -BOOL FindOrCreateDirectoryW(const wchar_t *path); - - -template -vector split(T1 str, T2 letter) { - vector arr; - size_t pos; - while ((pos = str.find_first_of(letter)) != T1::npos) { - T1 str1 = str.substr(0, pos); - arr.push_back(str1); - str = str.substr(pos + 1, str.length() - pos - 1); - } - arr.push_back(str); - return arr; -} - -template -T1 replace(T1 source, T2 replaced, T1 replaceto) { - vector v_arr = split(source, replaced); - if (v_arr.size() < 2) return source; - T1 temp; - for (unsigned int i = 0; i < v_arr.size() - 1; i++) { - temp += v_arr[i]; - temp += replaceto; - } - temp += v_arr[v_arr.size() - 1]; - return temp; -} -#endif \ No newline at end of file diff --git a/src/contact.cc b/src/contact.cc deleted file mode 100644 index 608cae9..0000000 --- a/src/contact.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "pch.h" -#include "contact.h" - -#include "common.h" -#include "wechat_data.h" - -#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x655d60 -#define WX_CONTACT_GET_LIST_OFFSET 0xa97da0 -#define WX_CONTACT_DEL_OFFSET 0xa9bd10 -#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40 -#define WX_DB_QUERY_OFFSET 0xa9ba20 -#define WX_SYNC_MGR_OFFSET 0x993fa0 -#define WX_SYNC_MGR_OFFSET 0x993fa0 -#define WX_DO_DEL_CONTACT_OFFSET 0xb9a750 -#define WX_DEL_CONTACT_VTABLE_OFFSET 0x2886990 -int GetAllContact(vector &vec) { - DWORD base = GetWeChatWinBase(); - DWORD get_instance = base + WX_CONTACT_MGR_INSTANCE_OFFSET; - DWORD contact_get_list = base + WX_CONTACT_GET_LIST_OFFSET; - // char contact[0xc] = {0}; - DWORD* contact[3] = {0, 0, 0}; - int success = 0; - __asm { - PUSHAD - CALL get_instance - LEA ECX,contact - PUSH ECX - MOV ECX,EAX - CALL contact_get_list - MOVZX EAX,AL - MOV success,EAX - POPAD - } - DWORD start = (DWORD)contact[0]; - DWORD end = (DWORD)contact[2]; -#ifdef _DEBUG - cout << "address = " << &contact << endl; - cout << "refresh contact = " << success << endl; - cout << "start = " << start << endl; - cout << "end = " << end << endl; -#endif - while (start < end) { - Contact temp{0}; - - temp.wxid.ptr = *(wchar_t **)(start + 0x10); - temp.wxid.length = *(DWORD *)(start + 0x14); - temp.wxid.max_length = *(DWORD *)(start + 0x18); - - temp.custom_account.ptr = *(wchar_t **)(start + 0x24); - temp.custom_account.length = *(DWORD *)(start + 0x28); - temp.custom_account.max_length = *(DWORD *)(start + 0x2C); - - temp.encrypt_name.ptr = *(wchar_t **)(start + 0x6c); - temp.encrypt_name.length = *(DWORD *)(start + 0x70); - temp.encrypt_name.max_length = *(DWORD *)(start + 0x74); - - temp.pinyin.ptr = *(wchar_t **)(start + 0xAC); - temp.pinyin.length = *(DWORD *)(start + 0xB0); - temp.pinyin.max_length = *(DWORD *)(start + 0xB4); - - temp.pinyin_all.ptr = *(wchar_t **)(start + 0xC0); - temp.pinyin_all.length = *(DWORD *)(start + 0xC4); - temp.pinyin_all.max_length = *(DWORD *)(start + 0xC8); - - temp.del_flag = *(DWORD *)(start + 0x4c); - temp.type = *(DWORD *)(start + 0x50); - temp.verify_flag = *(DWORD *)(start + 0x54); - vec.push_back(temp); - start += 0x3E8; - } - return success; -} -// todo -int DelContact(wchar_t *wxid) { - int success = 0; - WeChatString user_id(wxid); - DWORD id_ptr = (DWORD) &user_id; - DWORD base = GetWeChatWinBase(); - DWORD get_instance_addr = base + WX_CONTACT_MGR_INSTANCE_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - DWORD del_addr = base + WX_CONTACT_DEL_OFFSET; - DWORD db_op_addr = base + WX_DB_QUERY_OFFSET; - __asm{ - PUSHAD - PUSHFD - CALL get_instance_addr - MOV ECX,dword ptr[id_ptr] - PUSH ECX - MOV ECX,EAX - MOV ESI,EAX - CALL db_op_addr - SUB ESP,0x14 - MOV EAX,dword ptr[id_ptr] - MOV ECX,ESP - PUSH EAX - CALL init_chat_msg_addr - MOV ECX,ESI - CALL del_addr - MOV success,EAX - POPFD - POPAD - } - return success; -} - - diff --git a/src/contact.h b/src/contact.h deleted file mode 100644 index 8f643f4..0000000 --- a/src/contact.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef CONTACT_H_ -#define CONTACT_H_ -#include -#include "wechat_data.h" - -int GetAllContact(vector &vec); - - - -int DelContact(wchar_t* wxid); -#endif \ No newline at end of file diff --git a/src/db_operation.cc b/src/db_operation.cc deleted file mode 100644 index 3b43624..0000000 --- a/src/db_operation.cc +++ /dev/null @@ -1,155 +0,0 @@ -#include "pch.h" -#include "db_operation.h" - -#include "base64.h" -#include "common.h" -#include "new_sqlite3.h" - - -/// @brief free data -void FreeResult(vector> &data) { - if (data.size() == 0) { - return; - } - for (unsigned int i = 0; i < data.size(); i++) { - for (unsigned j = 0; j < data[i].size(); j++) { - SqlResult *sr = (SqlResult *)&data[i][j]; - if (sr->column_name) { - delete sr->column_name; - sr->column_name = NULL; - } - if (sr->content) { - delete sr->content; - sr->content = NULL; - } - } - data[i].clear(); - } - data.clear(); -} - -int SelectDataInner(DWORD db, const char *sql, - vector> &data) { - DWORD wxBaseAddress = GetWeChatWinBase(); - Sqlite3_prepare p_Sqlite3_prepare = - (Sqlite3_prepare)(wxBaseAddress + SQLITE3_PREPARE_OFFSET); - Sqlite3_step p_Sqlite3_step = - (Sqlite3_step)(wxBaseAddress + SQLITE3_STEP_OFFSET); - Sqlite3_column_count p_Sqlite3_column_count = - (Sqlite3_column_count)(wxBaseAddress + SQLITE3_COLUMN_COUNT_OFFSET); - Sqlite3_column_name p_Sqlite3_column_name = - (Sqlite3_column_name)(wxBaseAddress + SQLITE3_COLUMN_NAME_OFFSET); - Sqlite3_column_type p_Sqlite3_column_type = - (Sqlite3_column_type)(wxBaseAddress + SQLITE3_COLUMN_TYPE_OFFSET); - Sqlite3_column_blob p_Sqlite3_column_blob = - (Sqlite3_column_blob)(wxBaseAddress + SQLITE3_COLUMN_BLOB_OFFSET); - Sqlite3_column_bytes p_Sqlite3_column_bytes = - (Sqlite3_column_bytes)(wxBaseAddress + SQLITE3_COLUMN_BYTES_OFFSET); - Sqlite3_finalize p_Sqlite3_finalize = - (Sqlite3_finalize)(wxBaseAddress + SQLITE3_FINALIZE_OFFSET); - DWORD *stmt; - int rc = p_Sqlite3_prepare(db, sql, -1, &stmt, 0); - if (rc != SQLITE_OK) return NULL; - while (p_Sqlite3_step(stmt) == SQLITE_ROW) { - int col_count = p_Sqlite3_column_count(stmt); - vector tempStruct; - for (int i = 0; i < col_count; i++) { - SqlResult temp = {0}; - const char *ColName = p_Sqlite3_column_name(stmt, i); - int nType = p_Sqlite3_column_type(stmt, i); - const void *pReadBlobData = p_Sqlite3_column_blob(stmt, i); - int nLength = p_Sqlite3_column_bytes(stmt, i); - temp.column_name = new char[strlen(ColName) + 1]; - memcpy(temp.column_name, ColName, strlen(ColName) + 1); - temp.column_name_len = strlen(ColName); - temp.content_len = nLength; - switch (nType) { - case SQLITE_BLOB: { - temp.content = new char[nLength]; - memcpy(temp.content, pReadBlobData, nLength); - temp.is_blob = true; - break; - } - default: { - if (nLength != 0) { - temp.content = new char[nLength + 1]; - memcpy(temp.content, pReadBlobData, nLength + 1); - } else { - temp.content = new char[2]; - ZeroMemory(temp.content, 2); - } - temp.is_blob = false; - break; - } - } - tempStruct.push_back(temp); - } - data.push_back(tempStruct); - } - p_Sqlite3_finalize(stmt); - return 1; -} - -int Select(DWORD db_hanle, const char *sql, - vector> &query_result) { - vector> data; - int status = SelectDataInner(db_hanle, sql, data); - if (status == 0) { - return 0; - } - vector index; - for (size_t i = 0; i < data[0].size(); i++) - index.push_back(data[0][i].column_name); - query_result.push_back(index); - for (auto it : data) { - vector item; - for (size_t i = 0; i < it.size(); i++) { - if (!it[i].is_blob) { - string content(it[i].content); - item.push_back(content); - } else { - string b64_str = - base64_encode((BYTE *)it[i].content, it[i].content_len); - item.push_back(b64_str); - } - } - query_result.push_back(item); - } - FreeResult(data); - return 1; -} - -int SelectDbInfo(void *data, int argc, char **argv, char **name) { - vector result; - for (int i = 0; i < argc; i++) { - SqlResult temp = {0}; - temp.column_name = new char[strlen(name[i]) + 1]; - memcpy(temp.column_name, name[i], strlen(name[i]) + 1); - temp.column_name_len = strlen(name[i]); - if (argv[i]) { - temp.content = new char[strlen(argv[i]) + 1]; - memcpy(temp.content, argv[i], strlen(argv[i]) + 1); - temp.content_len = strlen(argv[i]); - } else { - temp.content = new char[2]; - ZeroMemory(temp.content, 2); - temp.content_len = 0; - } - result.push_back(temp); - } - return 1; -} - -/// @brief sqlite3_exec -/// @param db -/// @param sql -/// @param callback -/// @param data -/// @return -int ExecuteSQL(DWORD db, const char *sql, DWORD callback, void *data) { - DWORD base = GetWeChatWinBase(); - DWORD sqlite3_exec_addr = base + SQLITE3_EXEC_OFFSET; - Sqlite3_exec fn_sqlite3_exec = (Sqlite3_exec)sqlite3_exec_addr; - int status = fn_sqlite3_exec(db, sql, (Sqlite3_callback)callback, data, 0); - return status; -} \ No newline at end of file diff --git a/src/db_operation.h b/src/db_operation.h deleted file mode 100644 index ad987e8..0000000 --- a/src/db_operation.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef DB_OPERATION_H_ -#define DB_OPERATION_H_ -#include -#include -using namespace std; -struct SqlResult { - char *column_name; - DWORD column_name_len; - char *content; - DWORD content_len; - BOOL is_blob; -}; -/// @brief exec sql -/// @param db opened db -/// @param sql sql -/// @param callback callback func -/// @param data data -/// @return -int ExecuteSQL(DWORD db, const char *sql, DWORD callback, void *data); - -int Select(DWORD db_hanle, const char *sql,vector> &query_result); - -#endif \ No newline at end of file diff --git a/src/dllMain.cc b/src/dllMain.cc deleted file mode 100644 index 42cbf5e..0000000 --- a/src/dllMain.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "pch.h" -#include "api.h" -#include "common.h" - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, - LPVOID lpReserved) { - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: { - http_start(19088); - break; - } - case DLL_THREAD_ATTACH: { - break; - } - case DLL_THREAD_DETACH: { - break; - } - case DLL_PROCESS_DETACH: { - break; - } - } - return TRUE; -} diff --git a/src/forward.cc b/src/forward.cc deleted file mode 100644 index 62a421d..0000000 --- a/src/forward.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "pch.h" -#include "forward.h" - -#include "common.h" -#include "get_db_handle.h" -#include "wechat_data.h" -#define WX_FORWARD_MSG_OFFSET 0xb68c80 -#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40 - -int ForwardMsg(wchar_t *wxid, unsigned long long msgid) { - int success = 0; - - int db_index = 0; - int localid = GetLocalIdByMsgId(msgid, db_index); - - if (localid == 0) return 0; - WeChatString to_user(wxid); - DWORD base = GetWeChatWinBase(); - DWORD forward_msg_addr = base + WX_FORWARD_MSG_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - __asm { - PUSHAD - PUSHFD - MOV EDX, DWORD PTR [db_index] - PUSH EDX - MOV EAX, DWORD PTR [localid] - PUSH EAX - SUB ESP,0x14 - MOV ECX,ESP - LEA ESI, to_user; - PUSH ESI - CALL init_chat_msg_addr - CALL forward_msg_addr - MOVZX EAX,AL; - MOV success,EAX - ADD ESP,0x1c - POPFD - POPAD - } - return success; -} \ No newline at end of file diff --git a/src/forward.h b/src/forward.h deleted file mode 100644 index cce23c2..0000000 --- a/src/forward.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef FORWARD_H_ -#define FORWARD_H_ - -int ForwardMsg(wchar_t *wxid, unsigned long long msgid); -#endif \ No newline at end of file diff --git a/src/framework.h b/src/framework.h deleted file mode 100644 index 6c09fe4..0000000 --- a/src/framework.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef FRAMEWORK_H_ -#define FRAMEWORK_H_ -#define WIN32_LEAN_AND_MEAN - -#include - -#endif \ No newline at end of file diff --git a/src/get_db_handle.cc b/src/get_db_handle.cc deleted file mode 100644 index 015a395..0000000 --- a/src/get_db_handle.cc +++ /dev/null @@ -1,299 +0,0 @@ -#include "get_db_handle.h" - -#include "common.h" -#include "db_operation.h" -#include "new_sqlite3.h" -#include "pch.h" -#include "wechat_data.h" -#define CONTACT_G_PINSTANCE 0x2bee928 -#define DB_MICRO_MSG_OFFSET 0x68 -#define DB_CHAT_MSG_OFFSET 0x1C0 -#define DB_MISC_OFFSET 0x3D8 -#define DB_EMOTION_OFFSET 0x558 -#define DB_MEDIA_OFFSET 0x9B8 -#define DB_BIZCHAT_MSG_OFFSET 0x1120 -#define DB_FUNCTION_MSG_OFFSET 0x11B0 -#define DB_NAME_OFFSET 0x14 - -#define PUBLIC_MSG_MGR_OFFSET 0x2c294c0 -#define MULTI_DB_MSG_MGR_OFFSET 0x2c2aff4 -#define FAVORITE_STORAGE_MGR_OFFSET 0x2c2aa14 -#define FTS_FAVORITE_MGR_OFFSET 0x2bef468 - -using namespace std; -map dbmap; -std::vector dbs; - -int GetDbInfo(void *data, int argc, char **argv, char **name) { - DatabaseInfo *pdata = (DatabaseInfo *)data; - TableInfo tb = {0}; - if (argv[1]) { - tb.name = new char[strlen(argv[1]) + 1]; - memcpy(tb.name, argv[1], strlen(argv[1]) + 1); - } else { - tb.name = (char *)"NULL"; - } - if (argv[2]) { - tb.table_name = new char[strlen(argv[2]) + 1]; - memcpy(tb.table_name, argv[2], strlen(argv[2]) + 1); - } else { - tb.table_name = (char *)"NULL"; - } - if (argv[3]) { - tb.rootpage = new char[strlen(argv[3]) + 1]; - memcpy(tb.rootpage, argv[3], strlen(argv[3]) + 1); - } else { - tb.rootpage = (char *)"NULL"; - } - if (argv[4]) { - tb.sql = new char[strlen(argv[4]) + 1]; - memcpy(tb.sql, argv[4], strlen(argv[4]) + 1); - } else { - tb.sql = (char *)"NULL"; - } - tb.name_len = strlen(tb.name); - tb.table_name_len = strlen(tb.table_name); - tb.sql_len = strlen(tb.sql); - tb.rootpage_len = strlen(tb.rootpage); - pdata->tables.push_back(tb); - pdata->count = pdata->tables.size(); - return 0; -} - -std::vector GetDbHandles() { - dbs.clear(); - dbmap.clear(); - DWORD base = GetWeChatWinBase(); - DWORD p_contact_addr = *(DWORD *)(base + CONTACT_G_PINSTANCE); - DWORD micro_msg_db_addr = *(DWORD *)(p_contact_addr + DB_MICRO_MSG_OFFSET); - DWORD chat_msg_db_addr = *(DWORD *)(p_contact_addr + DB_CHAT_MSG_OFFSET); - DWORD misc_db_addr = *(DWORD *)(p_contact_addr + DB_MISC_OFFSET); - DWORD emotion_db_addr = *(DWORD *)(p_contact_addr + DB_EMOTION_OFFSET); - DWORD media_db_addr = *(DWORD *)(p_contact_addr + DB_MEDIA_OFFSET); - DWORD bizchat_msg_db_addr = - *(DWORD *)(p_contact_addr + DB_BIZCHAT_MSG_OFFSET); - DWORD function_msg_db_addr = - *(DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET); - - // microMsg.db - DatabaseInfo micro_msg_db{0}; - micro_msg_db.db_name = (wchar_t *)(*( - DWORD *)(p_contact_addr + DB_MICRO_MSG_OFFSET + DB_NAME_OFFSET)); - micro_msg_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_MICRO_MSG_OFFSET + DB_NAME_OFFSET + 0x4); - micro_msg_db.handle = micro_msg_db_addr; - ExecuteSQL(micro_msg_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, µ_msg_db); - dbs.push_back(micro_msg_db); - wstring micro_msg_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_MICRO_MSG_OFFSET + DB_NAME_OFFSET))); - dbmap[micro_msg_name] = micro_msg_db; - - // chatMsg.db - DatabaseInfo chat_msg_db{0}; - chat_msg_db.db_name = (wchar_t *)(*( - DWORD *)(p_contact_addr + DB_CHAT_MSG_OFFSET + DB_NAME_OFFSET)); - chat_msg_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_CHAT_MSG_OFFSET + DB_NAME_OFFSET + 0x4); - chat_msg_db.handle = chat_msg_db_addr; - ExecuteSQL(chat_msg_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &chat_msg_db); - dbs.push_back(chat_msg_db); - wstring chat_msg_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_CHAT_MSG_OFFSET + DB_NAME_OFFSET))); - dbmap[chat_msg_name] = chat_msg_db; - - // misc.db - DatabaseInfo misc_db{0}; - misc_db.db_name = - (wchar_t *)(*(DWORD *)(p_contact_addr + DB_MISC_OFFSET + DB_NAME_OFFSET)); - misc_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_MISC_OFFSET + DB_NAME_OFFSET + 0x4); - misc_db.handle = misc_db_addr; - ExecuteSQL(misc_db_addr, "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &misc_db); - dbs.push_back(misc_db); - wstring misc_name = wstring(( - wchar_t *)(*(DWORD *)(p_contact_addr + DB_MISC_OFFSET + DB_NAME_OFFSET))); - dbmap[misc_name] = misc_db; - - // emotion.db - DatabaseInfo emotion_db{0}; - emotion_db.db_name = (wchar_t *)(*( - DWORD *)(p_contact_addr + DB_EMOTION_OFFSET + DB_NAME_OFFSET)); - emotion_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_EMOTION_OFFSET + DB_NAME_OFFSET + 0x4); - emotion_db.handle = emotion_db_addr; - ExecuteSQL(emotion_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &emotion_db); - dbs.push_back(emotion_db); - wstring emotion_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_EMOTION_OFFSET + DB_NAME_OFFSET))); - dbmap[emotion_name] = emotion_db; - - // media.db - DatabaseInfo media_db{0}; - media_db.db_name = (wchar_t *)(*(DWORD *)(p_contact_addr + DB_MEDIA_OFFSET + - DB_NAME_OFFSET)); - media_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_MEDIA_OFFSET + DB_NAME_OFFSET + 0x4); - media_db.handle = media_db_addr; - ExecuteSQL(media_db_addr, "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &media_db); - dbs.push_back(media_db); - wstring media_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_MEDIA_OFFSET + DB_NAME_OFFSET))); - dbmap[media_name] = media_db; - - // functionMsg.db - DatabaseInfo function_msg_db{0}; - function_msg_db.db_name = (wchar_t *)(*( - DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET)); - function_msg_db.db_name_len = *( - DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET + 0x4); - function_msg_db.handle = function_msg_db_addr; - ExecuteSQL(function_msg_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &function_msg_db); - dbs.push_back(function_msg_db); - wstring function_msg_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET))); - dbmap[function_msg_name] = function_msg_db; - - if (bizchat_msg_db_addr) { - // functionMsg.db maybe null - DatabaseInfo bizchat_msg_db{0}; - bizchat_msg_db.db_name = (wchar_t *)(*( - DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET)); - bizchat_msg_db.db_name_len = - *(DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET + - 0x4); - bizchat_msg_db.handle = bizchat_msg_db_addr; - ExecuteSQL(bizchat_msg_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &bizchat_msg_db); - dbs.push_back(bizchat_msg_db); - wstring bizchat_msg_name = wstring((wchar_t *)(*( - DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET))); - dbmap[bizchat_msg_name] = bizchat_msg_db; - } - DWORD multi_db_mgr_addr = base + MULTI_DB_MSG_MGR_OFFSET; - DWORD public_msg_mgr_addr = base + PUBLIC_MSG_MGR_OFFSET; - DWORD favorite_storage_mgr_addr = base + FAVORITE_STORAGE_MGR_OFFSET; - DWORD fts_favorite_mgr_addr = base + FTS_FAVORITE_MGR_OFFSET; - - // MsgX.db - DWORD wrap_ptr = *(DWORD *)(multi_db_mgr_addr); - DWORD db_num = *(DWORD *)(wrap_ptr+0x30); - DWORD current_db_num = *(DWORD *)(wrap_ptr+0x38); - DWORD begin_ptr = *(DWORD *)(wrap_ptr + 0x2c); - - for (unsigned int i = 0; i < current_db_num; i++) { - DWORD next_addr = begin_ptr + i * 0x4; - DWORD db_addr = *(DWORD *) next_addr; - if (db_addr) { - DWORD msg0_db_addr = *(DWORD *)(db_addr + 0x60); - DatabaseInfo msg0_db{0}; - msg0_db.db_name = (wchar_t *)(*(DWORD *)(db_addr)); - msg0_db.db_name_len = *(DWORD *)(db_addr + 0x4); - msg0_db.handle = msg0_db_addr; - msg0_db.extrainfo = *(DWORD *) (*(DWORD *)(db_addr + 0x18) +0x144); - ExecuteSQL( - msg0_db_addr, "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &msg0_db); - dbs.push_back(msg0_db); - wstring msg_db_name = wstring((wchar_t *)(*(DWORD *)(db_addr))); - dbmap[msg_db_name] = msg0_db; - } - } - - // publicMsg.db - DWORD public_msg_ptr = *(DWORD *) (*(DWORD *)(public_msg_mgr_addr) + 0x8); - if (public_msg_ptr) { - DWORD public_msg_db_addr = *(DWORD *)(public_msg_ptr + 0x38); - DatabaseInfo public_msg_db{0}; - public_msg_db.db_name = (wchar_t *)(*(DWORD *)(public_msg_ptr + 0x4C)); - public_msg_db.db_name_len =*(DWORD *)(public_msg_ptr + 0x50); - public_msg_db.handle = public_msg_db_addr; - ExecuteSQL(public_msg_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &public_msg_db); - dbs.push_back(public_msg_db); - wstring public_msg_db_name =wstring((wchar_t *)(*(DWORD *)(public_msg_ptr + 0x4C))); - dbmap[public_msg_db_name] = public_msg_db; - } - - // Favorite.db - DWORD favItems_ptr = *(DWORD *)(*(DWORD *)(favorite_storage_mgr_addr) + 0x8); - if (favItems_ptr) { - DWORD favorite_db_addr = *(DWORD *)(favItems_ptr + 0x38); - DatabaseInfo favorite_db{0}; - favorite_db.db_name =(wchar_t *)(*(DWORD *)(favItems_ptr + 0x4C)); - favorite_db.db_name_len = *(DWORD *)(favItems_ptr + 0x50); - favorite_db.handle = favorite_db_addr; - ExecuteSQL(favorite_db_addr, - "select * from sqlite_master where type=\"table\";", - (DWORD)GetDbInfo, &favorite_db); - dbs.push_back(favorite_db); - wstring public_msg_db_name =wstring((wchar_t *)(*(DWORD *)(favItems_ptr + 0x4C))); - dbmap[public_msg_db_name] = favorite_db; - } - - DatabaseInfo db_end = {0}; - dbs.push_back(db_end); -#ifdef _DEBUG - for (unsigned int i = 0; i < dbs.size() - 1; i++) { - printf("dbname = %ws,handle = 0x%08X,table_count:%d\n", dbs[i].db_name, - dbs[i].handle, dbs[i].tables.size()); - for (unsigned int j = 0; j < dbs[i].tables.size(); j++) { - cout << "name = " << dbs[i].tables[j].name << endl; - cout << "tbl_name = " << dbs[i].tables[j].table_name << endl; - cout << "rootpage = " << dbs[i].tables[j].rootpage << endl; - cout << "sql = " << dbs[i].tables[j].sql << endl; - cout << endl; - } - cout << endl; - } -#endif - vector ret_array; - for (unsigned int i = 0; i < dbs.size() - 1; i++) - ret_array.push_back(&dbs[i]); - return ret_array; -} - -DWORD GetDbHandleByDbName(wchar_t *dbname) { - if (dbmap.size() == 0) { - GetDbHandles(); - } - if (dbmap.find(dbname) != dbmap.end()) { - return dbmap[dbname].handle; - } - - return 0; -} - -unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &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); - DWORD handle = GetDbHandleByDbName(dbname); - #ifdef _DEBUG - cout <<" handle =" <> result; - int ret = Select(handle, (const char *)sql, result); - #ifdef _DEBUG - cout <<" size =" < - -std::vector GetDbHandles(); -DWORD GetDbHandleByDbName(wchar_t *dbname); -unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex); -#endif \ No newline at end of file diff --git a/src/hook_img.cc b/src/hook_img.cc deleted file mode 100644 index 656f915..0000000 --- a/src/hook_img.cc +++ /dev/null @@ -1,231 +0,0 @@ -#include "pch.h" -#include "hook_img.h" - -#include "common.h" - - -// #define WX_HOOK_IMG_OFFSET 0xd7eaa5 -// #define WX_HOOK_IMG_NEXT_OFFSET 0xda56e0 -#define WX_HOOK_IMG_OFFSET 0xc63ebc -#define WX_HOOK_IMG_NEXT_OFFSET 0xd7e9e0 -#define WX_SELF_ID_OFFSET 0x2BEE08C -#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 - - - -static wstring kImgStorePath = L""; -static int kImgHooked = FALSE; -static DWORD kWeChatWinBase = GetWeChatWinBase(); -static char kOriginImgAsmCode[5] = {0}; - -static DWORD kHookImgNextAddress = kWeChatWinBase + WX_HOOK_IMG_NEXT_OFFSET; -static DWORD kHookImgJmpBackAddress = kWeChatWinBase + WX_HOOK_IMG_OFFSET + 0x5; - -void OnHookImg(DWORD obj_addr) { - DWORD wxid_addr = GetWeChatWinBase() + WX_SELF_ID_OFFSET; - string wxid = string(*(char **)wxid_addr, *(DWORD *)(wxid_addr + 0x10)); - wstring self_id = String2Wstring(wxid); - wstring save_path = kImgStorePath + self_id; - if (!FindOrCreateDirectoryW(save_path.c_str())) { - return; - } - wchar_t *origin_file_path = *(wchar_t **)obj_addr; - wstring img_path(origin_file_path); - if (img_path.find(L"_t.dat") != wstring::npos) { - return; - } - - int pos_begin = img_path.find_last_of(L"\\") + 1; - int pos_end = img_path.find_last_of(L"."); - wstring file_name = img_path.substr(pos_begin, pos_end - pos_begin); - char buffer[BUFSIZE] = {0}; - DWORD bytes_read = 0; - DWORD bytes_write = 0; - unsigned char magic_head[4] = {0}; - wchar_t suffix[5] = {0}; - - HANDLE h_origin_file = - CreateFileW(origin_file_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h_origin_file == INVALID_HANDLE_VALUE) { - return; - } - - if (ReadFile(h_origin_file, buffer, BUFSIZE, &bytes_read, NULL)) { - memcpy(magic_head, buffer, 3); - } - - if (magic_head[0] == PNG0 && magic_head[1] == PNG1 && magic_head[2] == PNG2) { - lstrcpyW(suffix, L".png"); - } else if (magic_head[0] == GIF0 && magic_head[1] == GIF1 && - magic_head[2] == GIF2) { - lstrcpyW(suffix, L".gif"); - } else if (magic_head[0] == JPEG0 && magic_head[1] == JPEG1 && - magic_head[2] == JPEG2) { - lstrcpyW(suffix, L".jpg"); - } else { - lstrcpyW(suffix, L""); - } - - wstring save_img_path = save_path + L"\\" + file_name + suffix; - HANDLE save_file = CreateFileW(save_img_path.c_str(), GENERIC_ALL, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (save_file == INVALID_HANDLE_VALUE) { - return; - } - if (!WriteFile(save_file, (LPCVOID)buffer, bytes_read, &bytes_write, 0)) { - CloseHandle(h_origin_file); - CloseHandle(save_file); - return; - } - do { - if (ReadFile(h_origin_file, buffer, BUFSIZE, &bytes_read, NULL)) { - if (!WriteFile(save_file, (LPCVOID)buffer, bytes_read, &bytes_write, 0)) { - CloseHandle(h_origin_file); - CloseHandle(save_file); - return; - } - } - } while (bytes_read == BUFSIZE); - CloseHandle(h_origin_file); - CloseHandle(save_file); -} - -/// @brief hook img implement -_declspec(naked) void handle_img() { - __asm { - PUSHAD - PUSHFD - PUSH ECX - CALL OnHookImg - ADD ESP, 0x4 - POPFD - POPAD - CALL kHookImgNextAddress - JMP kHookImgJmpBackAddress - } -} - -/// @brief hook image -/// @param save_path image save dir -/// @return -int HookImg(wstring save_path) { - kWeChatWinBase = GetWeChatWinBase(); - if (!kWeChatWinBase) { - return -1; - } - if (kImgHooked) { - return 2; - } - kImgStorePath = save_path; - if (kImgStorePath.back() != '\\') { - kImgStorePath += L"\\"; - } - wstring createpath = kImgStorePath.substr(0, kImgStorePath.length() - 1); - if (!FindOrCreateDirectoryW(createpath.c_str())) { - return -2; - } - DWORD hook_img_addr = kWeChatWinBase + WX_HOOK_IMG_OFFSET; - kHookImgNextAddress = kWeChatWinBase + WX_HOOK_IMG_NEXT_OFFSET; - static DWORD kHookImgJmpBackAddress = hook_img_addr + 0x5; - HookAnyAddress(hook_img_addr, (LPVOID)handle_img, kOriginImgAsmCode); - kImgHooked = TRUE; - return 1; -} - -int UnHookImg() { - if (!kImgHooked) return 1; - DWORD hook_img_addr = kWeChatWinBase + WX_HOOK_IMG_OFFSET; - UnHookAnyAddress(hook_img_addr, kOriginImgAsmCode); - kImgHooked = FALSE; - return 1; -} - -int GetImgByName(wchar_t* file_path,wchar_t* save_dir) { - wstring save_path(save_dir); - wstring orign_file_path(file_path); - if (!FindOrCreateDirectoryW(save_path.c_str())) { - return 0; - } - - int pos_begin = orign_file_path.find_last_of(L"\\") + 1; - int pos_end = orign_file_path.find_last_of(L"."); - wstring file_name = orign_file_path.substr(pos_begin, pos_end - pos_begin); - HANDLE h_origin_file = - CreateFileW(file_path, 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}; - 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"; - } - wstring save_img_path = save_path + 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; -} \ No newline at end of file diff --git a/src/hook_img.h b/src/hook_img.h deleted file mode 100644 index 68c458e..0000000 --- a/src/hook_img.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HOOK_IMG_H_ -#define HOOK_IMG_H_ -#include "windows.h" -using namespace std; - -int HookImg(wstring save_path); -int UnHookImg(); - -int GetImgByName(wchar_t* file_path,wchar_t* save_dir); -#endif \ No newline at end of file diff --git a/src/hook_recv_msg.cc b/src/hook_recv_msg.cc deleted file mode 100644 index 7043a4b..0000000 --- a/src/hook_recv_msg.cc +++ /dev/null @@ -1,220 +0,0 @@ -#include "hook_recv_msg.h" - -#include -#include - -#include - -#include "common.h" -#include "pch.h" -using namespace nlohmann; - -using namespace std; -#define WX_RECV_MSG_HOOK_OFFSET 0xb94796 -#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x6fe2c0 - -// SyncMgr::addMsgListToDB -// #define WX_RECV_MSG_HOOK_OFFSET 0xB9C919 -// #define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x722FF0 - -#define CLIENT_IP "127.0.0.1" -static int kServerPort = 0; -static int kMessageHooked = FALSE; -static DWORD kWeChatWinBase = GetWeChatWinBase(); - -static char kOriginReceMsgAsmCode[5] = {0}; -static DWORD kReceMsgJmpBackAddress = - kWeChatWinBase + WX_RECV_MSG_HOOK_OFFSET + 0x5; -static DWORD kReceMsgNextAddress = - kWeChatWinBase + WX_RECV_MSG_HOOK_NEXT_OFFSET; - -struct InnerMessageStruct { - char *buffer; - int length; - ~InnerMessageStruct() { - if (this->buffer != NULL) { - delete[] this->buffer; - this->buffer = NULL; - } - } -}; -/// @brief send message by socket -/// @param buffer content -/// @param len len -/// @return true/false -BOOL SendBySocket(const char *buffer, size_t len) { - if (kServerPort == 0) { - return false; - } - SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (client_socket < 0) { -#ifdef _DEBUG - cout << "create socket error," - << " errno:" << errno << endl; -#endif - return false; - } - BOOL status = false; - sockaddr_in client_addr; - memset(&client_addr, 0, sizeof(client_addr)); - client_addr.sin_family = AF_INET; - client_addr.sin_port = htons((u_short)kServerPort); - InetPtonA(AF_INET, CLIENT_IP, &client_addr.sin_addr.s_addr); - if (connect(client_socket, reinterpret_cast(&client_addr), - sizeof(sockaddr)) < 0) { -#ifdef _DEBUG - cout << "connect error," - << " errno:" << errno << endl; -#endif - return false; - } - char recv_buf[1024] = {0}; - int ret = send(client_socket, buffer, len, 0); - if (ret == -1 || ret == 0) { -#ifdef _DEBUG - cout << "send fail," - << " errno:" << errno << endl; -#endif - closesocket(client_socket); - return false; - } - memset(recv_buf, 0, sizeof(recv_buf)); - ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0); - closesocket(client_socket); - if (ret == -1 || ret == 0) { -#ifdef _DEBUG - cout << "the server close" << endl; -#endif - return false; - } - return true; -} -/// @brief send wrap -/// @param msg msg -void SendSocketMessage(InnerMessageStruct *msg) { - if (msg == NULL) { - return; - } - unique_ptr sms(msg); - json j_msg = - json::parse(msg->buffer, msg->buffer + msg->length, nullptr, false); - if (j_msg.is_discarded() == true) { - return; - } - string jstr = j_msg.dump() + "\n"; -#ifdef _DEBUG - cout << "json:" + jstr << endl; -#endif - SendBySocket(jstr.c_str(), jstr.size()); -} -/// @brief msg handle -/// @param msg_addr msg address in memory -void OnRecvMsg(DWORD msg_addr) { - json j_msg; - unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30); - j_msg["msgId"] = msgid; - j_msg["pid"] = GetCurrentProcessId(); - j_msg["type"] = *(DWORD *)(msg_addr + 0x38); - j_msg["isSendMsg"] = *(BOOL *)(msg_addr + 0x3C); - if (j_msg["isSendMsg"].get()) { - j_msg["isSendByPhone"] = (int)(*(BYTE *)(msg_addr + 0xD8)); - } - j_msg["time"] = - unicode_to_utf8((wchar_t *)GetTimeW(*(DWORD *)(msg_addr + 0x44)).c_str()); - j_msg["timestamp"] = *(DWORD *)(msg_addr + 0x44); - j_msg["fromGroup"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x48).c_str()); - int length = *(DWORD *)(msg_addr + 0x178); - if (length == 0) { - j_msg["fromUser"] = j_msg["fromGroup"].get(); - } else { - j_msg["fromUser"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x174).c_str()); - } - int content_len = *(DWORD *)(msg_addr + 0x74); - if (content_len > 0) { - j_msg["content"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x70).c_str()); -#ifdef _DEBUG - printf("%s", j_msg["content"].get().c_str()); -#endif - } - int sign_len = *(DWORD *)(msg_addr + 0x18C); - if (sign_len > 0) { - j_msg["sign"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x188).c_str()); - } - int thumb_len = *(DWORD *)(msg_addr + 0x1A0); - if (thumb_len > 0) { - j_msg["thumbPath"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x19C).c_str()); - } - int path_len = *(DWORD *)(msg_addr + 0x1B4); - if (path_len > 0) { - j_msg["path"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x1B0).c_str()); - } - - int signature_len = *(DWORD *)(msg_addr + 0x1F4); - if (signature_len > 0) { - j_msg["signature"] = - unicode_to_utf8((wchar_t *)READ_WSTRING(msg_addr, 0x1F0).c_str()); - } - - string jstr = j_msg.dump() + '\n'; - InnerMessageStruct *inner_msg = new InnerMessageStruct; - inner_msg->buffer = new char[jstr.size() + 1]; - memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1); - inner_msg->length = jstr.size(); - HANDLE thread = CreateThread( - NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0); - if (thread) { - CloseHandle(thread); - } -} -/// @brief hook implement -_declspec(naked) void handle_sync_msg() { - __asm { - PUSHAD - PUSHFD - PUSH ECX - CALL OnRecvMsg - ADD ESP, 0x4 - POPFD - POPAD - CALL kReceMsgNextAddress - JMP kReceMsgJmpBackAddress - } -} - -/// @brief hook any address address+0x5 -/// @param port 端口 -/// @return 成功返回1,已经hook返回2,失败返回-1 -int HookRecvMsg(int port) { - kServerPort = port; - kWeChatWinBase = GetWeChatWinBase(); - if (!kWeChatWinBase) { - return -1; - } - - if (kMessageHooked) { - return 2; - } - kWeChatWinBase = GetWeChatWinBase(); - DWORD hook_recv_msg_addr = kWeChatWinBase + WX_RECV_MSG_HOOK_OFFSET; - kReceMsgNextAddress = kWeChatWinBase + WX_RECV_MSG_HOOK_NEXT_OFFSET; - kReceMsgJmpBackAddress = hook_recv_msg_addr + 0x5; - HookAnyAddress(hook_recv_msg_addr, (LPVOID)handle_sync_msg, - kOriginReceMsgAsmCode); - kMessageHooked = TRUE; - return 1; -} - -int UnHookRecvMsg() { - kServerPort = 0; - if (!kMessageHooked) return 2; - DWORD hook_recv_msg_addr = kWeChatWinBase + WX_RECV_MSG_HOOK_OFFSET; - UnHookAnyAddress(hook_recv_msg_addr, kOriginReceMsgAsmCode); - kMessageHooked = FALSE; - return 1; -} \ No newline at end of file diff --git a/src/hook_recv_msg.h b/src/hook_recv_msg.h deleted file mode 100644 index c6927c6..0000000 --- a/src/hook_recv_msg.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HOOK_RECV_MSG_H_ -#define HOOK_RECV_MSG_H_ - -/// @brief hook any address address+0x5 -/// @param port 端口 -/// @return 成功返回1,已经hook返回2 -int HookRecvMsg(int port); - -int UnHookRecvMsg(); -#endif \ No newline at end of file diff --git a/src/new_sqlite3.h b/src/new_sqlite3.h deleted file mode 100644 index 4ea593c..0000000 --- a/src/new_sqlite3.h +++ /dev/null @@ -1,195 +0,0 @@ -#ifndef NEW_SQLITE3_H_ -#define NEW_SQLITE3_H_ -#include "Windows.h" -#define SQLITE_OK 0 /* Successful result */ -/* beginning-of-error-codes */ -#define SQLITE_ERROR 1 /* Generic error */ -#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */ -#define SQLITE_PERM 3 /* Access permission denied */ -#define SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define SQLITE_BUSY 5 /* The database file is locked */ -#define SQLITE_LOCKED 6 /* A table in the database is locked */ -#define SQLITE_NOMEM 7 /* A malloc() failed */ -#define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ -#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ -#define SQLITE_FULL 13 /* Insertion failed because database is full */ -#define SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Internal use only */ -#define SQLITE_SCHEMA 17 /* The database schema changed */ -#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ -#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ -#define SQLITE_MISMATCH 20 /* Data type mismatch */ -#define SQLITE_MISUSE 21 /* Library used incorrectly */ -#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define SQLITE_AUTH 23 /* Authorization denied */ -#define SQLITE_FORMAT 24 /* Not used */ -#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ -#define SQLITE_NOTADB 26 /* File opened that is not a database file */ -#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ -#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ -#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ -#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ -/* end-of-error-codes */ - -/* -** CAPI3REF: Extended Result Codes -** KEYWORDS: {extended result code definitions} -** -** In its default configuration, SQLite API routines return one of 30 integer -** [result codes]. However, experience has shown that many of -** these result codes are too coarse-grained. They do not provide as -** much information about problems as programmers might like. In an effort to -** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8] -** and later) include -** support for additional result codes that provide more detailed information -** about errors. These [extended result codes] are enabled or disabled -** on a per database connection basis using the -** [sqlite3_extended_result_codes()] API. Or, the extended code for -** the most recent error can be obtained using -** [sqlite3_extended_errcode()]. -*/ -#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1 << 8)) -#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2 << 8)) -#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3 << 8)) -#define SQLITE_IOERR_READ (SQLITE_IOERR | (1 << 8)) -#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2 << 8)) -#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3 << 8)) -#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4 << 8)) -#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5 << 8)) -#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6 << 8)) -#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7 << 8)) -#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8 << 8)) -#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9 << 8)) -#define SQLITE_IOERR_DELETE (SQLITE_IOERR | (10 << 8)) -#define SQLITE_IOERR_BLOCKED (SQLITE_IOERR | (11 << 8)) -#define SQLITE_IOERR_NOMEM (SQLITE_IOERR | (12 << 8)) -#define SQLITE_IOERR_ACCESS (SQLITE_IOERR | (13 << 8)) -#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14 << 8)) -#define SQLITE_IOERR_LOCK (SQLITE_IOERR | (15 << 8)) -#define SQLITE_IOERR_CLOSE (SQLITE_IOERR | (16 << 8)) -#define SQLITE_IOERR_DIR_CLOSE (SQLITE_IOERR | (17 << 8)) -#define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18 << 8)) -#define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19 << 8)) -#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20 << 8)) -#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21 << 8)) -#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22 << 8)) -#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23 << 8)) -#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24 << 8)) -#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25 << 8)) -#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26 << 8)) -#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27 << 8)) -#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28 << 8)) -#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29 << 8)) -#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30 << 8)) -#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31 << 8)) -#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32 << 8)) -#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33 << 8)) -#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1 << 8)) -#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2 << 8)) -#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1 << 8)) -#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2 << 8)) -#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3 << 8)) -#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1 << 8)) -#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2 << 8)) -#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3 << 8)) -#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4 << 8)) -#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5 << 8)) /* Not Used */ -#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6 << 8)) -#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1 << 8)) -#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2 << 8)) -#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3 << 8)) -#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1 << 8)) -#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2 << 8)) -#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3 << 8)) -#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4 << 8)) -#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5 << 8)) -#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6 << 8)) -#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2 << 8)) -#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1 << 8)) -#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2 << 8)) -#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3 << 8)) -#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4 << 8)) -#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5 << 8)) -#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6 << 8)) -#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7 << 8)) -#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8 << 8)) -#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9 << 8)) -#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT | (10 << 8)) -#define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT | (11 << 8)) -#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT | (12 << 8)) -#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1 << 8)) -#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2 << 8)) -#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1 << 8)) -#define SQLITE_AUTH_USER (SQLITE_AUTH | (1 << 8)) -#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1 << 8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2 << 8)) /* internal use only */ - - -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 -#define SQLITE_TEXT 3 - -#define SQLITE3_EXEC_OFFSET 0x1b623b0 -#define SQLITE3_BACKUP_INIT_OFFSET 0x1b27d50 -#define SQLITE3_PREPARE_OFFSET 0x1b68d00 -#define SQLITE3_OPEN_OFFSET 0x1b96cf0 -#define SQLITE3_BACKUP_STEP_OFFSET 0x1b28150 -#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1b28890 -#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1b288a0 -#define SQLITE3_BACKUP_FINISH_OFFSET 0x1b28790 -#define SQLITE3_SLEEP_OFFSET 0x1b97530 -#define SQLITE3_ERRCODE_OFFSET 0x1b95990 -#define SQLITE3_CLOSE_OFFSET 0x1b94110 -#define SQLITE3_STEP_OFFSET 0x1b30bc0 -#define SQLITE3_COLUMN_COUNT_OFFSET 0x1b310d0 -#define SQLITE3_COLUMN_NAME_OFFSET 0x1b319c0 -#define SQLITE3_COLUMN_TYPE_OFFSET 0x1b31860 -#define SQLITE3_COLUMN_BLOB_OFFSET 0x1b31110 -#define SQLITE3_COLUMN_BYTES_OFFSET 0x1b311f0 -#define SQLITE3_FINALIZE_OFFSET 0x1b2fb90 - -typedef int (*Sqlite3_callback)(void*, int, char**, char**); - -typedef int(__cdecl* Sqlite3_exec)(DWORD, /* An open database */ - const char* sql, /* SQL to be evaluated */ - Sqlite3_callback, /* Callback function */ - void*, /* 1st argument to callback */ - char** errmsg /* Error msg written here */ -); -typedef DWORD(__cdecl* Sqlite3_backup_init)( - DWORD* pDest, /* Destination database handle */ - const char* zDestName, /* Destination database name */ - DWORD* pSource, /* Source database handle */ - const char* zSourceName /* Source database name */ -); -typedef int(__cdecl* Sqlite3_prepare)( - DWORD db, /* Database handle */ - const char* zSql, /* SQL statement, UTF-8 encoded */ - int nByte, /* Maximum length of zSql in bytes. */ - DWORD** ppStmt, /* OUT: Statement handle */ - const char** pzTail /* OUT: Pointer to unused portion of zSql */ -); -typedef int(__cdecl* Sqlite3_open)(const char* filename, DWORD** ppDb); -typedef int(__cdecl* Sqlite3_backup_step)(DWORD* p, int nPage); -typedef int(__cdecl* Sqlite3_backup_remaining)(DWORD* p); -typedef int(__cdecl* Sqlite3_backup_pagecount)(DWORD* p); -typedef int(__cdecl* Sqlite3_backup_finish)(DWORD* p); -typedef int(__cdecl* Sqlite3_sleep)(int); -typedef int(__cdecl* Sqlite3_errcode)(DWORD* db); -typedef int(__cdecl* Sqlite3_close)(DWORD*); - -typedef int(__cdecl* Sqlite3_step)(DWORD*); -typedef int(__cdecl* Sqlite3_column_count)(DWORD* pStmt); -typedef const char*(__cdecl* Sqlite3_column_name)(DWORD*, int N); -typedef int(__cdecl* Sqlite3_column_type)(DWORD*, int iCol); -typedef const void*(__cdecl* Sqlite3_column_blob)(DWORD*, int iCol); -typedef int(__cdecl* Sqlite3_column_bytes)(DWORD*, int iCol); -typedef int(__cdecl* Sqlite3_finalize)(DWORD* pStmt); - -#endif \ No newline at end of file diff --git a/src/pch.h b/src/pch.h deleted file mode 100644 index 6e2a672..0000000 --- a/src/pch.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PCH_H -#define PCH_H - - -#define GLOG_NO_ABBREVIATED_SEVERITIES -#include "framework.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif // PCH_H - - diff --git a/src/self_info.cc b/src/self_info.cc deleted file mode 100644 index 561da22..0000000 --- a/src/self_info.cc +++ /dev/null @@ -1,139 +0,0 @@ -#include "pch.h" -#include "self_info.h" - -#include "common.h" - -#include "wechat_data.h" - -#define WX_SELF_NAME_OFFSET 0x2bee198 -#define WX_SELF_MOBILE_OFFSET 0x2BEE108 -#define WX_SELF_CITY_OFFSET 0x2BEE168 -#define WX_SELF_PROVINCE_OFFSET 0x2BEE150 -#define WX_SELF_COUNTRY_OFFSET 0x2BEE138 -#define WX_SELF_ACCOUNT_OFFSET 0x2BEE0F0 -#define WX_SELF_ID_OFFSET 0x2BEE08C -#define WX_SELF_SMALL_IMG_OFFSET 0x2BEE34C -#define WX_SELF_BIG_IMG_OFFSET 0x2BEE364 -#define WX_LOGIN_STATUS_OFFSET 0x2BEE4C0 -#define WX_APP_DATA_ROOT_PATH_OFFSET 0x2c2f478 -#define WX_APP_DATA_SAVE_PATH_OFFSET 0x2C10D04 -#define WX_CURRENT_DATA_PATH_OFFSET 0x2C0EC38 - - - -int GetSelfInfo(SelfInfoInner &out) { - DWORD base = GetWeChatWinBase(); -#ifdef _DEBUG - cout << "mobile:" << (char *)(base + WX_SELF_MOBILE_OFFSET) << endl; - cout << "name:" << (char *)(base + WX_SELF_NAME_OFFSET) << endl; - cout << "city:" << (char *)(base + WX_SELF_CITY_OFFSET) << endl; - cout << "city:" << (char *)(base + WX_SELF_CITY_OFFSET) << endl; - cout << "province:" << (char *)(base + WX_SELF_PROVINCE_OFFSET) << endl; - cout << "country:" << (char *)(base + WX_SELF_COUNTRY_OFFSET) << endl; - cout << "account:" << (char *)(base + WX_SELF_ACCOUNT_OFFSET) << endl; - cout << "wxid:" << (char *)(base + WX_SELF_ID_OFFSET) << endl; - cout << "small_img:" << (char *)(base + WX_SELF_SMALL_IMG_OFFSET) << endl; - cout << "big_img:" << (char *)(base + WX_SELF_BIG_IMG_OFFSET) << endl; -#endif - if (*(DWORD *)(base + WX_SELF_NAME_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_NAME_OFFSET + 0x10) == 0) { - out.name = string(); - } else { - out.name = string((char *)(base + WX_SELF_NAME_OFFSET), - *(DWORD *)(base + WX_SELF_NAME_OFFSET + 0x10)); - } - if (*(DWORD *)(base + WX_SELF_MOBILE_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_MOBILE_OFFSET + 0x10) == 0) { - out.mobile = string(); - } else { - out.mobile = string((char *)(base + WX_SELF_MOBILE_OFFSET), - *(DWORD *)(base + WX_SELF_MOBILE_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_CITY_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_CITY_OFFSET + 0x10) == 0) { - out.city = string(); - } else { - out.city = string((char *)(base + WX_SELF_CITY_OFFSET), - *(DWORD *)(base + WX_SELF_CITY_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_PROVINCE_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_PROVINCE_OFFSET + 0x10) == 0) { - out.province = string(); - } else { - out.province = string((char *)(base + WX_SELF_PROVINCE_OFFSET), - *(DWORD *)(base + WX_SELF_PROVINCE_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_COUNTRY_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_COUNTRY_OFFSET + 0x10) == 0) { - out.country = string(); - } else { - out.country = string((char *)(base + WX_SELF_COUNTRY_OFFSET), - *(DWORD *)(base + WX_SELF_COUNTRY_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET + 0x10) == 0) { - out.account = string(); - } else { - out.account = string(*(char **)(base + WX_SELF_ACCOUNT_OFFSET), - *(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_ID_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_ID_OFFSET + 0x10) == 0) { - out.wxid = string(); - } else { - out.wxid = string(*(char **)(base + WX_SELF_ID_OFFSET), - *(DWORD *)(base + WX_SELF_ID_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET + 0x10) == 0) { - out.small_img = string(); - } else { - out.small_img = string(*(char **)(base + WX_SELF_SMALL_IMG_OFFSET), - *(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET) == 0 || - *(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET + 0x10) == 0) { - out.big_img = string(); - } else { - out.big_img = string(*(char **)(base + WX_SELF_BIG_IMG_OFFSET), - *(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET + 0x10)); - } - - if (*(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET) == 0 || - *(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET + 0x4) == 0) { - out.data_root_path = string(); - } else { - out.data_root_path = Wstring2String(wstring(*(wchar_t **)(base + WX_APP_DATA_ROOT_PATH_OFFSET), - *(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET + 0x4))); - } - - if (*(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET) == 0 || - *(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET + 0x4) == 0) { - out.data_save_path = string(); - } else { - out.data_save_path = Wstring2String(wstring(*(wchar_t **)(base + WX_APP_DATA_SAVE_PATH_OFFSET), - *(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET + 0x4))); - } - if (*(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET) == 0 || - *(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET + 0x4) == 0) { - out.current_data_path = string(); - } else { - out.current_data_path = Wstring2String(wstring(*(wchar_t **)(base + WX_CURRENT_DATA_PATH_OFFSET), - *(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET + 0x4))); - } - - return 1; -} - - -int CheckLogin(){ - DWORD base = GetWeChatWinBase(); - return *(DWORD*) (base + WX_LOGIN_STATUS_OFFSET); -} \ No newline at end of file diff --git a/src/self_info.h b/src/self_info.h deleted file mode 100644 index 50ddac3..0000000 --- a/src/self_info.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SELF_INFO_H_ -#define SELF_INFO_H_ -#include "wechat_data.h" -int GetSelfInfo(SelfInfoInner& out); - -int CheckLogin(); -#endif \ No newline at end of file diff --git a/src/send_file.cc b/src/send_file.cc deleted file mode 100644 index a33727c..0000000 --- a/src/send_file.cc +++ /dev/null @@ -1,67 +0,0 @@ -#include "pch.h" -#include "send_file.h" -#include "common.h" -#include "wechat_data.h" - -#define WX_APP_MSG_MGR_OFFSET 0x665f60 -#define WX_SEND_FILE_OFFSET 0xa0ce20 -#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40 -#define WX_FREE_CHAT_MSG_OFFSET 0x651c40 - -int SendFile(wchar_t *wxid, wchar_t *file_path){ - int success = 0; - WeChatString to_user(wxid); - WeChatString path(file_path); - char chat_msg[0x2A8] = {0}; - DWORD base = GetWeChatWinBase(); - DWORD app_msg_mgr_addr = base + WX_APP_MSG_MGR_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - DWORD send_file_addr = base + WX_SEND_FILE_OFFSET; - DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET; - DWORD temp = 0; - WeChatString null_obj = {0}; - __asm{ - PUSHAD - PUSHFD - CALL app_msg_mgr_addr - SUB ESP,0x14 - MOV temp,EAX - LEA EAX,null_obj - MOV ECX,ESP - PUSH EAX - CALL init_chat_msg_addr - PUSH 0x0 - SUB ESP,0x14 - MOV EDI,ESP - MOV dword ptr [EDI],0 - MOV dword ptr [EDI + 0x4],0 - MOV dword ptr [EDI + 0x8],0 - MOV dword ptr [EDI + 0xc],0 - MOV dword ptr [EDI + 0x10],0 - SUB ESP,0x14 - LEA EAX,path - MOV ECX,ESP - PUSH EAX - CALL init_chat_msg_addr - SUB ESP,0x14 - LEA EAX,to_user - MOV ECX,ESP - PUSH EAX - CALL init_chat_msg_addr - MOV ECX,dword ptr [temp] - LEA EAX,chat_msg - PUSH EAX - CALL send_file_addr - MOV AL,byte ptr [eax + 0x38] - MOVZX EAX,AL - MOV success,EAX - LEA ECX,chat_msg - CALL free_msg_addr - POPFD - POPAD - } - if (success == 0x31){ - return 1; - } - return 0; -} \ No newline at end of file diff --git a/src/send_file.h b/src/send_file.h deleted file mode 100644 index 7436b4d..0000000 --- a/src/send_file.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef SEND_FILE_H_ -#define SEND_FILE_H_ - -int SendFile(wchar_t *wxid, wchar_t *file_path); -#endif \ No newline at end of file diff --git a/src/send_image.cc b/src/send_image.cc deleted file mode 100644 index 29a358a..0000000 --- a/src/send_image.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include "pch.h" -#include "send_image.h" -#include "common.h" -#include "wechat_data.h" - -#define WX_SEND_IMAGE_OFFSET 0xb68b90 -#define WX_SEND_MESSAGE_MGR_OFFSET 0x663320 -#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40 -#define WX_FREE_CHAT_MSG_OFFSET 0x651c40 - -int SendImage(wchar_t *wxid, wchar_t *image_path){ - - int success = 0; - WeChatString to_user(wxid); - WeChatString path(image_path); - char chat_msg[0x2A8] ={0}; - DWORD base = GetWeChatWinBase(); - DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET; - DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET; - DWORD send_image_msg_addr = base + WX_SEND_IMAGE_OFFSET; - DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET; - DWORD temp = 0; - WeChatString null_obj = {0}; - __asm{ - PUSHAD - CALL send_message_mgr_addr - SUB ESP,0x14 - MOV temp,EAX - LEA EAX,null_obj - MOV ECX,ESP - LEA EDI,path - PUSH EAX - CALL init_chat_msg_addr - MOV ECX,dword ptr [temp] - LEA EAX,to_user - PUSH EDI - PUSH EAX - LEA EAX,chat_msg - PUSH EAX - CALL send_image_msg_addr - MOV success,EAX - LEA ECX,chat_msg - CALL free_msg_addr - POPAD - } - return success; -} \ No newline at end of file diff --git a/src/send_image.h b/src/send_image.h deleted file mode 100644 index 0be9085..0000000 --- a/src/send_image.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef SEND_IMAGE_H_ -#define SEND_IMAGE_H_ - -int SendImage(wchar_t *wxid, wchar_t *image_path); -#endif \ No newline at end of file diff --git a/src/send_text.cc b/src/send_text.cc deleted file mode 100644 index 6ba20cc..0000000 --- a/src/send_text.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "pch.h" -#include "send_text.h" - - -#include "common.h" -#include "wechat_data.h" - -#define WX_SEND_TEXT_OFFSET 0xb690a0 - -#define WX_SEND_MESSAGE_MGR_OFFSET 0x663320 - -#define WX_FREE_CHAT_MSG_OFFSET 0x651c40 -/// @brief 发生文本消息 -/// @param wxid wxid -/// @param msg 文本消息 -/// @return 成功返回1 -int SendText(wchar_t* wxid, wchar_t* msg) { - int success = 0; - WeChatString to_user(wxid); - WeChatString text_msg(msg); - wchar_t **msg_pptr = &text_msg.ptr; - char chat_msg[0x2A8] ={0}; - DWORD base = GetWeChatWinBase(); - DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET; - DWORD send_text_msg_addr = base + WX_SEND_TEXT_OFFSET; - DWORD free_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET; - __asm{ - PUSHAD - PUSH 0x0 - PUSH 0x0 - PUSH 0x1 - PUSH 0x0 - MOV EDI,msg_pptr - PUSH EDI - LEA EDX,to_user - LEA ECX,chat_msg - CALL send_text_msg_addr - ADD ESP,0x14 - MOV success,EAX - LEA ECX,chat_msg - CALL free_msg_addr - POPAD - } - return success; -} \ No newline at end of file diff --git a/src/send_text.h b/src/send_text.h deleted file mode 100644 index 57005dd..0000000 --- a/src/send_text.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef SEND_TEXT_H_ -#define SEND_TEXT_H_ - -int SendText(wchar_t* wxid, wchar_t* msg); - -#endif \ No newline at end of file diff --git a/src/wechat_data.h b/src/wechat_data.h deleted file mode 100644 index d871ea5..0000000 --- a/src/wechat_data.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef WECHAT_DATA_H_ -#define WECHAT_DATA_H_ - -// #include - -#include -using namespace std; -struct WeChatString { - wchar_t *ptr; - DWORD length; - DWORD max_length; - DWORD c_ptr = 0; - DWORD c_len = 0; - WeChatString() { WeChatString(NULL); } - - WeChatString(wstring &s) { - ptr = (wchar_t *)(s.c_str()); - length = s.length(); - max_length = s.length() * 2; - } - WeChatString(const wchar_t *pStr) { WeChatString((wchar_t *)pStr); } - WeChatString(int tmp) { - ptr = NULL; - length = 0x0; - max_length = 0x0; - } - WeChatString(wchar_t *pStr) { - ptr = pStr; - length = wcslen(pStr); - max_length = wcslen(pStr) * 2; - } - void set_value(const wchar_t *pStr) { - ptr = (wchar_t *)pStr; - length = wcslen(pStr); - max_length = wcslen(pStr) * 2; - } -}; - -struct TableInfo { - char *name; - DWORD name_len; - char *table_name; - DWORD table_name_len; - char *sql; - DWORD sql_len; - char *rootpage; - DWORD rootpage_len; -}; - -struct DatabaseInfo { - DWORD handle = 0; - wchar_t *db_name = NULL; - DWORD db_name_len = 0; - vector tables; - DWORD count = 0; - DWORD extrainfo = 0; -}; - -struct Contact { - WeChatString wxid; - WeChatString custom_account; - WeChatString encrypt_name; - WeChatString nick_name; - WeChatString pinyin; - WeChatString pinyin_all; - int del_flag; - int type; - int verify_flag; -}; - -struct ChatRoomInfo { - DWORD vftable; - WeChatString chat_room_id; - WeChatString notice; - WeChatString admin; - DWORD filed_40; - DWORD filed_44; - DWORD filed_48; - DWORD filed_4C; - WeChatString xml; - DWORD filed_64; - DWORD filed_68; - DWORD filed_6C; - DWORD filed_70; - DWORD filed_74; - DWORD filed_78; - DWORD filed_7C; - DWORD filed_80; - DWORD filed_84; - DWORD filed_88; - DWORD filed_8c; - DWORD filed_90; - DWORD filed_94; - DWORD filed_98; - DWORD filed_9C; - DWORD filed_A0; -}; - -struct ChatRoomInfoInner { - WeChatString chat_room_id; - WeChatString notice; - WeChatString admin; - WeChatString xml; -}; - -struct VectorInner { -#ifdef _DEBUG - DWORD head; -#endif - DWORD start; - DWORD finsh; - DWORD end; -}; - -struct ChatRoomInner{ - char* members; - wchar_t* chat_room; - wchar_t* admin; - ~ChatRoomInner(){ - delete []members; - delete []chat_room; - delete []admin; - } -}; - -struct SelfInfoInner{ - string name; - string city; - string province; - string country; - string account; - string wxid; - string mobile; - string small_img; - string big_img; - string data_root_path; - string data_save_path; - string current_data_path; -}; -#endif