mirror of
https://github.com/ttttupup/wxhelper.git
synced 2025-04-20 03:49:17 +08:00
Compare commits
54 Commits
3.9.5.81-v
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
24bb7212fa | ||
|
1528b66b94 | ||
|
62a641d7f7 | ||
|
49188b7ef0 | ||
|
e4656e5139 | ||
|
0bd8b47da0 | ||
|
7a5a8a90df | ||
|
b5cc83be77 | ||
|
3b5f191bf2 | ||
|
dff024745c | ||
|
8b6e2d7160 | ||
|
5d7c1d1d48 | ||
|
d574af863a | ||
|
632d4222fa | ||
|
ee7d4ee9a3 | ||
|
1ba2ed87b7 | ||
|
2863f8258f | ||
|
fa31de81e0 | ||
|
758b773d99 | ||
|
b17af7a9e0 | ||
|
b364885daf | ||
|
427b43304c | ||
|
0593dbe79e | ||
|
13f182a95b | ||
|
1718ddefdd | ||
|
4c3c02283e | ||
|
bb46b9b8d9 | ||
|
e806914775 | ||
|
e5ead96c05 | ||
|
938e7e9bc2 | ||
|
8acad316a9 | ||
|
a5a2f0f17d | ||
|
3b76b2332c | ||
|
5088f5171b | ||
|
d8c8078f5c | ||
|
8bdc8c7e46 | ||
|
212613e3b6 | ||
|
608c6d26de | ||
|
2f6760e28e | ||
|
6436ce072a | ||
|
58caad4f34 | ||
|
bdf91943f3 | ||
|
41b3b6b18d | ||
|
129bb55c36 | ||
|
e9a6e0da57 | ||
|
e6e72dd492 | ||
|
9b4d326d63 | ||
|
64ba6007a8 | ||
|
f9b859baca | ||
|
ae44434662 | ||
|
4ab28cfc03 | ||
|
e6c57f8ede | ||
|
51a4693330 | ||
|
e0c946bf72 |
835
doc/3.9.5.81.md
835
doc/3.9.5.81.md
@ -215,7 +215,7 @@ enableHttp=0时,使用ip,port的tcp服务回传消息。
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"port": "19099"
|
||||
"port": "19099",
|
||||
"ip":"127.0.0.1",
|
||||
"url":"http://localhost:8080",
|
||||
"timeout":"3000",
|
||||
@ -994,3 +994,836 @@ enableHttp=0时,使用ip,port的tcp服务回传消息。
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 20.退群**
|
||||
###### 接口功能
|
||||
> 退群
|
||||
|
||||
###### 接口地址
|
||||
> [/api/quitChatRoom](/api/quitChatRoom)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId|string|群id|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId":"123456@chatroom"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 119536579329,
|
||||
"data": null,
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 21.转发消息**
|
||||
###### 接口功能
|
||||
> 转发消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/forwardMsg](/api/forwardMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|接收人id|
|
||||
|msgId|string|消息id|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"wxid":"filehelper",
|
||||
"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
|
||||
{
|
||||
"code": 1,
|
||||
"data": null,
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 24.收藏消息**
|
||||
###### 接口功能
|
||||
> 收藏消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/addFavFromMsg](/api/addFavFromMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId|number|消息id|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
|
||||
"msgId":123
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": null,
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 24.收藏图片**
|
||||
###### 接口功能
|
||||
> 收藏图片
|
||||
|
||||
###### 接口地址
|
||||
> [/api/addFavFromImage](/api/addFavFromImage)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|wxid|
|
||||
|imagePath|string|图片地址|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
|
||||
"wxid":"wxid_12333",
|
||||
"imagePath":"C:\\test\\test.png"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": null,
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 25.发送@消息**
|
||||
###### 接口功能
|
||||
> 发送@消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendAtText](/api/sendAtText)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxids|string|wxid字符串,多个用,分隔,发送所有人传值"notify@all"|
|
||||
|chatRoomId|string|群id|
|
||||
|msg|string|消息内容|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
|
||||
"wxids":"notify@all",
|
||||
"chatRoomId":"123@chatroom",
|
||||
"msg":"你们好啊"
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 67316444768,
|
||||
"data": null,
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 26.获取群成员信息**
|
||||
###### 接口功能
|
||||
> 获取群成员基础信息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/getContactProfile](/api/getContactProfile)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|wxid|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|  account|string|账号|
|
||||
|  headImage|string|头像|
|
||||
|  nickname|string|昵称|
|
||||
|  v3|string|v3|
|
||||
|  wxid|string|wxid|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"wxid":"wxid_123"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {
|
||||
"account": "account",
|
||||
"headImage": "https://wx.qlogo.cn/mmhead/ver_1/0",
|
||||
"nickname": "test",
|
||||
"v3": "wxid_123",
|
||||
"wxid": "wxid_123"
|
||||
},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 27.发送公众号消息**
|
||||
###### 接口功能
|
||||
> 自定义发送公众号消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/forwardPublicMsg](/api/forwardPublicMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|appName|string|公众号id,消息内容里的appname|
|
||||
|userName|string|公众号昵称,消息内容里的username|
|
||||
|title|string|链接地址,消息内容里的title|
|
||||
|url|string|链接地址,消息内容里的url|
|
||||
|thumbUrl|string|缩略图地址,消息内容里的thumburl|
|
||||
|digest|string|摘要,消息内容里的digest|
|
||||
|wxid|string|wxid|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"appName": "快手",
|
||||
"userName": "gh_271633",
|
||||
"title": "PC硬件、数码产品彻底反转",
|
||||
"url": "http://mp.weixin.qq.com/s?__biz=Mzg3MzYg==&mid=22440&idx=1&sn=bd8e8b0d9f2753f3c340&chksm=ced16f2ff9a6e639cc9bb76631ff03487f86486f0f29fcf9f8bed754354cb20eda31cc894a56&scene=0&xtrack=1#rd",
|
||||
"thumbUrl": "https://mmbiz.qpic.cn/sz__jpg/tpzwaqMCicQyEkpxmpmmP9KgoBHiciamYhqZ0ff4kNlozxgRq4AtEzibo4iaw/640?wxtype=jpeg&wxfrom=0",
|
||||
"digest": "这谁顶得住?",
|
||||
"wxid": "filehelper"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 28.转发公众号消息**
|
||||
###### 接口功能
|
||||
> 转发公众号消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/forwardPublicMsgByMsgId](/api/forwardPublicMsgByMsgId)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId|number|msgId|
|
||||
|wxid|string|wxid|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"msgId": 8871595889497690337,
|
||||
"wxid": "filehelper"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 29.下载附件**
|
||||
###### 接口功能
|
||||
> 下载附件,保存在微信文件目录下 wxid_xxx/wxhelper 目录下
|
||||
|
||||
###### 接口地址
|
||||
> [/api/downloadAttach](/api/downloadAttach)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId|number|msgId|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"msgId": 887159588949767
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 30.解码图片**
|
||||
###### 接口功能
|
||||
> 解码图片
|
||||
|
||||
###### 接口地址
|
||||
> [/api/decodeImage](/api/decodeImage)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|filePath|string|待解码图片地址|
|
||||
|storeDir|string|解码后图片的存储目录|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"filePath": "C:\\886206666148161980131.dat",
|
||||
"storeDir":"C:\\test"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 31.获取语音**
|
||||
###### 接口功能
|
||||
> 获取语音,SILK v3格式,可自行转换mp3格式
|
||||
|
||||
###### 接口地址
|
||||
> [/api/getVoiceByMsgId](/api/getVoiceByMsgId)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId|number|消息id|
|
||||
|storeDir|string|语音的存储目录|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"msgId":78804324411226,
|
||||
"storeDir":"c:\\test"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 32.发送图片**
|
||||
###### 接口功能
|
||||
> 发送图片
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendImagesMsg](/api/sendImagesMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|wxid|
|
||||
|imagePath|string|图片路径|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"wxid":"filehelper",
|
||||
"imagePath":"C:\\test.png"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
#### 33.发送自定义表情**
|
||||
###### 接口功能
|
||||
> 发送自定义表情
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendCustomEmotion](/api/sendCustomEmotion)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|wxid|
|
||||
|filePath|string|表情路径,可以直接查询CustomEmotion表的MD5字段,路径规则见下面示例|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"wxid":"filehelper",
|
||||
"filePath":"C:\\wechatDir\\WeChat Files\\wxid_123\\FileStorage\\CustomEmotion\\8F\\8F6423BC2E69188DCAC797E279C81DE9"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 34.发送小程序**
|
||||
###### 接口功能
|
||||
> 发送小程序(待完善,不稳定),相关参数可以参考示例的滴滴小程序的内容自行组装。
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendApplet](/api/sendApplet)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|接收人wxid|
|
||||
|waidConcat|string|app的wxid与回调信息之类绑定的拼接字符串,伪造的数据可以随意|
|
||||
|appletWxid|string|app的wxid|
|
||||
|jsonParam|string|相关参数|
|
||||
|headImgUrl|string|头像url|
|
||||
|mainImg|string|主图的本地路径,需要在小程序的临时目录下|
|
||||
|indexPage|string|小程序的跳转页面|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"wxid":"filehelper",
|
||||
"waidConcat":"wxaf35009675aa0b2a_118",
|
||||
"waid":"wxaf35009675aa0b2a",
|
||||
"appletWxid":"gh_7a5c4141778f@app",
|
||||
"jsonParam":"{\"current_path\":\"home/pages/index.html\",\"current_title\":\"\",\"image_url\":\"https://ut-static.udache.com/webx/mini-pics/U7mDFxU2yh-2-r1BJ-J0X.png\",\"scene\":1001,\"scene_note\":\"\",\"sessionId\":\"SessionId@1672284921_1#1692848476899\"}",
|
||||
"headImgUrl":"http://mmbiz.qpic.cn/sz_mmbiz_png/9n47wQlh4dH8afD9dQ9uQicibRm5mYz3lawXCLMjmnzFicribH51qsFYxjzPEcTGHGmgX4lkAkQ3jznia8UDEtqsX1w/640?wx_fmt=png&wxfrom=200",
|
||||
"mainImg":"C:\\wxid_123123\\Applet\\wxaf35009675aa0b2a\\temp\\2.png",
|
||||
"indexPage":"pages/index/index.html"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 35.拍一拍**
|
||||
###### 接口功能
|
||||
> 拍一拍
|
||||
|
||||
###### 接口地址
|
||||
> [/api/sendPatMsg](/api/sendPatMsg)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid|string|被拍人id|
|
||||
|receiver|string|接收人id,可以是自己wxid,私聊好友wxid,群id|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,大于0成功, -1失败|
|
||||
|msg|string|成功提示|
|
||||
|data|object|null|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
"wxid":"wxid_1234",
|
||||
"receiver":"wxid_1234",
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 1,
|
||||
"data": {},
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### 36.OCR**
|
||||
###### 接口功能
|
||||
> OCR识别文字,非0时再调用一次,一般需要调用2次
|
||||
|
||||
###### 接口地址
|
||||
> [/api/ocr](/api/ocr)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|imagePath|string|图片全路径|
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,0成功, 非0时再调用一次|
|
||||
|msg|string|成功提示|
|
||||
|data|object|识别得结果|
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
{
|
||||
|
||||
"imagePath":"C:\\var\\123.jpg"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{
|
||||
"code": 0,
|
||||
"data": "17 硬卧下铺别人能不能坐?12306回应\r\n18 中南财大被解聘女讲师已失联4个多月\r\n19 新一轮存款利率下调即将落地\r\n",
|
||||
"msg": "success"
|
||||
}
|
||||
```
|
640
doc/postman.json
Normal file
640
doc/postman.json
Normal file
@ -0,0 +1,640 @@
|
||||
{
|
||||
"info": {
|
||||
"name": "Wechat Hook 395",
|
||||
"_postman_id": "d2b6a4f2-6d7d-4a21-9bbf-65b5a5a3a5a",
|
||||
"description": "A collection of Wechat Hook 395 API requests.",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "checkLogin",
|
||||
"request": {
|
||||
"url": {
|
||||
"raw": "http://127.0.0.1:19088/api/checkLogin",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"127.0.0.1"
|
||||
],
|
||||
"port": "19088",
|
||||
"path": [
|
||||
"api",
|
||||
"checkLogin"
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to check login status."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "userInfo",
|
||||
"request": {
|
||||
"url": {
|
||||
"raw": "http://127.0.0.1:19088/api/userInfo",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"127.0.0.1"
|
||||
],
|
||||
"port": "19088",
|
||||
"path": [
|
||||
"api",
|
||||
"userInfo"
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to get user information."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sendTextMsg",
|
||||
"request": {
|
||||
"url": {
|
||||
"raw": "http://127.0.0.1:19088/api/sendTextMsg",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"127.0.0.1"
|
||||
],
|
||||
"port": "19088",
|
||||
"path": [
|
||||
"api",
|
||||
"sendTextMsg"
|
||||
]
|
||||
},
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"filehelper\",\"msg\": \"12www\"}"
|
||||
},
|
||||
"description": "API to send text messages."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sendImagesMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/sendImagesMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"filehelper\",\"imagePath\": \"C:\\pic.png\"}"
|
||||
},
|
||||
"description": "API to send image messages."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sendFileMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/sendFileMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"filehelper\",\"filePath\": \"C:\\test.zip\"}"
|
||||
},
|
||||
"description": "API to send file messages."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hookSyncMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/hookSyncMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"port\": \"19099\",\"ip\": \"127.0.0.1\",\"url\": \"http://localhost:8080\",\"timeout\": \"3000\",\"enableHttp\": \"0\"}"
|
||||
},
|
||||
"description": "API to hook sync messages."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "unhookSyncMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/unhookSyncMsg",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to unhook sync messages."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getContactList",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getContactList",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to get the contact list."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getDBInfo",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getDBInfo",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to get database information."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "execSql",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/execSql",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"dbHandle\": 1713425147584,\"sql\": \"select * from MSG where localId =100;\"}"
|
||||
},
|
||||
"description": "API to execute SQL queries."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getChatRoomDetailInfo",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getChatRoomDetailInfo",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123333@chatroom\"}"
|
||||
},
|
||||
"description": "API to get chat room detail information."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "addMemberToChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/addMemberToChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\",\"memberIds\": \"wxid_123\"}"
|
||||
},
|
||||
"description": "API to add member to chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "delMemberFromChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/delMemberFromChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"21363231004@chatroom\",\"memberIds\": \"wxid_123\"}"
|
||||
},
|
||||
"description": "API to delete member from chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "modifyNickname",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/modifyNickname",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\",\"wxid\": \"wxid_123\",\"nickName\": \"test\"}"
|
||||
},
|
||||
"description": "API to modify a nickname in a chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getMemberFromChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getMemberFromChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\"}"
|
||||
},
|
||||
"description": "API to get members from a chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "topMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/topMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"msgId\": 1222222}"
|
||||
},
|
||||
"description": "API to top a message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "removeTopMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/removeTopMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\",\"msgId\": 123}"
|
||||
},
|
||||
"description": "API to remove a topped message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "InviteMemberToChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/InviteMemberToChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\",\"memberIds\": \"wxid_123\"}"
|
||||
},
|
||||
"description": "API to invite members to a chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hookLog",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/hookLog",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to hook logs."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "unhookLog",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/unhookLog",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to unhook logs."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/createChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"memberIds\": \"wxid_8yn4k908tdqp22,wxid_oyb662qhop4422\"}"
|
||||
},
|
||||
"description": "API to create a chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "quitChatRoom",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/quitChatRoom",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"chatRoomId\": \"123@chatroom\"}"
|
||||
},
|
||||
"description": "API to quit a chat room."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "forwardMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/forwardMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"filehelper\",\"msgId\": \"12331\"}"
|
||||
},
|
||||
"description": "API to forward a message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getSNSFirstPage",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getSNSFirstPage",
|
||||
"method": "POST",
|
||||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": ""
|
||||
},
|
||||
"description": "API to get the first page of SNS data."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getSNSNextPage",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getSNSNextPage",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"snsId\": \"\"}"
|
||||
},
|
||||
"description": "API to get the next page of SNS data."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "addFavFromMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/addFavFromMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"msgId\": \"1222222\"}"
|
||||
},
|
||||
"description": "API to add a favorite from a message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "addFavFromImage",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/addFavFromImage",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"\",\"imagePath\": \"\"}"
|
||||
},
|
||||
"description": "API to add a favorite from an image."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getContactProfile",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getContactProfile",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxid\": \"\"}"
|
||||
},
|
||||
"description": "API to get contact profile."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sendAtText",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/sendAtText",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"wxids\": \"notify@all\",\"chatRoomId\": \"123@chatroom\",\"msg\": \"你好啊\"}"
|
||||
},
|
||||
"description": "API to send an at-text message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "forwardPublicMsg",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/forwardPublicMsg",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"appName\": \"\",\"userName\": \"\",\"title\": \"\",\"url\": \"\",\"thumbUrl\": \"\",\"digest\": \"\",\"wxid\": \"filehelper\"}"
|
||||
},
|
||||
"description": "API to forward a public message."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "forwardPublicMsgByMsgId",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/forwardPublicMsgByMsgId",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"msgId\": 123,\"wxid\": \"filehelper\"}"
|
||||
},
|
||||
"description": "API to forward a public message by message ID."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "downloadAttach",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/downloadAttach",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"msgId\": 123}"
|
||||
},
|
||||
"description": "API to download an attachment."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "decodeImage",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/decodeImage",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"filePath\": \"C:\\66664816980131.dat\",\"storeDir\": \"C:\\test\"}"
|
||||
},
|
||||
"description": "API to decode an image."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "getVoiceByMsgId",
|
||||
"request": {
|
||||
"url": "http://127.0.0.1:19088/api/getVoiceByMsgId",
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json",
|
||||
"description": "Specify that the request body is in JSON format."
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\"msgId\": 7880439644200,\"storeDir\": \"c:\\test\"}"
|
||||
},
|
||||
"description": "API to get voice by message ID."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
11
go_client/main.go
Normal file
11
go_client/main.go
Normal file
@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"go_client/tcpserver"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
tcpserver.Listen(19099)
|
||||
}
|
44
go_client/tcpserver/tcpserver.go
Normal file
44
go_client/tcpserver/tcpserver.go
Normal file
@ -0,0 +1,44 @@
|
||||
package tcpserver
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Listen(port int) {
|
||||
p := strconv.Itoa(port)
|
||||
adress := "127.0.0.1:" + p
|
||||
ln, err := net.Listen("tcp", adress)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer ln.Close()
|
||||
log.Println("tcp server started")
|
||||
for {
|
||||
conn, err := ln.Accept()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
go handle(conn)
|
||||
}
|
||||
}
|
||||
|
||||
func handle(conn net.Conn) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Println("发生了未处理的异常", err)
|
||||
}
|
||||
}()
|
||||
defer conn.Close()
|
||||
scanner := bufio.NewScanner(conn)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Bytes()
|
||||
log.Println("收到消息:", string(line))
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Println("错误:", err)
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<version>3.2.2</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
@ -14,7 +14,8 @@
|
||||
<name>wxhk</name>
|
||||
<description>wxhk</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<java.version>21</java.version>
|
||||
<vertx-web-client.version>4.5.3</vertx-web-client.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -39,7 +40,7 @@
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.92.Final</version>
|
||||
<version>4.1.105.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
@ -50,22 +51,22 @@
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-core</artifactId>
|
||||
<version>4.4.2</version>
|
||||
<version>${vertx-web-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-web</artifactId>
|
||||
<version>4.4.2</version>
|
||||
<version>${vertx-web-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-web-client</artifactId>
|
||||
<version>4.4.2</version>
|
||||
<version>${vertx-web-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.vertx</groupId>
|
||||
<artifactId>vertx-mysql-client</artifactId>
|
||||
<version>4.4.2</version>
|
||||
<version>${vertx-web-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -42,6 +42,11 @@ public class PrivateChatMsg implements Serializable {
|
||||
private String signature;
|
||||
private String time;
|
||||
private Integer timestamp;
|
||||
|
||||
/**
|
||||
* 对用户,如果是文件助手是filehelper
|
||||
*/
|
||||
private String toUser;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
|
@ -15,4 +15,17 @@ import lombok.experimental.Accessors;
|
||||
public class OpenHook implements SendMsg<OpenHook> {
|
||||
String port;
|
||||
String ip;
|
||||
/**
|
||||
* 0/1 :1.启用http 0.不启用http
|
||||
*/
|
||||
boolean enableHttp;
|
||||
/**
|
||||
* 超时时间,单位ms
|
||||
*/
|
||||
String timeout;
|
||||
|
||||
/**
|
||||
* http的请求地址,enableHttp=1时,不能为空
|
||||
*/
|
||||
String url;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.w3c.dom.NodeList;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@ -50,7 +51,12 @@ public class WxMsgHandle {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
add(chatMsg -> {
|
||||
wxSmgServer.私聊(chatMsg);
|
||||
if(Objects.equals(chatMsg.getToUser(), FILEHELPER)){
|
||||
wxSmgServer.文件助手(chatMsg);
|
||||
}else{
|
||||
wxSmgServer.私聊(chatMsg);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, WxMsgType.私聊信息);
|
||||
add(chatMsg -> {
|
||||
@ -174,8 +180,8 @@ public class WxMsgHandle {
|
||||
if (monery.startsWith("¥")) {
|
||||
String substring = monery.substring(1);
|
||||
BigDecimal decimal = new BigDecimal(substring);
|
||||
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), chatMsg.getFromUser(), remark);
|
||||
wxSmgServer.收款之后(new PayoutInformation(chatMsg.getFromUser(), decimal, remark));
|
||||
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), receiver_username, remark);
|
||||
wxSmgServer.收款之后(new PayoutInformation(receiver_username, decimal, remark));
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -32,12 +32,14 @@ public class WxSmgServerImpl implements com.example.wxhk.server.WxSmgServer {
|
||||
public void 私聊(PrivateChatMsg chatMsg) {
|
||||
if (Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)) {
|
||||
log.info("手机端对:{}发出:{}", chatMsg.getFromUser(), chatMsg.getContent());
|
||||
}else{
|
||||
log.info("收到私聊{}",chatMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 文件助手(PrivateChatMsg chatMsg) {
|
||||
|
||||
log.info("文件助手:{}",chatMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,7 +2,8 @@ package com.example.wxhk.tcp.vertx;
|
||||
|
||||
import com.example.wxhk.WxhkApplication;
|
||||
import com.example.wxhk.constant.WxMsgType;
|
||||
import com.example.wxhk.util.HttpAsyncUtil;
|
||||
import com.example.wxhk.model.request.OpenHook;
|
||||
import com.example.wxhk.util.HttpSendUtil;
|
||||
import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.DeploymentOptions;
|
||||
import io.vertx.core.Future;
|
||||
@ -75,7 +76,10 @@ public class VertxTcp extends AbstractVerticle implements CommandLineRunner {
|
||||
listen.onComplete(event -> {
|
||||
boolean succeeded = event.succeeded();
|
||||
if (succeeded) {
|
||||
HttpAsyncUtil.exec(HttpAsyncUtil.Type.开启hook, new JsonObject().put("port", InitWeChat.getVertxPort().toString()).put("ip", "127.0.0.1"));
|
||||
HttpSendUtil.开启hook(new OpenHook().setPort(InitWeChat.getVertxPort().toString()).setIp("127.0.0.1")
|
||||
.setEnableHttp(false)
|
||||
.setTimeout("5000"));
|
||||
// HttpAsyncUtil.exec(HttpAsyncUtil.Type.开启hook, new JsonObject().put("port", InitWeChat.getVertxPort().toString()).put("ip", "127.0.0.1"));
|
||||
startPromise.complete();
|
||||
} else {
|
||||
startPromise.fail(event.cause());
|
||||
|
@ -24,7 +24,7 @@ public class HttpAsyncUtil {
|
||||
protected static final Log log = Log.get();
|
||||
|
||||
public static Future<HttpResponse<Buffer>> exec(Type type, JsonObject object) {
|
||||
return client.post(InitWeChat.wxPort, "localhost", "/api/?type=" + type.getType())
|
||||
return client.post(InitWeChat.wxPort, "localhost", "/api/" + type.getType())
|
||||
.sendJsonObject(object)
|
||||
.onSuccess(event ->
|
||||
{
|
||||
@ -36,7 +36,7 @@ public class HttpAsyncUtil {
|
||||
}
|
||||
|
||||
public static Future<HttpResponse<Buffer>> exec(Type type, JsonObject object, Handler<AsyncResult<HttpResponse<Buffer>>> handler) {
|
||||
return client.post(InitWeChat.wxPort, "localhost", "/api/?type=" + type.getType())
|
||||
return client.post(InitWeChat.wxPort, "localhost", "/api/" + type.getType())
|
||||
.sendJsonObject(object)
|
||||
.onComplete(handler)
|
||||
;
|
||||
@ -45,22 +45,31 @@ public class HttpAsyncUtil {
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
检查微信登陆("0"),
|
||||
获取登录信息("1"),
|
||||
发送文本("2"),
|
||||
发送at文本("3"),
|
||||
检查微信登陆("checkLogin"),
|
||||
获取登录信息("userInfo"),
|
||||
发送文本("sendTextMsg"),
|
||||
转发消息("forwardMsg"),
|
||||
发送at文本("sendAtText"),
|
||||
发送图片("5"),
|
||||
发送文件("6"),
|
||||
开启hook("9"),
|
||||
关闭hook("10"),
|
||||
发送文件("sendFileMsg"),
|
||||
开启hook("hookSyncMsg"),
|
||||
关闭hook("unhookSyncMsg"),
|
||||
添加好友("20"),
|
||||
通过好友申请("23"),
|
||||
获取群成员("25"),
|
||||
获取群成员昵称("26"),
|
||||
删除群成员("27"),
|
||||
获取群成员("getMemberFromChatRoom"),
|
||||
获取群成员基础信息("getContactProfile"),
|
||||
获取群详情("getChatRoomDetailInfo"),
|
||||
添加群成员("addMemberToChatRoom"),
|
||||
修改群昵称("modifyNickname"),
|
||||
删除群成员("delMemberFromChatRoom"),
|
||||
置顶群消息("topMsg"),
|
||||
取消置顶群消息("removeTopMsg"),
|
||||
邀请入群("InviteMemberToChatRoom"),
|
||||
确认收款("45"),
|
||||
联系人列表("46"),
|
||||
联系人列表("getContactList"),
|
||||
查询微信信息("55"),
|
||||
下载附件("downloadAttach"),
|
||||
解码("decodeImage"),
|
||||
|
||||
|
||||
;
|
||||
|
@ -27,7 +27,7 @@ public class HttpSyncUtil {
|
||||
}
|
||||
|
||||
public static JsonObject exec(HttpAsyncUtil.Type type, JsonObject obj) {
|
||||
String post = engine.send(Request.of("http://localhost:" + InitWeChat.wxPort + "/api/?type=" + type.getType()).method(Method.POST).body(obj.encode())).bodyStr();
|
||||
String post = engine.send(Request.of("http://localhost:" + InitWeChat.wxPort + "/api/" + type.getType()).method(Method.POST).body(obj.encode())).bodyStr();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("type:{},{}", type.getType(), post);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
wx.path=D:\\Program Files (x86)\\Tencent\\WeChat\\[3.9.2.23]\\WeChat.exe
|
||||
wx.path=D:\\Program Files (x86)\\Tencent\\WeChat\\WeChat.exe
|
||||
wx.port=19088
|
||||
spring.profiles.active=local
|
||||
vertx.port=8080
|
Binary file not shown.
Binary file not shown.
@ -7,6 +7,8 @@ import org.dromara.hutool.core.lang.Console;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest
|
||||
@ -41,5 +43,7 @@ class HttpSendUtilTest {
|
||||
void 获取群成员() {
|
||||
GroupMembers 获取群成员 = HttpSendUtil.获取群成员(new GetGroupMembers().setChatRoomId("24964676359@chatroom"));
|
||||
Console.log(获取群成员);
|
||||
|
||||
Duration between = Duration.between(LocalDateTime.now(), LocalDateTime.now());
|
||||
}
|
||||
}
|
26
nodejs_client/tcp_server.js
Normal file
26
nodejs_client/tcp_server.js
Normal file
@ -0,0 +1,26 @@
|
||||
const net = require('net')
|
||||
|
||||
const server = net.createServer(socket => {
|
||||
console.log('New client connected')
|
||||
|
||||
let data = Buffer.from('')
|
||||
|
||||
socket.on('data', data => {
|
||||
data = Buffer.concat([data, chunk])
|
||||
console.log(`Received data: ${data}`)
|
||||
})
|
||||
|
||||
socket.on('end', () => {
|
||||
const decodedData = data.toString('utf8')
|
||||
console.log(`Received data: ${decodedData}`)
|
||||
})
|
||||
|
||||
socket.on('close', () => {
|
||||
console.log('Client disconnected')
|
||||
})
|
||||
})
|
||||
|
||||
const port = 19099
|
||||
server.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`)
|
||||
})
|
493
python/3.9.5.81/http_client.py
Normal file
493
python/3.9.5.81/http_client.py
Normal file
@ -0,0 +1,493 @@
|
||||
import requests
|
||||
import json
|
||||
|
||||
|
||||
def checkLogin():
|
||||
url = "127.0.0.1:19088/api/checkLogin"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def userInfo():
|
||||
url = "127.0.0.1:19088/api/userInfo"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def sendTextMsg():
|
||||
url = "127.0.0.1:19088/api/sendTextMsg"
|
||||
payload = json.dumps({
|
||||
"wxid": "filehelper",
|
||||
"msg": "12www"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def sendImagesMsg():
|
||||
url = "127.0.0.1:19088/api/sendImagesMsg"
|
||||
print("modify imagePath")
|
||||
raise RuntimeError("modify imagePath then deleted me")
|
||||
payload = json.dumps({
|
||||
"wxid": "filehelper",
|
||||
"imagePath": "C:\\pic.png"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
|
||||
def sendFileMsg():
|
||||
url = "127.0.0.1:19088/api/sendFileMsg"
|
||||
print("modify filePath")
|
||||
raise RuntimeError("modify filePath then deleted me")
|
||||
payload = json.dumps({
|
||||
"wxid": "filehelper",
|
||||
"filePath": "C:\\test.zip"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def hookSyncMsg():
|
||||
url = "127.0.0.1:19088/api/hookSyncMsg"
|
||||
print("modify ip port url ")
|
||||
raise RuntimeError("modify ip port url then deleted me")
|
||||
payload = json.dumps({
|
||||
"port": "19099",
|
||||
"ip": "127.0.0.1",
|
||||
"url": "http://localhost:8080",
|
||||
"timeout": "3000",
|
||||
"enableHttp": "0"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def unhookSyncMsg():
|
||||
url = "127.0.0.1:19088/api/unhookSyncMsg"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def getContactList():
|
||||
url = "127.0.0.1:19088/api/getContactList"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def getDBInfo():
|
||||
url = "127.0.0.1:19088/api/getDBInfo"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def execSql():
|
||||
url = "127.0.0.1:19088/api/execSql"
|
||||
print("modify dbHandle ")
|
||||
raise RuntimeError("modify dbHandle then deleted me")
|
||||
payload = json.dumps({
|
||||
"dbHandle": 1713425147584,
|
||||
"sql": "select * from MSG where localId =100;"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def getChatRoomDetailInfo():
|
||||
url = "127.0.0.1:19088/api/getChatRoomDetailInfo"
|
||||
print("modify chatRoomId ")
|
||||
raise RuntimeError("modify chatRoomId then deleted me")
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123333@chatroom"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def addMemberToChatRoom():
|
||||
url = "127.0.0.1:19088/api/addMemberToChatRoom"
|
||||
print("modify chatRoomId memberIds ")
|
||||
raise RuntimeError("modify chatRoomId memberIds then deleted me")
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom",
|
||||
"memberIds": "wxid_123"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
|
||||
def delMemberFromChatRoom():
|
||||
url = "127.0.0.1:19088/api/delMemberFromChatRoom"
|
||||
print("modify chatRoomId memberIds ")
|
||||
raise RuntimeError("modify chatRoomId memberIds then deleted me")
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "21363231004@chatroom",
|
||||
"memberIds": "wxid_123"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def modifyNickname():
|
||||
url = "127.0.0.1:19088/api/modifyNickname"
|
||||
print("modify chatRoomId wxid nickName")
|
||||
raise RuntimeError("modify chatRoomId wxid nickName then deleted me")
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom",
|
||||
"wxid": "wxid_123",
|
||||
"nickName": "test"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def getMemberFromChatRoom():
|
||||
print("modify chatRoomId ")
|
||||
raise RuntimeError("modify chatRoomId then deleted me")
|
||||
url = "127.0.0.1:19088/api/getMemberFromChatRoom"
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def topMsg():
|
||||
print("modify msgId ")
|
||||
raise RuntimeError("modify msgId then deleted me")
|
||||
url = "127.0.0.1:19088/api/topMsg"
|
||||
payload = json.dumps({
|
||||
"msgId": 1222222
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def removeTopMsg():
|
||||
print("modify msgId chatRoomId ")
|
||||
raise RuntimeError("modify msgId chatRoomId then deleted me")
|
||||
|
||||
url = "127.0.0.1:19088/api/removeTopMsg"
|
||||
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom",
|
||||
"msgId": 123
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def InviteMemberToChatRoom():
|
||||
print("modify memberIds chatRoomId ")
|
||||
raise RuntimeError("modify memberIds chatRoomId then deleted me")
|
||||
|
||||
url = "127.0.0.1:19088/api/InviteMemberToChatRoom"
|
||||
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom",
|
||||
"memberIds": "wxid_123"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def hookLog():
|
||||
url = "127.0.0.1:19088/api/hookLog"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def unhookLog():
|
||||
url = "127.0.0.1:19088/api/unhookLog"
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def createChatRoom():
|
||||
print("modify memberIds ")
|
||||
raise RuntimeError("modify memberIds then deleted me")
|
||||
url = "127.0.0.1:19088/api/createChatRoom"
|
||||
|
||||
payload = json.dumps({
|
||||
"memberIds": "wxid_8yn4k908tdqp22,wxid_oyb662qhop4422"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
def quitChatRoom():
|
||||
print("modify chatRoomId ")
|
||||
raise RuntimeError("modify chatRoomId then deleted me")
|
||||
url = "127.0.0.1:19088/api/quitChatRoom"
|
||||
|
||||
payload = json.dumps({
|
||||
"chatRoomId": "123@chatroom"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
def forwardMsg():
|
||||
print("modify msgId ")
|
||||
raise RuntimeError("modify msgId then deleted me")
|
||||
url = "127.0.0.1:19088/api/forwardMsg"
|
||||
|
||||
payload = json.dumps({
|
||||
"wxid": "filehelper",
|
||||
"msgId": "12331"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
def getSNSFirstPage():
|
||||
url = "127.0.0.1:19088/api/getSNSFirstPage"
|
||||
|
||||
payload = {}
|
||||
headers = {}
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
def getSNSNextPage():
|
||||
print("modify snsId ")
|
||||
raise RuntimeError("modify snsId then deleted me")
|
||||
url = "127.0.0.1:19088/api/getSNSNextPage"
|
||||
|
||||
payload = json.dumps({
|
||||
"snsId": ""
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def addFavFromMsg():
|
||||
print("modify msgId ")
|
||||
raise RuntimeError("modify msgId then deleted me")
|
||||
url = "127.0.0.1:19088/api/addFavFromMsg"
|
||||
|
||||
payload = json.dumps({
|
||||
"msgId": "1222222"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def addFavFromImage():
|
||||
print("modify wxid imagePath ")
|
||||
raise RuntimeError("modify wxid imagePath then deleted me")
|
||||
url = "127.0.0.1:19088/api/addFavFromImage"
|
||||
|
||||
payload = json.dumps({
|
||||
"wxid": "",
|
||||
"imagePath": ""
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def getContactProfile():
|
||||
print("modify wxid ")
|
||||
raise RuntimeError("modify wxid then deleted me")
|
||||
url = "127.0.0.1:19088/api/getContactProfile"
|
||||
|
||||
payload = json.dumps({
|
||||
"wxid": ""
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
print(response.text)
|
||||
|
||||
|
||||
def sendAtText():
|
||||
print("modify wxids chatRoomId")
|
||||
raise RuntimeError("modify wxids chatRoomId then deleted me")
|
||||
url = "127.0.0.1:19088/api/sendAtText"
|
||||
|
||||
payload = json.dumps({
|
||||
"wxids": "notify@all",
|
||||
"chatRoomId": "123@chatroom",
|
||||
"msg": "你好啊"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def forwardPublicMsg():
|
||||
print("modify param ")
|
||||
raise RuntimeError("modify param then deleted me")
|
||||
url = "127.0.0.1:19088/api/forwardPublicMsg"
|
||||
|
||||
payload = json.dumps({
|
||||
"appName": "",
|
||||
"userName": "",
|
||||
"title": "",
|
||||
"url": "",
|
||||
"thumbUrl": "",
|
||||
"digest": "",
|
||||
"wxid": "filehelper"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def forwardPublicMsgByMsgId():
|
||||
print("modify param ")
|
||||
raise RuntimeError("modify param then deleted me")
|
||||
url = "127.0.0.1:19088/api/forwardPublicMsgByMsgId"
|
||||
|
||||
payload = json.dumps({
|
||||
"msgId": 123,
|
||||
"wxid": "filehelper"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
def downloadAttach():
|
||||
print("modify param ")
|
||||
raise RuntimeError("modify param then deleted me")
|
||||
url = "127.0.0.1:19088/api/downloadAttach"
|
||||
|
||||
payload = json.dumps({
|
||||
"msgId": 123
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
|
||||
def decodeImage():
|
||||
print("modify param ")
|
||||
raise RuntimeError("modify param then deleted me")
|
||||
url = "127.0.0.1:19088/api/decodeImage"
|
||||
|
||||
payload = json.dumps({
|
||||
"filePath": "C:\\66664816980131.dat",
|
||||
"storeDir": "C:\\test"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
|
||||
def getVoiceByMsgId():
|
||||
print("modify param ")
|
||||
raise RuntimeError("modify param then deleted me")
|
||||
url = "127.0.0.1:19088/api/getVoiceByMsgId"
|
||||
|
||||
payload = json.dumps({
|
||||
"msgId": 7880439644200,
|
||||
"storeDir": "c:\\test"
|
||||
})
|
||||
headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
response = requests.request("POST", url, headers=headers, data=payload)
|
||||
|
||||
print(response.text)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
checkLogin()
|
||||
# userInfo()
|
@ -526,7 +526,7 @@ DWORD GetPIDForProcess(wchar_t* process)
|
||||
if (!hSnapshot) {
|
||||
return 0;
|
||||
}
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32W);
|
||||
for (working = Process32FirstW(hSnapshot, &pe32); working; working = Process32NextW(hSnapshot, &pe32))
|
||||
{
|
||||
if (!wcscmp(pe32.szExeFile, process))
|
||||
|
@ -17,7 +17,9 @@ GlobalContext::~GlobalContext() {
|
||||
void GlobalContext::initialize(HMODULE module) {
|
||||
state =GlobalContextState::INITIALIZING;
|
||||
module_ = module;
|
||||
// Utils::Hide(module);
|
||||
#ifndef _DEBUG
|
||||
Utils::Hide(module);
|
||||
#endif
|
||||
UINT64 base = Utils::GetWeChatWinBase();
|
||||
config.emplace();
|
||||
config->Initialize();
|
||||
|
@ -24,13 +24,6 @@ class GlobalContext : public Singleton<GlobalContext> {
|
||||
std::unique_ptr<HttpServer> http_server;
|
||||
std::unique_ptr<Manager> mgr;
|
||||
|
||||
// std::optional<ContactMgr> contact_mgr;
|
||||
// std::optional<MiscMgr> misc_mgr;
|
||||
// std::optional<SendMessageMgr> send_mgr;
|
||||
// std::optional<AccountMgr> account_mgr;
|
||||
// std::optional<ChatRoomMgr> chat_room_mgr;
|
||||
// std::optional<SNSMgr> sns_mgr;
|
||||
|
||||
GlobalContextState state = GlobalContextState::NOT_INITIALIZED;
|
||||
|
||||
private:
|
||||
|
65
src/hooks.cc
65
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;
|
||||
@ -72,7 +78,7 @@ VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
||||
goto clean;
|
||||
}
|
||||
char recv_buf[1024] = {0};
|
||||
ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
|
||||
ret = send(client_socket, jstr.c_str(), static_cast<int>(jstr.size()) , 0);
|
||||
if (ret < 0) {
|
||||
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
|
||||
goto clean;
|
||||
@ -119,9 +125,10 @@ void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
||||
msg["toUser"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x28));
|
||||
msg["content"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x30));
|
||||
msg["signature"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x48));
|
||||
msg["msgId"] = *(INT64 *)(param2 + 0x58);
|
||||
msg["msgSequence"] = *(DWORD *)(param2 + 0x20);
|
||||
msg["fromUserName"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
|
||||
msg["msgId"] = *(INT64 *)(param2 + 0x60);
|
||||
msg["msgSequence"] = *(DWORD *)(param2 + 0x5C);
|
||||
msg["createTime"] = *(DWORD *)(param2 + 0x58);
|
||||
msg["displayFullContent"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
|
||||
DWORD type = *(DWORD *)(param2 + 0x24);
|
||||
msg["type"] = type;
|
||||
if (type == 3) {
|
||||
@ -167,6 +174,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 +229,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 +260,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,14 +282,14 @@ int UnHookSyncMsg() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DetourRestoreAfterWith();
|
||||
// DetourRestoreAfterWith();
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
UINT64 do_add_msg_addr = base + offset::kHookLog;
|
||||
DetourAttach(&(PVOID &)R_Log, &HandlePrintLog);
|
||||
LONG ret = DetourTransactionCommit();
|
||||
if (ret == NO_ERROR) {
|
||||
kMsgHookFlag = true;
|
||||
kLogHookFlag = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ namespace wxhelper {
|
||||
}
|
||||
|
||||
// Send request
|
||||
int content_length = data.post_data.size();
|
||||
size_t content_length = data.post_data.size();
|
||||
mg_printf(c,
|
||||
"POST %s HTTP/1.0\r\n"
|
||||
"Host: %.*s\r\n"
|
||||
|
@ -6,10 +6,21 @@
|
||||
#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;
|
||||
|
||||
|
||||
int GetIntParam(nlohmann::json data, std::string key) {
|
||||
int result;
|
||||
try {
|
||||
result = data[key].get<int>();
|
||||
} catch (nlohmann::json::exception) {
|
||||
result = STR2I(data[key].get<std::string>());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
INT64 GetINT64Param(nlohmann::json data, std::string key) {
|
||||
INT64 result;
|
||||
@ -21,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<UINT64>();
|
||||
} catch (nlohmann::json::exception) {
|
||||
result = STR2ULL(data[key].get<std::string>());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string GetStringParam(nlohmann::json data, std::string key) {
|
||||
return data[key].get<std::string>();
|
||||
}
|
||||
@ -164,8 +185,17 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/hookSyncMsg")) {
|
||||
int port = GetIntParam(j_param, "port");
|
||||
std::string ip = GetStringParam(j_param, "ip");
|
||||
int enable = GetIntParam(j_param, "enableHttp");
|
||||
std::string url = "";
|
||||
int timeout = 0;
|
||||
if (enable) {
|
||||
url = GetStringParam(j_param, "url");
|
||||
timeout = GetIntParam(j_param, "timeout");
|
||||
}
|
||||
INT64 success =
|
||||
wxhelper::hooks::HookSyncMsg("127.0.0.1", 19099, "", 3000, false);
|
||||
wxhelper::hooks::HookSyncMsg(ip, port, url, timeout, enable);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||
ret = ret_data.dump();
|
||||
@ -388,14 +418,198 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else {
|
||||
} else if (mg_http_match_uri(hm, "/api/quitChatRoom")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->QuitChatRoom(room_id);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/forwardMsg")) {
|
||||
INT64 msg_id = GetINT64Param(j_param, "msgId");
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->ForwardMsg(msg_id,wxid);
|
||||
nlohmann::json ret_data = {
|
||||
{"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 if (mg_http_match_uri(hm, "/api/addFavFromMsg")) {
|
||||
UINT64 msg_id = GetUINT64Param(j_param, "msgId");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->AddFavFromMsg(msg_id);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/addFavFromImage")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->AddFavFromImage(
|
||||
wxid, image_path);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendAtText")) {
|
||||
std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
||||
std::vector<std::wstring> wxids = GetArrayParam(j_param, "wxids");
|
||||
std::wstring msg = GetWStringParam(j_param, "msg");
|
||||
std::vector<std::wstring> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
wxid_list.push_back(wxids[i]);
|
||||
}
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendAtText(
|
||||
chat_room_id, wxid_list, msg);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getContactProfile")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
common::ContactProfileInner profile;
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->GetContactByWxid(wxid,
|
||||
profile);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
if (success == 1) {
|
||||
nlohmann::json contact_profile = {
|
||||
{"account", profile.account}, {"headImage", profile.head_image},
|
||||
{"nickname", profile.nickname}, {"v3", profile.v3},
|
||||
{"wxid", profile.wxid},
|
||||
};
|
||||
ret_data["data"] = contact_profile;
|
||||
}
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/downloadAttach")) {
|
||||
UINT64 msg_id = GetUINT64Param(j_param, "msgId");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->DoDownloadTask(msg_id);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/forwardPublicMsg")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring appname = GetWStringParam(j_param, "appName");
|
||||
std::wstring username = GetWStringParam(j_param, "userName");
|
||||
std::wstring title = GetWStringParam(j_param, "title");
|
||||
std::wstring url = GetWStringParam(j_param, "url");
|
||||
std::wstring thumburl = GetWStringParam(j_param, "thumbUrl");
|
||||
std::wstring digest = GetWStringParam(j_param, "digest");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->ForwardPublicMsg(
|
||||
wxid, title, url, thumburl, username, appname, digest);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/forwardPublicMsgByMsgId")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
UINT64 msg_id = GetUINT64Param(j_param, "msgId");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->ForwardPublicMsgByMsgId(
|
||||
wxid, msg_id);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/decodeImage")) {
|
||||
std::wstring file_path = GetWStringParam(j_param, "filePath");
|
||||
std::wstring store_dir = GetWStringParam(j_param, "storeDir");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->DecodeImage(
|
||||
file_path, store_dir);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/getVoiceByMsgId")) {
|
||||
UINT64 msg_id = GetUINT64Param(j_param, "msgId");
|
||||
std::wstring store_dir = GetWStringParam(j_param, "storeDir");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->GetVoiceByDB(
|
||||
msg_id, store_dir);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendCustomEmotion")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring file_path = GetWStringParam(j_param, "filePath");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->SendCustomEmotion(file_path,
|
||||
wxid);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendApplet")) {
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
std::wstring waid_concat = GetWStringParam(j_param, "waidConcat");
|
||||
std::string waid = GetStringParam(j_param, "waid");
|
||||
std::string app_wxid = GetStringParam(j_param, "appletWxid");
|
||||
std::string json_param = GetStringParam(j_param, "jsonParam");
|
||||
std::string head_url = GetStringParam(j_param, "headImgUrl");
|
||||
std::string main_img = GetStringParam(j_param, "mainImg");
|
||||
std::string index_page = GetStringParam(j_param, "indexPage");
|
||||
|
||||
std::wstring waid_w = wxhelper::Utils::UTF8ToWstring(waid);
|
||||
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendApplet(
|
||||
wxid, waid_concat, waid_w, waid, app_wxid, json_param, head_url,
|
||||
main_img, index_page);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/sendPatMsg")) {
|
||||
std::wstring room_id = GetWStringParam(j_param, "receiver");
|
||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||
INT64 success =
|
||||
wxhelper::GlobalContext::GetInstance().mgr->SendPatMsg(room_id, wxid);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/ocr")) {
|
||||
std::wstring image_path = GetWStringParam(j_param, "imagePath");
|
||||
std::string text("");
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->DoOCRTask(image_path,text);
|
||||
nlohmann::json ret_data = {
|
||||
{"code", success}, {"msg", "success"}, {"data", text}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
} else if (mg_http_match_uri(hm, "/api/test")) {
|
||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->Test();
|
||||
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"}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "unreachable code."}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
||||
nlohmann::json ret_data = {
|
||||
{"code", 200}, {"data", {}}, {"msg", "unreachable code."}};
|
||||
ret = ret_data.dump();
|
||||
return ret;
|
||||
}
|
700
src/manager.cc
700
src/manager.cc
@ -4,6 +4,9 @@
|
||||
#include "export.h"
|
||||
#include "wechat_function.h"
|
||||
#include "db.h"
|
||||
#include "lz4.h"
|
||||
#include "base64.h"
|
||||
#include "tinyxml2.h"
|
||||
|
||||
namespace offset = wxhelper::V3_9_5_81::offset;
|
||||
namespace prototype = wxhelper::V3_9_5_81::prototype;
|
||||
@ -25,7 +28,19 @@ prototype::WeChatString * BuildWechatString(const std::wstring &ws){
|
||||
return p;
|
||||
}
|
||||
|
||||
Manager::Manager(UINT64 base) : base_addr_(base) {}
|
||||
prototype::WeChatStr * BuildWechatStr(const std::string &str){
|
||||
prototype::WeChatStr *p = Utils::WxHeapAlloc<prototype::WeChatStr>(
|
||||
sizeof(prototype::WeChatStr));
|
||||
char *p_chat_room_id = Utils::WxHeapAlloc<char>(str.size() + 1);
|
||||
memcpy(p_chat_room_id, str.c_str(), str.size() + 1);
|
||||
p->ptr = p_chat_room_id;
|
||||
p->len = static_cast<DWORD>(str.size());
|
||||
p->maxlen = static_cast<DWORD>(str.size());
|
||||
p->buf = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
Manager::Manager(UINT64 base) : base_addr_(base),js_api_addr_(0) {}
|
||||
Manager::~Manager() {}
|
||||
INT64 Manager::CheckLogin() {
|
||||
INT64 success = -1;
|
||||
@ -573,4 +588,687 @@ INT64 Manager::CreateChatRoom(const std::vector<std::wstring>& wxids){
|
||||
success = create_chat_room(mgr, head, end);
|
||||
return success;
|
||||
}
|
||||
INT64 Manager::QuitChatRoom(const std::wstring &room_id) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_room_mgr_addr = base_addr_ + offset::kChatRoomMgr;
|
||||
UINT64 quit_chat_room_addr = base_addr_ + offset::kQuitChatRoom;
|
||||
func::__GetChatRoomMgr get_chat_room_mgr =
|
||||
(func::__GetChatRoomMgr)get_chat_room_mgr_addr;
|
||||
func::__QuitChatRoom quit_chat_room =
|
||||
(func::__QuitChatRoom)quit_chat_room_addr;
|
||||
UINT64 mgr = get_chat_room_mgr();
|
||||
prototype::WeChatString chat_room_id(room_id);
|
||||
success = quit_chat_room(mgr, reinterpret_cast<UINT64>(&chat_room_id), 0);
|
||||
return success;
|
||||
}
|
||||
INT64 Manager::ForwardMsg(UINT64 msg_id, const std::wstring &wxid) {
|
||||
INT64 success = -1;
|
||||
UINT64 forward_addr = base_addr_ + offset::kForwardMsg;
|
||||
func::__ForwardMsg forward_msg = (func::__ForwardMsg)forward_addr;
|
||||
INT64 index = 0;
|
||||
INT64 local_id = DB::GetInstance().GetLocalIdByMsgId(msg_id, index);
|
||||
if (local_id <= 0 || index >> 32 == 0) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
LARGE_INTEGER l;
|
||||
l.HighPart = index >> 32;
|
||||
l.LowPart = (DWORD)local_id;
|
||||
prototype::WeChatString *recv = BuildWechatString(wxid);
|
||||
success = forward_msg(reinterpret_cast<UINT64>(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<UINT64>(&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;
|
||||
}
|
||||
|
||||
INT64 Manager::AddFavFromMsg(UINT64 msg_id) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr;
|
||||
UINT64 get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId;
|
||||
UINT64 add_fav_addr = base_addr_ + offset::kAddFavFromMsg;
|
||||
UINT64 get_favorite_mgr_addr = base_addr_ + offset::kGetFavoriteMgr;
|
||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
||||
func::__GetMgrByPrefixLocalId get_by_local_id = (func::__GetMgrByPrefixLocalId)get_by_local_id_addr;
|
||||
UINT64 new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter;
|
||||
|
||||
func::__AddFavFromMsg add_fav = (func::__AddFavFromMsg)add_fav_addr;
|
||||
func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr;
|
||||
func::__GetFavoriteMgr get_favorite_mgr = (func::__GetFavoriteMgr)get_favorite_mgr_addr;
|
||||
func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
||||
|
||||
INT64 index = 0;
|
||||
INT64 local_id = DB::GetInstance().GetLocalIdByMsgId(msg_id, index);
|
||||
if (local_id <= 0 || index >> 32 == 0) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
char chat_msg[0x460]= {0};
|
||||
LARGE_INTEGER l;
|
||||
l.HighPart = index >> 32;
|
||||
l.LowPart = (DWORD)local_id;
|
||||
UINT64 p_chat_msg = new_chat_msg(reinterpret_cast<UINT64>(&chat_msg));
|
||||
|
||||
get_chat_mgr();
|
||||
get_by_local_id(l.QuadPart,p_chat_msg);
|
||||
UINT64 mgr = get_favorite_mgr();
|
||||
success = add_fav(mgr,p_chat_msg);
|
||||
free_chat_msg(p_chat_msg);
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::AddFavFromImage(const std::wstring &wxid,
|
||||
const std::wstring &image_path) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_favorite_mgr_addr = base_addr_ + offset::kGetFavoriteMgr;
|
||||
UINT64 add_fav_from_image_addr = base_addr_ + offset::kAddFavFromImage;
|
||||
prototype::WeChatString *send_id = BuildWechatString(wxid);
|
||||
prototype::WeChatString *path = BuildWechatString(image_path);
|
||||
func::__GetFavoriteMgr get_favorite_mgr =
|
||||
(func::__GetFavoriteMgr)get_favorite_mgr_addr;
|
||||
func::__AddFavFromImage add_fav_from_image =
|
||||
(func::__AddFavFromImage)add_fav_from_image_addr;
|
||||
UINT64 mgr = get_favorite_mgr();
|
||||
success = add_fav_from_image(mgr, reinterpret_cast<UINT64>(path),
|
||||
reinterpret_cast<UINT64>(send_id));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::SendAtText(const std::wstring &room_id,
|
||||
const std::vector<std::wstring> &wxids,
|
||||
const std::wstring &msg) {
|
||||
INT64 success = -1;
|
||||
std::vector<prototype::WeChatString> wxid_list;
|
||||
common::VectorInner *list = (common::VectorInner *)&wxid_list;
|
||||
std::wstring at_msg = L"";
|
||||
int number = 0;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
||||
std::wstring nickname;
|
||||
std::wstring at_all = L"notify@all";
|
||||
if (at_all.compare(wxids[i]) == 0 ) {
|
||||
nickname = L"所有人";
|
||||
} else {
|
||||
nickname = GetContactOrChatRoomNickname(wxids[i]);
|
||||
}
|
||||
if (nickname.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
prototype::WeChatString id(wxids[i]);
|
||||
wxid_list.push_back(id);
|
||||
at_msg = at_msg + L"@" + nickname + L" ";
|
||||
number++;
|
||||
}
|
||||
if (number < 1) {
|
||||
return success;
|
||||
}
|
||||
at_msg += msg;
|
||||
|
||||
INT64 head = (INT64)&list->start;
|
||||
prototype::WeChatString to_user(room_id);
|
||||
prototype::WeChatString text_msg(at_msg);
|
||||
UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr;
|
||||
UINT64 send_text_msg_addr = base_addr_ + offset::kSendTextMsg;
|
||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
||||
char chat_msg[0x460] = {0};
|
||||
func::__GetSendMessageMgr mgr;
|
||||
mgr = (func::__GetSendMessageMgr)send_message_mgr_addr;
|
||||
func::__SendTextMsg send;
|
||||
send = (func::__SendTextMsg)send_text_msg_addr;
|
||||
func::__FreeChatMsg free;
|
||||
free = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
mgr();
|
||||
success = send(reinterpret_cast<UINT64>(&chat_msg),
|
||||
reinterpret_cast<UINT64>(&to_user),
|
||||
reinterpret_cast<UINT64>(&text_msg), head, 1, 1, 0, 0);
|
||||
free(reinterpret_cast<UINT64>(&chat_msg));
|
||||
return success;
|
||||
}
|
||||
|
||||
std::wstring Manager::GetContactOrChatRoomNickname(const std::wstring &wxid) {
|
||||
prototype::WeChatString to_user(wxid);
|
||||
UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr;
|
||||
UINT64 new_contact_addr = base_addr_ + offset::kNewContact;
|
||||
UINT64 get_contact_addr = base_addr_ + offset::kGetContact;
|
||||
UINT64 free_contact_addr = base_addr_ + offset::kFreeContact;
|
||||
func::__GetContactMgr get_contact_mgr =
|
||||
(func::__GetContactMgr)get_contact_mgr_addr;
|
||||
func::__GetContact get_contact = (func::__GetContact)get_contact_addr;
|
||||
func::__NewContact new_contact = (func::__NewContact)new_contact_addr;
|
||||
func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr;
|
||||
char buff[0x6A9] = {0};
|
||||
UINT64 contact = new_contact(reinterpret_cast<UINT64>(&buff));
|
||||
UINT64 mgr = get_contact_mgr();
|
||||
INT64 success = get_contact(mgr, reinterpret_cast<UINT64>(&to_user), contact);
|
||||
if (success == 1) {
|
||||
std::wstring nickname = Utils::ReadWstring(contact + 0xA0);
|
||||
free_contact(contact);
|
||||
return nickname;
|
||||
} else {
|
||||
free_contact(contact);
|
||||
return L"";
|
||||
}
|
||||
}
|
||||
|
||||
INT64 Manager::GetContactByWxid(const std::wstring &wxid,
|
||||
common::ContactProfileInner &profile) {
|
||||
INT64 success = -1;
|
||||
prototype::WeChatString to_user(wxid);
|
||||
UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr;
|
||||
UINT64 new_contact_addr = base_addr_ + offset::kNewContact;
|
||||
UINT64 get_contact_addr = base_addr_ + offset::kGetContact;
|
||||
UINT64 free_contact_addr = base_addr_ + offset::kFreeContact;
|
||||
func::__GetContactMgr get_contact_mgr =
|
||||
(func::__GetContactMgr)get_contact_mgr_addr;
|
||||
func::__GetContact get_contact = (func::__GetContact)get_contact_addr;
|
||||
func::__NewContact new_contact = (func::__NewContact)new_contact_addr;
|
||||
func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr;
|
||||
char buff[0x6A9] = {0};
|
||||
UINT64 contact = new_contact(reinterpret_cast<UINT64>(&buff));
|
||||
UINT64 mgr = get_contact_mgr();
|
||||
success = get_contact(mgr, reinterpret_cast<UINT64>(&to_user), contact);
|
||||
profile.wxid = Utils::ReadWstringThenConvert(contact + 0x10);
|
||||
profile.account = Utils::ReadWstringThenConvert(contact + 0x30);
|
||||
profile.v3 = Utils::ReadWstringThenConvert(contact + 0x50);
|
||||
profile.nickname = Utils::ReadWstringThenConvert(contact + 0xA0);
|
||||
profile.head_image = Utils::ReadWstringThenConvert(contact + 0x188);
|
||||
free_contact(contact);
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::DoDownloadTask(UINT64 msg_id) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId;
|
||||
func::__GetMgrByPrefixLocalId get_by_local_id =
|
||||
(func::__GetMgrByPrefixLocalId)get_by_local_id_addr;
|
||||
|
||||
UINT64 get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr;
|
||||
func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr;
|
||||
|
||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
||||
func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr;
|
||||
|
||||
UINT64 new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter;
|
||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
||||
|
||||
UINT64 get_current_data_path_addr = base_addr_ + offset::kGetCurrentDataPath;
|
||||
func::__GetCurrentDataPath GetCurrentDataPath =
|
||||
(func::__GetCurrentDataPath)get_current_data_path_addr;
|
||||
|
||||
UINT64 new_app_msg_info_addr = base_addr_ + offset::kNewAppMsgInfo;
|
||||
func::__NewAppMsgInfo new_app_msg_info =
|
||||
(func::__NewAppMsgInfo)new_app_msg_info_addr;
|
||||
|
||||
UINT64 free_app_msg_info_addr = base_addr_ + offset::kFreeAppMsgInfo;
|
||||
func::__FreeAppMsgInfo free_app_msg_info =
|
||||
(func::__NewAppMsgInfo)free_app_msg_info_addr;
|
||||
|
||||
UINT64 xml_to_app_info_addr = base_addr_ + offset::kParseAppMsgXml;
|
||||
func::__ParseAppMsgXml xml_to_app_info =
|
||||
(func::__ParseAppMsgXml)xml_to_app_info_addr;
|
||||
|
||||
UINT64 get_pre_download_mgr_addr = base_addr_ + offset::kGetPreDownLoadMgr;
|
||||
func::__GetPreDownLoadMgr get_pre_download_mgr =
|
||||
(func::__GetPreDownLoadMgr)get_pre_download_mgr_addr;
|
||||
|
||||
UINT64 push_attach_task_addr = base_addr_ + offset::kPushAttachTask;
|
||||
func::__PushAttachTask push_attach_task =
|
||||
(func::__PushAttachTask)push_attach_task_addr;
|
||||
|
||||
INT64 index = 0;
|
||||
INT64 local_id = DB::GetInstance().GetLocalIdByMsgId(msg_id, index);
|
||||
if (local_id <= 0 || index >> 32 == 0) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
char *chat_msg = Utils::WxHeapAlloc<char>(0x460);
|
||||
LARGE_INTEGER l;
|
||||
l.HighPart = index >> 32;
|
||||
l.LowPart = (DWORD)local_id;
|
||||
UINT64 p_chat_msg = new_chat_msg(reinterpret_cast<UINT64>(chat_msg));
|
||||
|
||||
get_chat_mgr();
|
||||
get_by_local_id(l.QuadPart, p_chat_msg);
|
||||
|
||||
std::wstring save_path = L"";
|
||||
std::wstring thumb_path = L"";
|
||||
|
||||
prototype::WeChatString current_data_path;
|
||||
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(¤t_data_path));
|
||||
|
||||
if (current_data_path.length > 0) {
|
||||
save_path += current_data_path.ptr;
|
||||
save_path += L"wxhelper";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
INT64 type = *(INT64 *)(chat_msg + 0x38);
|
||||
wchar_t *content = *(wchar_t **)(chat_msg + 0x88);
|
||||
DWORD len = *(DWORD *)(chat_msg + 0x94);
|
||||
std::wstring tmp_content(content, len);
|
||||
prototype::WeChatString *we_content = BuildWechatString(tmp_content);
|
||||
|
||||
switch (type) {
|
||||
case 0x3: {
|
||||
save_path += L"\\image";
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
thumb_path = save_path + L"\\" + std::to_wstring(msg_id) + L"_t.dat";
|
||||
save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".dat";
|
||||
break;
|
||||
}
|
||||
case 0x3E:
|
||||
case 0x2B: {
|
||||
save_path += L"\\video";
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
thumb_path = save_path + L"\\" + std::to_wstring(msg_id) + L".jpg";
|
||||
save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".mp4";
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x31: {
|
||||
save_path += L"\\file";
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
char *p_xml_app_msg = Utils::WxHeapAlloc<char>(0x3000);
|
||||
UINT64 xml_msg =
|
||||
new_app_msg_info(reinterpret_cast<UINT64>(p_xml_app_msg));
|
||||
UINT64 result =
|
||||
xml_to_app_info(xml_msg, reinterpret_cast<UINT64>(we_content), 1);
|
||||
if (result != 1) {
|
||||
return -4;
|
||||
}
|
||||
std::wstring file_name = Utils::ReadWstring(xml_msg + 0x70);
|
||||
save_path =
|
||||
save_path + L"\\" + std::to_wstring(msg_id) + L"_" + file_name;
|
||||
free_app_msg_info(xml_msg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
prototype::WeChatString *we_save_path = BuildWechatString(save_path);
|
||||
prototype::WeChatString *we_thumb_path = BuildWechatString(thumb_path);
|
||||
int temp = 1;
|
||||
memcpy(chat_msg + 0x280, we_thumb_path, sizeof(prototype::WeChatString));
|
||||
memcpy(chat_msg + 0x2A0, we_save_path, sizeof(prototype::WeChatString));
|
||||
memcpy(chat_msg + 0x40C, &temp, sizeof(temp));
|
||||
UINT64 mgr = get_pre_download_mgr();
|
||||
success = push_attach_task(mgr, p_chat_msg, 0, 1);
|
||||
free_chat_msg(p_chat_msg);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::ForwardPublicMsg(const std::wstring &wxid,
|
||||
const std::wstring &title,
|
||||
const std::wstring &url,
|
||||
const std::wstring &thumb_url,
|
||||
const std::wstring &sender_id,
|
||||
const std::wstring &sender_name,
|
||||
const std::wstring &digest) {
|
||||
INT64 success = -1;
|
||||
UINT64 new_item_addr = base_addr_ + offset::kNewMMReaderItem;
|
||||
func::__NewMMReaderItem new_item = (func::__NewMMReaderItem)new_item_addr;
|
||||
|
||||
UINT64 free_item_addr = base_addr_ + offset::kFreeMMReaderItem;
|
||||
func::__FreeMMReaderItem free_item = (func::__FreeMMReaderItem)free_item_addr;
|
||||
|
||||
UINT64 get_app_msg_mgr_addr = base_addr_ + offset::kGetAppMsgMgr;
|
||||
func::__GetAppMsgMgr get_app_mgr = (func::__GetAppMsgMgr)get_app_msg_mgr_addr;
|
||||
|
||||
UINT64 forward_public_msg_addr = base_addr_ + offset::kForwordPublicMsg;
|
||||
func::__ForwordPublicMsg forward_public_msg =
|
||||
(func::__ForwordPublicMsg)forward_public_msg_addr;
|
||||
|
||||
char *p_item = Utils::WxHeapAlloc<char>(0x3E4);
|
||||
new_item(reinterpret_cast<UINT64>(p_item));
|
||||
prototype::WeChatString *to_user = BuildWechatString(wxid);
|
||||
prototype::WeChatString *p_title = BuildWechatString(title);
|
||||
prototype::WeChatString *p_url = BuildWechatString(url);
|
||||
prototype::WeChatString *p_thumburl = BuildWechatString(thumb_url);
|
||||
prototype::WeChatString *p_sender_id = BuildWechatString(sender_id);
|
||||
prototype::WeChatString *p_name = BuildWechatString(sender_name);
|
||||
prototype::WeChatString *p_digest = BuildWechatString(digest);
|
||||
|
||||
memcpy(p_item + 0x8, p_title, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0x48, p_url, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0xB0, p_thumburl, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0xF0, p_digest, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0x2A0, p_sender_id, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0x2C0, p_name, sizeof(prototype::WeChatString));
|
||||
memcpy(p_item + 0x2C0, p_name, sizeof(prototype::WeChatString));
|
||||
|
||||
UINT64 mgr = get_app_mgr();
|
||||
success = forward_public_msg(mgr, reinterpret_cast<UINT64>(to_user),
|
||||
reinterpret_cast<UINT64>(p_item));
|
||||
free_item(reinterpret_cast<UINT64>(p_item));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::ForwardPublicMsgByMsgId(const std::wstring &wxid,
|
||||
UINT64 msg_id) {
|
||||
INT64 success = -1;
|
||||
std::string compress_content =
|
||||
DB::GetInstance().GetPublicMsgCompressContentByMsgId(msg_id);
|
||||
if (compress_content.empty()) {
|
||||
SPDLOG_INFO("Get compressContent is null from PublicMsg.db");
|
||||
return -3;
|
||||
}
|
||||
|
||||
std::string decode = base64_decode(compress_content);
|
||||
size_t len = decode.size();
|
||||
const char *src = decode.c_str();
|
||||
size_t dst_len = (len << 8);
|
||||
char *dst = new char[dst_len];
|
||||
|
||||
int decompress_len = LZ4_decompress_safe_partial(
|
||||
src, dst, static_cast<int>(len), static_cast<int>(dst_len), static_cast<int>(dst_len));
|
||||
if (decompress_len < 0) {
|
||||
SPDLOG_INFO("decompress content size :{}", decompress_len);
|
||||
return -1;
|
||||
}
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (doc.Parse(dst, decompress_len - 1) != 0) {
|
||||
SPDLOG_INFO("tinyxml2 parse error");
|
||||
return -2;
|
||||
}
|
||||
const char *title = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("title")
|
||||
->GetText();
|
||||
const char *digest = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("des")
|
||||
->GetText();
|
||||
|
||||
const char *url = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("mmreader")
|
||||
->FirstChildElement("category")
|
||||
->FirstChildElement("item")
|
||||
->FirstChildElement("url")
|
||||
->GetText();
|
||||
const char *thumb_url = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("thumburl")
|
||||
->GetText();
|
||||
const char *user_name = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("mmreader")
|
||||
->FirstChildElement("publisher")
|
||||
->FirstChildElement("username")
|
||||
->GetText();
|
||||
|
||||
const char *nickname = doc.FirstChildElement("msg")
|
||||
->FirstChildElement("appmsg")
|
||||
->FirstChildElement("mmreader")
|
||||
->FirstChildElement("publisher")
|
||||
->FirstChildElement("nickname")
|
||||
->GetText();
|
||||
|
||||
std::string s_title(title);
|
||||
std::string s_digest(digest);
|
||||
std::string s_url(url);
|
||||
std::string s_thumburl(thumb_url);
|
||||
std::string s_user_name(user_name);
|
||||
std::string s_nickname(nickname);
|
||||
|
||||
std::wstring ws_title = Utils::UTF8ToWstring(s_title);
|
||||
std::wstring ws_digest = Utils::UTF8ToWstring(s_digest);
|
||||
std::wstring ws_url = Utils::UTF8ToWstring(s_url);
|
||||
std::wstring ws_thumb_url = Utils::UTF8ToWstring(s_thumburl);
|
||||
std::wstring ws_user_name = Utils::UTF8ToWstring(s_user_name);
|
||||
std::wstring ws_nickname = Utils::UTF8ToWstring(s_nickname);
|
||||
success = ForwardPublicMsg(wxid, ws_title, ws_url, ws_thumb_url, ws_user_name,
|
||||
ws_nickname, ws_digest);
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::DecodeImage(const std::wstring &file_path, const std::wstring &save_dir) {
|
||||
return Utils::DecodeImage(file_path.c_str(), save_dir.c_str());
|
||||
}
|
||||
|
||||
INT64 Manager::GetVoiceByDB(ULONG64 msg_id, const std::wstring& dir) {
|
||||
INT64 success = -1;
|
||||
std::string buff = DB::GetInstance().GetVoiceBuffByMsgId(msg_id);
|
||||
if (buff.size() == 0) {
|
||||
success = 0;
|
||||
return success;
|
||||
}
|
||||
std::wstring save_path = dir;
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
save_path = save_path + L"\\" + std::to_wstring(msg_id) + L".amr";
|
||||
HANDLE file_handle = CreateFileW(save_path.c_str(), GENERIC_ALL, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
SPDLOG_ERROR("GetVoiceByDB save path invalid");
|
||||
return success;
|
||||
}
|
||||
DWORD bytes_write = 0;
|
||||
std::string decode = base64_decode(buff);
|
||||
WriteFile(file_handle, (LPCVOID)decode.c_str(), static_cast<DWORD>(decode.size()) , &bytes_write, 0);
|
||||
CloseHandle(file_handle);
|
||||
success = 1;
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::SendCustomEmotion(const std::wstring &file_path,
|
||||
const std::wstring &wxid) {
|
||||
INT64 success = -1;
|
||||
UINT64 get_custom_smiley_mgr_addr = base_addr_ + offset::kGetCustomSmileyMgr;
|
||||
func::__GetCustomSmileyMgr get_custom_smiley_mgr =
|
||||
(func::__GetCustomSmileyMgr)get_custom_smiley_mgr_addr;
|
||||
UINT64 send_custom_emotion_addr = base_addr_ + offset::kSendCustomEmotion;
|
||||
func::__SendCustomEmotion send_custom_emotion =
|
||||
(func::__SendCustomEmotion)send_custom_emotion_addr;
|
||||
prototype::WeChatString *path = BuildWechatString(file_path);
|
||||
prototype::WeChatString *recv = BuildWechatString(wxid);
|
||||
INT64 *temp = Utils::WxHeapAlloc<INT64>(0x20);
|
||||
memset(temp, 0, 0x20);
|
||||
UINT64 mgr = get_custom_smiley_mgr();
|
||||
success = send_custom_emotion(
|
||||
mgr, reinterpret_cast<UINT64>(path), reinterpret_cast<UINT64>(temp),
|
||||
reinterpret_cast<UINT64>(recv), 2, reinterpret_cast<UINT64>(temp), 0,
|
||||
reinterpret_cast<UINT64>(temp));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::SendApplet(const std::wstring &recv_wxid,
|
||||
const std::wstring &waid_suff,
|
||||
const std::wstring &waid_w, const std::string &waid_s,
|
||||
const std::string &wa_wxid,
|
||||
const std::string &json_param,
|
||||
const std::string &head_image,
|
||||
const std::string &big_image,
|
||||
const std::string &index_page) {
|
||||
INT64 success = -1;
|
||||
if (js_api_addr_ == 0) {
|
||||
auto vec2 = Utils::QWordScan(base_addr_ + 0x32D1318, 0x1000, 0x8);
|
||||
for (int i = 0; i < vec2.size(); i++) {
|
||||
INT64 ptr = vec2.at(i);
|
||||
if (*(INT64 *)ptr == base_addr_ + 0x32D1318) {
|
||||
js_api_addr_ = ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (js_api_addr_ == 0) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
|
||||
UINT64 share_app_msg_addr = base_addr_ + offset::kNewJsApiShareAppMessage;
|
||||
func::__JsApiShareAppMessage share_app_msg =
|
||||
(func::__JsApiShareAppMessage)share_app_msg_addr;
|
||||
|
||||
UINT64 init_addr = base_addr_ + offset::kInitJsConfig;
|
||||
func::__InitJsConfig init = (func::__InitJsConfig)init_addr;
|
||||
|
||||
UINT64 send_applet_addr = base_addr_ + offset::kSendApplet;
|
||||
func::__SendApplet send_applet = (func::__SendApplet)send_applet_addr;
|
||||
|
||||
UINT64 get_by_waid_addr = base_addr_ + offset::kGetAppInfoByWaid;
|
||||
func::__GetAppInfoByWaid get_app_info =
|
||||
(func::__GetAppInfoByWaid)get_by_waid_addr;
|
||||
|
||||
UINT64 copy_app_req_addr = base_addr_ + offset::kCopyShareAppMessageRequest;
|
||||
func::__CopyShareAppMessageRequest copy_app_req =
|
||||
(func::__CopyShareAppMessageRequest)copy_app_req_addr;
|
||||
|
||||
UINT64 new_wa_msg_addr = base_addr_ + offset::kNewWAUpdatableMsgInfo;
|
||||
func::__NewWAUpdatableMsgInfo new_wa_msg =
|
||||
(func::__NewWAUpdatableMsgInfo)new_wa_msg_addr;
|
||||
|
||||
UINT64 free_wa_msg_addr = base_addr_ + offset::kFreeWAUpdatableMsgInfo;
|
||||
func::__FreeWAUpdatableMsgInfo free_wa_msg =
|
||||
(func::__FreeWAUpdatableMsgInfo)free_wa_msg_addr;
|
||||
|
||||
std::vector<prototype::WeChatString> *temp =
|
||||
Utils::WxHeapAlloc<std::vector<prototype::WeChatString>>(0x20);
|
||||
// std::vector<prototype::WeChatString>* temp = new
|
||||
// std::vector<prototype::WeChatString>();
|
||||
common::VectorInner *list = (common::VectorInner *)temp;
|
||||
|
||||
prototype::WeChatString *member = BuildWechatString(recv_wxid);
|
||||
#ifdef _DEBUG
|
||||
list->head = reinterpret_cast<UINT64>(member);
|
||||
#endif
|
||||
list->start = reinterpret_cast<UINT64>(member);
|
||||
list->finsh = reinterpret_cast<UINT64>(member) + 0x20;
|
||||
list->end = reinterpret_cast<UINT64>(member) + 0x20;
|
||||
|
||||
INT64 head = reinterpret_cast<UINT64>(&(list->start));
|
||||
|
||||
prototype::WeChatString *waid_cat = BuildWechatString(waid_suff);
|
||||
prototype::WeChatString *waid = BuildWechatString(waid_w);
|
||||
|
||||
prototype::WeChatString *waid_2 = BuildWechatString(waid_suff);
|
||||
|
||||
prototype::WeChatStr *waid_str = BuildWechatStr(waid_s);
|
||||
prototype::WeChatStr *app_wxid = BuildWechatStr(wa_wxid);
|
||||
prototype::WeChatStr *json_str = BuildWechatStr(json_param);
|
||||
prototype::WeChatStr *head_image_url = BuildWechatStr(head_image);
|
||||
prototype::WeChatStr *image = BuildWechatStr(big_image);
|
||||
prototype::WeChatStr *index = BuildWechatStr(index_page);
|
||||
|
||||
UINT64 app_msg = js_api_addr_;
|
||||
|
||||
UINT64 data = *(UINT64 *)(app_msg + 0x8);
|
||||
char *share_req = Utils::WxHeapAlloc<char>(0x2000);
|
||||
|
||||
char *mid_ptr = Utils::WxHeapAlloc<char>(0x18);
|
||||
memcpy(mid_ptr, &share_req, sizeof(INT64));
|
||||
memcpy(mid_ptr + 0x8, &share_req, sizeof(INT64));
|
||||
memcpy(mid_ptr + 0x10, &share_req, sizeof(INT64));
|
||||
|
||||
memcpy((void *)data, mid_ptr, 0x18);
|
||||
|
||||
memcpy(share_req, (void *)(app_msg + 0x8), sizeof(UINT64));
|
||||
memcpy(share_req + 0x8, (void *)(app_msg + 0x8), sizeof(UINT64));
|
||||
memcpy(share_req + 0x10, (void *)(app_msg + 0x8), sizeof(UINT64));
|
||||
memcpy(share_req + 0x20, waid_2, sizeof(prototype::WeChatString));
|
||||
memcpy(share_req + 0x48, waid_str, sizeof(prototype::WeChatStr));
|
||||
memcpy(share_req + 0x98, app_wxid, sizeof(prototype::WeChatStr));
|
||||
memcpy(share_req + 0xF8, json_str, sizeof(prototype::WeChatStr));
|
||||
memcpy(share_req + 0x178, head_image_url, sizeof(prototype::WeChatStr));
|
||||
memcpy(share_req + 0x198, image, sizeof(prototype::WeChatStr));
|
||||
memcpy(share_req + 0x1c0, index, sizeof(prototype::WeChatStr));
|
||||
|
||||
success = send_applet(app_msg, reinterpret_cast<UINT64>(waid_cat), head, 0);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::SendPatMsg(const std::wstring &room_id,
|
||||
const std::wstring &wxid) {
|
||||
INT64 success = -1;
|
||||
UINT64 send_pat_msg_addr = base_addr_ + offset::kSendPatMsg;
|
||||
func::__SendPatMsg send_pat_msg =(func::__SendPatMsg)send_pat_msg_addr;
|
||||
prototype::WeChatString chat_room(room_id);
|
||||
prototype::WeChatString target(wxid);
|
||||
success = send_pat_msg(reinterpret_cast<UINT64>(&chat_room),reinterpret_cast<UINT64>(&target));
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::DoOCRTask(const std::wstring &img_path, std::string &result) {
|
||||
INT64 success = -1;
|
||||
UINT64 ocr_manager_addr = base_addr_ + offset::kGetOCRManager;
|
||||
func::__GetOCRManager ocr_manager = (func::__GetOCRManager)ocr_manager_addr;
|
||||
|
||||
UINT64 do_ocr_task_addr = base_addr_ + offset::kDoOCRTask;
|
||||
func::__DoOCRTask do_ocr_task = (func::__DoOCRTask)do_ocr_task_addr;
|
||||
|
||||
prototype::WeChatString img(img_path);
|
||||
std::vector<INT64> *temp = Utils::WxHeapAlloc<std::vector<INT64>>(0x20);
|
||||
INT64 unkonwn = 0;
|
||||
common::VectorInner *list = (common::VectorInner *)temp;
|
||||
list->start = reinterpret_cast<INT64>(&list->start);
|
||||
list->finsh = list->start;
|
||||
char buff[0x28] = {0};
|
||||
memcpy(buff, &list->start, sizeof(INT64));
|
||||
UINT64 mgr = ocr_manager();
|
||||
success = do_ocr_task(mgr, reinterpret_cast<UINT64>(&img),1,
|
||||
reinterpret_cast<UINT64>(buff),reinterpret_cast<UINT64>(&unkonwn));
|
||||
INT64 number = *(INT64 *)(buff + 0x8);
|
||||
if (number > 0) {
|
||||
INT64 header = *(INT64 *)(buff);
|
||||
for (unsigned int i = 0; i < number; i++) {
|
||||
INT64 content = *(INT64 *)header;
|
||||
result += Utils::ReadWstringThenConvert(content + 0x28);
|
||||
result += "\r\n";
|
||||
header = content;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
INT64 Manager::Test() {
|
||||
auto vec = Utils::QWordScan(base_addr_ + 0x32D1318, 0x1, L"WeChatWin.dll");
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
INT64 re = vec.at(i);
|
||||
SPDLOG_INFO("scan result :{},{}", i, re);
|
||||
}
|
||||
|
||||
auto vec2 = Utils::QWordScan(base_addr_ + 0x32D1318, 0x1000, 0x8);
|
||||
for (int i = 0; i < vec2.size(); i++) {
|
||||
INT64 re = vec2.at(i);
|
||||
SPDLOG_INFO("scan2 result :{},{}", i, re);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} // namespace wxhelper
|
@ -30,9 +30,44 @@ class Manager {
|
||||
INT64 InviteMemberToChatRoom(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& wxids);
|
||||
INT64 CreateChatRoom(const std::vector<std::wstring>& wxids);
|
||||
INT64 QuitChatRoom(const std::wstring& room_id);
|
||||
INT64 ForwardMsg(UINT64 msg_id, const std::wstring& wxid);
|
||||
INT64 GetSNSFirstPage();
|
||||
INT64 GetSNSNextPage(UINT64 sns_id);
|
||||
INT64 AddFavFromMsg(UINT64 msg_id);
|
||||
INT64 AddFavFromImage(const std::wstring& wxid,
|
||||
const std::wstring& image_path);
|
||||
INT64 SendAtText(const std::wstring& room_id,
|
||||
const std::vector<std::wstring>& wxids,
|
||||
const std::wstring& msg);
|
||||
std::wstring GetContactOrChatRoomNickname(const std::wstring& wxid);
|
||||
INT64 GetContactByWxid(const std::wstring& wxid,
|
||||
common::ContactProfileInner& profile);
|
||||
INT64 DoDownloadTask(UINT64 msg_id);
|
||||
INT64 ForwardPublicMsg(const std::wstring& wxid, const std::wstring& title,
|
||||
const std::wstring& url, const std::wstring& thumb_url,
|
||||
const std::wstring& sender_id,
|
||||
const std::wstring& sender_name,
|
||||
const std::wstring& digest);
|
||||
INT64 ForwardPublicMsgByMsgId(const std::wstring& wxid, UINT64 msg_id);
|
||||
|
||||
INT64 DecodeImage(const std::wstring& file_path,
|
||||
const std::wstring& save_dir);
|
||||
INT64 GetVoiceByDB(ULONG64 msg_id, const std::wstring& dir);
|
||||
INT64 SendCustomEmotion(const std::wstring& file_path,
|
||||
const std::wstring& wxid);
|
||||
INT64 SendApplet(
|
||||
const std::wstring& recv_wxid, const std::wstring& waid_suff,
|
||||
const std::wstring& waid_w, const std::string& waid_s,
|
||||
const std::string& wa_wxid, const std::string& json_param,
|
||||
const std::string& head_image, const std::string& big_image,
|
||||
const std::string& index_page);
|
||||
INT64 SendPatMsg(const std::wstring& room_id, const std::wstring& wxid);
|
||||
INT64 DoOCRTask(const std::wstring& img_path, std::string &result);
|
||||
INT64 Test();
|
||||
private:
|
||||
UINT64 base_addr_;
|
||||
UINT64 js_api_addr_;
|
||||
};
|
||||
|
||||
} // namespace wxhelper
|
||||
|
138
src/utils.cc
138
src/utils.cc
@ -1,6 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "utils.h"
|
||||
#include <winternl.h>
|
||||
#include <Psapi.h>
|
||||
#define BUFSIZE 1024
|
||||
#define JPEG0 0xFF
|
||||
#define JPEG1 0xD8
|
||||
@ -319,4 +320,141 @@ std::string Utils::ReadWstringThenConvert(INT64 addr){
|
||||
std::wstring wstr = ReadWstring(addr);
|
||||
return WstringToUTF8(wstr);
|
||||
}
|
||||
|
||||
INT64 Utils::DecodeImage(const wchar_t* file_path,const wchar_t* save_dir){
|
||||
std::wstring save_path(save_dir);
|
||||
std::wstring orign_file_path(file_path);
|
||||
if (!Utils::FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT64 pos_begin = orign_file_path.find_last_of(L"\\") + 1;
|
||||
INT64 pos_end = orign_file_path.find_last_of(L".");
|
||||
std::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};
|
||||
std::wstring suffix;
|
||||
short key = 0;
|
||||
if (ReadFile(h_origin_file, buffer, BUFSIZE, &bytes_read, NULL)) {
|
||||
memcpy(magic_head, buffer, 3);
|
||||
} else {
|
||||
CloseHandle(h_origin_file);
|
||||
return 0;
|
||||
}
|
||||
if ((magic_head[0] ^ JPEG0) == (magic_head[1] ^ JPEG1)) {
|
||||
key = magic_head[0] ^ JPEG0;
|
||||
suffix = L".jpg";
|
||||
} else if ((magic_head[0] ^ PNG1) == (magic_head[1] ^ PNG2)) {
|
||||
key = magic_head[0] ^ PNG1;
|
||||
suffix = L".png";
|
||||
} else if ((magic_head[0] ^ GIF0) == (magic_head[1] ^ GIF1)) {
|
||||
key = magic_head[0] ^ GIF0;
|
||||
suffix = L".gif";
|
||||
} else if ((magic_head[0] ^ BMP0) == (magic_head[1] ^ BMP1)) {
|
||||
key = magic_head[0] ^ BMP0;
|
||||
suffix = L".bmp";
|
||||
} else {
|
||||
key = -1;
|
||||
suffix = L".dat";
|
||||
}
|
||||
std::wstring save_img_path = save_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;
|
||||
}
|
||||
|
||||
std::vector<INT64> Utils::QWordScan(INT64 value, int align,
|
||||
const wchar_t *module) {
|
||||
MODULEINFO module_info;
|
||||
std::vector<INT64> result;
|
||||
if (GetModuleInformation(GetCurrentProcess(), GetModuleHandleW(module),
|
||||
&module_info, sizeof(module_info))) {
|
||||
auto start = static_cast<const char *>(module_info.lpBaseOfDll);
|
||||
const auto end = start + module_info.SizeOfImage - 0x8;
|
||||
|
||||
auto current_addr = start;
|
||||
while (current_addr < end) {
|
||||
if (*(INT64*)current_addr == value) {
|
||||
result.push_back(reinterpret_cast<INT64>(current_addr));
|
||||
}
|
||||
start += align;
|
||||
current_addr = start;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<INT64> Utils::QWordScan(INT64 value, INT64 start,int align) {
|
||||
SYSTEM_INFO sys_info;
|
||||
GetSystemInfo(&sys_info);
|
||||
std::vector<INT64> result;
|
||||
INT64 min_addr =
|
||||
reinterpret_cast<INT64>(sys_info.lpMinimumApplicationAddress);
|
||||
INT64 max_addr =
|
||||
reinterpret_cast<INT64>(sys_info.lpMaximumApplicationAddress);
|
||||
const INT64 page_size = sys_info.dwPageSize;
|
||||
min_addr = min_addr > start ? min_addr : start;
|
||||
|
||||
auto current_addr = min_addr;
|
||||
MEMORY_BASIC_INFORMATION mem_info = {};
|
||||
HANDLE handle = GetCurrentProcess();
|
||||
while (current_addr < max_addr) {
|
||||
VirtualQueryEx(handle, reinterpret_cast<LPVOID>(current_addr), &mem_info,
|
||||
sizeof(MEMORY_BASIC_INFORMATION));
|
||||
|
||||
if ((INT64)mem_info.RegionSize <= 0) {
|
||||
break;
|
||||
}
|
||||
INT64 region_size = mem_info.RegionSize;
|
||||
if ((mem_info.State & MEM_COMMIT) == MEM_COMMIT &&
|
||||
(mem_info.Protect & PAGE_GUARD) != PAGE_GUARD &&
|
||||
(mem_info.Protect & PAGE_NOACCESS) != PAGE_NOACCESS) {
|
||||
for (INT64 i = 0; i < region_size; i += align) {
|
||||
if (value == *(INT64 *)current_addr) {
|
||||
result.push_back(current_addr);
|
||||
}
|
||||
current_addr += align;
|
||||
}
|
||||
} else {
|
||||
current_addr += region_size;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace wxhelper
|
@ -58,6 +58,12 @@ class Utils {
|
||||
static std::wstring ReadWstring(INT64 addr);
|
||||
static std::string ReadWstringThenConvert(INT64 addr);
|
||||
|
||||
static INT64 DecodeImage(const wchar_t* file_path,const wchar_t* save_dir);
|
||||
|
||||
static std::vector<INT64> QWordScan(INT64 value, int align,
|
||||
const wchar_t *module);
|
||||
|
||||
static std::vector<INT64> QWordScan(INT64 value, INT64 start,int align);
|
||||
template <typename T1, typename T2>
|
||||
static std::vector<T1> split(T1 str, T2 letter) {
|
||||
std::vector<T1> arr;
|
||||
|
@ -112,7 +112,7 @@ struct SqlResult {
|
||||
|
||||
struct InnerMessageStruct {
|
||||
char *buffer;
|
||||
int length;
|
||||
INT64 length;
|
||||
~InnerMessageStruct() {
|
||||
if (this->buffer != NULL) {
|
||||
delete[] this->buffer;
|
||||
@ -198,6 +198,16 @@ struct ChatRoomMemberInner {
|
||||
member("") {}
|
||||
};
|
||||
|
||||
struct ContactProfileInner {
|
||||
std::string wxid;
|
||||
std::string account;
|
||||
std::string v3;
|
||||
std::string nickname;
|
||||
std::string head_image;
|
||||
ContactProfileInner()
|
||||
: wxid(""), account(""), v3(""), nickname(""), head_image("") {}
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
namespace V3_9_5_81 {
|
||||
namespace function {
|
||||
@ -238,6 +248,43 @@ typedef UINT64 (*__RemoveTopMsg)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__InviteMemberToChatRoom)(UINT64,UINT64,UINT64,UINT64);
|
||||
|
||||
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)();
|
||||
typedef UINT64 (*__GetMgrByPrefixLocalId)(UINT64,UINT64);
|
||||
typedef UINT64 (*__AddFavFromMsg)(UINT64,UINT64);
|
||||
typedef UINT64 (*__GetChatMgr)();
|
||||
typedef UINT64 (*__GetFavoriteMgr)();
|
||||
typedef UINT64 (*__AddFavFromImage)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__GetContact)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__NewContact)(UINT64);
|
||||
typedef UINT64 (*__FreeContact)(UINT64);
|
||||
typedef UINT64 (*__NewMMReaderItem)(UINT64);
|
||||
typedef UINT64 (*__FreeMMReaderItem)(UINT64);
|
||||
typedef UINT64 (*__ForwordPublicMsg)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__NewAppMsgInfo)(UINT64);
|
||||
typedef UINT64 (*__FreeAppMsgInfo)(UINT64);
|
||||
typedef UINT64 (*__ParseAppMsgXml)(UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__GetPreDownLoadMgr)();
|
||||
typedef UINT64 (*__PushAttachTask)(UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__GetCustomSmileyMgr)();
|
||||
typedef UINT64 (*__SendCustomEmotion)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__JsApiShareAppMessage)(UINT64);
|
||||
typedef UINT64 (*__InitJsConfig)(UINT64,UINT64);
|
||||
typedef UINT64 (*__SendApplet)(UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__SendAppletSecond)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
|
||||
typedef UINT64 (*__GetAppInfoByWaid)(UINT64,UINT64);
|
||||
typedef UINT64 (*__CopyShareAppMessageRequest)(UINT64,UINT64);
|
||||
typedef UINT64 (*__NewWAUpdatableMsgInfo)(UINT64);
|
||||
typedef UINT64 (*__FreeWAUpdatableMsgInfo)(UINT64);
|
||||
typedef UINT64 (*__SendPatMsg)(UINT64,UINT64);
|
||||
typedef UINT64 (*__GetOCRManager)();
|
||||
typedef UINT64 (*__DoOCRTask)(UINT64,UINT64,UINT64,UINT64,UINT64);
|
||||
|
||||
|
||||
} // namespace function
|
||||
@ -277,6 +324,26 @@ struct WeChatString {
|
||||
}
|
||||
};
|
||||
|
||||
struct WeChatStr{
|
||||
char * ptr;
|
||||
INT64 buf;
|
||||
INT64 len;
|
||||
INT64 maxlen;
|
||||
|
||||
WeChatStr(const char* p) {
|
||||
ptr = (char *)p;
|
||||
buf = 0;
|
||||
len = strlen(p);
|
||||
maxlen = len | 0xF;
|
||||
}
|
||||
WeChatStr() {
|
||||
ptr = NULL;
|
||||
buf = 0;
|
||||
len = 0;
|
||||
maxlen = 0xF;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace prototype
|
||||
namespace offset {
|
||||
const UINT64 kGetAccountServiceMgr = 0x8c1230;
|
||||
@ -342,6 +409,43 @@ const UINT64 kInviteMember = 0xe63650;
|
||||
const UINT64 kHookLog = 0x1304e60;
|
||||
|
||||
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;
|
||||
const UINT64 kGetMgrByPrefixLocalId = 0xe4add0;
|
||||
const UINT64 kAddFavFromMsg = 0x1601520;
|
||||
const UINT64 kGetChatMgr = 0x8f0400;
|
||||
const UINT64 kGetFavoriteMgr = 0x8c69b0;
|
||||
const UINT64 kAddFavFromImage = 0x160b920;
|
||||
const UINT64 kGetContact = 0xEA5F90;
|
||||
const UINT64 kNewContact = 0x1212e40;
|
||||
const UINT64 kFreeContact = 0x12134e0;
|
||||
const UINT64 kNewMMReaderItem = 0x8c79a0;
|
||||
const UINT64 kFreeMMReaderItem = 0x8c6da0;
|
||||
const UINT64 kForwordPublicMsg = 0xddc6c0;
|
||||
const UINT64 kParseAppMsgXml = 0x11b0a70;
|
||||
const UINT64 kNewAppMsgInfo = 0x91a550;
|
||||
const UINT64 kFreeAppMsgInfo = 0x8fd1a0;
|
||||
const UINT64 kGetPreDownLoadMgr = 0x9996f0;
|
||||
const UINT64 kPushAttachTask = 0x9c0080;
|
||||
const UINT64 kGetCustomSmileyMgr = 0x915c00;
|
||||
const UINT64 kSendCustomEmotion = 0xec0a40;
|
||||
const UINT64 kNewJsApiShareAppMessage = 0x13be1a0;
|
||||
const UINT64 kInitJsConfig = 0x137bc00;
|
||||
const UINT64 kSendApplet = 0x13c0920;
|
||||
const UINT64 kSendAppletSecond = 0x13c1150;
|
||||
const UINT64 kGetAppInfoByWaid = 0x13c5790;
|
||||
const UINT64 kCopyShareAppMessageRequest = 0x13c0670;
|
||||
const UINT64 kNewWAUpdatableMsgInfo = 0x919ca0;
|
||||
const UINT64 kFreeWAUpdatableMsgInfo = 0x8fc230;
|
||||
const UINT64 kSendPatMsg = 0x195f340;
|
||||
const UINT64 kGetOCRManager = 0x999780;
|
||||
const UINT64 kDoOCRTask = 0x190b2a0;
|
||||
|
||||
} // namespace offset
|
||||
} // namespace V3_9_5_81
|
||||
|
Loading…
x
Reference in New Issue
Block a user