Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebde430aec | ||
|
|
1216733b82 | ||
|
|
6dca99474b | ||
|
|
d818c826e5 | ||
|
|
b0e73002ff | ||
|
|
a2cfb13217 | ||
|
|
911f87211c | ||
|
|
2f1793b2b1 | ||
|
|
6b36287c4d | ||
|
|
d86d4c0bf6 | ||
|
|
f82f85b2b6 | ||
|
|
c508ae30f8 | ||
|
|
c05e9ce303 | ||
|
|
4758fbf005 | ||
|
|
088a7d28cb | ||
|
|
a9b01eebe1 | ||
|
|
8b68a347a0 | ||
|
|
fd66a641f6 | ||
|
|
ab3780c413 | ||
|
|
e62a37b354 |
@@ -30,3 +30,6 @@
|
||||
#*.exe
|
||||
*.out
|
||||
*.app
|
||||
/out
|
||||
CMakePresets.json
|
||||
.vscode
|
||||
+1
-1
@@ -11,7 +11,7 @@ file(GLOB CPP_FILES ${PROJECT_SOURCE_DIR}/src/*.cc ${PROJECT_SOURCE_DIR}/src/*
|
||||
|
||||
|
||||
|
||||
include_directories(c:/soft/vcpkg/installed/x86-windows/include)
|
||||
include_directories(${VCPKG_INSTALLED_DIR}/x86-windows/include)
|
||||
|
||||
# add_subdirectory(3rd)
|
||||
|
||||
|
||||
@@ -1,33 +1,126 @@
|
||||
# wxhelper
|
||||
wechat hook .
|
||||
wechat hook 。PC端微信逆向学习。支持3.8.0.41,3.8.1.26版本。
|
||||
#### 免责声明:
|
||||
本仓库发布的内容,仅用于学习研究,请勿用于非法用途和商业用途!如因此产生任何法律纠纷,均与作者无关!
|
||||
|
||||
#### 项目说明:
|
||||
本项目是个人学习学习逆向的项目,主要参考https://github.com/ttttupup/ComWeChatRobot,在此基础上实现了wechat 3.8.0.41的版本的部分内容。
|
||||
本项目是个人学习学习逆向的项目,主要参考https://github.com/ttttupup/ComWeChatRobot,在此基础上实现了微信的的其它版本的部分内容。
|
||||
|
||||
#### 使用说明:
|
||||
支持的版本3.8.0.41,目前是最新版本。
|
||||
支持的版本3.8.0.41,3.8.1.26。
|
||||
src:主要的dll代码
|
||||
tool:简单的注入工具,一个是控制台,一个是图形界面。
|
||||
python: 简单的服务器,用以接收消息内容。
|
||||
release:编译好的dll。
|
||||
|
||||
1.通过cmake构建成功后,将wxhelper.dll注入到微信,本地启动tcp server,监听19088端口。
|
||||
2.通过http协议与dll通信,方便客户端操作。
|
||||
3.接口的url为http://127.0.0.1:19088,注入成功后,直接进行调用即可。
|
||||
4.特别注意数据库查询接口需要先调用获取到句柄之后,才能进行查询。
|
||||
5.相关功能只在win11环境下进行简单测试,其他环境无法保证。
|
||||
0.首先安装对应的微信版本,主分支是3.8.0.41版本,3.8.1.26分支对应3.8.1.26版本。
|
||||
1.通过cmake构建成功后,将wxhelper.dll注入到微信,本地启动tcp server,监听19088端口。
|
||||
2.通过http协议与dll通信,方便客户端操作。
|
||||
3.接口的url为http://127.0.0.1:19088,注入成功后,直接进行调用即可。
|
||||
4.特别注意数据库查询接口需要先调用获取到句柄之后,才能进行查询。
|
||||
5.相关功能只在win11环境下进行简单测试,其他环境无法保证。
|
||||
6.注意个别接口在3.8.0.41版本没有实现,具体参考源码。
|
||||
7.对应分支接口文档都是支持指定版本的,其他版本不支持,请特别注意版本。
|
||||
|
||||
#### 编译环境
|
||||
|
||||
Visual Studio 2022(x86)
|
||||
Visual Studio code
|
||||
cmake
|
||||
vcpkg
|
||||
Visual Studio 2022(x86)
|
||||
|
||||
Visual Studio code
|
||||
|
||||
cmake
|
||||
|
||||
vcpkg
|
||||
#### 构建步骤
|
||||
以下是在vscode中操作,vs中的操作类似。
|
||||
1.安装vcpkg,cmake,vscode
|
||||
|
||||
2.安装相应的库,如果安装的版本不同,则根据vcpkg安装成功后提示的find_package修改CMakeLists.txt内容即可。或者自己编译。
|
||||
```
|
||||
vcpkg install mongoose
|
||||
vcpkg install nlohmann-json
|
||||
```
|
||||
3.vscode 配置CMakePresets.json,主要设置CMAKE_C_COMPILER 和CMAKE_CXX_COMPILER 为cl.exe.参考如下
|
||||
```
|
||||
{
|
||||
"name": "x86-release",
|
||||
"displayName": "x86-release",
|
||||
"description": "Sets Ninja generator, build and install directory",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"architecture":{
|
||||
"value": "x86",
|
||||
"strategy": "external"
|
||||
},
|
||||
"cacheVariables": {
|
||||
"CMAKE_C_COMPILER": "cl.exe",
|
||||
"CMAKE_CXX_COMPILER": "cl.exe",
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}",
|
||||
"CMAKE_TOOLCHAIN_FILE": {
|
||||
"value": "C:/soft/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||
"type": "FILEPATH"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
4.vscode中右键configure all projects,在Terminal中点击Run Task,如没有先配置build任务,然后运行即可
|
||||
|
||||
5.命令行注入工具,注入命令
|
||||
``` javascript
|
||||
//-i 注入程序名 -p 注入dll路径
|
||||
// -u 卸载程序名 -d 卸载dll名称
|
||||
//注入
|
||||
ConsoleInject.exe -i demo.exe -p E:\testInject.dll
|
||||
//卸载
|
||||
ConsoleInject.exe -u demo.exe -d testInject.dll
|
||||
```
|
||||
|
||||
#### 更新说明
|
||||
2022-12-26 : 增加3.8.1.26版本支持。
|
||||
|
||||
2022-12-29 : 新增提取文字功能。
|
||||
|
||||
2023-01-02 : 退出微信登录。
|
||||
|
||||
2023-01-31 : 新增修改群昵称(仅支持3.8.1.26)。
|
||||
|
||||
2023-02-01 : 新增拍一拍(仅支持3.8.1.26)。
|
||||
|
||||
2023-02-04 : 新增群消息置顶和取消置顶。
|
||||
#### 功能预览:
|
||||
0.检查是否登录
|
||||
1.获取登录微信信息
|
||||
2.发送文本
|
||||
5.发送图片
|
||||
6.发送文件
|
||||
9.hook消息
|
||||
10.取消hook消息
|
||||
11.hook图片
|
||||
12.取消hook图片
|
||||
17.删除好友
|
||||
25.获取群成员
|
||||
27.删除群成员
|
||||
28.增加群成员
|
||||
31.修改群昵称
|
||||
32.获取数据库句柄
|
||||
34.查询数据库
|
||||
40.转发消息
|
||||
44.退出登录
|
||||
46.联系人列表
|
||||
47.获取群详情
|
||||
48.获取解密图片
|
||||
49.图片提取文字ocr
|
||||
50.拍一拍
|
||||
51.群消息置顶消息
|
||||
52.群消息取消置顶
|
||||
### 接口文档:
|
||||
|
||||
|
||||
#### 0.检查微信登录**
|
||||
###### 接口功能
|
||||
> 检查微信是否登录
|
||||
@@ -51,7 +144,6 @@ vcpkg
|
||||
|data|string|响应内容|
|
||||
|
||||
###### 接口示例
|
||||
地址:https://www.bincoding.cn/test
|
||||
入参:
|
||||
``` javascript
|
||||
```
|
||||
@@ -98,7 +190,6 @@ vcpkg
|
||||
|wxid|string|wxid|
|
||||
|
||||
###### 接口示例
|
||||
地址:https://www.bincoding.cn/test
|
||||
入参:
|
||||
``` javascript
|
||||
```
|
||||
@@ -134,7 +225,7 @@ vcpkg
|
||||
|
||||
|
||||
###### 接口示例
|
||||
地址:https://www.bincoding.cn/test
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
@@ -238,7 +329,7 @@ vcpkg
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|port |ture |string| 本地服务端端口,用来接收消息内容 |
|
||||
|
||||
|ip |ture |string| 服务端ip地址,用来接收消息内容,可以是任意ip,即tcp客户端连接的服务端的ip (3.8.1.26版本)|
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
@@ -252,6 +343,7 @@ vcpkg
|
||||
``` javascript
|
||||
{
|
||||
"port": "19099"
|
||||
"ip":"127.0.0.1"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
@@ -260,6 +352,38 @@ vcpkg
|
||||
```
|
||||
|
||||
|
||||
#### 10.取消hook消息**
|
||||
###### 接口功能
|
||||
> 取消hook消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=10](/api/?type=10)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
#### 11.hook图片**
|
||||
###### 接口功能
|
||||
@@ -297,6 +421,38 @@ vcpkg
|
||||
```
|
||||
|
||||
|
||||
#### 12.取消hook图片**
|
||||
###### 接口功能
|
||||
> 取消hook图片
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=12](/api/?type=12)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
#### 17.删除好友**
|
||||
###### 接口功能
|
||||
@@ -453,6 +609,43 @@ vcpkg
|
||||
```
|
||||
|
||||
|
||||
#### 31.修改自身群昵称**
|
||||
###### 接口功能
|
||||
> 修改群名片
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=31](/api/?type=31)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |ture |string| 群id |
|
||||
|wxid |ture |string| 自己的id,只能修改自己的群名片 |
|
||||
|nickName |ture |string| 修改的昵称 |
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId":"34932563384@chatroom",
|
||||
"wxid":"wxid_272211111121112",
|
||||
"nickName":"昵称test"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -555,6 +748,80 @@ vcpkg
|
||||
```
|
||||
|
||||
|
||||
#### 40.转发消息**
|
||||
###### 接口功能
|
||||
> 直接转发消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=40](/api/?type=40)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid |ture |string| 消息接收人wxid |
|
||||
|msgid |ture |number| 消息id,hook消息接口中返回的消息id |
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,非0成功|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"wxid": "filehelper",
|
||||
"msgid":7215505498606506901
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":4344,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 44.退出登录**
|
||||
###### 接口功能
|
||||
> 退出登录微信,相当于直接退出微信,跟手动退出比,少了重新打开登录的一步,dll注入后也会随微信关闭而关闭。调用后不能再继续操作dll。
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=44](/api/?type=44)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,非0成功|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":4344,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 46.联系人列表**
|
||||
###### 接口功能
|
||||
@@ -682,7 +949,146 @@ vcpkg
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 49.提取文字**
|
||||
###### 接口功能
|
||||
> 提取图片中的文字
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=49](/api/?type=49)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|imagePath |ture |string| 图片路径 |
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,0成功, -1失败,1 2 则是缓存或者正在进行中需再调用一次|
|
||||
|result|string|成功提示|
|
||||
|text|string|提取的相应文字|
|
||||
|
||||
|
||||
#### 50.拍一拍**
|
||||
###### 接口功能
|
||||
> 群里拍一拍用户
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=50](/api/?type=50)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |ture |string| 微信群聊id |
|
||||
|wxid |ture |string| 要拍的用户wxid,如果使用用户自定义的微信号,则不会显示群内昵称 |
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, -1失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId":"123331@chatroom",
|
||||
"wxid":"wxid_123456"
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 51.群内消息置顶**
|
||||
###### 接口功能
|
||||
> 在群聊里置顶某条消息,可以置顶文字和图片消息,其他消息未测试,部分低版本移动端置顶消息点击后会直接取消,高版本会一直置顶,其他未测试。
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=51](/api/?type=51)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|wxid |ture |string| 置顶消息的发送人wxid |
|
||||
|msgid |ture |string| 消息id |
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,0成功, -1失败,-2 未查到该消息|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"wxid":"wxid_oy11111p4422",
|
||||
"msgid":3334956046278903121
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":0,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 52.取消群内消息置顶**
|
||||
###### 接口功能
|
||||
> 取消置顶的消息。部分低版本移动端会不显示移除消息,但是会正常移除。
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=52](/api/?type=52)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |ture |string| 微信群聊id |
|
||||
|msgid |ture |string| 消息id |
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,0成功, -1失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId":"2136311004@chatroom",
|
||||
"msgid":3374951233278903120
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":0,"result":"OK"}
|
||||
```
|
||||
|
||||
#### 感谢
|
||||
https://github.com/ljc545w/ComWeChatRobot
|
||||
https://github.com/NationalSecurityAgency/ghidra
|
||||
https://github.com/x64dbg/x64dbg
|
||||
https://github.com/ljc545w/ComWeChatRobot
|
||||
|
||||
https://github.com/NationalSecurityAgency/ghidra
|
||||
|
||||
https://github.com/x64dbg/x64dbg
|
||||
|
||||
Binary file not shown.
+49
-1
@@ -18,6 +18,8 @@
|
||||
#include "chat_room.h"
|
||||
#include "self_info.h"
|
||||
#include "hook_img.h"
|
||||
#include "ocr.h"
|
||||
#include "pat.h"
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
using namespace std;
|
||||
@@ -265,7 +267,11 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
}
|
||||
case WECHAT_MSG_START_HOOK: {
|
||||
int port = get_http_req_param_int(hm, j_param, "port", is_post);
|
||||
int success = HookRecvMsg(port);
|
||||
wstring ip = get_http_req_param(hm, j_param, "ip", is_post);
|
||||
string client_ip = Wstring2String(ip);
|
||||
char ip_cstr[16];
|
||||
strcpy_s(ip_cstr,client_ip.c_str());
|
||||
int success = HookRecvMsg(ip_cstr,port);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
@@ -380,6 +386,12 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CHATROOM_SET_SELF_NICKNAME: {
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
wstring nick = get_http_req_param(hm, j_param, "nickName", is_post);
|
||||
int success = ModChatRoomMemberNickName(WS2LW(room_id),WS2LW(wxid),WS2LW(nick));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_DATABASE_GET_HANDLES: {
|
||||
@@ -460,6 +472,9 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_LOGOUT: {
|
||||
int success = Logout();
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_TRANSFER: {
|
||||
@@ -535,6 +550,39 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
int success = GetImgByName(WS2LW(image_path),WS2LW(save_path));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_DO_OCR:{
|
||||
wstring image_path = get_http_req_param(hm, j_param, "imagePath", is_post);
|
||||
string text("");
|
||||
int success = DoOCRTask(WS2LW(image_path),text);
|
||||
json ret_data = {{"code", success}, {"result", "OK"},{"text",text}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_SEND_PAT_MSG:{
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
int success = SendPatMsg(WS2LW(room_id),WS2LW(wxid));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_SET_TOP_MSG:{
|
||||
wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
ULONG64 msgid = get_http_param_ulong64(hm, j_param, "msgid", is_post);
|
||||
int success = SetTopMsg(WS2LW(wxid),msgid);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_REMOVE_TOP_MSG:{
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
ULONG64 msgid = get_http_param_ulong64(hm, j_param, "msgid", is_post);
|
||||
int success = RemoveTopMsg(WS2LW(room_id),msgid);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -63,6 +63,10 @@ typedef enum WECHAT_HTTP_APISTag
|
||||
WECHAT_GET_CONTACT_ALL,
|
||||
WECHAT_GET_CHATROOM_INFO,
|
||||
WECHAT_GET_IMG_BY_NAME,
|
||||
WECHAT_DO_OCR,
|
||||
WECHAT_SEND_PAT_MSG,
|
||||
WECHAT_SET_TOP_MSG,
|
||||
WECHAT_REMOVE_TOP_MSG,
|
||||
} WECHAT_HTTP_APIS,
|
||||
*PWECHAT_HTTP_APIS;
|
||||
|
||||
|
||||
+193
-26
@@ -2,19 +2,26 @@
|
||||
#include "chat_room.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "get_db_handle.h"
|
||||
#include "wechat_data.h"
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x686e40
|
||||
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xa70920
|
||||
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xd03ec0
|
||||
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0x7226e0
|
||||
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xa668f0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x651c40
|
||||
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xa66400
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xa71650
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xd01c30
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xa79310
|
||||
#include "base64.h"
|
||||
using namespace std;
|
||||
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x67ee70
|
||||
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xa73a80
|
||||
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xd07010
|
||||
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xd072f0
|
||||
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xa69a50
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbf380
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x649ac0
|
||||
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xa69560
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xa749b0
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xd04d80
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xa7c620
|
||||
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xa6f8f0
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x64adc0
|
||||
#define WX_TOP_MSG_OFFSET 0xa76e60
|
||||
#define WX_REMOVE_TOP_MSG_OFFSET 0xa76c50
|
||||
|
||||
int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info) {
|
||||
int success = 0;
|
||||
@@ -24,7 +31,7 @@ int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info) {
|
||||
DWORD get_chat_room_detail_addr = base + WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET;
|
||||
DWORD create_chat_room_info_addr = base + WX_NEW_CHAT_ROOM_INFO_OFFSET;
|
||||
DWORD free_chat_room_info_addr = base + WX_FREE_CHAT_ROOM_INFO_OFFSET;
|
||||
char chat_room_info[0xA4] = {0};
|
||||
char chat_room_info[0xDC] = {0};
|
||||
__asm {
|
||||
PUSHAD
|
||||
LEA ECX,chat_room_info
|
||||
@@ -40,21 +47,54 @@ int GetChatRoomDetailInfo(wchar_t* chat_room_id, ChatRoomInfoInner& room_info) {
|
||||
MOV success,EAX
|
||||
POPAD
|
||||
}
|
||||
room_info.chat_room_id.ptr = *(wchar_t**)(chat_room_info + 0x4);
|
||||
room_info.chat_room_id.length = *(DWORD*)(chat_room_info + 0x8);
|
||||
room_info.chat_room_id.max_length = *(DWORD*)(chat_room_info + 0xC);
|
||||
DWORD room_id_len = *(DWORD*)(chat_room_info + 0x8);
|
||||
DWORD room_id_max_len = *(DWORD*)(chat_room_info + 0xC);
|
||||
wchar_t * room_id = new wchar_t[room_id_len + 1];
|
||||
wmemcpy(room_id,*(wchar_t**)(chat_room_info + 0x4),room_id_len + 1);
|
||||
room_info.chat_room_id.ptr = room_id;
|
||||
room_info.chat_room_id.length = room_id_len;
|
||||
room_info.chat_room_id.max_length = room_id_max_len;
|
||||
|
||||
|
||||
room_info.notice.ptr = *(wchar_t**)(chat_room_info + 0x18);
|
||||
room_info.notice.length = *(DWORD*)(chat_room_info + 0x1C);
|
||||
room_info.notice.max_length = *(DWORD*)(chat_room_info + 0x20);
|
||||
DWORD notice_len = *(DWORD*)(chat_room_info + 0x1C);
|
||||
DWORD notice_max_len = *(DWORD*)(chat_room_info + 0x20);
|
||||
wchar_t* notice_ptr = *(wchar_t**)(chat_room_info + 0x18);
|
||||
if(notice_len <= 0){
|
||||
room_info.notice.ptr = nullptr;
|
||||
}else{
|
||||
wchar_t * notice = new wchar_t[notice_len + 1];
|
||||
wmemcpy(notice,notice_ptr,notice_len+1);
|
||||
room_info.notice.ptr = notice;
|
||||
}
|
||||
room_info.notice.length = notice_len;
|
||||
room_info.notice.max_length = notice_max_len;
|
||||
|
||||
room_info.admin.ptr = *(wchar_t**)(chat_room_info + 0x2C);
|
||||
room_info.admin.length = *(DWORD*)(chat_room_info + 0x30);
|
||||
room_info.admin.max_length = *(DWORD*)(chat_room_info + 0x34);
|
||||
DWORD admin_len = *(DWORD*)(chat_room_info + 0x30);
|
||||
DWORD admin_max_len = *(DWORD*)(chat_room_info + 0x34);
|
||||
wchar_t* admin_ptr = *(wchar_t**)(chat_room_info + 0x2C);
|
||||
if(admin_len <= 0){
|
||||
room_info.admin.ptr = nullptr;
|
||||
}else{
|
||||
wchar_t * admin = new wchar_t[admin_len + 1];
|
||||
wmemcpy(admin,admin_ptr,admin_len+1);
|
||||
room_info.admin.ptr = admin;
|
||||
}
|
||||
room_info.admin.length = admin_len;
|
||||
room_info.admin.max_length = admin_max_len;
|
||||
|
||||
DWORD xml_len = *(DWORD*)(chat_room_info + 0x54);
|
||||
DWORD xml_max_len = *(DWORD*)(chat_room_info + 0x58);
|
||||
wchar_t* xml_ptr = *(wchar_t**)(chat_room_info + 0x50);
|
||||
if (xml_len <= 0){
|
||||
room_info.xml.ptr = nullptr;
|
||||
}else{
|
||||
wchar_t * xml = new wchar_t[xml_len + 1];
|
||||
wmemcpy(xml,xml_ptr,xml_len+1);
|
||||
room_info.xml.ptr = xml;
|
||||
}
|
||||
room_info.xml.length = xml_len;
|
||||
room_info.xml.max_length = xml_max_len;
|
||||
|
||||
room_info.xml.ptr = *(wchar_t**)(chat_room_info + 0x50);
|
||||
room_info.xml.length = *(DWORD*)(chat_room_info + 0x54);
|
||||
room_info.xml.max_length = *(DWORD*)(chat_room_info + 0x58);
|
||||
__asm {
|
||||
PUSHAD
|
||||
LEA ECX,chat_room_info
|
||||
@@ -144,7 +184,7 @@ int GetMemberFromChatRoom(wchar_t* chat_room_id,ChatRoomInner & out){
|
||||
int success = 0;
|
||||
WeChatString chat_room(chat_room_id);
|
||||
DWORD chat_room_ptr = (DWORD) &chat_room;
|
||||
char buffer[0x1A0] = {0};
|
||||
char buffer[0x1D4] = {0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD get_member_addr = base + WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET;
|
||||
DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET;
|
||||
@@ -182,3 +222,130 @@ int GetMemberFromChatRoom(wchar_t* chat_room_id,ChatRoomInner & out){
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
int ModChatRoomMemberNickName(wchar_t* chat_room_id,wchar_t* wxid,wchar_t * nick){
|
||||
int success = 0;
|
||||
WeChatString chat_room(chat_room_id);
|
||||
WeChatString self_wxid(wxid);
|
||||
WeChatString new_nick(nick);
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET;
|
||||
DWORD mod_member_nick_name_addr = base + WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL get_chat_room_mgr_addr
|
||||
SUB ESP,0x14
|
||||
MOV ECX,ESP
|
||||
LEA EDI,new_nick
|
||||
PUSH EDI
|
||||
CALL init_chat_msg_addr
|
||||
SUB ESP,0x14
|
||||
LEA EAX,self_wxid
|
||||
MOV ECX,ESP
|
||||
PUSH EAX
|
||||
CALL init_chat_msg_addr
|
||||
SUB ESP,0x14
|
||||
LEA EAX,chat_room
|
||||
MOV ECX,ESP
|
||||
PUSH EAX
|
||||
CALL init_chat_msg_addr
|
||||
CALL mod_member_nick_name_addr
|
||||
MOVZX EAX,AL
|
||||
MOV success,EAX
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
int SetTopMsg(wchar_t* wxid,ULONG64 msg_id){
|
||||
int success = -1;
|
||||
char chat_msg[0x2A8] ={0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD new_chat_msg_addr = base + WX_NEW_CHAT_MSG_OFFSET;
|
||||
DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET;
|
||||
DWORD handle_top_msg_addr = base + WX_TOP_MSG_OFFSET;
|
||||
DWORD free_addr = base + WX_FREE_CHAT_ROOM_OFFSET;
|
||||
vector<string> local_msg = GetChatMsgByMsgId(msg_id);
|
||||
if(local_msg.empty()){
|
||||
return -2;
|
||||
}
|
||||
string type = local_msg[3];
|
||||
string status = local_msg[10];
|
||||
string talker = local_msg[13];
|
||||
string content = local_msg[14];
|
||||
wstring w_talker = String2Wstring(talker);
|
||||
wstring w_content = String2Wstring(content);
|
||||
int msg_type =stoi(type);
|
||||
int msg_status =stoi(status);
|
||||
|
||||
#ifdef _DEBUG
|
||||
wcout << "w_talker:" <<w_talker <<endl;
|
||||
wcout << "w_content:" <<w_content <<endl;
|
||||
#endif
|
||||
WeChatString chat_room(w_talker);
|
||||
WeChatString msg_content(w_content);
|
||||
|
||||
WeChatString user_id(wxid);
|
||||
__asm{
|
||||
PUSHAD
|
||||
LEA ECX,chat_msg
|
||||
CALL new_chat_msg_addr
|
||||
POPAD
|
||||
}
|
||||
|
||||
memcpy(&chat_msg[0x30],&msg_id,sizeof(msg_id));
|
||||
memcpy(&chat_msg[0x38],&msg_type,sizeof(msg_type));
|
||||
memcpy(&chat_msg[0x40],&msg_status,sizeof(msg_status));
|
||||
memcpy(&chat_msg[0x48],&chat_room,sizeof(chat_room));
|
||||
|
||||
memcpy(&chat_msg[0x70],&msg_content,sizeof(msg_content));
|
||||
memcpy(&chat_msg[0x174],&user_id,sizeof(user_id));
|
||||
|
||||
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL get_chat_room_mgr_addr
|
||||
PUSH 0x1
|
||||
LEA EAX,chat_msg
|
||||
PUSH EAX
|
||||
CALL handle_top_msg_addr
|
||||
MOV success,EAX
|
||||
LEA ECX,chat_msg
|
||||
CALL free_addr
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
int RemoveTopMsg(wchar_t* chat_room_id,ULONG64 msg_id){
|
||||
|
||||
int success = -1;
|
||||
WeChatString chat_room(chat_room_id);
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET;
|
||||
DWORD new_chat_msg_addr = base + WX_NEW_CHAT_MSG_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
DWORD remove_top_msg_addr = base + WX_REMOVE_TOP_MSG_OFFSET;
|
||||
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL get_chat_room_mgr_addr
|
||||
MOV EDI,dword ptr [msg_id]
|
||||
LEA EAX,chat_room
|
||||
MOV ESI,dword ptr [msg_id + 0x4]
|
||||
SUB ESP,0x14
|
||||
MOV ECX,ESP
|
||||
PUSH EAX
|
||||
CALL init_chat_msg_addr
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
CALL remove_top_msg_addr
|
||||
MOV success,EAX
|
||||
POPAD
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -7,4 +7,8 @@ int DelMemberFromChatRoom(wchar_t* chat_room_id,wchar_t** wxids,int len);
|
||||
int AddMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids,int len);
|
||||
|
||||
int GetMemberFromChatRoom(wchar_t* chat_room_id,ChatRoomInner & out);
|
||||
int ModChatRoomMemberNickName(wchar_t* chat_room_id,wchar_t* wxid,wchar_t * nick);
|
||||
|
||||
int SetTopMsg(wchar_t* wxid,ULONG64 msg_id);
|
||||
int RemoveTopMsg(wchar_t* chat_room_id,ULONG64 msg_id);
|
||||
#endif
|
||||
+1
-1
@@ -25,7 +25,7 @@ wstring utf8_to_unicode(const char *buffer) {
|
||||
/// @param wstr unicode
|
||||
/// @return string utf8
|
||||
string unicode_to_utf8(wchar_t *wstr) {
|
||||
int c_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, FALSE);
|
||||
int c_size = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, FALSE);
|
||||
if (c_size > 0) {
|
||||
char *buffer = new char[c_size + 1];
|
||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, c_size, NULL, FALSE);
|
||||
|
||||
+7
-8
@@ -1,18 +1,17 @@
|
||||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
#include <string>
|
||||
using namespace std;
|
||||
#define READ_WSTRING(addr, offset) ((*(DWORD *)(addr + offset + 0x4) == 0) ? wstring(L"") : wstring((wchar_t *)(*(DWORD *)(addr + offset)), *(DWORD *)(addr + offset + 0x4)))
|
||||
#define READ_WSTRING(addr, offset) ((*(DWORD *)(addr + offset + 0x4) == 0) ? std::wstring(L"") : std::wstring((wchar_t *)(*(DWORD *)(addr + offset)), *(DWORD *)(addr + offset + 0x4)))
|
||||
|
||||
/// @brief utf8 转换成unicode
|
||||
/// @param buffer utf8
|
||||
/// @return unicode
|
||||
wstring utf8_to_unicode(const char *buffer);
|
||||
std::wstring utf8_to_unicode(const char *buffer);
|
||||
|
||||
/// @brief unicode转换utf8
|
||||
/// @param wstr unicode
|
||||
/// @return utf8
|
||||
string unicode_to_utf8(wchar_t *wstr);
|
||||
std::string unicode_to_utf8(wchar_t *wstr);
|
||||
|
||||
/// @brief 获取WeChatWin.dll基址
|
||||
/// @return 基址
|
||||
@@ -35,7 +34,7 @@ void UnHookAnyAddress(DWORD hook_addr, char *origin);
|
||||
/// @brief get timeW
|
||||
/// @param timestamp timestamp
|
||||
/// @return str
|
||||
wstring GetTimeW(long long timestamp);
|
||||
std::wstring GetTimeW(long long timestamp);
|
||||
/// @brief unicode trans utf8
|
||||
/// @param str unicode str
|
||||
/// @return utf8 str
|
||||
@@ -43,11 +42,11 @@ std::string UnicodeToUtf8(const wchar_t *str);
|
||||
/// @brief string convert wstring
|
||||
/// @param str
|
||||
/// @return
|
||||
wstring String2Wstring(string str);
|
||||
std::wstring String2Wstring(std::string str);
|
||||
/// @brief wstring convert string
|
||||
/// @param str
|
||||
/// @return
|
||||
string Wstring2String(wstring wstr);
|
||||
std::string Wstring2String(std::wstring wstr);
|
||||
|
||||
/// @brief create dir
|
||||
/// @param path
|
||||
@@ -56,7 +55,7 @@ BOOL FindOrCreateDirectoryW(const wchar_t *path);
|
||||
|
||||
|
||||
template <typename T1, typename T2>
|
||||
vector<T1> split(T1 str, T2 letter) {
|
||||
std::vector<T1> split(T1 str, T2 letter) {
|
||||
vector<T1> arr;
|
||||
size_t pos;
|
||||
while ((pos = str.find_first_of(letter)) != T1::npos) {
|
||||
|
||||
+7
-11
@@ -3,16 +3,12 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x655d60
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xa97da0
|
||||
#define WX_CONTACT_DEL_OFFSET 0xa9bd10
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40
|
||||
#define WX_DB_QUERY_OFFSET 0xa9ba20
|
||||
#define WX_SYNC_MGR_OFFSET 0x993fa0
|
||||
#define WX_SYNC_MGR_OFFSET 0x993fa0
|
||||
#define WX_DO_DEL_CONTACT_OFFSET 0xb9a750
|
||||
#define WX_DEL_CONTACT_VTABLE_OFFSET 0x2886990
|
||||
using namespace std;
|
||||
#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x64dc30
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xa9b000
|
||||
#define WX_CONTACT_DEL_OFFSET 0xa9ef40
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbf380
|
||||
#define WX_DB_QUERY_OFFSET 0xa9ec40
|
||||
int GetAllContact(vector<Contact> &vec) {
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD get_instance = base + WX_CONTACT_MGR_INSTANCE_OFFSET;
|
||||
@@ -66,7 +62,7 @@ int GetAllContact(vector<Contact> &vec) {
|
||||
temp.type = *(DWORD *)(start + 0x50);
|
||||
temp.verify_flag = *(DWORD *)(start + 0x54);
|
||||
vec.push_back(temp);
|
||||
start += 0x3E8;
|
||||
start += 0x438;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
#include <vector>
|
||||
#include "wechat_data.h"
|
||||
|
||||
int GetAllContact(vector<Contact> &vec);
|
||||
int GetAllContact(std::vector<Contact> &vec);
|
||||
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
#include "base64.h"
|
||||
#include "common.h"
|
||||
#include "new_sqlite3.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/// @brief free data
|
||||
void FreeResult(vector<vector<SqlResult>> &data) {
|
||||
@@ -15,11 +15,11 @@ void FreeResult(vector<vector<SqlResult>> &data) {
|
||||
for (unsigned j = 0; j < data[i].size(); j++) {
|
||||
SqlResult *sr = (SqlResult *)&data[i][j];
|
||||
if (sr->column_name) {
|
||||
delete sr->column_name;
|
||||
delete[] sr->column_name;
|
||||
sr->column_name = NULL;
|
||||
}
|
||||
if (sr->content) {
|
||||
delete sr->content;
|
||||
delete[] sr->content;
|
||||
sr->content = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
#define DB_OPERATION_H_
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
struct SqlResult {
|
||||
char *column_name;
|
||||
DWORD column_name_len;
|
||||
@@ -18,6 +17,6 @@ struct SqlResult {
|
||||
/// @return
|
||||
int ExecuteSQL(DWORD db, const char *sql, DWORD callback, void *data);
|
||||
|
||||
int Select(DWORD db_hanle, const char *sql,vector<vector<string>> &query_result);
|
||||
int Select(DWORD db_hanle, const char *sql,std::vector<std::vector<std::string>> &query_result);
|
||||
|
||||
#endif
|
||||
+4
-4
@@ -4,8 +4,8 @@
|
||||
#include "common.h"
|
||||
#include "get_db_handle.h"
|
||||
#include "wechat_data.h"
|
||||
#define WX_FORWARD_MSG_OFFSET 0xb68c80
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40
|
||||
#define WX_FORWARD_MSG_OFFSET 0xb6a4e0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbf380
|
||||
|
||||
int ForwardMsg(wchar_t *wxid, unsigned long long msgid) {
|
||||
int success = 0;
|
||||
@@ -27,11 +27,11 @@ int ForwardMsg(wchar_t *wxid, unsigned long long msgid) {
|
||||
PUSH EAX
|
||||
SUB ESP,0x14
|
||||
MOV ECX,ESP
|
||||
LEA ESI, to_user;
|
||||
LEA ESI,to_user
|
||||
PUSH ESI
|
||||
CALL init_chat_msg_addr
|
||||
CALL forward_msg_addr
|
||||
MOVZX EAX,AL;
|
||||
MOVZX EAX,AL
|
||||
MOV success,EAX
|
||||
ADD ESP,0x1c
|
||||
POPFD
|
||||
|
||||
+24
-5
@@ -5,7 +5,7 @@
|
||||
#include "new_sqlite3.h"
|
||||
#include "pch.h"
|
||||
#include "wechat_data.h"
|
||||
#define CONTACT_G_PINSTANCE 0x2bee928
|
||||
#define CONTACT_G_PINSTANCE 0x2c42e78
|
||||
#define DB_MICRO_MSG_OFFSET 0x68
|
||||
#define DB_CHAT_MSG_OFFSET 0x1C0
|
||||
#define DB_MISC_OFFSET 0x3D8
|
||||
@@ -15,10 +15,10 @@
|
||||
#define DB_FUNCTION_MSG_OFFSET 0x11B0
|
||||
#define DB_NAME_OFFSET 0x14
|
||||
|
||||
#define PUBLIC_MSG_MGR_OFFSET 0x2c294c0
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x2c2aff4
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x2c2aa14
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x2bef468
|
||||
#define PUBLIC_MSG_MGR_OFFSET 0x2c7ec88
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x2c807d0
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x2c801f8
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x2c439b8
|
||||
|
||||
using namespace std;
|
||||
map<wstring, DatabaseInfo> dbmap;
|
||||
@@ -296,4 +296,23 @@ unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex) {
|
||||
return stoi(result[1][0]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
vector<string> GetChatMsgByMsgId(ULONG64 msgid){
|
||||
char sql[260] = {0};
|
||||
sprintf_s(sql, "select localId,TalkerId,MsgSvrID,Type,SubType,IsSender,CreateTime,Sequence,StatusEx,FlagEx,Status,MsgServerSeq,MsgSequence,StrTalker,StrContent,BytesExtra from MSG where MsgSvrID=%llu;", msgid);
|
||||
wchar_t dbname[20] = {0};
|
||||
for (int i = 0;; i++) {
|
||||
swprintf_s(dbname, L"MSG%d.db", i);
|
||||
DWORD handle = GetDbHandleByDbName(dbname);
|
||||
if (handle == 0) return {};
|
||||
vector<vector<string>> result;
|
||||
int ret = Select(handle, (const char *)sql, result);
|
||||
#ifdef _DEBUG
|
||||
cout <<" size =" <<result.size()<<endl;
|
||||
#endif
|
||||
if (result.size() == 0) continue;
|
||||
return result[1];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
#define GET_DB_HANDLE_H_
|
||||
#include "windows.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
std::vector<void *> GetDbHandles();
|
||||
DWORD GetDbHandleByDbName(wchar_t *dbname);
|
||||
unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex);
|
||||
std::vector<std::string> GetChatMsgByMsgId(ULONG64 msgid);
|
||||
#endif
|
||||
+4
-4
@@ -2,13 +2,13 @@
|
||||
#include "hook_img.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// #define WX_HOOK_IMG_OFFSET 0xd7eaa5
|
||||
// #define WX_HOOK_IMG_NEXT_OFFSET 0xda56e0
|
||||
#define WX_HOOK_IMG_OFFSET 0xc63ebc
|
||||
#define WX_HOOK_IMG_NEXT_OFFSET 0xd7e9e0
|
||||
#define WX_SELF_ID_OFFSET 0x2BEE08C
|
||||
#define WX_HOOK_IMG_OFFSET 0xc672cc
|
||||
#define WX_HOOK_IMG_NEXT_OFFSET 0xd82370
|
||||
#define WX_SELF_ID_OFFSET 0x2C42A38
|
||||
#define BUFSIZE 1024
|
||||
|
||||
#define JPEG0 0xFF
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
#ifndef HOOK_IMG_H_
|
||||
#define HOOK_IMG_H_
|
||||
#include "windows.h"
|
||||
using namespace std;
|
||||
|
||||
int HookImg(wstring save_path);
|
||||
int HookImg(std::wstring save_path);
|
||||
int UnHookImg();
|
||||
|
||||
int GetImgByName(wchar_t* file_path,wchar_t* save_dir);
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
using namespace nlohmann;
|
||||
|
||||
using namespace std;
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xb94796
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x6fe2c0
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xb97126
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x6fc850
|
||||
|
||||
// SyncMgr::addMsgListToDB
|
||||
// #define WX_RECV_MSG_HOOK_OFFSET 0xB9C919
|
||||
@@ -20,6 +20,7 @@ using namespace std;
|
||||
#define CLIENT_IP "127.0.0.1"
|
||||
static int kServerPort = 0;
|
||||
static int kMessageHooked = FALSE;
|
||||
static char kServerIp[16]= "127.0.0.1";
|
||||
static DWORD kWeChatWinBase = GetWeChatWinBase();
|
||||
|
||||
static char kOriginReceMsgAsmCode[5] = {0};
|
||||
@@ -59,10 +60,12 @@ BOOL SendBySocket(const char *buffer, size_t len) {
|
||||
memset(&client_addr, 0, sizeof(client_addr));
|
||||
client_addr.sin_family = AF_INET;
|
||||
client_addr.sin_port = htons((u_short)kServerPort);
|
||||
InetPtonA(AF_INET, CLIENT_IP, &client_addr.sin_addr.s_addr);
|
||||
InetPtonA(AF_INET, kServerIp, &client_addr.sin_addr.s_addr);
|
||||
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
|
||||
sizeof(sockaddr)) < 0) {
|
||||
#ifdef _DEBUG
|
||||
cout << "kServerIp:" << kServerIp <<endl;
|
||||
cout << "port:" << kServerPort <<endl;
|
||||
cout << "connect error,"
|
||||
<< " errno:" << errno << endl;
|
||||
#endif
|
||||
@@ -190,8 +193,9 @@ _declspec(naked) void handle_sync_msg() {
|
||||
/// @brief hook any address address+0x5
|
||||
/// @param port 端口
|
||||
/// @return 成功返回1,已经hook返回2,失败返回-1
|
||||
int HookRecvMsg(int port) {
|
||||
int HookRecvMsg(char* client_ip,int port) {
|
||||
kServerPort = port;
|
||||
strcpy_s(kServerIp,client_ip);
|
||||
kWeChatWinBase = GetWeChatWinBase();
|
||||
if (!kWeChatWinBase) {
|
||||
return -1;
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
/// @brief hook any address address+0x5
|
||||
/// @param port 端口
|
||||
/// @return 成功返回1,已经hook返回2
|
||||
int HookRecvMsg(int port);
|
||||
int HookRecvMsg(char* client_ip,int port);
|
||||
|
||||
int UnHookRecvMsg();
|
||||
#endif
|
||||
+18
-18
@@ -135,24 +135,24 @@
|
||||
#define SQLITE_NULL 5
|
||||
#define SQLITE_TEXT 3
|
||||
|
||||
#define SQLITE3_EXEC_OFFSET 0x1b623b0
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1b27d50
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1b68d00
|
||||
#define SQLITE3_OPEN_OFFSET 0x1b96cf0
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1b28150
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1b28890
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1b288a0
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1b28790
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1b97530
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1b95990
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1b94110
|
||||
#define SQLITE3_STEP_OFFSET 0x1b30bc0
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1b310d0
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1b319c0
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1b31860
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1b31110
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1b311f0
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1b2fb90
|
||||
#define SQLITE3_EXEC_OFFSET 0x1ba9de0
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1b6f760
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1bb0730
|
||||
#define SQLITE3_OPEN_OFFSET 0x1bde730
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1b6fb60
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1b702a0
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1b702b0
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1b701a0
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1bdef70
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1bdd3d0
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1bdbb20
|
||||
#define SQLITE3_STEP_OFFSET 0x1b785d0
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1b78ae0
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1b793d0
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1b79270
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1b78b20
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1b78c00
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1b775a0
|
||||
|
||||
typedef int (*Sqlite3_callback)(void*, int, char**, char**);
|
||||
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
#include "pch.h"
|
||||
#include "ocr.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_INIT_OBJ_OFFSET 0x6cbab0
|
||||
#define WX_OCR_MANAGER_OFFSET 0x6cff00
|
||||
#define WX_DO_OCR_TASK_OFFSET 0x11e3210
|
||||
using namespace std;
|
||||
int DoOCRTask(wchar_t *img_path, std::string &result) {
|
||||
int success = -1;
|
||||
WeChatString path(img_path);
|
||||
WeChatString null_obj = {0};
|
||||
WeChatString ocr_result = {0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD ocr_manager_addr = base + WX_OCR_MANAGER_OFFSET;
|
||||
DWORD do_ocr_task_addr = base + WX_DO_OCR_TASK_OFFSET;
|
||||
DWORD init_addr = base + WX_INIT_OBJ_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,ocr_result
|
||||
CALL init_addr
|
||||
CALL ocr_manager_addr
|
||||
LEA ECX,null_obj
|
||||
PUSH ECX
|
||||
LEA ECX,ocr_result
|
||||
PUSH ECX
|
||||
PUSH ECX
|
||||
LEA ECX,path
|
||||
PUSH ECX
|
||||
MOV ECX,EAX
|
||||
CALL do_ocr_task_addr
|
||||
MOV success,EAX
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
|
||||
if (success == 0) {
|
||||
DWORD addr = (DWORD)&ocr_result;
|
||||
DWORD ptr = *(DWORD *)addr;
|
||||
DWORD num = *(DWORD *)(addr + 0x4);
|
||||
if (num <= 0) {
|
||||
return success;
|
||||
}
|
||||
|
||||
DWORD header = *(DWORD *)ptr;
|
||||
for (unsigned int i = 0; i < num -1; i++) {
|
||||
DWORD content = *(DWORD *)header;
|
||||
result += unicode_to_utf8((wchar_t *)READ_WSTRING(content, 0x14).c_str());
|
||||
|
||||
header = content;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
cout << "num:" << num << endl;
|
||||
cout << "all:" << result << endl;
|
||||
#endif
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef OCR_H_
|
||||
#define OCR_H_
|
||||
#include <string>
|
||||
int DoOCRTask(wchar_t* img_path,std::string &result);
|
||||
#endif
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#include "pch.h"
|
||||
#include "pat.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_PAT_MGR_OFFSET 0x7e91c0
|
||||
#define WX_SEND_PAT_MSG_OFFSET 0x1228510
|
||||
#define WX_RET_OFFSET 0x1AE4A45
|
||||
|
||||
int SendPatMsg(wchar_t* chat_room_id, wchar_t* wxid) {
|
||||
int success = -1;
|
||||
WeChatString chat_room(chat_room_id);
|
||||
WeChatString self_wxid(wxid);
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD get_pat_mgr_addr = base + WX_PAT_MGR_OFFSET;
|
||||
DWORD send_pat_msg_addr = base + WX_SEND_PAT_MSG_OFFSET;
|
||||
DWORD ret_addr = base + WX_RET_OFFSET;
|
||||
__asm {
|
||||
PUSHAD
|
||||
CALL get_pat_mgr_addr
|
||||
PUSH ret_addr
|
||||
PUSH 0x0
|
||||
PUSH EAX
|
||||
LEA ECX,chat_room
|
||||
LEA EDX,self_wxid
|
||||
CALL send_pat_msg_addr
|
||||
ADD ESP,0xc
|
||||
MOVZX EAX,AL
|
||||
MOV success,EAX
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef PAT_H_
|
||||
#define PAT_H_
|
||||
int SendPatMsg(wchar_t* chat_room_id,wchar_t* wxid);
|
||||
#endif
|
||||
+37
-14
@@ -4,22 +4,24 @@
|
||||
#include "common.h"
|
||||
|
||||
#include "wechat_data.h"
|
||||
using namespace std;
|
||||
|
||||
#define WX_SELF_NAME_OFFSET 0x2bee198
|
||||
#define WX_SELF_MOBILE_OFFSET 0x2BEE108
|
||||
#define WX_SELF_CITY_OFFSET 0x2BEE168
|
||||
#define WX_SELF_PROVINCE_OFFSET 0x2BEE150
|
||||
#define WX_SELF_COUNTRY_OFFSET 0x2BEE138
|
||||
#define WX_SELF_ACCOUNT_OFFSET 0x2BEE0F0
|
||||
#define WX_SELF_ID_OFFSET 0x2BEE08C
|
||||
#define WX_SELF_SMALL_IMG_OFFSET 0x2BEE34C
|
||||
#define WX_SELF_BIG_IMG_OFFSET 0x2BEE364
|
||||
#define WX_LOGIN_STATUS_OFFSET 0x2BEE4C0
|
||||
#define WX_APP_DATA_ROOT_PATH_OFFSET 0x2c2f478
|
||||
#define WX_APP_DATA_SAVE_PATH_OFFSET 0x2C10D04
|
||||
#define WX_CURRENT_DATA_PATH_OFFSET 0x2C0EC38
|
||||
|
||||
#define WX_SELF_NAME_OFFSET 0x2C426E8
|
||||
#define WX_SELF_MOBILE_OFFSET 0x2C42658
|
||||
#define WX_SELF_CITY_OFFSET 0x2C426B8
|
||||
#define WX_SELF_PROVINCE_OFFSET 0x2C426A0
|
||||
#define WX_SELF_COUNTRY_OFFSET 0x2C42688
|
||||
#define WX_SELF_ACCOUNT_OFFSET 0x2C42640
|
||||
#define WX_SELF_ID_OFFSET 0x2C42A38
|
||||
#define WX_SELF_SMALL_IMG_OFFSET 0x2C4289C
|
||||
#define WX_SELF_BIG_IMG_OFFSET 0x2C428B4
|
||||
#define WX_LOGIN_STATUS_OFFSET 0x2c42a10
|
||||
#define WX_APP_DATA_ROOT_PATH_OFFSET 0x2c84ae0
|
||||
#define WX_APP_DATA_SAVE_PATH_OFFSET 0x2c65728
|
||||
#define WX_CURRENT_DATA_PATH_OFFSET 0x2c636fc
|
||||
|
||||
#define WX_LOGOUT_OFFSET 0xccc320
|
||||
#define WX_ACCOUT_SERVICE_OFFSET 0x65bcc0
|
||||
|
||||
int GetSelfInfo(SelfInfoInner &out) {
|
||||
DWORD base = GetWeChatWinBase();
|
||||
@@ -136,4 +138,25 @@ int GetSelfInfo(SelfInfoInner &out) {
|
||||
int CheckLogin(){
|
||||
DWORD base = GetWeChatWinBase();
|
||||
return *(DWORD*) (base + WX_LOGIN_STATUS_OFFSET);
|
||||
}
|
||||
|
||||
|
||||
int Logout(){
|
||||
int success = 0;
|
||||
if(!CheckLogin()){
|
||||
return success;
|
||||
}
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD account_service_addr = base + WX_ACCOUT_SERVICE_OFFSET;
|
||||
DWORD logout_addr = base + WX_LOGOUT_OFFSET;
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL account_service_addr
|
||||
PUSH 0x0
|
||||
MOV ECX,EAX
|
||||
CALL logout_addr
|
||||
MOV success,EAX
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@@ -4,4 +4,6 @@
|
||||
int GetSelfInfo(SelfInfoInner& out);
|
||||
|
||||
int CheckLogin();
|
||||
|
||||
int Logout();
|
||||
#endif
|
||||
+4
-4
@@ -3,10 +3,10 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x665f60
|
||||
#define WX_SEND_FILE_OFFSET 0xa0ce20
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x651c40
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x65df50
|
||||
#define WX_SEND_FILE_OFFSET 0xa10190
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbf380
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x649ac0
|
||||
|
||||
int SendFile(wchar_t *wxid, wchar_t *file_path){
|
||||
int success = 0;
|
||||
|
||||
+4
-4
@@ -3,10 +3,10 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_SEND_IMAGE_OFFSET 0xb68b90
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x663320
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbcc40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x651c40
|
||||
#define WX_SEND_IMAGE_OFFSET 0xb6a3f0
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x65b2a0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xdbf380
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x649ac0
|
||||
|
||||
int SendImage(wchar_t *wxid, wchar_t *image_path){
|
||||
|
||||
|
||||
+3
-3
@@ -5,11 +5,11 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_SEND_TEXT_OFFSET 0xb690a0
|
||||
#define WX_SEND_TEXT_OFFSET 0xb6a930
|
||||
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x663320
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x65b2a0
|
||||
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x651c40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x649ac0
|
||||
/// @brief 发生文本消息
|
||||
/// @param wxid wxid
|
||||
/// @param msg 文本消息
|
||||
|
||||
+33
-15
@@ -4,7 +4,6 @@
|
||||
// #include <windows.h>
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
struct WeChatString {
|
||||
wchar_t *ptr;
|
||||
DWORD length;
|
||||
@@ -13,7 +12,7 @@ struct WeChatString {
|
||||
DWORD c_len = 0;
|
||||
WeChatString() { WeChatString(NULL); }
|
||||
|
||||
WeChatString(wstring &s) {
|
||||
WeChatString(std::wstring &s) {
|
||||
ptr = (wchar_t *)(s.c_str());
|
||||
length = s.length();
|
||||
max_length = s.length() * 2;
|
||||
@@ -51,7 +50,7 @@ struct DatabaseInfo {
|
||||
DWORD handle = 0;
|
||||
wchar_t *db_name = NULL;
|
||||
DWORD db_name_len = 0;
|
||||
vector<TableInfo> tables;
|
||||
std::vector<TableInfo> tables;
|
||||
DWORD count = 0;
|
||||
DWORD extrainfo = 0;
|
||||
};
|
||||
@@ -101,6 +100,25 @@ struct ChatRoomInfoInner {
|
||||
WeChatString notice;
|
||||
WeChatString admin;
|
||||
WeChatString xml;
|
||||
|
||||
~ChatRoomInfoInner(){
|
||||
if(chat_room_id.ptr){
|
||||
delete []chat_room_id.ptr;
|
||||
chat_room_id.ptr = nullptr;
|
||||
}
|
||||
if(notice.ptr){
|
||||
delete []notice.ptr;
|
||||
notice.ptr = nullptr;
|
||||
}
|
||||
if(admin.ptr){
|
||||
delete []admin.ptr;
|
||||
admin.ptr = nullptr;
|
||||
}
|
||||
if(xml.ptr){
|
||||
delete []xml.ptr;
|
||||
xml.ptr = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct VectorInner {
|
||||
@@ -124,17 +142,17 @@ struct ChatRoomInner{
|
||||
};
|
||||
|
||||
struct SelfInfoInner{
|
||||
string name;
|
||||
string city;
|
||||
string province;
|
||||
string country;
|
||||
string account;
|
||||
string wxid;
|
||||
string mobile;
|
||||
string small_img;
|
||||
string big_img;
|
||||
string data_root_path;
|
||||
string data_save_path;
|
||||
string current_data_path;
|
||||
std::string name;
|
||||
std::string city;
|
||||
std::string province;
|
||||
std::string country;
|
||||
std::string account;
|
||||
std::string wxid;
|
||||
std::string mobile;
|
||||
std::string small_img;
|
||||
std::string big_img;
|
||||
std::string data_root_path;
|
||||
std::string data_save_path;
|
||||
std::string current_data_path;
|
||||
};
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user