Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a3ef64467 | ||
|
|
789b4b6e75 | ||
|
|
1a1a1fe964 | ||
|
|
93798ddeca | ||
|
|
df57bb3317 | ||
|
|
a097ae334a | ||
|
|
4b88354f46 | ||
|
|
8ea5cbec8a | ||
|
|
b8db52d522 | ||
|
|
e52a9b87ed | ||
|
|
19d146db99 |
@@ -1,112 +1,7 @@
|
||||
# wxhelper
|
||||
wechat hook 。PC端微信逆向学习。支持3.8.0.41,3.8.1.26,3.9.0.28版本。
|
||||
#### 免责声明:
|
||||
本仓库发布的内容,仅用于学习研究,请勿用于非法用途和商业用途!如因此产生任何法律纠纷,均与作者无关!
|
||||
|
||||
#### 项目说明:
|
||||
本项目是个人学习学习逆向的项目,主要参考 https://github.com/ljc545w/ComWeChatRobot ,在此基础上实现了微信的的其它版本的部分内容。
|
||||
|
||||
#### 使用说明:
|
||||
支持的版本3.8.0.41,3.8.1.26, 3.9.0.28。
|
||||
src:主要的dll代码
|
||||
tool:简单的注入工具,一个是控制台,一个是图形界面。
|
||||
python: 简单的服务器,用以接收hook的消息内容。
|
||||
|
||||
|
||||
0.首先安装对应的微信版本,主分支是3.8.0.41版本,分支对应相应的微信版本号.
|
||||
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.对应分支接口文档都是支持指定版本的,其他版本不支持,请特别注意版本。
|
||||
8.相应分支的文档对应相应版本,带有删除线的接口表示该版本的暂未实现,其他版本有实现。后续会继续实现。
|
||||
|
||||
|
||||
#### 编译环境
|
||||
|
||||
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 : 新增群消息置顶和取消置顶。
|
||||
|
||||
2023-02-06 : 新增确认收款。
|
||||
|
||||
2023-02-08 : 新增朋友圈消息。
|
||||
|
||||
2023-02-09 : 新增3.9.0.28版本基础功能。
|
||||
|
||||
2023-02-13 : 新增查询联系人昵称功能。
|
||||
|
||||
2023-02-17 : 新增通过wxid添加好友和查找微信。
|
||||
|
||||
## 3.9.2.23版本,预览功能没有的接口,不能使用,文档仅供参考。
|
||||
#### 功能预览:
|
||||
0.检查是否登录
|
||||
0.检查是否登录
|
||||
1.获取登录微信信息
|
||||
2.发送文本
|
||||
5.发送图片
|
||||
@@ -114,33 +9,35 @@ vcpkg
|
||||
9.hook消息
|
||||
10.取消hook消息
|
||||
11.hook图片
|
||||
12.取消hook图片
|
||||
17.删除好友
|
||||
19.通过手机或qq查找微信
|
||||
20.通过wxid添加好友
|
||||
12.取消hook图片
|
||||
13.hook语音
|
||||
14.取消hook语音
|
||||
<!-- 17.删除好友 -->
|
||||
<!-- 19.通过手机或qq查找微信 -->
|
||||
<!-- 20.通过wxid添加好友 -->
|
||||
25.获取群成员
|
||||
26.获取群成员昵称
|
||||
<!-- 26.获取群成员昵称
|
||||
27.删除群成员
|
||||
28.增加群成员
|
||||
31.修改群昵称
|
||||
31.修改群昵称 -->
|
||||
32.获取数据库句柄
|
||||
34.查询数据库
|
||||
35.hook日志
|
||||
36.关闭hook日志
|
||||
<!-- 35.hook日志
|
||||
36.关闭hook日志 -->
|
||||
40.转发消息
|
||||
44.退出登录
|
||||
45.确认收款
|
||||
<!-- 45.确认收款 -->
|
||||
46.联系人列表
|
||||
47.获取群详情
|
||||
<!-- 47.获取群详情 -->
|
||||
48.获取解密图片
|
||||
49.图片提取文字ocr
|
||||
<!-- 49.图片提取文字ocr -->
|
||||
50.拍一拍
|
||||
51.群消息置顶消息
|
||||
52.群消息取消置顶
|
||||
<!-- 51.群消息置顶消息
|
||||
52.群消息取消置顶 -->
|
||||
53.朋友圈首页
|
||||
54.朋友圈下一页
|
||||
55.获取联系人或者群名称
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
<!-- 55.获取联系人或者群名称 -->
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
### 接口文档:
|
||||
|
||||
|
||||
@@ -210,6 +107,7 @@ vcpkg
|
||||
|province|string|省|
|
||||
|wxid|string|wxid|
|
||||
|signature|string|个人签名|
|
||||
|dbKey|string|数据库的SQLCipher的加密key,可以使用该key配合decrypt.py解密数据库
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
@@ -217,7 +115,7 @@ vcpkg
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"data":{"account":"xx","headImage":"https://wx.qlogo.cn/mmhead/ver_1xx","city":"xx","country":"CN","currentDataPath":"C:\\xx\\wxid_xxxxx","dataSavePath":"C:\\xx","mobie":"13812345678","name":"xx","province":"xx","signature":"xx","wxid":"xx"},"result":"OK"}
|
||||
{"code":1,"data":{"account":"xx","headImage":"https://wx.qlogo.cn/mmhead/ver_1xx","city":"xx","country":"CN","currentDataPath":"C:\\xx\\wxid_xxxxx","dataSavePath":"C:\\xx","mobie":"13812345678","name":"xx","province":"xx","signature":"xx","wxid":"xx","dbKey":"aaa2222"},"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
@@ -515,7 +413,77 @@ vcpkg
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
#### 13.hook语音**
|
||||
###### 接口功能
|
||||
> hook语音
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=13](/api/?type=13)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|voiceDir |true |string| 语音保存的目录 |
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"voiceDir":"C:\\other"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 14.取消hook语音**
|
||||
###### 接口功能
|
||||
> 取消hook语音
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=14](/api/?type=14)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 17.删除好友**
|
||||
###### 接口功能
|
||||
|
||||
+27
@@ -25,6 +25,7 @@
|
||||
#include "search_contact.h"
|
||||
#include "download.h"
|
||||
#include "hook_log.h"
|
||||
#include "hook_voice.h"
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
using namespace std;
|
||||
@@ -227,6 +228,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
{"signature",self_info.signature},
|
||||
{"dataSavePath",self_info.data_save_path},
|
||||
{"currentDataPath",self_info.current_data_path},
|
||||
{"dbKey",self_info.db_key},
|
||||
};
|
||||
ret_data["data"] = j_info;
|
||||
}
|
||||
@@ -242,6 +244,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_SEND_AT: {
|
||||
break;
|
||||
wstring chat_room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
vector<wstring> wxids = get_http_param_array(hm, j_param, "wxids", is_post);
|
||||
wstring msg = get_http_req_param(hm, j_param, "msg", is_post);
|
||||
@@ -297,6 +300,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_START_IMAGE_HOOK: {
|
||||
break;
|
||||
wstring img_dir = get_http_req_param(hm, j_param, "imgDir", is_post);
|
||||
int success = HookImg(img_dir);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
@@ -304,15 +308,23 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_STOP_IMAGE_HOOK: {
|
||||
break;
|
||||
int success = UnHookImg();
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_START_VOICE_HOOK: {
|
||||
wstring voice_dir = get_http_req_param(hm, j_param, "voiceDir", is_post);
|
||||
int success = HookVoice(voice_dir);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_STOP_VOICE_HOOK: {
|
||||
int success = UnHookVoice();
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_CONTACT_GET_LIST: {
|
||||
@@ -323,6 +335,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CONTACT_DEL: {
|
||||
break;
|
||||
wstring user_id = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
int success = DelContact(WS2LW(user_id));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
@@ -333,6 +346,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CONTACT_SEARCH_BY_NET: {
|
||||
break;
|
||||
wstring keyword = get_http_req_param(hm, j_param, "keyword", is_post);
|
||||
UserInfo *user = nullptr;
|
||||
int success = SearchContactNetScene(WS2LW(keyword), &user);
|
||||
@@ -356,6 +370,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CONTACT_ADD_BY_WXID: {
|
||||
break;
|
||||
wstring user_id = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
int success = AddFriendByWxid(WS2LW(user_id));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
@@ -391,6 +406,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CHATROOM_GET_MEMBER_NICKNAME: {
|
||||
break;
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
wstring member_id = get_http_req_param(hm, j_param, "memberId", is_post);
|
||||
|
||||
@@ -400,6 +416,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CHATROOM_DEL_MEMBER: {
|
||||
break;
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
vector<wstring> wxids = get_http_param_array(hm, j_param, "memberIds", is_post);
|
||||
vector<wchar_t *> wxid_list;
|
||||
@@ -412,6 +429,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CHATROOM_ADD_MEMBER: {
|
||||
break;
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
vector<wstring> wxids = get_http_param_array(hm, j_param, "memberIds", is_post);
|
||||
vector<wchar_t *> wxid_list;
|
||||
@@ -430,6 +448,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CHATROOM_SET_SELF_NICKNAME: {
|
||||
break;
|
||||
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);
|
||||
@@ -487,12 +506,14 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_LOG_START_HOOK: {
|
||||
break;
|
||||
int success = HookLog();
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_LOG_STOP_HOOK: {
|
||||
break;
|
||||
int success = UnHookLog();
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
@@ -528,6 +549,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_TRANSFER: {
|
||||
break;
|
||||
wstring wxid = get_http_req_param(hm, j_param, "wxid", is_post);
|
||||
wstring transcationid = get_http_req_param(hm, j_param, "transcationId", is_post);
|
||||
wstring transferid = get_http_req_param(hm, j_param, "transferId", is_post);
|
||||
@@ -574,6 +596,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_CHATROOM_INFO: {
|
||||
break;
|
||||
wstring room_id = get_http_req_param(hm, j_param, "chatRoomId", is_post);
|
||||
ChatRoomInfoInner chat_room_detail{0};
|
||||
int success = GetChatRoomDetailInfo(WS2LW(room_id), chat_room_detail);
|
||||
@@ -609,6 +632,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_DO_OCR:{
|
||||
break;
|
||||
wstring image_path = get_http_req_param(hm, j_param, "imagePath", is_post);
|
||||
string text("");
|
||||
int success = DoOCRTask(WS2LW(image_path),text);
|
||||
@@ -625,6 +649,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_SET_TOP_MSG:{
|
||||
break;
|
||||
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);
|
||||
@@ -633,6 +658,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_REMOVE_TOP_MSG:{
|
||||
break;
|
||||
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);
|
||||
@@ -654,6 +680,7 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_CONTACT_NAME:{
|
||||
break;
|
||||
wstring pri_id = get_http_req_param(hm, j_param, "id", is_post);
|
||||
wstring name =GetContactOrChatRoomNickname(WS2LW(pri_id));
|
||||
json ret_data = {{"code", 1}, {"result", "OK"},{"name",unicode_to_utf8(WS2LW(name))}};
|
||||
|
||||
+4
-4
@@ -7,16 +7,16 @@
|
||||
#include "base64.h"
|
||||
using namespace std;
|
||||
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x72cf60
|
||||
#define WX_CHAT_ROOM_MGR_OFFSET 0x78cf20
|
||||
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xb6f260
|
||||
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe15de0
|
||||
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe160b0
|
||||
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xb64180
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xed3be0
|
||||
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xb63c50
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xB70260
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xe13b30
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xe13d50
|
||||
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbdf260
|
||||
#define WX_INIT_CHAT_ROOM_OFFSET 0xe97890
|
||||
#define WX_FREE_CHAT_ROOM_OFFSET 0xe97ab0
|
||||
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xb6adf0
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x70e2a0
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
|
||||
+46
-1
@@ -142,4 +142,49 @@ void CloseConsole(){
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
FreeConsole();
|
||||
}
|
||||
}
|
||||
|
||||
std::string EncodeHexString(const std::string &str) {
|
||||
const std::string hex_table = "0123456789abcdef";
|
||||
string sb;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
sb += hex_table.at((str[i] & 0xf0) >> 4);
|
||||
sb += hex_table.at((str[i] & 0x0f) >> 0);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
std::string Hex2String(const std::string &hex_str) {
|
||||
std::string ret;
|
||||
const std::string hex_table = "0123456789abcdef";
|
||||
for (int i = 0; i < hex_str.length(); i += 2) {
|
||||
ret += BYTE(hex_table.find(hex_str.at(i)) << 4 |
|
||||
hex_table.find(hex_str.at(i + 1)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string Bytes2Hex(const BYTE *bytes, const int length) {
|
||||
if (bytes == NULL) {
|
||||
return "";
|
||||
}
|
||||
std::string buff;
|
||||
const int len = length;
|
||||
for (int j = 0; j < len; j++) {
|
||||
int high = bytes[j] / 16, low = bytes[j] % 16;
|
||||
buff += (high < 10) ? ('0' + high) : ('a' + high - 10);
|
||||
buff += (low < 10) ? ('0' + low) : ('a' + low - 10);
|
||||
}
|
||||
return buff;
|
||||
}
|
||||
|
||||
void Hex2Bytes(const std::string &hex, BYTE *bytes) {
|
||||
int byte_len = hex.length() / 2;
|
||||
std::string str;
|
||||
unsigned int n;
|
||||
for (int i = 0; i < byte_len; i++) {
|
||||
str = hex.substr(i * 2, 2);
|
||||
sscanf_s(str.c_str(), "%x", &n);
|
||||
bytes[i] = n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,14 @@ BOOL FindOrCreateDirectoryW(const wchar_t *path);
|
||||
|
||||
void CloseConsole();
|
||||
|
||||
std::string EncodeHexString(const std::string &str);
|
||||
|
||||
std::string Hex2String(const std::string &hex_str);
|
||||
|
||||
std::string Bytes2Hex(const BYTE *bytes, const int length);
|
||||
|
||||
void Hex2Bytes(const std::string &hex, BYTE *bytes);
|
||||
|
||||
template <typename T1, typename T2>
|
||||
std::vector<T1> split(T1 str, T2 letter) {
|
||||
vector<T1> arr;
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
using namespace std;
|
||||
#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x6f8990
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xb97550
|
||||
#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x75a4a0
|
||||
#define WX_CONTACT_GET_LIST_OFFSET 0xc089f0
|
||||
#define WX_CONTACT_DEL_OFFSET 0xb9b3b0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xed3be0
|
||||
#define WX_SYNC_MGR_OFFSET 0xa87fd0
|
||||
|
||||
+16
-16
@@ -6,20 +6,20 @@
|
||||
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x70e2a0
|
||||
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x7ae310
|
||||
#define WX_PUSH_ATTACH_TASK_OFFSET 0x7c94a0
|
||||
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x6f5370
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
#define WX_CHAT_MGR_OFFSET 0x732660
|
||||
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xb54950
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc11140
|
||||
#define WX_APP_MSG_INFO_OFFSET 0x7571d0
|
||||
#define WX_GET_APP_MSG_XML_OFFSET 0xddef80
|
||||
#define WX_FREE_APP_MSG_INFO_OFFSET 0x73d820
|
||||
#define WX_PUSH_THUMB_TASK_OFFSET 0x7c93a0
|
||||
#define WX_VIDEO_MGR_OFFSET 0x7c7300
|
||||
#define WX_DOWNLOAD_VIDEO_IMG_OFFSET 0xcc6d80
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x76f010
|
||||
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80f110
|
||||
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82bb40
|
||||
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x756e30
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
#define WX_CHAT_MGR_OFFSET 0x792700
|
||||
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc0370
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
|
||||
#define WX_APP_MSG_INFO_OFFSET 0x7b3d20
|
||||
#define WX_GET_APP_MSG_XML_OFFSET 0xe628a0
|
||||
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79d900
|
||||
#define WX_PUSH_THUMB_TASK_OFFSET 0x82ba40
|
||||
#define WX_VIDEO_MGR_OFFSET 0x829820
|
||||
#define WX_DOWNLOAD_VIDEO_IMG_OFFSET 0xd46c30
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -31,7 +31,7 @@ int DoDownloadTask(ULONG64 msg_id) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
char chat_msg[0x2C4] = {0};
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD new_chat_msg_addr = base + WX_NEW_CHAT_MSG_OFFSET;
|
||||
DWORD get_chat_mgr_addr = base + WX_CHAT_MGR_OFFSET;
|
||||
@@ -143,7 +143,7 @@ int DoDownloadTask(ULONG64 msg_id) {
|
||||
int temp =1;
|
||||
memcpy(&chat_msg[0x19C], &w_thumb_path, sizeof(w_thumb_path));
|
||||
memcpy(&chat_msg[0x1B0], &w_save_path, sizeof(w_save_path));
|
||||
memcpy(&chat_msg[0x290], &temp, sizeof(temp));
|
||||
memcpy(&chat_msg[0x29C], &temp, sizeof(temp));
|
||||
// note: the image has been downloaded and will not be downloaded again
|
||||
// use low-level method
|
||||
// this function does not work, need to modify chatmsg.
|
||||
|
||||
+4
-3
@@ -4,8 +4,8 @@
|
||||
#include "common.h"
|
||||
#include "get_db_handle.h"
|
||||
#include "wechat_data.h"
|
||||
#define WX_FORWARD_MSG_OFFSET 0xc715f0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xed3be0
|
||||
#define WX_FORWARD_MSG_OFFSET 0xce6730
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
|
||||
|
||||
int ForwardMsg(wchar_t *wxid, unsigned long long msgid) {
|
||||
int success = 0;
|
||||
@@ -29,7 +29,8 @@ int ForwardMsg(wchar_t *wxid, unsigned long long msgid) {
|
||||
MOV ECX,ESP
|
||||
LEA ESI,to_user
|
||||
PUSH ESI
|
||||
CALL init_chat_msg_addr
|
||||
CALL init_chat_msg_addr
|
||||
XOR ECX,ECX
|
||||
CALL forward_msg_addr
|
||||
MOVZX EAX,AL
|
||||
MOV success,EAX
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "new_sqlite3.h"
|
||||
#include "pch.h"
|
||||
#include "wechat_data.h"
|
||||
#define CONTACT_G_PINSTANCE_OFFSET 0x2e2d628
|
||||
#define CONTACT_G_PINSTANCE_OFFSET 0x2ffddc8
|
||||
#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 0x2e6ce20
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x2e6ec84
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x2e6e630
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x2e2e168
|
||||
#define PUBLIC_MSG_MGR_OFFSET 0x303df74
|
||||
#define MULTI_DB_MSG_MGR_OFFSET 0x30403b8
|
||||
#define FAVORITE_STORAGE_MGR_OFFSET 0x303fd40
|
||||
#define FTS_FAVORITE_MGR_OFFSET 0x2ffe908
|
||||
|
||||
using namespace std;
|
||||
map<wstring, DatabaseInfo> dbmap;
|
||||
@@ -227,7 +227,7 @@ std::vector<void *> GetDbHandles() {
|
||||
}
|
||||
|
||||
// Favorite.db
|
||||
DWORD favItems_ptr = *(DWORD *)(*(DWORD *)(favorite_storage_mgr_addr) + 0x8);
|
||||
DWORD favItems_ptr = *(DWORD *)(*(DWORD *)(*(DWORD *)(favorite_storage_mgr_addr) + 0x8) + 0x4);
|
||||
if (favItems_ptr) {
|
||||
DWORD favorite_db_addr = *(DWORD *)(favItems_ptr + 0x38);
|
||||
DatabaseInfo favorite_db{0};
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
using namespace nlohmann;
|
||||
|
||||
using namespace std;
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xca0284
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x7d5030
|
||||
#define WX_SNS_HOOK_OFFSET 0x143ef09
|
||||
#define WX_SNS_HOOK_NEXT_OFFSET 0x143f1b0
|
||||
#define WX_RECV_MSG_HOOK_OFFSET 0xd19a0b
|
||||
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x756960
|
||||
#define WX_SNS_HOOK_OFFSET 0x14f9e15
|
||||
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fa0a0
|
||||
|
||||
// SyncMgr::addMsgListToDB
|
||||
// #define WX_RECV_MSG_HOOK_OFFSET 0xB9C919
|
||||
@@ -230,7 +230,7 @@ _declspec(naked) void handle_sync_msg() {
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
PUSH ECX
|
||||
PUSH ECX
|
||||
CALL OnRecvMsg
|
||||
ADD ESP, 0x4
|
||||
POPFD
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "pch.h"
|
||||
#include "hook_voice.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WX_HOOK_VOICE_OFFSET 0xd4d8d8
|
||||
#define WX_HOOK_VOICE_NEXT_OFFSET 0x203d130
|
||||
#define WX_SELF_ID_OFFSET 0x2FFD484
|
||||
|
||||
static wstring kVoiceStorePath = L"";
|
||||
static int kVoiceHooked = FALSE;
|
||||
static DWORD kWeChatWinBase = GetWeChatWinBase();
|
||||
static char kOriginVoiceAsmCode[5] = {0};
|
||||
|
||||
static DWORD kHookVoiceNextAddress = kWeChatWinBase + WX_HOOK_VOICE_NEXT_OFFSET;
|
||||
static DWORD kHookVoiceJmpBackAddress =
|
||||
kWeChatWinBase + WX_HOOK_VOICE_OFFSET + 0x5;
|
||||
|
||||
void OnHookVoice(DWORD buff,int len , DWORD msg_addr) {
|
||||
DWORD wxid_addr = GetWeChatWinBase() + WX_SELF_ID_OFFSET;
|
||||
string wxid = string(*(char **)wxid_addr, *(DWORD *)(wxid_addr + 0x10));
|
||||
wstring self_id = utf8_to_unicode(wxid.c_str());
|
||||
wstring save_path = kVoiceStorePath + self_id;
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return;
|
||||
}
|
||||
unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30);
|
||||
save_path = save_path + L"\\" + to_wstring(msgid) + L".amr";
|
||||
HANDLE file_handle = CreateFileW(save_path.c_str(), GENERIC_ALL, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
DWORD bytes_write = 0;
|
||||
WriteFile(file_handle, (LPCVOID)buff, len, &bytes_write, 0);
|
||||
CloseHandle(file_handle);
|
||||
}
|
||||
|
||||
/// @brief hook voice implement
|
||||
_declspec(naked) void handle_voice() {
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
PUSH EDI
|
||||
PUSH EDX
|
||||
PUSH EAX
|
||||
CALL OnHookVoice
|
||||
ADD ESP, 0xC
|
||||
POPFD
|
||||
POPAD
|
||||
CALL kHookVoiceNextAddress
|
||||
JMP kHookVoiceJmpBackAddress
|
||||
}
|
||||
}
|
||||
|
||||
int HookVoice(std::wstring save_path) {
|
||||
kWeChatWinBase = GetWeChatWinBase();
|
||||
if (!kWeChatWinBase) {
|
||||
return -1;
|
||||
}
|
||||
if (kVoiceHooked) {
|
||||
return 2;
|
||||
}
|
||||
kVoiceStorePath = save_path;
|
||||
if (kVoiceStorePath.back() != '\\') {
|
||||
kVoiceStorePath += L"\\";
|
||||
}
|
||||
wstring createpath = kVoiceStorePath.substr(0, kVoiceStorePath.length() - 1);
|
||||
if (!FindOrCreateDirectoryW(createpath.c_str())) {
|
||||
return -2;
|
||||
}
|
||||
DWORD hook_voice_addr = kWeChatWinBase + WX_HOOK_VOICE_OFFSET;
|
||||
kHookVoiceNextAddress = kWeChatWinBase + WX_HOOK_VOICE_NEXT_OFFSET;
|
||||
static DWORD kHookVoiceJmpBackAddress = hook_voice_addr + 0x5;
|
||||
HookAnyAddress(hook_voice_addr, (LPVOID)handle_voice, kOriginVoiceAsmCode);
|
||||
kVoiceHooked = TRUE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UnHookVoice() {
|
||||
if (!kVoiceHooked) return 1;
|
||||
DWORD hook_voice_addr = kWeChatWinBase + WX_HOOK_VOICE_OFFSET;
|
||||
UnHookAnyAddress(hook_voice_addr, kOriginVoiceAsmCode);
|
||||
kVoiceHooked = FALSE;
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef HOOK_VOICE_H_
|
||||
#define HOOK_VOICE_H_
|
||||
#include <string>
|
||||
|
||||
int HookVoice(std::wstring save_path);
|
||||
|
||||
int UnHookVoice();
|
||||
#endif
|
||||
+18
-18
@@ -135,24 +135,24 @@
|
||||
#define SQLITE_NULL 5
|
||||
#define SQLITE_TEXT 3
|
||||
|
||||
#define SQLITE3_EXEC_OFFSET 0x1d5cf70
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1d228d0
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1d638c0
|
||||
#define SQLITE3_OPEN_OFFSET 0x1d918b0
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1d22ce0
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1d23420
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1d23430
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1d23320
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1d920f0
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1d90550
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1d8ecd0
|
||||
#define SQLITE3_STEP_OFFSET 0x1d2b750
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1d2bc60
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1d2c550
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1d2c3f0
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1d2bca0
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1d2bd80
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1d2a720
|
||||
#define SQLITE3_EXEC_OFFSET 0x1e24f70
|
||||
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dea900
|
||||
#define SQLITE3_PREPARE_OFFSET 0x1e2b8c0
|
||||
#define SQLITE3_OPEN_OFFSET 0x1e598b0
|
||||
#define SQLITE3_BACKUP_STEP_OFFSET 0x1dead00
|
||||
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1deb440
|
||||
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1deb450
|
||||
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1deb340
|
||||
#define SQLITE3_SLEEP_OFFSET 0x1e5a0f0
|
||||
#define SQLITE3_ERRCODE_OFFSET 0x1e58550
|
||||
#define SQLITE3_CLOSE_OFFSET 0x1e56cd0
|
||||
#define SQLITE3_STEP_OFFSET 0x1df3770
|
||||
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df3c80
|
||||
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df4570
|
||||
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df4410
|
||||
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df3cc0
|
||||
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df3da0
|
||||
#define SQLITE3_FINALIZE_OFFSET 0x1df2740
|
||||
|
||||
typedef int (*Sqlite3_callback)(void*, int, char**, char**);
|
||||
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_PAT_MGR_OFFSET 0x8d0c00
|
||||
#define WX_SEND_PAT_MSG_OFFSET 0x1369850
|
||||
#define WX_RET_OFFSET 0x1C94D34
|
||||
#define WX_PAT_MGR_OFFSET 0x931730
|
||||
#define WX_SEND_PAT_MSG_OFFSET 0x1421940
|
||||
#define WX_RET_OFFSET 0x1D58751
|
||||
|
||||
int SendPatMsg(wchar_t* chat_room_id, wchar_t* wxid) {
|
||||
int success = -1;
|
||||
|
||||
+14
-17
@@ -6,24 +6,12 @@
|
||||
#include "wechat_data.h"
|
||||
using namespace std;
|
||||
|
||||
#define WX_SELF_NAME_OFFSET 0x2E2CE48
|
||||
#define WX_SELF_MOBILE_OFFSET 0x2E2CDB8
|
||||
#define WX_SELF_CITY_OFFSET 0x2E2CE18
|
||||
#define WX_SELF_PROVINCE_OFFSET 0x2E2CE00
|
||||
#define WX_SELF_COUNTRY_OFFSET 0x2E2CDE8
|
||||
#define WX_SELF_ACCOUNT_OFFSET 0x2e2d1d0
|
||||
#define WX_SELF_ID_OFFSET 0x2E2CD3C
|
||||
#define WX_SELF_SMALL_IMG_OFFSET 0x2E2D014
|
||||
#define WX_SELF_BIG_IMG_OFFSET 0x2E2CFFC
|
||||
#define WX_LOGIN_STATUS_OFFSET 0x2E2D1C0
|
||||
#define WX_APP_DATA_ROOT_PATH_OFFSET 0x2E73010
|
||||
#define WX_APP_DATA_SAVE_PATH_OFFSET 0x2E52DB0
|
||||
#define WX_CURRENT_DATA_PATH_OFFSET 0x2E4F290
|
||||
|
||||
#define WX_LOGOUT_OFFSET 0xdd5c90
|
||||
#define WX_ACCOUNT_SERVICE_OFFSET 0x707960
|
||||
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xeb4b00
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc11140
|
||||
|
||||
#define WX_LOGOUT_OFFSET 0xe58870
|
||||
#define WX_ACCOUNT_SERVICE_OFFSET 0x768c80
|
||||
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3a610
|
||||
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc872c0
|
||||
int GetSelfInfo(SelfInfoInner &out) {
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD accout_service_addr = base + WX_ACCOUNT_SERVICE_OFFSET;
|
||||
@@ -153,6 +141,15 @@ int GetSelfInfo(SelfInfoInner &out) {
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x4CC) == 0 ||
|
||||
*(DWORD *)(service_addr +0x4D0) == 0) {
|
||||
out.db_key = string();
|
||||
} else {
|
||||
DWORD byte_addr = *(DWORD *)(service_addr + 0x4CC);
|
||||
DWORD len = *(DWORD *)(service_addr +0x4D0);
|
||||
out.db_key = Bytes2Hex((BYTE *)byte_addr,len);
|
||||
}
|
||||
}
|
||||
|
||||
WeChatString data_save_path;
|
||||
|
||||
+5
-5
@@ -3,16 +3,16 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x709bb0
|
||||
#define WX_SEND_FILE_OFFSET 0xb06240
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xed3be0
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
#define WX_APP_MSG_MGR_OFFSET 0x76ae20
|
||||
#define WX_SEND_FILE_OFFSET 0xb6d1f0
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
|
||||
int SendFile(wchar_t *wxid, wchar_t *file_path){
|
||||
int success = 0;
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(file_path);
|
||||
char chat_msg[0x2C4] = {0};
|
||||
char chat_msg[0x2D8] = {0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD app_msg_mgr_addr = base + WX_APP_MSG_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
|
||||
+5
-6
@@ -3,17 +3,16 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
|
||||
#define WX_SEND_IMAGE_OFFSET 0xc71500
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x706d30
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xed3be0
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
|
||||
#define WX_SEND_IMAGE_OFFSET 0xce6640
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768140
|
||||
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
int SendImage(wchar_t *wxid, wchar_t *image_path){
|
||||
|
||||
int success = 0;
|
||||
WeChatString to_user(wxid);
|
||||
WeChatString path(image_path);
|
||||
char chat_msg[0x2C4] ={0};
|
||||
char chat_msg[0x2D8] ={0};
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD init_chat_msg_addr = base + WX_INIT_CHAT_MSG_OFFSET;
|
||||
|
||||
+5
-5
@@ -6,11 +6,11 @@
|
||||
#include "wechat_data.h"
|
||||
#include "contact.h"
|
||||
|
||||
#define WX_SEND_TEXT_OFFSET 0xc71a60
|
||||
#define WX_SEND_TEXT_OFFSET 0xce6c80
|
||||
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x706d30
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768140
|
||||
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
|
||||
using namespace std;
|
||||
/// @brief 发生文本消息
|
||||
/// @param wxid wxid
|
||||
@@ -26,7 +26,7 @@ int SendText(wchar_t* wxid, wchar_t* msg) {
|
||||
DWORD send_message_mgr_addr = base + WX_SEND_MESSAGE_MGR_OFFSET;
|
||||
DWORD send_text_msg_addr = base + WX_SEND_TEXT_OFFSET;
|
||||
DWORD free_chat_msg_addr = base + WX_FREE_CHAT_MSG_OFFSET;
|
||||
char chat_msg[0x2C4] ={0};
|
||||
char chat_msg[0x2D8] ={0};
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL send_message_mgr_addr
|
||||
@@ -59,7 +59,7 @@ int SendAtText(wchar_t* chat_room_id,wchar_t** wxids,int len,wchar_t* msg){
|
||||
for (int i = 0; i < len; i++) {
|
||||
wstring nickname;
|
||||
if (!lstrcmpiW((wchar_t *)wxids[i], (wchar_t *)L"notify@all")) {
|
||||
nickname = L"所有人";
|
||||
nickname = L"������";
|
||||
} else {
|
||||
nickname = GetContactOrChatRoomNickname(wxids[i]);
|
||||
}
|
||||
|
||||
+3
-3
@@ -4,9 +4,9 @@
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
using namespace std;
|
||||
#define WX_SNS_DATA_MGR_OFFSET 0xbc4100
|
||||
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x1427be0
|
||||
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x1427c80
|
||||
#define WX_SNS_DATA_MGR_OFFSET 0xc39680
|
||||
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e2140
|
||||
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e21e0
|
||||
|
||||
int GetFirstPage() {
|
||||
int success = -1;
|
||||
|
||||
@@ -153,6 +153,7 @@ struct SelfInfoInner{
|
||||
std::string data_save_path;
|
||||
std::string signature;
|
||||
std::string current_data_path;
|
||||
std::string db_key;
|
||||
};
|
||||
|
||||
struct UserInfo {
|
||||
|
||||
Reference in New Issue
Block a user