diff --git a/doc/3.9.5.81.md b/doc/3.9.5.81.md index f335d5e..386fa62 100644 --- a/doc/3.9.5.81.md +++ b/doc/3.9.5.81.md @@ -1071,6 +1071,102 @@ enableHttp=0时,使用ip,port的tcp服务回传消息。 "msgId":"1233312233123" } +``` +响应: +``` javascript +{ + "code": 1, + "data": null, + "msg": "success" +} +``` + +#### 22.朋友圈首页** +###### 接口功能 +> 朋友圈首页,前置条件需先调用hook消息接口成功,具体内容会在hook消息里返回,格式如下: +``` javascript +{ + "data":[ + { + "content": "", + "createTime': 1691125287, + "senderId': "", + "snsId': 123, + "xml':"" + } + ] +} +``` + +###### 接口地址 +> [/api/getSNSFirstPage](/api/getSNSFirstPage) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| + + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,1成功, -1失败| +|msg|string|成功提示| +|data|object|null| + + +###### 接口示例 + +入参: +``` javascript + + +``` +响应: +``` javascript +{ + "code": 1, + "data": null, + "msg": "success" +} +``` + +#### 23.朋友圈下一页** +###### 接口功能 +> 朋友圈下一页 + +###### 接口地址 +> [/api/getSNSNextPage](/api/getSNSNextPage) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|snsId|number|snsId| + + + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,1成功, -1失败| +|msg|string|成功提示| +|data|object|null| + + +###### 接口示例 + +入参: +``` javascript +{ + + "snsid":123 +} + ``` 响应: ``` javascript diff --git a/src/hooks.cc b/src/hooks.cc index 4387a42..9b3e0c9 100644 --- a/src/hooks.cc +++ b/src/hooks.cc @@ -18,6 +18,8 @@ static char kServerIp[16] = "127.0.0.1"; static bool kEnableHttp = false; static bool kLogHookFlag = false; +static bool kSnsFinishHookFlag = false; + static UINT64 (*R_DoAddMsg)(UINT64, UINT64, UINT64) = (UINT64(*)( @@ -29,6 +31,10 @@ static UINT64 (*R_Log)(UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64))(Utils::GetWeChatWinBase() + offset::kHookLog); +static UINT64 (*R_OnSnsTimeLineSceneFinish)(UINT64, UINT64, UINT64) = + (UINT64(*)(UINT64, UINT64, UINT64))(Utils::GetWeChatWinBase() + + offset::kOnSnsTimeLineSceneFinish); + VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context, PTP_WORK Work) { common::InnerMessageStruct *msg = (common::InnerMessageStruct *)context; @@ -167,6 +173,39 @@ if(p== 0 || p == 1){ return p; } +void HandleSNSMsg(INT64 param1, INT64 param2, INT64 param3) { + nlohmann::json j_sns; + INT64 begin_addr = *(INT64 *)(param2 + 0x30); + INT64 end_addr = *(INT64 *)(param2 + 0x38); + if (begin_addr == 0) { + j_sns = {{"data", nlohmann::json::array()}}; + } else { + while (begin_addr < end_addr) { + nlohmann::json j_item; + j_item["snsId"] = *(UINT64 *)(begin_addr); + j_item["createTime"] = *(DWORD *)(begin_addr + 0x38); + j_item["senderId"] = Utils::ReadWstringThenConvert(begin_addr + 0x18); + j_item["content"] = Utils::ReadWstringThenConvert(begin_addr + 0x48); + j_item["xml"] = Utils::ReadWstringThenConvert(begin_addr + 0x580); + j_sns["data"].push_back(j_item); + begin_addr += 0x11E0; + } + } + std::string jstr = j_sns.dump() + '\n'; + common::InnerMessageStruct *inner_msg = new common::InnerMessageStruct; + inner_msg->buffer = new char[jstr.size() + 1]; + memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1); + inner_msg->length = jstr.size(); + if (kEnableHttp) { + bool add = ThreadPool::GetInstance().AddWork(SendHttpMsgCallback, inner_msg); + SPDLOG_INFO("hook sns add http msg work:{}", add); + } else { + bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback, inner_msg); + SPDLOG_INFO("hook sns add msg work:{}", add); + } + R_OnSnsTimeLineSceneFinish(param1, param2, param3); +} + int HookSyncMsg(std::string client_ip, int port, std::string url, uint64_t timeout, bool enable) { if (kMsgHookFlag) { @@ -189,15 +228,23 @@ int HookSyncMsg(std::string client_ip, int port, std::string url, return -1; } - DetourRestoreAfterWith(); + // DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - UINT64 do_add_msg_addr = base + offset::kDoAddMsg; DetourAttach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg); LONG ret = DetourTransactionCommit(); if(ret == NO_ERROR){ kMsgHookFlag = true; } + SPDLOG_INFO("hook sync {}",ret); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(&(PVOID&)R_OnSnsTimeLineSceneFinish, &HandleSNSMsg); + ret = DetourTransactionCommit(); + if(ret == NO_ERROR){ + kSnsFinishHookFlag = true; + } + SPDLOG_INFO("hook sns {}",ret); return ret; } @@ -212,7 +259,6 @@ int UnHookSyncMsg() { UINT64 base = Utils::GetWeChatWinBase(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); - UINT64 do_add_msg_addr = base + offset::kDoAddMsg; DetourDetach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg); LONG ret = DetourTransactionCommit(); if (ret == NO_ERROR) { @@ -235,7 +281,7 @@ int UnHookSyncMsg() { return -1; } - DetourRestoreAfterWith(); + // DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); UINT64 do_add_msg_addr = base + offset::kHookLog; diff --git a/src/http_server_callback.cc b/src/http_server_callback.cc index a495747..01d364a 100644 --- a/src/http_server_callback.cc +++ b/src/http_server_callback.cc @@ -6,6 +6,8 @@ #include "hooks.h" #include "db.h" + +#define STR2ULL(str) (wxhelper::Utils::IsDigit(str) ? stoull(str) : 0) #define STR2LL(str) (wxhelper::Utils::IsDigit(str) ? stoll(str) : 0) #define STR2I(str) (wxhelper::Utils::IsDigit(str) ? stoi(str) : 0) namespace common = wxhelper::common; @@ -30,6 +32,16 @@ INT64 GetINT64Param(nlohmann::json data, std::string key) { return result; } +INT64 GetUINT64Param(nlohmann::json data, std::string key) { + UINT64 result; + try { + result = data[key].get(); + } catch (nlohmann::json::exception) { + result = STR2ULL(data[key].get()); + } + return result; +} + std::string GetStringParam(nlohmann::json data, std::string key) { return data[key].get(); } @@ -423,6 +435,21 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) { {"code", success}, {"msg", "success"}, {"data", {}}}; ret = ret_data.dump(); return ret; + } else if (mg_http_match_uri(hm, "/api/getSNSFirstPage")) { + INT64 success = + wxhelper::GlobalContext::GetInstance().mgr->GetSNSFirstPage(); + nlohmann::json ret_data = { + {"code", success}, {"msg", "success"}, {"data", {}}}; + ret = ret_data.dump(); + return ret; + } else if (mg_http_match_uri(hm, "/api/getSNSNextPage")) { + UINT64 snsid = GetUINT64Param(j_param, "snsId"); + INT64 success = + wxhelper::GlobalContext::GetInstance().mgr->GetSNSNextPage(snsid); + nlohmann::json ret_data = { + {"code", success}, {"msg", "success"}, {"data", {}}}; + ret = ret_data.dump(); + return ret; } else { nlohmann::json ret_data = { {"code", 200}, {"data", {}}, {"msg", "not support url"}}; diff --git a/src/manager.cc b/src/manager.cc index 0bde19b..47c5329 100644 --- a/src/manager.cc +++ b/src/manager.cc @@ -603,4 +603,30 @@ INT64 Manager::ForwardMsg(UINT64 msg_id, const std::wstring &wxid) { success = forward_msg(reinterpret_cast(recv), l.QuadPart, 0x4, 0x0); return success; } + +INT64 Manager::GetSNSFirstPage() { + INT64 success = -1; + UINT64 sns_data_mgr_addr = base_addr_ + offset::kSNSDataMgr; + UINT64 sns_first_page_addr = base_addr_ + offset::kSNSGetFirstPage; + func::__GetSNSDataMgr sns_data_mgr = (func::__GetSNSDataMgr)sns_data_mgr_addr; + func::__GetSNSFirstPage sns_first_page = + (func::__GetSNSFirstPage)sns_first_page_addr; + UINT64 mgr = sns_data_mgr(); + INT64 buff[16] = {0}; + success = sns_first_page(mgr, reinterpret_cast(&buff), 1); + return success; +} + +INT64 Manager::GetSNSNextPage(UINT64 sns_id) { + INT64 success = -1; + UINT64 time_line_mgr_addr = base_addr_ + offset::kSNSTimeLineMgr; + UINT64 sns_next_page_addr = base_addr_ + offset::kSNSGetNextPageScene; + func::__GetSnsTimeLineMgr time_line_mgr = + (func::__GetSnsTimeLineMgr)time_line_mgr_addr; + func::__GetSNSNextPageScene sns_next_page = + (func::__GetSNSNextPageScene)sns_next_page_addr; + UINT64 mgr = time_line_mgr(); + success = sns_next_page(mgr, sns_id); + return success; +} } // namespace wxhelper \ No newline at end of file diff --git a/src/manager.h b/src/manager.h index 3d0fff8..4c1fa30 100644 --- a/src/manager.h +++ b/src/manager.h @@ -32,6 +32,8 @@ class Manager { INT64 CreateChatRoom(const std::vector& wxids); INT64 QuitChatRoom(const std::wstring& room_id); INT64 ForwardMsg(UINT64 msg_id, const std::wstring& wxid); + INT64 GetSNSFirstPage(); + INT64 GetSNSNextPage(UINT64 sns_id); private: UINT64 base_addr_; diff --git a/src/wechat_function.h b/src/wechat_function.h index 47bf639..d2fa115 100644 --- a/src/wechat_function.h +++ b/src/wechat_function.h @@ -241,6 +241,12 @@ typedef UINT64 (*__CreateChatRoom)(UINT64,UINT64,UINT64); typedef UINT64 (*__QuitChatRoom)(UINT64,UINT64,UINT64); typedef UINT64 (*__ForwardMsg)(UINT64,UINT64,UINT64,UINT64); +typedef UINT64 (*__GetSNSFirstPage)(UINT64,UINT64,UINT64); +typedef UINT64 (*__GetSNSNextPageScene)(UINT64,UINT64); + +typedef UINT64 (*__GetSNSDataMgr)(); +typedef UINT64 (*__GetSnsTimeLineMgr)(); + } // namespace function namespace prototype { @@ -347,6 +353,12 @@ const UINT64 kCreateChatRoom = 0xe63340; const UINT64 kQuitChatRoom = 0xe6e3b0; const UINT64 kForwardMsg = 0xfcd0f0; +const UINT64 kOnSnsTimeLineSceneFinish = 0x1a73150; +const UINT64 kSNSGetFirstPage = 0x1a51dd0; +const UINT64 kSNSGetNextPageScene = 0x1a77240; +const UINT64 kSNSDataMgr = 0xeebda0; +const UINT64 kSNSTimeLineMgr = 0x19e83a0; + } // namespace offset } // namespace V3_9_5_81