mirror of
https://github.com/ttttupup/wxhelper.git
synced 2025-04-20 03:49:17 +08:00
Compare commits
73 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 | ||
|
1268d37a57 | ||
|
e6c57f8ede | ||
|
17aff3b6aa | ||
|
51a4693330 | ||
|
7e06eaf4e4 | ||
|
b996a9d91c | ||
|
e0c946bf72 | ||
|
bf52de1560 | ||
|
2ed409e7b0 | ||
|
6f97a499b8 | ||
|
d33df9391e | ||
|
23fc28d011 | ||
|
e373b2f063 | ||
|
7e0b877d99 | ||
|
2ee16e36bf | ||
|
91bd8f5977 | ||
|
a9029e4a3d | ||
|
53a7938335 | ||
|
ce72262d58 | ||
|
bdf19fe4e4 | ||
|
44623e5b2e | ||
|
1824d6507c |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "spdlog"]
|
||||||
|
path = spdlog
|
||||||
|
url = https://github.com/gabime/spdlog
|
@ -4,7 +4,7 @@ wechat hook 。PC端微信逆向学习。支持3.8.0.41,3.8.1.26, 3.9.0.28, 3.
|
|||||||
本仓库发布的内容,仅用于学习研究,请勿用于非法用途和商业用途!如因此产生任何法律纠纷,均与作者无关!
|
本仓库发布的内容,仅用于学习研究,请勿用于非法用途和商业用途!如因此产生任何法律纠纷,均与作者无关!
|
||||||
|
|
||||||
#### 项目说明:
|
#### 项目说明:
|
||||||
本项目是个人学习学习逆向的项目,参考 https://github.com/ljc545w/ComWeChatRobot ,在此基础上实现了微信的的其它版本的部分内容。
|
<font color= "#dd0000">本项目是逆向练习项目,可能会造成封号等后果。请自行承担风险。仅用于学习研究,请勿于非法用途。</font>
|
||||||
|
|
||||||
#### 实现原理:
|
#### 实现原理:
|
||||||
逆向分析PC端微信客户端,定位相关功能关键Call,编写dll调用关键Call。然后将该dll文件注入到微信进程。
|
逆向分析PC端微信客户端,定位相关功能关键Call,编写dll调用关键Call。然后将该dll文件注入到微信进程。
|
||||||
@ -19,7 +19,7 @@ dll在注入成功时,创建了一个默认端口为19088的http服务端,
|
|||||||
|
|
||||||
```
|
```
|
||||||
#### 使用说明:
|
#### 使用说明:
|
||||||
支持的版本3.8.0.41、3.8.1.26、3.9.0.28、3.9.2.23、3.9.2.26 。
|
支持的版本3.8.0.41、3.8.1.26、3.9.0.28、3.9.2.23、3.9.2.26 、3.9.5.81。
|
||||||
源码和主要实现在相应的分支内。
|
源码和主要实现在相应的分支内。
|
||||||
src:主要的dll代码
|
src:主要的dll代码
|
||||||
tool:简单的注入工具,一个是控制台,一个是图形界面。
|
tool:简单的注入工具,一个是控制台,一个是图形界面。
|
||||||
@ -62,7 +62,9 @@ cmake
|
|||||||
|
|
||||||
vcpkg
|
vcpkg
|
||||||
#### 编译构建
|
#### 编译构建
|
||||||
|
|
||||||
先准备好编译环境。
|
先准备好编译环境。
|
||||||
|
#### <font color= "#dd0000"> 以下是x86环境构建,3.9.5.81是x64环境,具体参考对应分支。</font>
|
||||||
```
|
```
|
||||||
cd wxhelper
|
cd wxhelper
|
||||||
mkdir build
|
mkdir build
|
||||||
@ -179,6 +181,8 @@ port=19099
|
|||||||
|
|
||||||
2023-06-05 :3.9.2.26版本更新
|
2023-06-05 :3.9.2.26版本更新
|
||||||
|
|
||||||
|
2023-07-07 :3.9.5.81版本更新
|
||||||
|
|
||||||
#### 功能预览:
|
#### 功能预览:
|
||||||
0.检查是否登录
|
0.检查是否登录
|
||||||
1.获取登录微信信息
|
1.获取登录微信信息
|
||||||
|
1356
doc/3.9.5.81.md
1356
doc/3.9.5.81.md
File diff suppressed because it is too large
Load Diff
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>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.2.2</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.example</groupId>
|
<groupId>com.example</groupId>
|
||||||
@ -14,7 +14,8 @@
|
|||||||
<name>wxhk</name>
|
<name>wxhk</name>
|
||||||
<description>wxhk</description>
|
<description>wxhk</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>21</java.version>
|
||||||
|
<vertx-web-client.version>4.5.3</vertx-web-client.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -39,7 +40,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
<version>4.1.92.Final</version>
|
<version>4.1.105.Final</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.okhttp3</groupId>
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
@ -50,22 +51,22 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.vertx</groupId>
|
<groupId>io.vertx</groupId>
|
||||||
<artifactId>vertx-core</artifactId>
|
<artifactId>vertx-core</artifactId>
|
||||||
<version>4.4.2</version>
|
<version>${vertx-web-client.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.vertx</groupId>
|
<groupId>io.vertx</groupId>
|
||||||
<artifactId>vertx-web</artifactId>
|
<artifactId>vertx-web</artifactId>
|
||||||
<version>4.4.2</version>
|
<version>${vertx-web-client.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.vertx</groupId>
|
<groupId>io.vertx</groupId>
|
||||||
<artifactId>vertx-web-client</artifactId>
|
<artifactId>vertx-web-client</artifactId>
|
||||||
<version>4.4.2</version>
|
<version>${vertx-web-client.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.vertx</groupId>
|
<groupId>io.vertx</groupId>
|
||||||
<artifactId>vertx-mysql-client</artifactId>
|
<artifactId>vertx-mysql-client</artifactId>
|
||||||
<version>4.4.2</version>
|
<version>${vertx-web-client.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -42,6 +42,11 @@ public class PrivateChatMsg implements Serializable {
|
|||||||
private String signature;
|
private String signature;
|
||||||
private String time;
|
private String time;
|
||||||
private Integer timestamp;
|
private Integer timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对用户,如果是文件助手是filehelper
|
||||||
|
*/
|
||||||
|
private String toUser;
|
||||||
/**
|
/**
|
||||||
* 类型
|
* 类型
|
||||||
*/
|
*/
|
||||||
|
@ -15,4 +15,17 @@ import lombok.experimental.Accessors;
|
|||||||
public class OpenHook implements SendMsg<OpenHook> {
|
public class OpenHook implements SendMsg<OpenHook> {
|
||||||
String port;
|
String port;
|
||||||
String ip;
|
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.math.BigDecimal;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
@ -50,7 +51,12 @@ public class WxMsgHandle {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
add(chatMsg -> {
|
add(chatMsg -> {
|
||||||
wxSmgServer.私聊(chatMsg);
|
if(Objects.equals(chatMsg.getToUser(), FILEHELPER)){
|
||||||
|
wxSmgServer.文件助手(chatMsg);
|
||||||
|
}else{
|
||||||
|
wxSmgServer.私聊(chatMsg);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, WxMsgType.私聊信息);
|
}, WxMsgType.私聊信息);
|
||||||
add(chatMsg -> {
|
add(chatMsg -> {
|
||||||
@ -174,8 +180,8 @@ public class WxMsgHandle {
|
|||||||
if (monery.startsWith("¥")) {
|
if (monery.startsWith("¥")) {
|
||||||
String substring = monery.substring(1);
|
String substring = monery.substring(1);
|
||||||
BigDecimal decimal = new BigDecimal(substring);
|
BigDecimal decimal = new BigDecimal(substring);
|
||||||
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), chatMsg.getFromUser(), remark);
|
log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), receiver_username, remark);
|
||||||
wxSmgServer.收款之后(new PayoutInformation(chatMsg.getFromUser(), decimal, remark));
|
wxSmgServer.收款之后(new PayoutInformation(receiver_username, decimal, remark));
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,12 +32,14 @@ public class WxSmgServerImpl implements com.example.wxhk.server.WxSmgServer {
|
|||||||
public void 私聊(PrivateChatMsg chatMsg) {
|
public void 私聊(PrivateChatMsg chatMsg) {
|
||||||
if (Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)) {
|
if (Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)) {
|
||||||
log.info("手机端对:{}发出:{}", chatMsg.getFromUser(), chatMsg.getContent());
|
log.info("手机端对:{}发出:{}", chatMsg.getFromUser(), chatMsg.getContent());
|
||||||
|
}else{
|
||||||
|
log.info("收到私聊{}",chatMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void 文件助手(PrivateChatMsg chatMsg) {
|
public void 文件助手(PrivateChatMsg chatMsg) {
|
||||||
|
log.info("文件助手:{}",chatMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,7 +2,8 @@ package com.example.wxhk.tcp.vertx;
|
|||||||
|
|
||||||
import com.example.wxhk.WxhkApplication;
|
import com.example.wxhk.WxhkApplication;
|
||||||
import com.example.wxhk.constant.WxMsgType;
|
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.AbstractVerticle;
|
||||||
import io.vertx.core.DeploymentOptions;
|
import io.vertx.core.DeploymentOptions;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
@ -75,7 +76,10 @@ public class VertxTcp extends AbstractVerticle implements CommandLineRunner {
|
|||||||
listen.onComplete(event -> {
|
listen.onComplete(event -> {
|
||||||
boolean succeeded = event.succeeded();
|
boolean succeeded = event.succeeded();
|
||||||
if (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();
|
startPromise.complete();
|
||||||
} else {
|
} else {
|
||||||
startPromise.fail(event.cause());
|
startPromise.fail(event.cause());
|
||||||
|
@ -24,7 +24,7 @@ public class HttpAsyncUtil {
|
|||||||
protected static final Log log = Log.get();
|
protected static final Log log = Log.get();
|
||||||
|
|
||||||
public static Future<HttpResponse<Buffer>> exec(Type type, JsonObject object) {
|
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)
|
.sendJsonObject(object)
|
||||||
.onSuccess(event ->
|
.onSuccess(event ->
|
||||||
{
|
{
|
||||||
@ -36,7 +36,7 @@ public class HttpAsyncUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Future<HttpResponse<Buffer>> exec(Type type, JsonObject object, Handler<AsyncResult<HttpResponse<Buffer>>> handler) {
|
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)
|
.sendJsonObject(object)
|
||||||
.onComplete(handler)
|
.onComplete(handler)
|
||||||
;
|
;
|
||||||
@ -45,22 +45,31 @@ public class HttpAsyncUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
检查微信登陆("0"),
|
检查微信登陆("checkLogin"),
|
||||||
获取登录信息("1"),
|
获取登录信息("userInfo"),
|
||||||
发送文本("2"),
|
发送文本("sendTextMsg"),
|
||||||
发送at文本("3"),
|
转发消息("forwardMsg"),
|
||||||
|
发送at文本("sendAtText"),
|
||||||
发送图片("5"),
|
发送图片("5"),
|
||||||
发送文件("6"),
|
发送文件("sendFileMsg"),
|
||||||
开启hook("9"),
|
开启hook("hookSyncMsg"),
|
||||||
关闭hook("10"),
|
关闭hook("unhookSyncMsg"),
|
||||||
添加好友("20"),
|
添加好友("20"),
|
||||||
通过好友申请("23"),
|
通过好友申请("23"),
|
||||||
获取群成员("25"),
|
获取群成员("getMemberFromChatRoom"),
|
||||||
获取群成员昵称("26"),
|
获取群成员基础信息("getContactProfile"),
|
||||||
删除群成员("27"),
|
获取群详情("getChatRoomDetailInfo"),
|
||||||
|
添加群成员("addMemberToChatRoom"),
|
||||||
|
修改群昵称("modifyNickname"),
|
||||||
|
删除群成员("delMemberFromChatRoom"),
|
||||||
|
置顶群消息("topMsg"),
|
||||||
|
取消置顶群消息("removeTopMsg"),
|
||||||
|
邀请入群("InviteMemberToChatRoom"),
|
||||||
确认收款("45"),
|
确认收款("45"),
|
||||||
联系人列表("46"),
|
联系人列表("getContactList"),
|
||||||
查询微信信息("55"),
|
查询微信信息("55"),
|
||||||
|
下载附件("downloadAttach"),
|
||||||
|
解码("decodeImage"),
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -27,7 +27,7 @@ public class HttpSyncUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static JsonObject exec(HttpAsyncUtil.Type type, JsonObject obj) {
|
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()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("type:{},{}", type.getType(), post);
|
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
|
wx.port=19088
|
||||||
spring.profiles.active=local
|
spring.profiles.active=local
|
||||||
vertx.port=8080
|
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.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@ -41,5 +43,7 @@ class HttpSendUtilTest {
|
|||||||
void 获取群成员() {
|
void 获取群成员() {
|
||||||
GroupMembers 获取群成员 = HttpSendUtil.获取群成员(new GetGroupMembers().setChatRoomId("24964676359@chatroom"));
|
GroupMembers 获取群成员 = HttpSendUtil.获取群成员(new GetGroupMembers().setChatRoomId("24964676359@chatroom"));
|
||||||
Console.log(获取群成员);
|
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()
|
@ -1,51 +0,0 @@
|
|||||||
import ctypes
|
|
||||||
import hashlib
|
|
||||||
import hmac
|
|
||||||
|
|
||||||
# pip install pycryptodome
|
|
||||||
from Crypto.Cipher import AES
|
|
||||||
|
|
||||||
|
|
||||||
def decrypt(password, input_file, out_file):
|
|
||||||
password = bytes.fromhex(password.replace(' ', ''))
|
|
||||||
with open(input_file, 'rb') as (f):
|
|
||||||
blist = f.read()
|
|
||||||
print(len(blist))
|
|
||||||
salt = blist[:16]
|
|
||||||
key = hashlib.pbkdf2_hmac('sha1', password, salt, DEFAULT_ITER, KEY_SIZE)
|
|
||||||
first = blist[16:DEFAULT_PAGESIZE]
|
|
||||||
mac_salt = bytes([x ^ 58 for x in salt])
|
|
||||||
mac_key = hashlib.pbkdf2_hmac('sha1', key, mac_salt, 2, KEY_SIZE)
|
|
||||||
hash_mac = hmac.new(mac_key, digestmod='sha1')
|
|
||||||
hash_mac.update(first[:-32])
|
|
||||||
hash_mac.update(bytes(ctypes.c_int(1)))
|
|
||||||
if hash_mac.digest() == first[-32:-12]:
|
|
||||||
print('decrypt success')
|
|
||||||
else:
|
|
||||||
print('password error')
|
|
||||||
return
|
|
||||||
blist = [blist[i:i + DEFAULT_PAGESIZE] for i in range(DEFAULT_PAGESIZE, len(blist), DEFAULT_PAGESIZE)]
|
|
||||||
with open(out_file, 'wb') as (f):
|
|
||||||
f.write(SQLITE_FILE_HEADER)
|
|
||||||
t = AES.new(key, AES.MODE_CBC, first[-48:-32])
|
|
||||||
f.write(t.decrypt(first[:-48]))
|
|
||||||
f.write(first[-48:])
|
|
||||||
for i in blist:
|
|
||||||
t = AES.new(key, AES.MODE_CBC, i[-48:-32])
|
|
||||||
f.write(t.decrypt(i[:-48]))
|
|
||||||
f.write(i[-48:])
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
password = '565735E30E474DA09250CB5AA047E3940FFA1C6F767C4263B13ABB512933DA49'
|
|
||||||
input_file = 'C:/var/Applet.db'
|
|
||||||
out_file = 'c:/var/out/Applet.db'
|
|
||||||
decrypt(password, input_file, out_file)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
SQLITE_FILE_HEADER = bytes('SQLite format 3', encoding='ASCII') + bytes(1)
|
|
||||||
KEY_SIZE = 32
|
|
||||||
DEFAULT_PAGESIZE = 4096
|
|
||||||
DEFAULT_ITER = 64000
|
|
||||||
main()
|
|
26
python/http_server.py
Normal file
26
python/http_server.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
from fastapi import FastAPI, Request
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# pip install fastapi
|
||||||
|
# run command :uvicorn test:app --reload
|
||||||
|
# 127.0.0.1:8000/api
|
||||||
|
|
||||||
|
@app.post("/api")
|
||||||
|
def create_item(request: Request):
|
||||||
|
print("recv msg")
|
||||||
|
return {"code": 0, "msg": "success"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.middleware("http")
|
||||||
|
async def TestCustomMiddleware(request: Request, call_next):
|
||||||
|
the_headers = request.headers
|
||||||
|
the_body = await request.json()
|
||||||
|
|
||||||
|
print(the_headers)
|
||||||
|
print(the_body)
|
||||||
|
|
||||||
|
response = await call_next(request)
|
||||||
|
|
||||||
|
return response
|
10
python/readme.md
Normal file
10
python/readme.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
### 常用的一些工具
|
||||||
|
|
||||||
|
|
||||||
|
client.py : 快速测试dll的http接口。
|
||||||
|
|
||||||
|
decrpt.py : 微信数据库解密工具。password 为dll个人信息里返回的dbkey。
|
||||||
|
|
||||||
|
http_server.py : 一个简单的http server,用来接收hook的消息。
|
||||||
|
|
||||||
|
tcpserver.py: 一个简单的tcp server,用来接收hook的消息。
|
@ -526,7 +526,7 @@ DWORD GetPIDForProcess(wchar_t* process)
|
|||||||
if (!hSnapshot) {
|
if (!hSnapshot) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
pe32.dwSize = sizeof(PROCESSENTRY32W);
|
||||||
for (working = Process32FirstW(hSnapshot, &pe32); working; working = Process32NextW(hSnapshot, &pe32))
|
for (working = Process32FirstW(hSnapshot, &pe32); working; working = Process32NextW(hSnapshot, &pe32))
|
||||||
{
|
{
|
||||||
if (!wcscmp(pe32.szExeFile, process))
|
if (!wcscmp(pe32.szExeFile, process))
|
||||||
@ -934,6 +934,9 @@ int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DWORD dErrorCode = GetLastError();
|
||||||
|
printf("dll inject fail");
|
||||||
|
printf("error code : %d ", dErrorCode);
|
||||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
result = 0;
|
result = 0;
|
||||||
@ -941,6 +944,9 @@ int InjectDll(wchar_t* szPName, wchar_t* szDllPath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DWORD dErrorCode = GetLastError();
|
||||||
|
printf("dll inject fail.VirtualAllocEx method fail.");
|
||||||
|
printf("error code : %d ", dErrorCode);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
@ -986,6 +992,9 @@ int InjectDllByPid(unsigned int pid, wchar_t* szDllPath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DWORD dErrorCode = GetLastError();
|
||||||
|
printf("dll inject fail");
|
||||||
|
printf("error code : %d ", dErrorCode);
|
||||||
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
VirtualFreeEx(hProcess, lpRemoteDllBase, ulDllLength, MEM_DECOMMIT | MEM_RELEASE);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
result = 0;
|
result = 0;
|
||||||
@ -993,6 +1002,9 @@ int InjectDllByPid(unsigned int pid, wchar_t* szDllPath)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DWORD dErrorCode = GetLastError();
|
||||||
|
printf("dll inject fail.VirtualAllocEx method fail.");
|
||||||
|
printf("error code : %d ", dErrorCode);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
1
spdlog
Submodule
1
spdlog
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit ad0e89cbfb4d0c1ce4d097e134eb7be67baebb36
|
@ -344,6 +344,7 @@ std::vector<void *> DB::GetDbHandles() {
|
|||||||
msg0_db.db_name = (wchar_t *)(*(UINT64 *)(db_addr));
|
msg0_db.db_name = (wchar_t *)(*(UINT64 *)(db_addr));
|
||||||
msg0_db.db_name_len = *(DWORD *)(db_addr + 0x8);
|
msg0_db.db_name_len = *(DWORD *)(db_addr + 0x8);
|
||||||
msg0_db.handle = msg0_db_addr;
|
msg0_db.handle = msg0_db_addr;
|
||||||
|
msg0_db.extrainfo = *(UINT64 *)(*(UINT64 *)(db_addr + 0x28) + 0x1E8);
|
||||||
ExecuteSQL(msg0_db_addr,
|
ExecuteSQL(msg0_db_addr,
|
||||||
"select * from sqlite_master where type=\"table\";",
|
"select * from sqlite_master where type=\"table\";",
|
||||||
(UINT64)GetDbInfo, &msg0_db);
|
(UINT64)GetDbInfo, &msg0_db);
|
||||||
@ -458,7 +459,7 @@ std::vector<std::string> DB::GetChatMsgByMsgId(ULONG64 msgid) {
|
|||||||
wchar_t dbname[20] = {0};
|
wchar_t dbname[20] = {0};
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; i++) {
|
||||||
swprintf_s(dbname, L"MSG%d.db", i);
|
swprintf_s(dbname, L"MSG%d.db", i);
|
||||||
DWORD handle = GetDbHandleByDbName(dbname);
|
UINT64 handle = GetDbHandleByDbName(dbname);
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
// LOG(INFO) << "MSG db handle is null";
|
// LOG(INFO) << "MSG db handle is null";
|
||||||
return {};
|
return {};
|
||||||
|
@ -17,7 +17,9 @@ GlobalContext::~GlobalContext() {
|
|||||||
void GlobalContext::initialize(HMODULE module) {
|
void GlobalContext::initialize(HMODULE module) {
|
||||||
state =GlobalContextState::INITIALIZING;
|
state =GlobalContextState::INITIALIZING;
|
||||||
module_ = module;
|
module_ = module;
|
||||||
// Utils::Hide(module);
|
#ifndef _DEBUG
|
||||||
|
Utils::Hide(module);
|
||||||
|
#endif
|
||||||
UINT64 base = Utils::GetWeChatWinBase();
|
UINT64 base = Utils::GetWeChatWinBase();
|
||||||
config.emplace();
|
config.emplace();
|
||||||
config->Initialize();
|
config->Initialize();
|
||||||
|
@ -24,13 +24,6 @@ class GlobalContext : public Singleton<GlobalContext> {
|
|||||||
std::unique_ptr<HttpServer> http_server;
|
std::unique_ptr<HttpServer> http_server;
|
||||||
std::unique_ptr<Manager> mgr;
|
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;
|
GlobalContextState state = GlobalContextState::NOT_INITIALIZED;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
132
src/hooks.cc
132
src/hooks.cc
@ -16,12 +16,25 @@ static int kServerPort = 19099;
|
|||||||
static bool kMsgHookFlag = false;
|
static bool kMsgHookFlag = false;
|
||||||
static char kServerIp[16] = "127.0.0.1";
|
static char kServerIp[16] = "127.0.0.1";
|
||||||
static bool kEnableHttp = false;
|
static bool kEnableHttp = false;
|
||||||
|
static bool kLogHookFlag = false;
|
||||||
|
|
||||||
|
static bool kSnsFinishHookFlag = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static UINT64 (*R_DoAddMsg)(UINT64, UINT64, UINT64) = (UINT64(*)(
|
static UINT64 (*R_DoAddMsg)(UINT64, UINT64, UINT64) = (UINT64(*)(
|
||||||
UINT64, UINT64, UINT64))(Utils::GetWeChatWinBase() + offset::kDoAddMsg);
|
UINT64, UINT64, UINT64))(Utils::GetWeChatWinBase() + offset::kDoAddMsg);
|
||||||
|
|
||||||
|
static UINT64 (*R_Log)(UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64,
|
||||||
|
UINT64, UINT64, UINT64, UINT64, UINT64) =
|
||||||
|
(UINT64(*)(UINT64, 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,
|
VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
||||||
PTP_WORK Work) {
|
PTP_WORK Work) {
|
||||||
common::InnerMessageStruct *msg = (common::InnerMessageStruct *)context;
|
common::InnerMessageStruct *msg = (common::InnerMessageStruct *)context;
|
||||||
@ -65,7 +78,7 @@ VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
|||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
char recv_buf[1024] = {0};
|
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) {
|
if (ret < 0) {
|
||||||
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
|
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
|
||||||
goto clean;
|
goto clean;
|
||||||
@ -101,7 +114,7 @@ VOID CALLBACK SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string jstr = j_msg.dump() + "\n";
|
std::string jstr = j_msg.dump() + "\n";
|
||||||
// HttpClient::GetInstance().SendRequest(jstr);
|
HttpClient::GetInstance().SendRequest(jstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
||||||
@ -112,9 +125,10 @@ void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
|||||||
msg["toUser"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x28));
|
msg["toUser"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x28));
|
||||||
msg["content"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x30));
|
msg["content"] = Utils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x30));
|
||||||
msg["signature"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x48));
|
msg["signature"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x48));
|
||||||
msg["msgId"] = *(INT64 *)(param2 + 0x58);
|
msg["msgId"] = *(INT64 *)(param2 + 0x60);
|
||||||
msg["msgSequence"] = *(DWORD *)(param2 + 0x20);
|
msg["msgSequence"] = *(DWORD *)(param2 + 0x5C);
|
||||||
msg["fromUserName"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
|
msg["createTime"] = *(DWORD *)(param2 + 0x58);
|
||||||
|
msg["displayFullContent"] = Utils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
|
||||||
DWORD type = *(DWORD *)(param2 + 0x24);
|
DWORD type = *(DWORD *)(param2 + 0x24);
|
||||||
msg["type"] = type;
|
msg["type"] = type;
|
||||||
if (type == 3) {
|
if (type == 3) {
|
||||||
@ -140,6 +154,59 @@ void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
|||||||
R_DoAddMsg(param1,param2,param3);
|
R_DoAddMsg(param1,param2,param3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT64 HandlePrintLog(UINT64 param1, UINT64 param2, UINT64 param3, UINT64 param4,
|
||||||
|
UINT64 param5, UINT64 param6, UINT64 param7, UINT64 param8,
|
||||||
|
UINT64 param9, UINT64 param10, UINT64 param11,
|
||||||
|
UINT64 param12) {
|
||||||
|
UINT64 p = R_Log(param1, param2, param3, param4, param5, param6, param7, param8, param9,
|
||||||
|
param10, param11, param12);
|
||||||
|
if(p== 0 || p == 1){
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
char *msg = (char *)p;
|
||||||
|
if (msg != NULL) {
|
||||||
|
// INT64 size = *(INT64 *)(p - 0x8);
|
||||||
|
std::string str(msg);
|
||||||
|
std::wstring ws = Utils::UTF8ToWstring(str);
|
||||||
|
std::string out = Utils::WstringToAnsi(ws, CP_ACP);
|
||||||
|
spdlog::info("wechat log:{}", out);
|
||||||
|
}
|
||||||
|
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,
|
int HookSyncMsg(std::string client_ip, int port, std::string url,
|
||||||
uint64_t timeout, bool enable) {
|
uint64_t timeout, bool enable) {
|
||||||
if (kMsgHookFlag) {
|
if (kMsgHookFlag) {
|
||||||
@ -162,15 +229,23 @@ int HookSyncMsg(std::string client_ip, int port, std::string url,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DetourRestoreAfterWith();
|
// DetourRestoreAfterWith();
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
UINT64 do_add_msg_addr = base + offset::kDoAddMsg;
|
|
||||||
DetourAttach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg);
|
DetourAttach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg);
|
||||||
LONG ret = DetourTransactionCommit();
|
LONG ret = DetourTransactionCommit();
|
||||||
if(ret == NO_ERROR){
|
if(ret == NO_ERROR){
|
||||||
kMsgHookFlag = true;
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +260,6 @@ int UnHookSyncMsg() {
|
|||||||
UINT64 base = Utils::GetWeChatWinBase();
|
UINT64 base = Utils::GetWeChatWinBase();
|
||||||
DetourTransactionBegin();
|
DetourTransactionBegin();
|
||||||
DetourUpdateThread(GetCurrentThread());
|
DetourUpdateThread(GetCurrentThread());
|
||||||
UINT64 do_add_msg_addr = base + offset::kDoAddMsg;
|
|
||||||
DetourDetach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg);
|
DetourDetach(&(PVOID&)R_DoAddMsg, &HandleSyncMsg);
|
||||||
LONG ret = DetourTransactionCommit();
|
LONG ret = DetourTransactionCommit();
|
||||||
if (ret == NO_ERROR) {
|
if (ret == NO_ERROR) {
|
||||||
@ -196,5 +270,47 @@ int UnHookSyncMsg() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HookLog() {
|
||||||
|
if (kLogHookFlag) {
|
||||||
|
SPDLOG_INFO("log hook already called");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT64 base = Utils::GetWeChatWinBase();
|
||||||
|
if (!base) {
|
||||||
|
SPDLOG_INFO("base addr is null");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DetourRestoreAfterWith();
|
||||||
|
DetourTransactionBegin();
|
||||||
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
UINT64 do_add_msg_addr = base + offset::kHookLog;
|
||||||
|
DetourAttach(&(PVOID &)R_Log, &HandlePrintLog);
|
||||||
|
LONG ret = DetourTransactionCommit();
|
||||||
|
if (ret == NO_ERROR) {
|
||||||
|
kLogHookFlag = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UnHookLog() {
|
||||||
|
if (!kLogHookFlag) {
|
||||||
|
kLogHookFlag = false;
|
||||||
|
SPDLOG_INFO("hook log reset");
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
UINT64 base = Utils::GetWeChatWinBase();
|
||||||
|
DetourTransactionBegin();
|
||||||
|
DetourUpdateThread(GetCurrentThread());
|
||||||
|
UINT64 do_add_msg_addr = base + offset::kHookLog;
|
||||||
|
DetourDetach(&(PVOID &)R_Log, &HandlePrintLog);
|
||||||
|
LONG ret = DetourTransactionCommit();
|
||||||
|
if (ret == NO_ERROR) {
|
||||||
|
kLogHookFlag = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace hooks
|
} // namespace hooks
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
@ -10,6 +10,10 @@ int HookSyncMsg(std::string client_ip, int port, std::string url, uint64_t timeo
|
|||||||
|
|
||||||
int UnHookSyncMsg();
|
int UnHookSyncMsg();
|
||||||
|
|
||||||
|
int HookLog();
|
||||||
|
|
||||||
|
int UnHookLog();
|
||||||
|
|
||||||
} // namespace hooks
|
} // namespace hooks
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
||||||
#endif
|
#endif
|
@ -34,7 +34,7 @@ namespace wxhelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
int content_length = data.post_data.size();
|
size_t content_length = data.post_data.size();
|
||||||
mg_printf(c,
|
mg_printf(c,
|
||||||
"POST %s HTTP/1.0\r\n"
|
"POST %s HTTP/1.0\r\n"
|
||||||
"Host: %.*s\r\n"
|
"Host: %.*s\r\n"
|
||||||
|
@ -6,10 +6,21 @@
|
|||||||
#include "hooks.h"
|
#include "hooks.h"
|
||||||
#include "db.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 STR2LL(str) (wxhelper::Utils::IsDigit(str) ? stoll(str) : 0)
|
||||||
|
#define STR2I(str) (wxhelper::Utils::IsDigit(str) ? stoi(str) : 0)
|
||||||
namespace common = wxhelper::common;
|
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 GetINT64Param(nlohmann::json data, std::string key) {
|
||||||
INT64 result;
|
INT64 result;
|
||||||
@ -21,6 +32,16 @@ INT64 GetINT64Param(nlohmann::json data, std::string key) {
|
|||||||
return result;
|
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) {
|
std::string GetStringParam(nlohmann::json data, std::string key) {
|
||||||
return data[key].get<std::string>();
|
return data[key].get<std::string>();
|
||||||
}
|
}
|
||||||
@ -29,6 +50,14 @@ std::wstring GetWStringParam(nlohmann::json data, std::string key) {
|
|||||||
return wxhelper::Utils::UTF8ToWstring(data[key].get<std::string>());
|
return wxhelper::Utils::UTF8ToWstring(data[key].get<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::wstring> GetArrayParam(nlohmann::json data, std::string key) {
|
||||||
|
std::vector<std::wstring> result;
|
||||||
|
std::wstring param = GetWStringParam(data, key);
|
||||||
|
result = wxhelper::Utils::split(param, L',');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void StartHttpServer(wxhelper::HttpServer *server) {
|
void StartHttpServer(wxhelper::HttpServer *server) {
|
||||||
int port = server->GetPort();
|
int port = server->GetPort();
|
||||||
std::string lsten_addr = "http://0.0.0.0:" + std::to_string(port);
|
std::string lsten_addr = "http://0.0.0.0:" + std::to_string(port);
|
||||||
@ -123,7 +152,8 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
|||||||
return ret;
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/userInfo")) {
|
} else if (mg_http_match_uri(hm, "/api/userInfo")) {
|
||||||
common::SelfInfoInner self_info;
|
common::SelfInfoInner self_info;
|
||||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->GetSelfInfo(self_info);
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->GetSelfInfo(self_info);
|
||||||
nlohmann::json ret_data = {
|
nlohmann::json ret_data = {
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
if (success) {
|
if (success) {
|
||||||
@ -148,39 +178,53 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
|||||||
} else if (mg_http_match_uri(hm, "/api/sendTextMsg")) {
|
} else if (mg_http_match_uri(hm, "/api/sendTextMsg")) {
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||||
std::wstring msg = GetWStringParam(j_param, "msg");
|
std::wstring msg = GetWStringParam(j_param, "msg");
|
||||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendTextMsg(wxid, msg);
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->SendTextMsg(wxid, msg);
|
||||||
nlohmann::json ret_data = {
|
nlohmann::json ret_data = {
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/hookSyncMsg")) {
|
} else if (mg_http_match_uri(hm, "/api/hookSyncMsg")) {
|
||||||
INT64 success = wxhelper::hooks::HookSyncMsg("127.0.0.1",19099,"",3000,false);
|
int port = GetIntParam(j_param, "port");
|
||||||
nlohmann::json ret_data = {
|
std::string ip = GetStringParam(j_param, "ip");
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
int enable = GetIntParam(j_param, "enableHttp");
|
||||||
ret = ret_data.dump();
|
std::string url = "";
|
||||||
return ret;
|
int timeout = 0;
|
||||||
|
if (enable) {
|
||||||
|
url = GetStringParam(j_param, "url");
|
||||||
|
timeout = GetIntParam(j_param, "timeout");
|
||||||
|
}
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::hooks::HookSyncMsg(ip, port, url, timeout, enable);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/sendImagesMsg")) {
|
} else if (mg_http_match_uri(hm, "/api/sendImagesMsg")) {
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||||
std::wstring path = GetWStringParam(j_param, "imagePath");
|
std::wstring path = GetWStringParam(j_param, "imagePath");
|
||||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendImageMsg(wxid, path);
|
INT64 success =
|
||||||
nlohmann::json ret_data = {
|
wxhelper::GlobalContext::GetInstance().mgr->SendImageMsg(wxid, path);
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
nlohmann::json ret_data = {
|
||||||
ret = ret_data.dump();
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
return ret;
|
ret = ret_data.dump();
|
||||||
} else if (mg_http_match_uri(hm, "/api/sendFileMsg")) {
|
return ret;
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
} else if (mg_http_match_uri(hm, "/api/sendFileMsg")) {
|
||||||
std::wstring path = GetWStringParam(j_param, "filePath");
|
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->SendFileMsg(wxid, path);
|
std::wstring path = GetWStringParam(j_param, "filePath");
|
||||||
nlohmann::json ret_data = {
|
INT64 success =
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
wxhelper::GlobalContext::GetInstance().mgr->SendFileMsg(wxid, path);
|
||||||
ret = ret_data.dump();
|
nlohmann::json ret_data = {
|
||||||
return ret;
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
} else if (mg_http_match_uri(hm, "/api/getContactList")) {
|
ret = ret_data.dump();
|
||||||
std::vector<common::ContactInner> vec;
|
return ret;
|
||||||
INT64 success = wxhelper::GlobalContext::GetInstance().mgr->GetContacts(vec);
|
} else if (mg_http_match_uri(hm, "/api/getContactList")) {
|
||||||
nlohmann::json ret_data = {
|
std::vector<common::ContactInner> vec;
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
INT64 success =
|
||||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
wxhelper::GlobalContext::GetInstance().mgr->GetContacts(vec);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
|
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||||
nlohmann::json item = {
|
nlohmann::json item = {
|
||||||
{"customAccount", vec[i].custom_account},
|
{"customAccount", vec[i].custom_account},
|
||||||
{"encryptName", vec[i].encrypt_name},
|
{"encryptName", vec[i].encrypt_name},
|
||||||
@ -194,19 +238,19 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
|||||||
{"reserved2", vec[i].reserved2},
|
{"reserved2", vec[i].reserved2},
|
||||||
};
|
};
|
||||||
ret_data["data"].push_back(item);
|
ret_data["data"].push_back(item);
|
||||||
}
|
}
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/unhookSyncMsg")) {
|
} else if (mg_http_match_uri(hm, "/api/unhookSyncMsg")) {
|
||||||
INT64 success = wxhelper::hooks::UnHookSyncMsg();
|
INT64 success = wxhelper::hooks::UnHookSyncMsg();
|
||||||
nlohmann::json ret_data = {
|
nlohmann::json ret_data = {
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
{"code", success}, {"data", {}}, {"msg", "success"}};
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/getDBInfo")) {
|
} else if (mg_http_match_uri(hm, "/api/getDBInfo")) {
|
||||||
std::vector<void *> v_ptr = wxhelper::DB::GetInstance().GetDbHandles();
|
std::vector<void *> v_ptr = wxhelper::DB::GetInstance().GetDbHandles();
|
||||||
nlohmann::json ret_data = {{"data", nlohmann::json::array()}};
|
nlohmann::json ret_data = {{"data", nlohmann::json::array()}};
|
||||||
for (unsigned int i = 0; i < v_ptr.size(); i++) {
|
for (unsigned int i = 0; i < v_ptr.size(); i++) {
|
||||||
nlohmann::json db_info;
|
nlohmann::json db_info;
|
||||||
db_info["tables"] = nlohmann::json::array();
|
db_info["tables"] = nlohmann::json::array();
|
||||||
common::DatabaseInfo *db =
|
common::DatabaseInfo *db =
|
||||||
@ -222,40 +266,350 @@ std::string HttpDispatch(struct mg_connection *c, struct mg_http_message *hm) {
|
|||||||
db_info["tables"].push_back(table_info);
|
db_info["tables"].push_back(table_info);
|
||||||
}
|
}
|
||||||
ret_data["data"].push_back(db_info);
|
ret_data["data"].push_back(db_info);
|
||||||
}
|
}
|
||||||
ret_data["code"] = 1;
|
ret_data["code"] = 1;
|
||||||
ret_data["msg"] = "success";
|
ret_data["msg"] = "success";
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
} else if (mg_http_match_uri(hm, "/api/execSql")) {
|
} else if (mg_http_match_uri(hm, "/api/execSql")) {
|
||||||
UINT64 db_handle = GetINT64Param(j_param, "dbHandle");
|
UINT64 db_handle = GetINT64Param(j_param, "dbHandle");
|
||||||
std::string sql = GetStringParam(j_param, "sql");
|
std::string sql = GetStringParam(j_param, "sql");
|
||||||
std::vector<std::vector<std::string>> items;
|
std::vector<std::vector<std::string>> items;
|
||||||
int success = wxhelper::DB::GetInstance().Select(db_handle, sql.c_str(), items);
|
int success =
|
||||||
nlohmann::json ret_data = {
|
wxhelper::DB::GetInstance().Select(db_handle, sql.c_str(), items);
|
||||||
{"data", nlohmann::json::array()}, {"code", success}, {"msg", "success"}};
|
nlohmann::json ret_data = {{"data", nlohmann::json::array()},
|
||||||
if (success == 0) {
|
{"code", success},
|
||||||
|
{"msg", "success"}};
|
||||||
|
if (success == 0) {
|
||||||
ret_data["msg"] = "no data";
|
ret_data["msg"] = "no data";
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
for (auto it : items) {
|
for (auto it : items) {
|
||||||
nlohmann::json temp_arr = nlohmann::json::array();
|
nlohmann::json temp_arr = nlohmann::json::array();
|
||||||
for (size_t i = 0; i < it.size(); i++) {
|
for (size_t i = 0; i < it.size(); i++) {
|
||||||
temp_arr.push_back(it[i]);
|
temp_arr.push_back(it[i]);
|
||||||
}
|
}
|
||||||
ret_data["data"].push_back(temp_arr);
|
ret_data["data"].push_back(temp_arr);
|
||||||
}
|
}
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else if (mg_http_match_uri(hm, "/api/getChatRoomDetailInfo")) {
|
||||||
nlohmann::json ret_data = {
|
std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
{"code", 200}, {"data", {}}, {"msg", "not support url"}};
|
common::ChatRoomInfoInner chat_room_detail;
|
||||||
ret = ret_data.dump();
|
INT64 success =
|
||||||
return ret;
|
wxhelper::GlobalContext::GetInstance().mgr->GetChatRoomDetailInfo(
|
||||||
}
|
chat_room_id, chat_room_detail);
|
||||||
nlohmann::json ret_data = {
|
nlohmann::json ret_data = {
|
||||||
{"code", 200}, {"data", {}}, {"msg", "unreachable code."}};
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
ret = ret_data.dump();
|
|
||||||
return ret;
|
nlohmann::json detail = {
|
||||||
|
{"chatRoomId", chat_room_detail.chat_room_id},
|
||||||
|
{"notice", chat_room_detail.notice},
|
||||||
|
{"admin", chat_room_detail.admin},
|
||||||
|
{"xml", chat_room_detail.xml},
|
||||||
|
};
|
||||||
|
ret_data["data"] = detail;
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/addMemberToChatRoom")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||||
|
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->AddMemberToChatRoom(
|
||||||
|
room_id, wxid_list);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/modifyNickname")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
||||||
|
std::wstring nickName = GetWStringParam(j_param, "nickName");
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->ModChatRoomMemberNickName(
|
||||||
|
room_id, wxid, nickName);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/delMemberFromChatRoom")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||||
|
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->DelMemberFromChatRoom(
|
||||||
|
room_id, wxid_list);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/getMemberFromChatRoom")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
common::ChatRoomMemberInner member;
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->GetMemberFromChatRoom(
|
||||||
|
room_id, member);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
if (success >= 0) {
|
||||||
|
nlohmann::json member_info = {
|
||||||
|
{"admin", member.admin},
|
||||||
|
{"chatRoomId", member.chat_room_id},
|
||||||
|
{"members", member.member},
|
||||||
|
{"adminNickname", member.admin_nickname},
|
||||||
|
{"memberNickname", member.member_nickname},
|
||||||
|
};
|
||||||
|
ret_data["data"] = member_info;
|
||||||
|
}
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/topMsg")) {
|
||||||
|
INT64 msg_id = GetINT64Param(j_param, "msgId");
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->SetTopMsg(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/removeTopMsg")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
INT64 msg_id = GetINT64Param(j_param, "msgId");
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->RemoveTopMsg(room_id,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/InviteMemberToChatRoom")) {
|
||||||
|
std::wstring room_id = GetWStringParam(j_param, "chatRoomId");
|
||||||
|
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->InviteMemberToChatRoom(
|
||||||
|
room_id, wxids);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/hookLog")) {
|
||||||
|
int success = wxhelper::hooks::HookLog();
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/unhookLog")) {
|
||||||
|
int success = wxhelper::hooks::UnHookLog();
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} else if (mg_http_match_uri(hm, "/api/createChatRoom")) {
|
||||||
|
std::vector<std::wstring> wxids = GetArrayParam(j_param, "memberIds");
|
||||||
|
INT64 success =
|
||||||
|
wxhelper::GlobalContext::GetInstance().mgr->CreateChatRoom(wxids);
|
||||||
|
nlohmann::json ret_data = {
|
||||||
|
{"code", success}, {"msg", "success"}, {"data", {}}};
|
||||||
|
ret = ret_data.dump();
|
||||||
|
return ret;
|
||||||
|
} 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;
|
||||||
}
|
}
|
970
src/manager.cc
970
src/manager.cc
File diff suppressed because it is too large
Load Diff
@ -13,8 +13,61 @@ class Manager {
|
|||||||
INT64 SendImageMsg(const std::wstring& wxid, const std::wstring& image_path);
|
INT64 SendImageMsg(const std::wstring& wxid, const std::wstring& image_path);
|
||||||
INT64 SendFileMsg(const std::wstring& wxid, const std::wstring& file_path);
|
INT64 SendFileMsg(const std::wstring& wxid, const std::wstring& file_path);
|
||||||
INT64 GetContacts(std::vector<common::ContactInner> &vec);
|
INT64 GetContacts(std::vector<common::ContactInner> &vec);
|
||||||
|
INT64 GetChatRoomDetailInfo(const std::wstring& room_id,
|
||||||
|
common::ChatRoomInfoInner& room_info);
|
||||||
|
INT64 AddMemberToChatRoom(const std::wstring& room_id,
|
||||||
|
const std::vector<std::wstring>& members);
|
||||||
|
|
||||||
|
INT64 ModChatRoomMemberNickName(const std::wstring& room_id,
|
||||||
|
const std::wstring& wxid,
|
||||||
|
const std::wstring& nickname);
|
||||||
|
INT64 DelMemberFromChatRoom(const std::wstring& room_id,
|
||||||
|
const std::vector<std::wstring>& members);
|
||||||
|
INT64 GetMemberFromChatRoom(const std::wstring& room_id,
|
||||||
|
common::ChatRoomMemberInner& member);
|
||||||
|
INT64 SetTopMsg(ULONG64 msg_id);
|
||||||
|
INT64 RemoveTopMsg(const std::wstring& room_id,ULONG64 msg_id);
|
||||||
|
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:
|
private:
|
||||||
UINT64 base_addr_;
|
UINT64 base_addr_;
|
||||||
|
UINT64 js_api_addr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
||||||
|
138
src/utils.cc
138
src/utils.cc
@ -1,6 +1,7 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
|
#include <Psapi.h>
|
||||||
#define BUFSIZE 1024
|
#define BUFSIZE 1024
|
||||||
#define JPEG0 0xFF
|
#define JPEG0 0xFF
|
||||||
#define JPEG1 0xD8
|
#define JPEG1 0xD8
|
||||||
@ -319,4 +320,141 @@ std::string Utils::ReadWstringThenConvert(INT64 addr){
|
|||||||
std::wstring wstr = ReadWstring(addr);
|
std::wstring wstr = ReadWstring(addr);
|
||||||
return WstringToUTF8(wstr);
|
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
|
} // namespace wxhelper
|
21
src/utils.h
21
src/utils.h
@ -46,9 +46,9 @@ class Utils {
|
|||||||
|
|
||||||
static std::string WCharToUTF8(wchar_t *wstr);
|
static std::string WCharToUTF8(wchar_t *wstr);
|
||||||
|
|
||||||
static bool IsTextUtf8(const char * str,INT64 length) ;
|
static bool IsTextUtf8(const char *str, INT64 length);
|
||||||
|
|
||||||
static void Hide(HMODULE module);
|
static void Hide(HMODULE module);
|
||||||
|
|
||||||
static std::string ReadSKBuiltinString(INT64 addr);
|
static std::string ReadSKBuiltinString(INT64 addr);
|
||||||
static std::string ReadSKBuiltinBuffer(INT64 addr);
|
static std::string ReadSKBuiltinBuffer(INT64 addr);
|
||||||
@ -57,8 +57,15 @@ class Utils {
|
|||||||
static std::string ImageXor(std::string buf);
|
static std::string ImageXor(std::string buf);
|
||||||
static std::wstring ReadWstring(INT64 addr);
|
static std::wstring ReadWstring(INT64 addr);
|
||||||
static std::string ReadWstringThenConvert(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>
|
template <typename T1, typename T2>
|
||||||
static std::vector<T1> split(T1 str, T2 letter) {
|
static std::vector<T1> split(T1 str, T2 letter) {
|
||||||
std::vector<T1> arr;
|
std::vector<T1> arr;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
while ((pos = str.find_first_of(letter)) != T1::npos) {
|
while ((pos = str.find_first_of(letter)) != T1::npos) {
|
||||||
@ -71,7 +78,7 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
static T1 replace(T1 source, T2 replaced, T1 replaceto) {
|
static T1 replace(T1 source, T2 replaced, T1 replaceto) {
|
||||||
std::vector<T1> v_arr = split(source, replaced);
|
std::vector<T1> v_arr = split(source, replaced);
|
||||||
if (v_arr.size() < 2) return source;
|
if (v_arr.size() < 2) return source;
|
||||||
T1 temp;
|
T1 temp;
|
||||||
@ -82,6 +89,12 @@ class Utils {
|
|||||||
temp += v_arr[v_arr.size() - 1];
|
temp += v_arr[v_arr.size() - 1];
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static T *WxHeapAlloc(size_t n) {
|
||||||
|
return (T *)HeapAlloc(GetProcessHeap(), 0, n);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
||||||
#endif
|
#endif
|
@ -112,7 +112,7 @@ struct SqlResult {
|
|||||||
|
|
||||||
struct InnerMessageStruct {
|
struct InnerMessageStruct {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int length;
|
INT64 length;
|
||||||
~InnerMessageStruct() {
|
~InnerMessageStruct() {
|
||||||
if (this->buffer != NULL) {
|
if (this->buffer != NULL) {
|
||||||
delete[] this->buffer;
|
delete[] this->buffer;
|
||||||
@ -161,6 +161,53 @@ struct ContactInner {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChatRoomInfoInner {
|
||||||
|
std::string chat_room_id;
|
||||||
|
std::string notice;
|
||||||
|
std::string admin;
|
||||||
|
std::string xml;
|
||||||
|
ChatRoomInfoInner(){
|
||||||
|
chat_room_id = "";
|
||||||
|
notice = "";
|
||||||
|
admin = "";
|
||||||
|
xml = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VectorInner {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
INT64 head;
|
||||||
|
#endif
|
||||||
|
INT64 start;
|
||||||
|
INT64 finsh;
|
||||||
|
INT64 end;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ChatRoomMemberInner {
|
||||||
|
std::string chat_room_id;
|
||||||
|
std::string admin;
|
||||||
|
std::string admin_nickname;
|
||||||
|
std::string member_nickname;
|
||||||
|
std::string member;
|
||||||
|
ChatRoomMemberInner()
|
||||||
|
: chat_room_id(""),
|
||||||
|
admin(""),
|
||||||
|
admin_nickname(""),
|
||||||
|
member_nickname(""),
|
||||||
|
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 common
|
||||||
namespace V3_9_5_81 {
|
namespace V3_9_5_81 {
|
||||||
namespace function {
|
namespace function {
|
||||||
@ -184,6 +231,62 @@ typedef UINT64(*__Free)();
|
|||||||
typedef UINT64 (*__GetContactMgr)();
|
typedef UINT64 (*__GetContactMgr)();
|
||||||
typedef UINT64 (*__GetContactList)(UINT64,UINT64);
|
typedef UINT64 (*__GetContactList)(UINT64,UINT64);
|
||||||
|
|
||||||
|
typedef UINT64 (*__GetChatRoomMgr)();
|
||||||
|
typedef UINT64 (*__NewChatRoomInfo)(UINT64);
|
||||||
|
typedef UINT64 (*__FreeChatRoomInfo)(UINT64);
|
||||||
|
typedef UINT64 (*__GetChatRoomDetailInfo)(UINT64,UINT64,UINT64,UINT64);
|
||||||
|
typedef UINT64 (*__DoAddMemberToChatRoom)(UINT64,UINT64,UINT64,UINT64);
|
||||||
|
|
||||||
|
typedef UINT64 (*__DoModChatRoomMemberNickName)(UINT64,UINT64,UINT64,UINT64);
|
||||||
|
typedef UINT64 (*__DoDelMemberFromChatRoom)(UINT64,UINT64,UINT64);
|
||||||
|
typedef UINT64 (*__GetMemberFromChatRoom)(UINT64,UINT64,UINT64);
|
||||||
|
typedef UINT64 (*__NewChatRoom)(UINT64);
|
||||||
|
typedef UINT64 (*__FreeChatRoom)(UINT64);
|
||||||
|
|
||||||
|
typedef UINT64 (*__DoTopMsg)(UINT64,UINT64);
|
||||||
|
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
|
} // namespace function
|
||||||
namespace prototype {
|
namespace prototype {
|
||||||
|
|
||||||
@ -221,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 prototype
|
||||||
namespace offset {
|
namespace offset {
|
||||||
const UINT64 kGetAccountServiceMgr = 0x8c1230;
|
const UINT64 kGetAccountServiceMgr = 0x8c1230;
|
||||||
@ -254,20 +377,75 @@ const UINT64 k_sqlite3_column_blob = 0x24f2ba0;
|
|||||||
const UINT64 k_sqlite3_column_bytes = 0x24f2c90;
|
const UINT64 k_sqlite3_column_bytes = 0x24f2c90;
|
||||||
const UINT64 k_sqlite3_finalize = 0x24f1400;
|
const UINT64 k_sqlite3_finalize = 0x24f1400;
|
||||||
|
|
||||||
const UINT64 kGPInstance = 0x3a6f908;
|
const UINT64 kGPInstance = 0x3a6f908;
|
||||||
const UINT64 kMicroMsgDB= 0xb8;
|
const UINT64 kMicroMsgDB = 0xb8;
|
||||||
const UINT64 kChatMsgDB = 0x2c8;
|
const UINT64 kChatMsgDB = 0x2c8;
|
||||||
const UINT64 kMiscDB = 0x5f0;
|
const UINT64 kMiscDB = 0x5f0;
|
||||||
const UINT64 kEmotionDB = 0x838;
|
const UINT64 kEmotionDB = 0x838;
|
||||||
const UINT64 kMediaDB = 0xef8;
|
const UINT64 kMediaDB = 0xef8;
|
||||||
const UINT64 kBizchatMsgDB = 0x1a70;
|
const UINT64 kBizchatMsgDB = 0x1a70;
|
||||||
const UINT64 kFunctionMsgDB = 0x1b48;
|
const UINT64 kFunctionMsgDB = 0x1b48;
|
||||||
const UINT64 kDBName = 0x28;
|
const UINT64 kDBName = 0x28;
|
||||||
const UINT64 kStorageStart = 0x0;
|
const UINT64 kStorageStart = 0x0;
|
||||||
const UINT64 kStorageEnd= 0x0;
|
const UINT64 kStorageEnd = 0x0;
|
||||||
const UINT64 kMultiDBMgr= 0x3acfb68;
|
const UINT64 kMultiDBMgr = 0x3acfb68;
|
||||||
const UINT64 kPublicMsgMgr= 0x3acc268;
|
const UINT64 kPublicMsgMgr = 0x3acc268;
|
||||||
const UINT64 kFavoriteStorageMgr= 0x3acf0d0;
|
const UINT64 kFavoriteStorageMgr = 0x3acf0d0;
|
||||||
|
|
||||||
|
const UINT64 kChatRoomMgr = 0x8e9d30;
|
||||||
|
const UINT64 kGetChatRoomDetailInfo = 0xe73590;
|
||||||
|
const UINT64 kNewChatRoomInfo = 0x12006b0;
|
||||||
|
const UINT64 kFreeChatRoomInfo = 0x1200890;
|
||||||
|
const UINT64 kDoAddMemberToChatRoom = 0xe63c70;
|
||||||
|
const UINT64 kDoModChatRoomMemberNickName = 0xe6db00;
|
||||||
|
const UINT64 kDelMemberFromChatRoom = 0xe64290;
|
||||||
|
const UINT64 kGetMemberFromChatRoom = 0xe74de0;
|
||||||
|
const UINT64 kNewChatRoom = 0x11fde50;
|
||||||
|
const UINT64 kFreeChatRoom = 0x11fe030;
|
||||||
|
|
||||||
|
const UINT64 kTopMsg = 0xa5e4f0;
|
||||||
|
const UINT64 kRemoveTopMsg = 0xe787b0;
|
||||||
|
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 offset
|
||||||
} // namespace V3_9_5_81
|
} // namespace V3_9_5_81
|
||||||
|
BIN
tool/injector/ConsoleApplication.exe
Normal file
BIN
tool/injector/ConsoleApplication.exe
Normal file
Binary file not shown.
@ -1 +1,14 @@
|
|||||||
## 可以使用对应分支下的注入工具,或者自己编译一下 source目录下的注入程序。
|
## 可以使用对应分支下的注入工具,或者自己编译一下 source目录下的注入程序。
|
||||||
|
|
||||||
|
1.ConsoleApplication.exe
|
||||||
|
编译好的x64版本的注入器
|
||||||
|
命令行注入工具,注入命令
|
||||||
|
``` javascript
|
||||||
|
//-i 注入程序名 -p 注入dll路径
|
||||||
|
// -u 卸载程序名 -d 卸载dll名称
|
||||||
|
//注入
|
||||||
|
ConsoleInject.exe -i demo.exe -p E:\wxhelper.dll
|
||||||
|
//卸载
|
||||||
|
ConsoleInject.exe -u demo.exe -d wxhelper.dll
|
||||||
|
|
||||||
|
```
|
BIN
tool/injector/微信DLL注入器V1.0.3.exe
Normal file
BIN
tool/injector/微信DLL注入器V1.0.3.exe
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user