From 254a9eeb30c9bf31782434ae1b6e0fe167dc1008 Mon Sep 17 00:00:00 2001 From: hugy <504650082@qq.com> Date: Wed, 8 Feb 2023 13:35:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8B=E5=8F=8B=E5=9C=88=E6=B6=88=E6=81=AFho?= =?UTF-8?q?ok=E5=92=8C=E6=9C=8B=E5=8F=8B=E5=9C=88=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 107 ++++++++++++++++++++++++++++++++++++++++++- src/api.cc | 14 ++++++ src/api.h | 2 + src/hook_recv_msg.cc | 82 ++++++++++++++++++++++++++++++++- src/sns.cc | 68 +++++++++++++++++++++++++++ src/sns.h | 6 +++ 6 files changed, 277 insertions(+), 2 deletions(-) create mode 100644 src/sns.cc create mode 100644 src/sns.h diff --git a/README.md b/README.md index 841769f..a98fbba 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,9 @@ vcpkg 2023-02-04 : 新增群消息置顶和取消置顶。 -2023-02-04 : 新增确认收款。 +2023-02-06 : 新增确认收款。 + +2023-02-08 : 新增朋友圈消息。 #### 功能预览: 0.检查是否登录 @@ -122,6 +124,8 @@ vcpkg 50.拍一拍 51.群消息置顶消息 52.群消息取消置顶 +53.朋友圈首页 +54.朋友圈下一页 ### 接口文档: @@ -1127,6 +1131,107 @@ vcpkg 响应: ``` javascript {"code":0,"result":"OK"} +``` + + + +#### 53.朋友圈首页消息** +###### 接口功能 +> 获取朋友圈最新消息,调用之后,会在tcpserver服务中收到朋友圈的消息。格式如下: +``` javascript +{ + 'data': [ + { + 'content': '朋友圈[玫瑰][玫瑰]', + 'createTime': 1675827480, + 'senderId': 'wxid_12333', + 'snsId': 14057859804711563695, + 'xml': '00' + }] +} + +``` + +###### 接口地址 +> [/api/?type=53](/api/?type=53) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| + + + + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,1成功, -1失败| +|result|string|成功提示| + + + +###### 接口示例 +入参: +``` javascript + + +``` +响应: +``` javascript +{"code":1,"result":"OK"} +``` + + +#### 54.朋友圈下一页** +###### 接口功能 +> 朋友圈下一页,会在tcpserver服务中收到朋友圈的消息。格式如下: +``` javascript +{ + 'data': [ + { + 'content': '朋友圈[玫瑰][玫瑰]', + 'createTime': 1675827480, + 'senderId': 'wxid_12333', + 'snsId': 14057859804711563695, + 'xml': '00' + }] +} + +``` + +###### 接口地址 +> [/api/?type=54](/api/?type=54) + +###### HTTP请求方式 +> POST JSON + +###### 请求参数 +|参数|必选|类型|说明| +|---|---|---|---| +|snsId |ture |string| 朋友圈的snsId | + + + +###### 返回字段 +|返回字段|字段类型|说明 | +|---|---|---| +|code|int|返回状态,1成功, -1失败| +|result|string|成功提示| + + + +###### 接口示例 +入参: +``` javascript + + +``` +响应: +``` javascript +{"code":1,"result":"OK"} ``` #### 感谢 diff --git a/src/api.cc b/src/api.cc index 4882982..37d6732 100644 --- a/src/api.cc +++ b/src/api.cc @@ -21,6 +21,7 @@ #include "ocr.h" #include "pat.h" #include "confirm_receipt.h" +#include "sns.h" #pragma comment(lib, "ws2_32.lib") using namespace std; @@ -591,6 +592,19 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) { ret = ret_data.dump(); break; } + case WECHAT_SNS_GET_FIRST_PAGE:{ + int success = GetFirstPage(); + json ret_data = {{"code", success}, {"result", "OK"}}; + ret = ret_data.dump(); + break; + } + case WECHAT_SNS_GET_NEXT_PAGE:{ + ULONG64 snsid = get_http_param_ulong64(hm, j_param, "snsId", is_post); + int success = GetNextPage(snsid); + json ret_data = {{"code", success}, {"result", "OK"}}; + ret = ret_data.dump(); + break; + } default: break; } diff --git a/src/api.h b/src/api.h index 2cff9e5..7c04269 100644 --- a/src/api.h +++ b/src/api.h @@ -67,6 +67,8 @@ typedef enum WECHAT_HTTP_APISTag WECHAT_SEND_PAT_MSG, WECHAT_SET_TOP_MSG, WECHAT_REMOVE_TOP_MSG, + WECHAT_SNS_GET_FIRST_PAGE, + WECHAT_SNS_GET_NEXT_PAGE, } WECHAT_HTTP_APIS, *PWECHAT_HTTP_APIS; diff --git a/src/hook_recv_msg.cc b/src/hook_recv_msg.cc index 71fe1a5..a4e1ff9 100644 --- a/src/hook_recv_msg.cc +++ b/src/hook_recv_msg.cc @@ -12,6 +12,8 @@ using namespace nlohmann; using namespace std; #define WX_RECV_MSG_HOOK_OFFSET 0xb97126 #define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x6fc850 +#define WX_SNS_HOOK_OFFSET 0x12fb9a5 +#define WX_SNS_HOOK_NEXT_OFFSET 0x12fbc30 // SyncMgr::addMsgListToDB // #define WX_RECV_MSG_HOOK_OFFSET 0xB9C919 @@ -29,6 +31,13 @@ static DWORD kReceMsgJmpBackAddress = static DWORD kReceMsgNextAddress = kWeChatWinBase + WX_RECV_MSG_HOOK_NEXT_OFFSET; + +static char kOriginSnsMsgAsmCode[5] = {0}; +static DWORD kSnsMsgJmpBackAddress = + kWeChatWinBase + WX_SNS_HOOK_OFFSET + 0x5; +static DWORD kSnsMsgNextAddress = + kWeChatWinBase + WX_SNS_HOOK_NEXT_OFFSET; + struct InnerMessageStruct { char *buffer; int length; @@ -112,7 +121,7 @@ void SendSocketMessage(InnerMessageStruct *msg) { } /// @brief msg handle /// @param msg_addr msg address in memory -void OnRecvMsg(DWORD msg_addr) { +void __cdecl OnRecvMsg(DWORD msg_addr) { json j_msg; unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30); j_msg["msgId"] = msgid; @@ -175,6 +184,50 @@ void OnRecvMsg(DWORD msg_addr) { CloseHandle(thread); } } + + + + void __cdecl OnSnsTimeLineMsg(DWORD msg_addr) { + json j_sns; + DWORD begin_addr = *(DWORD *)(msg_addr + 0x20); + DWORD end_addr = *(DWORD *)(msg_addr + 0x24); + #ifdef _DEBUG + cout << "begin" <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 { @@ -190,6 +243,23 @@ _declspec(naked) void handle_sync_msg() { } } + +/// @brief hook sns msg implement +_declspec(naked) void handle_sns_msg() { + __asm { + PUSHAD + PUSHFD + PUSH [ESP + 0x24] + CALL OnSnsTimeLineMsg + ADD ESP, 0x4 + POPFD + POPAD + CALL kSnsMsgNextAddress + JMP kSnsMsgJmpBackAddress + } +} + + /// @brief hook any address address+0x5 /// @param port 端口 /// @return 成功返回1,已经hook返回2,失败返回-1 @@ -210,6 +280,14 @@ int HookRecvMsg(char* client_ip,int port) { kReceMsgJmpBackAddress = hook_recv_msg_addr + 0x5; HookAnyAddress(hook_recv_msg_addr, (LPVOID)handle_sync_msg, kOriginReceMsgAsmCode); + + DWORD hook_sns_msg_addr = kWeChatWinBase + WX_SNS_HOOK_OFFSET; + kSnsMsgNextAddress = kWeChatWinBase + WX_SNS_HOOK_NEXT_OFFSET; + kSnsMsgJmpBackAddress = hook_sns_msg_addr + 0x5; + HookAnyAddress(hook_sns_msg_addr, (LPVOID)handle_sns_msg, + kOriginSnsMsgAsmCode); + + kMessageHooked = TRUE; return 1; } @@ -218,7 +296,9 @@ int UnHookRecvMsg() { kServerPort = 0; if (!kMessageHooked) return 2; DWORD hook_recv_msg_addr = kWeChatWinBase + WX_RECV_MSG_HOOK_OFFSET; + DWORD hook_sns_addr = kWeChatWinBase + WX_SNS_HOOK_OFFSET; UnHookAnyAddress(hook_recv_msg_addr, kOriginReceMsgAsmCode); + UnHookAnyAddress(hook_sns_addr, kOriginSnsMsgAsmCode); kMessageHooked = FALSE; return 1; } \ No newline at end of file diff --git a/src/sns.cc b/src/sns.cc new file mode 100644 index 0000000..e46e0cf --- /dev/null +++ b/src/sns.cc @@ -0,0 +1,68 @@ +#include "pch.h" +#include "sns.h" + +#include "common.h" +#include "wechat_data.h" +using namespace std; +#define WX_SNS_DATA_MGR_OFFSET 0xac66a0 +#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x12e46c0 +#define WX_SNS_TIME_LINE_MGR_OFFSET 0x128e6a0 +#define WX_SNS_TRY_GET_FIRST_PAGE_SCENE_OFFSET 0x12ff300 +#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x12e4760 + +int GetFirstPage() { + int success = -1; + DWORD base = GetWeChatWinBase(); + DWORD sns_data_mgr_addr = base + WX_SNS_DATA_MGR_OFFSET; + DWORD get_first_page_addr = base + WX_SNS_GET_FIRST_PAGE_OFFSET; + + DWORD time_line_mgr_addr = base + WX_SNS_TIME_LINE_MGR_OFFSET; + DWORD get_first_page_scene_addr = base + WX_SNS_TRY_GET_FIRST_PAGE_SCENE_OFFSET; + char buff[0xB44] = {}; + __asm { + PUSHAD + CALL sns_data_mgr_addr + PUSH 0x1 + LEA ECX,buff + PUSH ECX + MOV ECX,EAX + CALL get_first_page_addr + MOV success,EAX + POPAD + } + +// __asm { +// PUSHAD +// CALL time_line_mgr_addr +// PUSH 0x1 +// MOV ECX,EAX +// CALL get_first_page_scene_addr +// MOV success, EAX +// POPAD +// } + return success; +} + + +int GetNextPage(ULONG64 sns_id) { + int success = -1; + DWORD base = GetWeChatWinBase(); + DWORD sns_data_mgr_addr = base + WX_SNS_DATA_MGR_OFFSET; + DWORD get_next_page_addr = base + WX_SNS_GET_NEXT_PAGE_OFFSET; + VectorInner temp = {}; + __asm{ + PUSHAD + CALL sns_data_mgr_addr + LEA ECX,temp + PUSH ECX + MOV EBX,dword ptr [sns_id + 0x4] + PUSH EBX + MOV EDI,dword ptr [sns_id ] + PUSH EDI + MOV ECX,EAX + CALL get_next_page_addr + MOV success,EAX + POPAD + } + return success; +} diff --git a/src/sns.h b/src/sns.h new file mode 100644 index 0000000..db782c0 --- /dev/null +++ b/src/sns.h @@ -0,0 +1,6 @@ +#ifndef SNS_H_ +#define SNS_H_ + +int GetFirstPage(); +int GetNextPage(ULONG64 sns_id); +#endif \ No newline at end of file