mirror of
https://github.com/ttttupup/wxhelper.git
synced 2024-11-23 02:39:25 +08:00
朋友圈消息hook和朋友圈消息获取
This commit is contained in:
parent
a0f83b5a99
commit
254a9eeb30
107
README.md
107
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.朋友圈下一页
|
||||
### 接口文档:
|
||||
|
||||
|
||||
@ -1129,6 +1133,107 @@ vcpkg
|
||||
{"code":0,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 53.朋友圈首页消息**
|
||||
###### 接口功能
|
||||
> 获取朋友圈最新消息,调用之后,会在tcpserver服务中收到朋友圈的消息。格式如下:
|
||||
``` javascript
|
||||
{
|
||||
'data': [
|
||||
{
|
||||
'content': '朋友圈[玫瑰][玫瑰]',
|
||||
'createTime': 1675827480,
|
||||
'senderId': 'wxid_12333',
|
||||
'snsId': 14057859804711563695,
|
||||
'xml': '<TimelineObject><id><![CDATA[1405712322563695]]></id><username><![CDATA[wxid_12333]]></username><createTime><![CDATA[1675827480]]></createTime><contentDescShowType>0</contentDescShowType><contentDescScene>0</contentDescScene><private><![CDATA[0]]></private><contentDesc><![CDATA[朋友圈[玫瑰][玫瑰]]]></contentDesc><contentattr><![CDATA[0]]></contentattr><sourceUserName></sourceUserName><sourceNickName></sourceNickName><statisticsData></statisticsData><weappInfo><appUserName></appUserName><pagePath></pagePath><version><![CDATA[0]]></version><debugMode><![CDATA[0]]></debugMode><shareActionId></shareActionId><isGame><![CDATA[0]]></isGame><messageExtraData></messageExtraData><subType><![CDATA[0]]></subType><preloadResources></preloadResources></weappInfo><canvasInfoXml></canvasInfoXml><ContentObject><contentStyle><![CDATA[2]]></contentStyle><contentSubStyle><![CDATA[0]]></contentSubStyle><title></title><description></description><contentUrl></contentUrl></ContentObject><actionInfo><appMsg><mediaTagName></mediaTagName><messageExt></messageExt><messageAction></messageAction></appMsg></actionInfo><appInfo><id></id></appInfo><location poiClassifyId="" poiName="" poiAddress="" poiClassifyType="0" city=""></location><publicUserName></publicUserName><streamvideo><streamvideourl></streamvideourl><streamvideothumburl></streamvideothumburl><streamvideoweburl></streamvideoweburl></streamvideo></TimelineObject>'
|
||||
}]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
###### 接口地址
|
||||
> [/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': '<TimelineObject><id><![CDATA[1405712322563695]]></id><username><![CDATA[wxid_12333]]></username><createTime><![CDATA[1675827480]]></createTime><contentDescShowType>0</contentDescShowType><contentDescScene>0</contentDescScene><private><![CDATA[0]]></private><contentDesc><![CDATA[朋友圈[玫瑰][玫瑰]]]></contentDesc><contentattr><![CDATA[0]]></contentattr><sourceUserName></sourceUserName><sourceNickName></sourceNickName><statisticsData></statisticsData><weappInfo><appUserName></appUserName><pagePath></pagePath><version><![CDATA[0]]></version><debugMode><![CDATA[0]]></debugMode><shareActionId></shareActionId><isGame><![CDATA[0]]></isGame><messageExtraData></messageExtraData><subType><![CDATA[0]]></subType><preloadResources></preloadResources></weappInfo><canvasInfoXml></canvasInfoXml><ContentObject><contentStyle><![CDATA[2]]></contentStyle><contentSubStyle><![CDATA[0]]></contentSubStyle><title></title><description></description><contentUrl></contentUrl></ContentObject><actionInfo><appMsg><mediaTagName></mediaTagName><messageExt></messageExt><messageAction></messageAction></appMsg></actionInfo><appInfo><id></id></appInfo><location poiClassifyId="" poiName="" poiAddress="" poiClassifyType="0" city=""></location><publicUserName></publicUserName><streamvideo><streamvideourl></streamvideourl><streamvideothumburl></streamvideothumburl><streamvideoweburl></streamvideoweburl></streamvideo></TimelineObject>'
|
||||
}]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
###### 接口地址
|
||||
> [/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"}
|
||||
```
|
||||
|
||||
#### 感谢
|
||||
https://github.com/ljc545w/ComWeChatRobot
|
||||
|
||||
|
14
src/api.cc
14
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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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" <<begin_addr<<endl;
|
||||
cout << "end" <<end_addr<<endl;
|
||||
#endif
|
||||
if (begin_addr == 0) {
|
||||
j_sns = {{"data", json::array()}};
|
||||
} else {
|
||||
while (begin_addr < end_addr) {
|
||||
json j_item;
|
||||
j_item["snsId"] = *(unsigned long long *)(begin_addr);
|
||||
j_item["createTime"] = *(DWORD *)(begin_addr + 0x2C);
|
||||
|
||||
j_item["senderId"] =
|
||||
unicode_to_utf8((wchar_t *)READ_WSTRING(begin_addr, 0x18).c_str());
|
||||
|
||||
j_item["content"] =
|
||||
unicode_to_utf8((wchar_t *)READ_WSTRING(begin_addr, 0x3c).c_str());
|
||||
|
||||
j_item["xml"] =
|
||||
unicode_to_utf8((wchar_t *)READ_WSTRING(begin_addr, 0x384).c_str());
|
||||
|
||||
j_sns["data"].push_back(j_item);
|
||||
begin_addr += 0xB48;
|
||||
}
|
||||
}
|
||||
string jstr = j_sns.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 {
|
||||
@ -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;
|
||||
}
|
68
src/sns.cc
Normal file
68
src/sns.cc
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user