Compare commits

...
Author SHA1 Message Date
ttttupupandGitHub 57ab98351a Merge pull request #493 from rainhon/3.9.2.23-V10
添加微信进入接口 3.9.2.23 v10
2024-11-27 08:49:27 +08:00
rain 88e89c4836 添加进入微信接口 2024-11-26 21:49:40 +08:00
rain 158da3fb64 11 2024-11-15 19:02:31 +08:00
hugy 5e04ddfcd2 doc: update 2023-06-08 09:27:14 +08:00
hugy 6d254c5f82 feat: 修改好友备注 2023-06-08 00:29:52 +08:00
hugy 9b541f993e feat: 3.9.2.23同步3.9.2.26功能 2023-06-07 15:41:31 +08:00
hugy 4cd508506f Merge branch 'dev-3.9.2.26' into dev-3.9.2.23-temp 2023-06-07 13:45:22 +08:00
hugy a777f05512 fix: add friend by wxid . close #148 2023-06-06 16:02:32 +08:00
hugy 926babbc66 test: add http server 2023-06-05 14:19:12 +08:00
hugy bf0018ae05 feat: hook消息增加http支持 2023-06-05 14:10:24 +08:00
hugy d6d650335f feat: hook消息增加http支持 2023-06-05 14:10:01 +08:00
hugy d22aa9de2d fix: sendAppMsg update free addr 2023-06-03 17:06:48 +08:00
hugy 64a603c96b fix: close socket 2023-06-02 23:18:05 +08:00
hugy 63ac97c864 feat: 头像 2023-06-02 14:28:25 +08:00
hugy 1b8c3a851c doc: update doc 2023-06-01 22:06:56 +08:00
hugy d38f413c3d feat: 退款 2023-06-01 22:02:56 +08:00
hugy ef666c59a2 feat: 发送小程序 close issue #158 2023-06-01 21:13:45 +08:00
hugy e0b8805263 doc: 更新注入工具 2023-06-01 08:55:54 +08:00
hugy f36f838726 doc: update 2023-06-01 08:46:18 +08:00
ttttupupandGitHub b37e448d8e Merge pull request #140 from 502647092/dev-3.9.2.23
feat: 0接口 新增二维码登录地址
2023-05-25 22:12:52 +08:00
MiaoWoo bce8ec25af feat: add 新增二维码登录地址 2023-05-25 10:09:48 +08:00
27 changed files with 1264 additions and 209 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ include_directories(${VCPKG_INSTALLED_DIR}/x86-windows/include ${PROJECT_SOURCE
add_subdirectory(spdlog)
# add_subdirectory(source)
add_subdirectory(source)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(unofficial-mongoose CONFIG REQUIRED)
+437 -3
View File
@@ -28,7 +28,7 @@
36.关闭hook日志
40.转发消息
44.退出登录
<!-- 45.确认收款 -->
45.确认收款
46.联系人列表
47.获取群详情
48.获取解密图片
@@ -41,6 +41,16 @@
55.获取联系人或者群名称
56.获取消息附件(图片,视频,文件)
57.获取消息语音文件
58.登录二维码
59.邀请入群
60.获取群/群成员详情
61.撤回消息
62.发送公众号消息
63.转发公众号消息
64.发送小程序
65.退款
66.下载头像
67.修改好友备注
### 接口文档:
@@ -293,7 +303,10 @@
|参数|必选|类型|说明|
|---|---|---|---|
|port |true |string| 本地服务端端口,用来接收消息内容 |
|ip |true |string| 服务端ip地址,用来接收消息内容,可以是任意ip,即tcp客户端连接的服务端的ip (3.8.1.26版本)|
|ip |true |string| 服务端ip地址,用来接收消息内容,可以是任意ip,即tcp客户端连接的服务端的ip |
|url |true |string| http的请求地址,enableHttp=1时,不能为空 |
|timeout |true |string| 超时时间,单位ms|
|enableHttp |true |number| 0/1 :1.启用http 0.不启用http|
###### 返回字段
|返回字段|字段类型|说明 |
@@ -307,7 +320,10 @@
``` javascript
{
"port": "19099"
"ip":"127.0.0.1"
"ip":"127.0.0.1",
"url":"http://test.com",
"timeout":"3000",
"enableHttp":1
}
```
响应:
@@ -1622,6 +1638,424 @@
```
#### 58.登录url**
###### 接口功能
> 登录的url,生成二维码即可扫描登录
###### 接口地址
> [/api/?type=58](/api/?type=58)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
|url|string|登录url|
###### 接口示例
入参:
``` javascript
```
响应:
``` javascript
{"code":1,"result":"OK","url":"https://weixin.qq.com/x/qqqqxxxxxx"}
```
#### 59.邀请入群**
###### 接口功能
> 邀请入群
###### 接口地址
> [/api/?type=58](/api/?type=58)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|chatRoomId|string|群id|
|memberIds|string|成员id,以,分隔|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"chatRoomId":"1111@chatroom",
"memberIds":"wxid_1111"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 60.群/群成员详情**
###### 接口功能
> 邀请入群
###### 接口地址
> [/api/?type=60](/api/?type=60)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_8888"
}
```
响应:
``` javascript
{
"account": "lllla",
"code": 1,
"headImage": "",
"nickname": "昵称",
"result": "OK",
"v3": "v3_020b3sssd031xxxxx05@stranger",
"wxid": "wxid_888888"
}
```
#### 61.撤回消息**
###### 接口功能
> 撤回消息,有时间限制。
###### 接口地址
> [/api/?type=61](/api/?type=61)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|msgId|string|消息id|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"msgId":45645454654654874548888
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 62.发送公众号消息**
###### 接口功能
> 公众号文章分享/转发的功能
###### 接口地址
> [/api/?type=62](/api/?type=62)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|appname|string|消息xml中的appname|
|username|string|消息xml中的username|
|title|string|消息xml中的title,文章的title|
|url|string|消息xml中的url,文章的uerl|
|thumburl|string|消息xml中的thumburl,缩略图|
|digest|string|消息xml中的digest|
|wxid|string|接收人wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"appname": "电手",
"username": "gh_271633b4f577",
"title": "PC硬件、数码产品彻底反转,搞机佬春天回来了",
"url": "http://mp.weixin.qq.com/s?__biz=Mzg3MzY2MjgxMg==&mid=2247712540&idx=1&sn=bd8e8b0d9f2753f3c34a2bfc01770510&chksm=ced16f2ff9a6e639cc9bb76631ff03487f86486f0f29fcf9f8bed754354cb20eda31cc894a56&scene=0&xtrack=1#rd",
"thumburl": "https://mmbiz.qpic.cn/sz_mmbiz_jpg/tpzwaqMCicQyEkBtLgibrKXVKD5gGUEtL00rJ2pxmpmmP9KgoBHiciamYhqZ0ff4kNlnPpnATqozxgRq4AtEzibo4iaw/640?wxtype=jpeg&wxfrom=0",
"digest": "这谁顶得住?",
"wxid": "filehelper"
}
```
响应:
``` javascript
{"code":0,"result":"OK"}
```
#### 63.转发公众号消息**
###### 接口功能
> 转发收到的公众号的文章
###### 接口地址
> [/api/?type=63](/api/?type=63)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|msgId|string|收到的消息msgId,type=49|
|wxid|string|接收人wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"msgId": "123456456456",
"wxid": "filehelper"
}
```
响应:
``` javascript
{"code":0,"result":"OK"}
```
#### 64.发送小程序**
###### 接口功能
> 发送小程序(该接口不是很完善,调用多了就提示操作过于频繁,可稍后再试。有兴趣的可以完善一下)
###### 接口地址
> [/api/?type=64](/api/?type=64)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|appletId|string|小程序id|
|wxid|string|接收人wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"appletId": "wa11223212",
"wxid": "filehelper"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 65.退款**
###### 接口功能
> 收到转账消息后,自动退款。type=49 即是转账消息。
###### 接口地址
> [/api/?type=65](/api/?type=65)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|转账人微信id,从hook的消息中获取|
|transcationId|string|从hook的消息中获取对应的字段内容。|
|transferId|string|从hook的消息中获取对应的字段内容。|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_agz5q76f11112",
"transcationId":"10000500012302060002831233124719620",
"transferId":"10000500012023020619112332136412"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 66.查询或下载头像**
###### 接口功能
> 暂时没用的功能
###### 接口地址
> [/api/?type=66](/api/?type=66)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|微信id|
|imageUrl|string|头像地址|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_agz5q76f11112",
"imageUrl":""
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 67.修改好友备注**
###### 接口功能
> 修改好友备注
###### 接口地址
> [/api/?type=67](/api/?type=67)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|微信id|
|remark|string|备注内容|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_agz5q76f11112",
"remark":"123"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 感谢
https://github.com/ljc545w/ComWeChatRobot
+179 -7
View File
@@ -39,8 +39,10 @@
60.获取群/群成员详情
61.撤回消息
62.发送公众号消息
63.转发公众号消息
64.发送小程序
65.退款
66.下载头像
### 接口文档:
@@ -282,7 +284,10 @@
#### 9.hook消息**
###### 接口功能
> hook接收文本消息,图片消息,群消息.该接口将hook的消息通过tcp回传给本地的端口
> hook接收文本消息,图片消息,群消息.该接口将hook的消息通过tcp回传给本地的端口。
enableHttp=1时,使用url,timeout参数配置服务端的接收地址。请求为post,Content-Type 为json。
enableHttp=0时,使用ip,port的tcp服务回传消息。
###### 接口地址
> [/api/?type=9](/api/?type=9)
@@ -294,7 +299,10 @@
|参数|必选|类型|说明|
|---|---|---|---|
|port |true |string| 本地服务端端口,用来接收消息内容 |
|ip |true |string| 服务端ip地址,用来接收消息内容,可以是任意ip,即tcp客户端连接的服务端的ip (3.8.1.26版本)|
|ip |true |string| 服务端ip地址,用来接收消息内容,可以是任意ip,即tcp客户端连接的服务端的ip |
|url |true |string| http的请求地址,enableHttp=1时,不能为空 |
|timeout |true |string| 超时时间,单位ms|
|enableHttp |true |number| 0/1 :1.启用http 0.不启用http|
###### 返回字段
|返回字段|字段类型|说明 |
@@ -308,7 +316,10 @@
``` javascript
{
"port": "19099"
"ip":"127.0.0.1"
"ip":"127.0.0.1",
"url":"http://test.com",
"timeout":"3000",
"enableHttp":1,
}
```
响应:
@@ -1753,7 +1764,7 @@
> 撤回消息,有时间限制。
###### 接口地址
> [/api/?type=60](/api/?type=61)
> [/api/?type=61](/api/?type=61)
###### HTTP请求方式
> POST JSON
@@ -1793,7 +1804,7 @@
> 公众号文章分享/转发的功能
###### 接口地址
> [/api/?type=60](/api/?type=61)
> [/api/?type=62](/api/?type=62)
###### HTTP请求方式
> POST JSON
@@ -1835,4 +1846,165 @@
响应:
``` javascript
{"code":0,"result":"OK"}
```
#### 63.转发公众号消息**
###### 接口功能
> 转发收到的公众号的文章
###### 接口地址
> [/api/?type=63](/api/?type=63)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|msgId|string|收到的消息msgId,type=49|
|wxid|string|接收人wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 非0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"msgId": "123456456456",
"wxid": "filehelper"
}
```
响应:
``` javascript
{"code":0,"result":"OK"}
```
#### 64.发送小程序**
###### 接口功能
> 发送小程序(该接口不是很完善,调用多了就提示操作过于频繁,可稍后再试。有兴趣的可以完善一下)
###### 接口地址
> [/api/?type=64](/api/?type=64)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|appletId|string|小程序id|
|wxid|string|接收人wxid|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功, 0失败|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"appletId": "wa11223212",
"wxid": "filehelper"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 65.退款**
###### 接口功能
> 收到转账消息后,自动退款。type=49 即是转账消息。
###### 接口地址
> [/api/?type=65](/api/?type=65)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|转账人微信id,从hook的消息中获取|
|transcationId|string|从hook的消息中获取对应的字段内容。|
|transferId|string|从hook的消息中获取对应的字段内容。|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_agz5q76f11112",
"transcationId":"10000500012302060002831233124719620",
"transferId":"10000500012023020619112332136412"
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
#### 66.查询或下载头像**
###### 接口功能
> 暂时没用的功能
###### 接口地址
> [/api/?type=66](/api/?type=66)
###### HTTP请求方式
> POST JSON
###### 请求参数
|参数|必选|类型|说明|
|---|---|---|---|
|wxid|string|微信id|
|imageUrl|string|头像地址|
###### 返回字段
|返回字段|字段类型|说明 |
|---|---|---|
|code|int|返回状态,1成功|
|result|string|成功提示|
###### 接口示例
入参:
``` javascript
{
"wxid":"wxid_agz5q76f11112",
"imageUrl":""
}
```
响应:
``` javascript
{"code":1,"result":"OK"}
```
+26
View 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
+35
View File
@@ -1,6 +1,7 @@
#include "pch.h"
#include "account_mgr.h"
#include "wechat_function.h"
#include "spdlog/spdlog.h"
using namespace std;
namespace wxhelper {
@@ -175,6 +176,11 @@ int AccountMgr::GetSelfInfo(SelfInfoInner &out) {
return 1;
}
string AccountMgr::GetLoginUrl() {
DWORD login_url_addr = base_addr_ + WX_LOGIN_URL_OFFSET;
return "http://weixin.qq.com/x/" + std::string(reinterpret_cast<char*>(*(DWORD*)login_url_addr));
}
int AccountMgr::CheckLogin() {
int success = -1;
DWORD accout_service_addr = base_addr_ + WX_ACCOUNT_SERVICE_OFFSET;
@@ -210,6 +216,35 @@ int AccountMgr::Logout() {
return success;
}
int AccountMgr::EnterWeChat() {
int success = -1;
DWORD enter_wechat_callback_addr = base_addr_ + WX_ENTER_WECHAT_CALLBACK_OFFSET;
std::vector<DWORD> vec;
bool found = Utils::ScanAndMatchValue(base_addr_ + 0x2A66A18, vec);
if (found) {
HANDLE handle = GetCurrentProcess();
for (int i = 0; i < vec.size(); i++) {
DWORD ptr = vec.at(i);
DWORD value;
if (ReadProcessMemory(handle, (LPVOID)ptr, &value, sizeof(value), NULL)) {
if (value == base_addr_ + 0x2A66A18) {
DWORD login_wnd = ptr;
__asm {
PUSHAD
MOV ECX, login_wnd
CALL enter_wechat_callback_addr
POPAD
}
success = 1;
break;
}
}
}
}
return success;
}
/// @brief 根据 502647092 提供的偏移 获取二维码url
/// @return
std::string AccountMgr::GetQRCodeUrl() {
+5
View File
@@ -8,6 +8,9 @@ namespace wxhelper{
public:
explicit AccountMgr(DWORD base);
~AccountMgr();
std::string GetLoginUrl();
int GetSelfInfo(SelfInfoInner& out);
int CheckLogin();
@@ -15,6 +18,8 @@ namespace wxhelper{
int Logout();
std::string GetQRCodeUrl();
int EnterWeChat();
};
}
+5
View File
@@ -77,6 +77,11 @@ typedef enum HTTP_API_ROUTE {
WECHAT_REVOKE_MSG,
WECHAT_FORWARD_PUBLIC_MSG,
WECHAT_FORWARD_PUBLIC_MSG_BY_SVRID,
WECHAT_SEND_APP_MSG,
WECHAT_REFUSE,
WECHAT_GET_HEAD_IMG,
WECHAT_MOD_CONTACT_REMARK,
WECHAT_ENTER_WECHAT,
} WECHAT_HTTP_APIS,
*PWECHAT_HTTP_APIS;
+5 -5
View File
@@ -390,11 +390,11 @@ int ChatRoomMgr::InviteMemberToChatRoom(wchar_t* chat_room_id, wchar_t** wxids,
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
DWORD get_share_record_mgr_addr = base_addr_ + WX_SHARE_RECORD_MGR_OFFSET;
DWORD fn1 = base_addr_ + 0x7fa730;
DWORD fn2 = base_addr_ + 0x78d9a0;
DWORD fn3 = base_addr_ + 0x7fb6e0;
DWORD fn4 = base_addr_ + 0x755af0;
DWORD invite_addr = base_addr_ + 0xbd28a0;
DWORD fn1 = base_addr_ + 0x7f99d0;
DWORD fn2 = base_addr_ + 0x78cef0;
DWORD fn3 = base_addr_ + 0x7fa980;
DWORD fn4 = base_addr_ + 0x755060;
DWORD invite_addr = base_addr_ + 0xbd1a00;
DWORD sys_addr = (DWORD)GetModuleHandleA("win32u.dll") + 0x116C;
DWORD addr[2] = {sys_addr,0};
+54 -4
View File
@@ -131,13 +131,17 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
WeChatString w_msg(msg);
DWORD instance =0;
Unkown null_obj={0,0,0,0,0,0xF};
// EDI,0xE ESI,0 all
// EDI,0xE ESI,8 only chat
// EDI,0xE ESI,1 no let look
// EDI,0xE ESI,2 no look
__asm{
PUSHAD
PUSHFD
CALL contact_mgr_addr
MOV dword ptr [instance],EAX
MOV EDI,0x6
MOV ESI,0
MOV EDI,0xE
MOV ESI,0x8
MOV EAX,0x2
SUB ESP,0x18
MOV EAX,ESP
@@ -150,8 +154,8 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
MOV ECX,ESP
PUSH EAX
CALL fn1_addr
PUSH 0x0
PUSH 0x6
PUSH ESI
PUSH EDI
MOV EAX,w_msg
SUB ESP,0x14
@@ -255,4 +259,50 @@ int ContactMgr::AddFriendByWxid(wchar_t *wxid,wchar_t* msg) {
success = 1;
return success;
}
int ContactMgr::GetHeadImage(wchar_t* wxid,wchar_t* url){
int success = -1;
WeChatString contact(wxid);
WeChatString img_url(url);
DWORD head_image_mgr_addr = base_addr_ + WX_HEAD_IMAGE_MGR_OFFSET;
DWORD get_img_download_addr = base_addr_ + QUERY_THEN_DOWNLOAD_OFFSET;
char temp[0x8] ={0};
__asm{
PUSHAD
PUSHFD
CALL head_image_mgr_addr
LEA ECX,img_url
PUSH ECX
LEA ECX,contact
PUSH ECX
LEA ECX,temp
PUSH ECX
MOV ECX,EAX
CALL get_img_download_addr
POPFD
POPAD
}
success = 1;
return success;
}
int ContactMgr::ModifyContactRemark(wchar_t* wxid,wchar_t* remark){
int success = -1;
WeChatString contact(wxid);
WeChatString content(remark);
DWORD mod__addr = base_addr_ + WX_MOD_REMARK_OFFSET;
__asm{
PUSHAD
PUSHFD
LEA EAX,content
PUSH EAX
LEA EAX,contact
PUSH EAX
CALL mod__addr
POPFD
POPAD
}
success = 1;
return success;
}
} // namespace wxhelper
+2
View File
@@ -16,6 +16,8 @@ class ContactMgr : public BaseMgr {
int AddFriendByWxid(wchar_t* wxid,wchar_t* msg);
int VerifyApply(wchar_t *v3, wchar_t *v4,int permission);
int GetContactByWxid(wchar_t* wxid,ContactProfile& profile);
int GetHeadImage(wchar_t* wxid,wchar_t* url);
int ModifyContactRemark(wchar_t* wxid,wchar_t* remark);
};
} // namespace wxhelper
-1
View File
@@ -3,7 +3,6 @@
#include <string>
#include <vector>
#include "base_mgr.h"
#include "wechat_function.h"
#include "windows.h"
#include "singleton.h"
+1 -2
View File
@@ -18,7 +18,7 @@ void GlobalContext::initialize(HMODULE module) {
#ifndef _DEBUG
hide_module->Hide(module_);
#endif
ThreadPool::GetInstance().Create(2,8);
HttpServer::GetInstance().Init(config->GetPort());
HttpServer::GetInstance().HttpStart();
DB::GetInstance().init(base);
@@ -28,7 +28,6 @@ void GlobalContext::initialize(HMODULE module) {
account_mgr.emplace(AccountMgr{base});
chat_room_mgr.emplace(ChatRoomMgr{base});
sns_mgr.emplace(SNSMgr{base});
ThreadPool::GetInstance().Create(1,512);
}
void GlobalContext::finally() {
+51 -75
View File
@@ -5,8 +5,10 @@
#include <nlohmann/json.hpp>
#include "thread_pool.h"
#include "wechat_function.h"
#include "http_client.h"
using namespace nlohmann;
using namespace std;
namespace wxhelper {
namespace hooks {
static int server_port_ = 0;
@@ -43,53 +45,7 @@ static DWORD user_info_next_addr_ = 0;
UserInfo userinfo = {};
void SendSocketMessage(InnerMessageStruct *msg) {
if (msg == NULL) {
return;
}
unique_ptr<InnerMessageStruct> sms(msg);
json j_msg =
json::parse(msg->buffer, msg->buffer + msg->length, nullptr, false);
if (j_msg.is_discarded() == true) {
return;
}
string jstr = j_msg.dump() + "\n";
if (server_port_ == 0) {
SPDLOG_ERROR("http server port error :{}",server_port_);
return;
}
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_socket < 0) {
SPDLOG_ERROR("socket init fail");
return;
}
BOOL status = false;
sockaddr_in client_addr;
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons((u_short)server_port_);
InetPtonA(AF_INET, server_ip_, &client_addr.sin_addr.s_addr);
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
sizeof(sockaddr)) < 0) {
SPDLOG_ERROR("socket connect fail");
return;
}
char recv_buf[1024] = {0};
int ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
if (ret == -1 || ret == 0) {
SPDLOG_ERROR("socket send fail ,ret::{}",ret);
closesocket(client_socket);
return;
}
memset(recv_buf, 0, sizeof(recv_buf));
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
closesocket(client_socket);
if (ret == -1 || ret == 0) {
SPDLOG_ERROR("socket recv fail ,ret:{}",ret);
return;
}
}
static bool enable_http_ = false;
VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work) {
@@ -131,38 +87,49 @@ VOID CALLBACK SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
sizeof(sockaddr)) < 0) {
SPDLOG_ERROR("socket connect fail");
closesocket(client_socket);
WSACleanup();
return ;
goto clean;
}
char recv_buf[1024] = {0};
ret = send(client_socket, jstr.c_str(), jstr.size(), 0);
if (ret == -1 || ret == 0) {
if (ret < 0) {
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
closesocket(client_socket);
WSACleanup();
return;
goto clean;
}
ret = shutdown(client_socket, SD_SEND);
if (ret == SOCKET_ERROR) {
SPDLOG_ERROR("shutdown failed with erro:{}", ret);
closesocket(client_socket);
WSACleanup();
return ;
goto clean;
}
memset(recv_buf, 0, sizeof(recv_buf));
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
closesocket(client_socket);
if (ret == -1 || ret == 0) {
if (ret < 0) {
SPDLOG_ERROR("socket recv fail ,ret:{}", ret);
WSACleanup();
return;
goto clean;
}
clean:
closesocket(client_socket);
WSACleanup();
return;
}
VOID CALLBACK SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
PTP_WORK Work) {
InnerMessageStruct *msg = (InnerMessageStruct *)context;
if (msg == NULL) {
SPDLOG_INFO("http msg is null");
return;
}
unique_ptr<InnerMessageStruct> sms(msg);
json j_msg =
json::parse(msg->buffer, msg->buffer + msg->length, nullptr, false);
if (j_msg.is_discarded() == true) {
return;
}
string jstr = j_msg.dump() + "\n";
HttpClient::GetInstance().SendRequest(jstr);
}
void __cdecl OnRecvMsg(DWORD msg_addr) {
json j_msg;
unsigned long long msgid = *(unsigned long long *)(msg_addr + 0x30);
@@ -210,13 +177,14 @@ void __cdecl OnRecvMsg(DWORD msg_addr) {
inner_msg->buffer = new char[jstr.size() + 1];
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
inner_msg->length = jstr.size();
bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback,inner_msg);
SPDLOG_INFO("add work:{}",add);
// HANDLE thread = CreateThread(
// NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
// if (thread) {
// CloseHandle(thread);
// }
if(enable_http_){
bool add = ThreadPool::GetInstance().AddWork(SendHttpMsgCallback,inner_msg);
SPDLOG_INFO("add http msg work:{}",add);
}else{
bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback,inner_msg);
SPDLOG_INFO("add msg work:{}",add);
}
}
@@ -263,10 +231,12 @@ void __cdecl OnSnsTimeLineMsg(DWORD msg_addr) {
inner_msg->buffer = new char[jstr.size() + 1];
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
inner_msg->length = jstr.size();
HANDLE thread = CreateThread(
NULL, 0, (LPTHREAD_START_ROUTINE)SendSocketMessage, inner_msg, NULL, 0);
if (thread) {
CloseHandle(thread);
if(enable_http_){
bool add = ThreadPool::GetInstance().AddWork(SendHttpMsgCallback,inner_msg);
SPDLOG_INFO("add http msg work:{}",add);
}else{
bool add = ThreadPool::GetInstance().AddWork(SendMsgCallback,inner_msg);
SPDLOG_INFO("add msg work:{}",add);
}
}
@@ -285,7 +255,12 @@ _declspec(naked) void HandleSNSMsg() {
}
}
int HookRecvMsg(char *client_ip, int port) {
int HookRecvMsg(char *client_ip, int port,char* url,uint64_t timeout,bool enable) {
enable_http_ = enable;
if(enable_http_){
HttpClient::GetInstance().SetConfig(url,timeout);
}
server_port_ = port;
strcpy_s(server_ip_, client_ip);
DWORD base = Utils::GetWeChatWinBase();
@@ -317,6 +292,7 @@ int HookRecvMsg(char *client_ip, int port) {
int UnHookRecvMsg() {
server_port_ = 0;
enable_http_ = false;
if (!msg_hook_flag_) {
SPDLOG_INFO("recv msg hook already called");
return 2;
+1 -1
View File
@@ -7,7 +7,7 @@ namespace hooks {
extern UserInfo userinfo;
extern bool user_info_flag_ ;
int HookRecvMsg(char* client_ip, int port);
int HookRecvMsg(char* client_ip, int port,char* url,uint64_t timeout,bool enable);
int UnHookRecvMsg();
+65
View File
@@ -0,0 +1,65 @@
#include "pch.h"
#include "http_client.h"
namespace wxhelper {
void HttpClient::SendRequest(std::string content) {
struct mg_mgr mgr;
Data data ;
data.done = false;
data.post_data = content;
mg_mgr_init(&mgr);
mg_http_connect(&mgr, url_.c_str(), OnHttpEvent, &data);
while (!data.done){
mg_mgr_poll(&mgr, 500);
}
mg_mgr_free(&mgr);
}
void HttpClient::OnHttpEvent(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
const char * s_url = GetInstance().url_.c_str();
Data data = *(Data*)fn_data;
if (ev == MG_EV_OPEN) {
// Connection created. Store connect expiration time in c->data
*(uint64_t *) c->data = mg_millis() + GetInstance().timeout_;
} else if (ev == MG_EV_POLL) {
if (mg_millis() > *(uint64_t *) c->data &&
(c->is_connecting || c->is_resolving)) {
mg_error(c, "Connect timeout");
}
} else if (ev == MG_EV_CONNECT) {
struct mg_str host = mg_url_host(s_url);
if (mg_url_is_ssl(s_url)) {
// no implement
}
// Send request
int content_length = data.post_data.size();
mg_printf(c,
"POST %s HTTP/1.0\r\n"
"Host: %.*s\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"\r\n",
mg_url_uri(s_url), (int) host.len,
host.ptr, content_length);
mg_send(c, data.post_data.c_str(), content_length);
} else if (ev == MG_EV_HTTP_MSG) {
// Response is received. Print it
#ifdef _DEBUG
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
printf("%.*s", (int) hm->message.len, hm->message.ptr);
#endif
c->is_closing = 1; // Tell mongoose to close this connection
data.done = true; // Tell event loop to stops
} else if (ev == MG_EV_ERROR) {
data.done = true; // Error, tell event loop to stop
}
}
void HttpClient::SetConfig(char* url,uint64_t timeout){
url_=url;
timeout_=timeout;
}
} // namespace wxhelper
+24
View File
@@ -0,0 +1,24 @@
#ifndef WXHELPER_HTTP_CLIENT_H_
#define WXHELPER_HTTP_CLIENT_H_
#include "mongoose.h"
#include "singleton.h"
namespace wxhelper {
struct Data {
bool done;
std::string post_data;
};
class HttpClient : public Singleton<HttpClient> {
public:
void SendRequest(std::string content);
void SetConfig(char* url,uint64_t timeout);
static void OnHttpEvent(struct mg_connection *c, int ev, void *ev_data,
void *fn_data);
private:
std::string url_;
uint64_t timeout_;
};
} // namespace wxhelper
#endif
+53 -4
View File
@@ -93,7 +93,7 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
case WECHAT_IS_LOGIN: {
int success = -1;
success = g_context.account_mgr->CheckLogin();
json ret_data = {{"result", "OK"}, {"code", success}};
json ret_data = {{"result", "OK"}, {"code", success}, {"login_url", g_context.account_mgr->GetLoginUrl()}};
ret = ret_data.dump();
break;
}
@@ -171,12 +171,21 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
break;
}
case WECHAT_MSG_START_HOOK: {
int port = GetIntParam(j_param, "port");
wstring ip = GetWStringParam(j_param, "ip");
string client_ip = Utils::WstringToUTF8(ip);
int enable = GetIntParam(j_param, "enableHttp");
string s_url ="";
int timeout = 0;
if(enable){
wstring url = GetWStringParam(j_param, "url");
timeout = GetIntParam(j_param, "timeout");
s_url = Utils::WstringToUTF8(url);
}
char ip_cstr[16];
strcpy_s(ip_cstr, client_ip.c_str());
int success = hooks::HookRecvMsg(ip_cstr, port);
int success = hooks::HookRecvMsg(ip_cstr, port,(char *)s_url.c_str(),timeout,enable);
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
@@ -429,9 +438,9 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
wstring wxid = GetWStringParam(j_param, "wxid");
wstring transcationid = GetWStringParam(j_param, "transcationId");
wstring transferid = GetWStringParam(j_param, "transferId");
BOOL response =g_context.misc_mgr->DoConfirmReceipt(
int success =g_context.misc_mgr->DoConfirmReceipt(
WS2LPWS(wxid), WS2LPWS(transcationid), WS2LPWS(transferid));
json ret_data = {{"msg", response}, {"result", "OK"}};
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
@@ -642,6 +651,46 @@ string Dispatch(struct mg_connection *c, struct mg_http_message *hm) {
ret = ret_data.dump();
break;
}
case WECHAT_SEND_APP_MSG:{
wstring wxid = GetWStringParam(j_param, "wxid");
wstring applet = GetWStringParam(j_param, "appletId");
int success= g_context.send_mgr->SendAppletMsg(WS2LPWS(wxid),WS2LPWS(applet));
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_REFUSE:{
wstring wxid = GetWStringParam(j_param, "wxid");
wstring transcationid = GetWStringParam(j_param, "transcationId");
wstring transferid = GetWStringParam(j_param, "transferId");
int success =g_context.misc_mgr->DoRefuseReceipt(
WS2LPWS(wxid), WS2LPWS(transcationid), WS2LPWS(transferid));
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_GET_HEAD_IMG:{
wstring wxid = GetWStringParam(j_param, "wxid");
wstring url = GetWStringParam(j_param, "imageUrl");
int success =g_context.contact_mgr->GetHeadImage(WS2LPWS(wxid), WS2LPWS(url));
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_MOD_CONTACT_REMARK:{
wstring wxid = GetWStringParam(j_param, "wxid");
wstring remark = GetWStringParam(j_param, "remark");
int success =g_context.contact_mgr->ModifyContactRemark(WS2LPWS(wxid), WS2LPWS(remark));
json ret_data = {{"code", success}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_ENTER_WECHAT: {
int success = g_context.account_mgr->EnterWeChat();
json ret_data = { {"code", success}, {"result", "OK"} };
ret = ret_data.dump();
break;
}
default:
json ret_data = {{"result", "ERROR"}, {"msg", "not support api"}};
ret = ret_data.dump();
+38
View File
@@ -135,6 +135,44 @@ int MiscMgr::DoConfirmReceipt(wchar_t *wxid, wchar_t *transcationid,
return success;
}
int MiscMgr::DoRefuseReceipt(wchar_t *wxid, wchar_t *transcationid,
wchar_t *transferid) {
int success = -1;
WeChatString recv_id(wxid);
WeChatString transcation_id(transcationid);
WeChatString transfer_id(transferid);
char pay_info[0x134] = {0};
DWORD new_pay_info_addr = base_addr_ + WX_NEW_WCPAYINFO_OFFSET;
DWORD free_pay_info_addr = base_addr_ + WX_FREE_WCPAYINFO_OFFSET;
DWORD do_confirm_addr = base_addr_ + WX_CONFIRM_RECEIPT_OFFSET;
__asm {
PUSHAD
LEA ECX,pay_info
CALL new_pay_info_addr
MOV dword ptr [pay_info + 0x4], 0x1
MOV dword ptr [pay_info + 0x4C], 0x1
POPAD
}
memcpy(&pay_info[0x1c], &transcation_id, sizeof(transcation_id));
memcpy(&pay_info[0x38], &transfer_id, sizeof(transfer_id));
__asm {
PUSHAD
PUSH 0x0
SUB ESP,0x8
LEA EDX,recv_id
LEA ECX,pay_info
CALL do_confirm_addr
MOV success,EAX
ADD ESP,0xC
PUSH 0x0
LEA ECX,pay_info
CALL free_pay_info_addr
POPAD
}
return success;
}
int MiscMgr::DoDownloadTask(ULONG64 msg_id) {
int success = -1;
int db_index = 0;
+2
View File
@@ -13,6 +13,8 @@ class MiscMgr :public BaseMgr{
int DoOCRTask(wchar_t* img_path, std::string& result);
int DoConfirmReceipt(wchar_t* wxid, wchar_t* transcationid,
wchar_t* transferid);
int DoRefuseReceipt(wchar_t* wxid, wchar_t* transcationid,
wchar_t* transferid);
int DoDownloadTask(ULONG64 msg_id);
int GetVoice(ULONG64 msg_id, wchar_t* dir);
+92 -1
View File
@@ -371,4 +371,95 @@ int SendMessageMgr::ForwardPublicMsgByMsgSvrId(wchar_t *wxid, unsigned long long
return code;
}
} // namespace wxhelper
int SendMessageMgr::SendAppletMsg(wchar_t* wxid, wchar_t* appletid){
int success = -1;
DWORD init_chat_msg_addr = base_addr_ + WX_INIT_CHAT_MSG_OFFSET;
DWORD new_share_app_msg_req_addr = base_addr_ + NEW_SHARE_APP_MSG_REQ_OFFSET;
DWORD free_share_app_msg_req_addr = base_addr_ + FREE_SHARE_APP_MSG_REQ_OFFSET;
DWORD send_app_msg_addr = base_addr_ + SEND_APP_MSG_OFFSET;
DWORD new_wa_updatable_msg_info_addr = base_addr_ + NEW_WA_UPDATABLE_MSG_INFO_OFFSET;
DWORD free_wa_addr = base_addr_ + FREE_WA_UPDATABLE_MSG_INFO_OFFSET;
std::wstring applet_id(appletid);
std::string s_applet_id = Utils::WCharToUTF8(appletid);
const char * c_applet_id = s_applet_id.c_str();
std::vector<WeChatString> receiver_list;
WeChatString wwxid(wxid);
receiver_list.push_back(wwxid);
VectorInner* list = (VectorInner*)&receiver_list;
DWORD receiver_list_ptr = (DWORD)&list->start;
WeChatString wapplet(appletid);
char req[0x268] = {0};
char temp[0x4] = {0};
char buff[0x88] = {0};
DWORD flag = 0xF;
DWORD zero = 0;
WeChatStr clean;
WeChatStr app_id(c_applet_id);
__asm{
PUSHAD
PUSHFD
LEA ECX,req
CALL new_share_app_msg_req_addr
POPFD
POPAD
}
// 0x40 gh
// 0xE8 img
memcpy(&req[0x4], &app_id, sizeof(app_id));
__asm{
PUSHAD
PUSHFD
LEA ECX,buff
CALL new_wa_updatable_msg_info_addr
LEA EAX,buff
PUSH EAX
SUB ESP,0x14
MOV ESI,ESP
MOV dword ptr [EBP - 0x280],ESP
MOV dword ptr [EBP - 0x27c],ESI
MOV dword ptr [ESI],0x0
MOV dword ptr [ESI + 0x4],0
MOV dword ptr [ESI + 0x8],0
MOV dword ptr [ESI + 0xc],0
MOV dword ptr [ESI + 0x10],0
LEA EAX,req
PUSH EAX
MOV EAX,dword ptr[receiver_list_ptr]
PUSH EAX
SUB ESP,0x14
LEA EAX,wapplet
MOV ECX,ESP
PUSH EAX
CALL init_chat_msg_addr
LEA ECX,temp
CALL send_app_msg_addr
MOV success,EAX
LEA ECX,buff
CALL free_wa_addr
POPFD
POPAD
}
// no need for WeChat to release memory
memcpy(&req[0x4], &clean, sizeof(clean));
memcpy(&req[0xC8], &zero, sizeof(zero));
memcpy(&req[0xCC], &flag, sizeof(flag));
__asm {
PUSHAD
PUSHFD
LEA ECX,req
CALL free_share_app_msg_req_addr
POPFD
POPAD
}
return success;
}
} // namespace wxhelperg
+1
View File
@@ -13,6 +13,7 @@ class SendMessageMgr:public BaseMgr {
int ForwardMsg(wchar_t *wxid, unsigned long long msgid);
int ForwardPublicMsg(wchar_t* wxid, wchar_t* title, wchar_t* url, wchar_t* thumburl,wchar_t* senderId,wchar_t* senderName,wchar_t* digest);
int ForwardPublicMsgByMsgSvrId(wchar_t *wxid, unsigned long long msgid);
int SendAppletMsg(wchar_t* wxid, wchar_t* appletid);
private:
};
+10 -3
View File
@@ -6,10 +6,16 @@
namespace wxhelper {
ThreadPool::~ThreadPool() {
CloseThreadpoolCleanupGroupMembers(cleanup_group_, true, NULL);
CloseThreadpoolCleanupGroup(cleanup_group_);
CloseThreadpool(pool_);
if(cleanup_group_){
CloseThreadpoolCleanupGroupMembers(cleanup_group_, true, NULL);
CloseThreadpoolCleanupGroup(cleanup_group_);
}
DestroyThreadpoolEnvironment(&env_);
if (pool_){
CloseThreadpool(pool_);
}
}
bool ThreadPool::Create(unsigned long min, unsigned long max) {
InitializeThreadpoolEnvironment(&env_);
pool_ = CreateThreadpool(NULL);
@@ -38,4 +44,5 @@ bool ThreadPool::AddWork(PTP_WORK_CALLBACK callback,PVOID opt) {
SubmitThreadpoolWork(work);
return true;
}
} // namespace wxhelper
-3
View File
@@ -13,9 +13,6 @@ class ThreadPool :public Singleton<ThreadPool>{
bool AddWork(PTP_WORK_CALLBACK callback,PVOID opt);
private:
void operator=(const ThreadPool&) = delete;
void operator=(ThreadPool&&) = delete;
PTP_POOL pool_;
PTP_CLEANUP_GROUP cleanup_group_;
TP_CALLBACK_ENVIRON env_;
+32
View File
@@ -211,4 +211,36 @@ bool Utils::IsTextUtf8(const char *str,int length) {
}
return (bytes_num == 0);
}
bool Utils::ScanAndMatchValue(DWORD value, std::vector<DWORD>& result) {
SYSTEM_INFO sys_info;
GetSystemInfo(&sys_info);
LPVOID current_addr = sys_info.lpMinimumApplicationAddress;
DWORD pageSize = sys_info.dwPageSize;
MEMORY_BASIC_INFORMATION mem_info = {};
HANDLE handle = GetCurrentProcess();
while (current_addr < sys_info.lpMaximumApplicationAddress) {
if (VirtualQueryEx(handle, current_addr, &mem_info, sizeof(MEMORY_BASIC_INFORMATION))) {
if (mem_info.State == MEM_COMMIT && (mem_info.Protect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE))) {
// 读取内存并搜索值
LPVOID pBuffer = new BYTE[mem_info.RegionSize];
if (ReadProcessMemory(handle, mem_info.BaseAddress, pBuffer, mem_info.RegionSize, NULL)) {
for (DWORD i = 0; i < mem_info.RegionSize; i += sizeof(DWORD)) {
if (*(PDWORD)((LPBYTE)pBuffer + i) == value) {
result.push_back((DWORD)mem_info.BaseAddress + i);
}
}
}
delete[] pBuffer;
}
current_addr = (LPBYTE)mem_info.BaseAddress + mem_info.RegionSize;
}
else {
current_addr = (LPBYTE)current_addr + pageSize;
}
};
return !result.empty();
}
} // namespace wxhelper
+2
View File
@@ -49,6 +49,8 @@ class Utils {
static bool IsTextUtf8(const char * str,int length) ;
static bool ScanAndMatchValue(DWORD value, std::vector<DWORD>& result);
template <typename T1, typename T2>
static std::vector<T1> split(T1 str, T2 letter) {
std::vector<T1> arr;
+143 -99
View File
@@ -4,145 +4,150 @@
#include <string>
// snsDataMgr
#define WX_SNS_DATA_MGR_OFFSET 0xc3a500
#define WX_SNS_DATA_MGR_OFFSET 0xc39680
// chatRoomMgr
#define WX_CHAT_ROOM_MGR_OFFSET 0x78d9d0
#define WX_CHAT_ROOM_MGR_OFFSET 0x78cf20
// contactMgr
#define WX_CONTACT_MGR_OFFSET 0x75af30
#define WX_CONTACT_MGR_OFFSET 0x75a4a0
// syncMgr
#define WX_SYNC_MGR_OFFSET 0xa87fd0
// preDownloadMgr
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80fe50
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80f110
// chatMgr
#define WX_CHAT_MGR_OFFSET 0x7931b0
#define WX_CHAT_MGR_OFFSET 0x792700
// videoMgr
#define WX_VIDEO_MGR_OFFSET 0x82a560
#define WX_VIDEO_MGR_OFFSET 0x829820
// patMgr
#define WX_PAT_MGR_OFFSET 0x932470
#define WX_PAT_MGR_OFFSET 0x931730
// searchContactMgr
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6d860
#define WX_SEARCH_CONTACT_MGR_OFFSET 0xa6cb00
// appMsgMgr
#define WX_APP_MSG_MGR_OFFSET 0x76b8c0
#define WX_APP_MSG_MGR_OFFSET 0x76ae20
// sendMessageMgr
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768be0
#define WX_SEND_MESSAGE_MGR_OFFSET 0x768140
// shareRecordMgr
#define WX_SHARE_RECORD_MGR_OFFSET 0x78d5f0
#define WX_SHARE_RECORD_MGR_OFFSET 0x78cb40
// headImageMgr
#define WX_HEAD_IMAGE_MGR_OFFSET 0x807b00
// setChatMsgValue
#define WX_INIT_CHAT_MSG_OFFSET 0xf5b3f0
#define WX_INIT_CHAT_MSG_OFFSET 0xf59e40
// chatMsg
#define WX_NEW_CHAT_MSG_OFFSET 0x76fab0
#define WX_FREE_CHAT_MSG_OFFSET 0x7573f0
#define WX_NEW_CHAT_MSG_OFFSET 0x76f010
#define WX_FREE_CHAT_MSG_OFFSET 0x756960
// #define WX_FREE_CHAT_MSG_2_OFFSET 0x6f4ea0
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x7578c0
#define WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET 0x756e30
//sns
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e36e0
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e3780
#define WX_SNS_GET_FIRST_PAGE_OFFSET 0x14e2140
#define WX_SNS_GET_NEXT_PAGE_OFFSET 0x14e21e0
//chat room
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbdef30
#define WX_GET_CHAT_ROOM_DETAIL_INFO_OFFSET 0xbde090
// chatRoomInfo
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe9abd0
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe9aed0
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd3140
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd2c60
#define WX_NEW_CHAT_ROOM_INFO_OFFSET 0xe99c40
#define WX_FREE_CHAT_ROOM_INFO_OFFSET 0xe99f40
#define WX_DEL_CHAT_ROOM_MEMBER_OFFSET 0xbd22a0
#define WX_ADD_MEMBER_TO_CHAT_ROOM_OFFSET 0xbd1dc0
// chatRoom
#define WX_INIT_CHAT_ROOM_OFFSET 0xe98820
#define WX_FREE_CHAT_ROOM_OFFSET 0xe98a40
#define WX_INIT_CHAT_ROOM_OFFSET 0xe97890
#define WX_FREE_CHAT_ROOM_OFFSET 0xe97ab0
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbe0100
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbda520
#define WX_GET_MEMBER_FROM_CHAT_ROOM_OFFSET 0xbdf260
#define WX_MOD_CHAT_ROOM_MEMBER_NICK_NAME_OFFSET 0xbd9680
#define WX_TOP_MSG_OFFSET 0xbe26e0
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe24c0
#define WX_TOP_MSG_OFFSET 0xbe1840
#define WX_REMOVE_TOP_MSG_OFFSET 0xbe1620
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbe0290
#define WX_GET_MEMBER_NICKNAME_OFFSET 0xbdf3f0
#define WX_FREE_CONTACT_OFFSET 0xea8800
#define WX_FREE_CONTACT_OFFSET 0xea7880
// wcpayinfo
#define WX_NEW_WCPAYINFO_OFFSET 0x7b3900
#define WX_FREE_WCPAYINFO_OFFSET 0x79cd00
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e41d0
#define WX_NEW_WCPAYINFO_OFFSET 0x7b2e60
#define WX_FREE_WCPAYINFO_OFFSET 0x79c250
#define WX_CONFIRM_RECEIPT_OFFSET 0x15e2c20
//contact
#define WX_CONTACT_GET_LIST_OFFSET 0xc09890
#define WX_CONTACT_GET_LIST_OFFSET 0xc089f0
#define WX_CONTACT_DEL_OFFSET 0xb9b3b0
#define WX_SET_VALUE_OFFSET 0x1f80900
#define WX_DO_DEL_CONTACT_OFFSET 0xca6480
#define WX_GET_CONTACT_OFFSET 0xc05ca0
#define WX_DO_VERIFY_USER_OFFSET 0xc02f90
#define WX_VERIFY_MSG_OFFSET 0xf5b2f0
#define WX_VERIFY_OK_OFFSET 0xa19940
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa18ac0
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa18be0
#define WX_GET_CONTACT_OFFSET 0xc04e00
#define WX_DO_VERIFY_USER_OFFSET 0xc02100
#define WX_VERIFY_MSG_OFFSET 0xf59d40
#define WX_VERIFY_OK_OFFSET 0xa18bd0
#define WX_NEW_ADD_FRIEND_HELPER_OFFSET 0xa17d50
#define WX_FREE_ADD_FRIEND_HELPER_OFFSET 0xa17e70
#define WX_MOD_REMARK_OFFSET 0xbfd5e0
// pushAttachTask
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82c880
#define WX_PUSH_ATTACH_TASK_OFFSET 0x82bb40
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc11d0
#define WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET 0xbc0370
#define WX_APP_MSG_INFO_OFFSET 0x7b3d20
#define WX_GET_APP_MSG_XML_OFFSET 0xe628a0
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79e3b0
#define WX_PUSH_THUMB_TASK_OFFSET 0x82c780
#define WX_FREE_APP_MSG_INFO_OFFSET 0x79d900
#define WX_PUSH_THUMB_TASK_OFFSET 0x82ba40
#define WX_DOWNLOAD_VIDEO_IMG_OFFSET 0xd46c30
// revoke
#define WX_REVOKE_MSG_OFFSET 0xbb6dc0
#define WX_REVOKE_MSG_OFFSET 0xbb5f70
// pat
#define WX_SEND_PAT_MSG_OFFSET 0x1422f30
#define WX_RET_OFFSET 0x1D59DB1
#define WX_SEND_PAT_MSG_OFFSET 0x1421940
#define WX_RET_OFFSET 0x1D58751
//search hook
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17ed4
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf58fd0
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8dc00
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8de50
#define WX_SEARCH_CONTACT_OFFSET 0xcd2370
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_OFFSET 0xe17054
#define WX_SEARCH_CONTACT_ERROR_CODE_HOOK_NEXT_OFFSET 0xf57a20
#define WX_SEARCH_CONTACT_DETAIL_HOOK_OFFSET 0xa8ceb0
#define WX_SEARCH_CONTACT_DETAIL_HOOK_NEXT_OFFSET 0xa8d100
#define WX_SEARCH_CONTACT_OFFSET 0xcd1510
//login
#define WX_LOGOUT_OFFSET 0xe596d0
#define WX_ACCOUNT_SERVICE_OFFSET 0x769720
#define WX_GET_APP_DATA_SAVE_PATH_OFFSET 0xf3bbd0
#define WX_GET_CURRENT_DATA_PATH_OFFSET 0xc88120
#define WX_QR_CODE_LOGIN_MGR_OFFSET 0xaeab70
#define WX_GET_QR_CODE_IMAGE_OFFSET 0xcdb560
#define WX_LOGIN_URL_OFFSET 0x3040DE8
#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
#define WX_QR_CODE_LOGIN_MGR_OFFSET 0xae9db0
#define WX_GET_QR_CODE_IMAGE_OFFSET 0xcda6f0
#define WX_ENTER_WECHAT_CALLBACK_OFFSET 0xaf5050
//forward
#define WX_FORWARD_MSG_OFFSET 0xce75a0
#define WX_FORWARD_MSG_OFFSET 0xce6730
// send file
#define WX_SEND_FILE_OFFSET 0xb6dfd0
#define WX_SEND_FILE_OFFSET 0xb6d1f0
// send image
#define WX_SEND_IMAGE_OFFSET 0xce74b0
#define WX_SEND_IMAGE_OFFSET 0xce6640
// send text
#define WX_SEND_TEXT_OFFSET 0xce7af0
#define WX_SEND_TEXT_OFFSET 0xce6c80
//ocr
#define WX_INIT_OBJ_OFFSET 0x80b540
#define WX_OCR_MANAGER_OFFSET 0x80ffc0
#define WX_DO_OCR_TASK_OFFSET 0x13db9a0
#define WX_INIT_OBJ_OFFSET 0x80a800
#define WX_OCR_MANAGER_OFFSET 0x80f270
#define WX_DO_OCR_TASK_OFFSET 0x13da3e0
//storage
#define CONTACT_G_PINSTANCE_OFFSET 0x2fffe08
#define CONTACT_G_PINSTANCE_OFFSET 0x2ffddc8
#define DB_MICRO_MSG_OFFSET 0x68
#define DB_CHAT_MSG_OFFSET 0x1C0
#define DB_MISC_OFFSET 0x3D8
@@ -155,10 +160,10 @@
#define STORAGE_START_OFFSET 0x13f8
#define STORAGE_END_OFFSET 0x13fc
#define PUBLIC_MSG_MGR_OFFSET 0x30400a4
#define MULTI_DB_MSG_MGR_OFFSET 0x30424dc
#define FAVORITE_STORAGE_MGR_OFFSET 0x3041e70
#define FTS_FAVORITE_MGR_OFFSET 0x3000948
#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
#define OP_LOG_STORAGE_VFTABLE 0x2AD3A20
#define CHAT_MSG_STORAGE_VFTABLE 0x2AC10F0
@@ -190,10 +195,23 @@
// public msg forward
#define NEW_MM_READ_ITEM_OFFSET 0x76f0d0
#define FREE_MM_READ_ITEM_OFFSET 0x76e4d0
#define FREE_MM_READ_ITEM_2_OFFSET 0x76edf0
#define FORWARD_PUBLIC_MSG_OFFSET 0xb73de0
#define NEW_MM_READ_ITEM_OFFSET 0x76e630
#define FREE_MM_READ_ITEM_OFFSET 0x76da30
#define FREE_MM_READ_ITEM_2_OFFSET 0x76e350
#define FORWARD_PUBLIC_MSG_OFFSET 0xb73000
// send app msg
#define NEW_SHARE_APP_MSG_REQ_OFFSET 0xfb9890
// #define FREE_SHARE_APP_MSG_REQ_OFFSET 0xfbc0d0
#define FREE_SHARE_APP_MSG_REQ_OFFSET 0xfbab40
#define NEW_WA_UPDATABLE_MSG_INFO_OFFSET 0x7b3290
#define FREE_WA_UPDATABLE_MSG_INFO_OFFSET 0x79ca10
#define SEND_APP_MSG_OFFSET 0xfe7840
// query head image then download
#define QUERY_THEN_DOWNLOAD_OFFSET 0xc63470
/*******************hook*********************************************/
@@ -205,21 +223,21 @@
// hook log
#define WX_HOOK_LOG_OFFSET 0xf59317
#define WX_HOOK_LOG_NEXT_OFFSET 0x24102b4
#define WX_HOOK_LOG_OFFSET 0xf57d67
#define WX_HOOK_LOG_NEXT_OFFSET 0x240ea71
// hook msg
#define WX_RECV_MSG_HOOK_OFFSET 0xd1a89b
#define WX_RECV_MSG_HOOK_NEXT_OFFSET 0x7573f0
#define WX_SNS_HOOK_OFFSET 0x14fb3b5
#define WX_SNS_HOOK_NEXT_OFFSET 0x14fb640
#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
// hook voice
#define WX_HOOK_VOICE_OFFSET 0xd4d8d8
#define WX_HOOK_VOICE_NEXT_OFFSET 0x203d130
#define WX_SELF_ID_OFFSET 0x2FFD484
#define WX_SELF_ID_OFFSET 0x2FFD484
/*******************hook end*********************************************/
@@ -359,24 +377,24 @@
#define SQLITE_NULL 5
#define SQLITE_TEXT 3
#define SQLITE3_EXEC_OFFSET 0x1e26770
#define SQLITE3_BACKUP_INIT_OFFSET 0x1dec100
#define SQLITE3_PREPARE_OFFSET 0x1E2D0C0
#define SQLITE3_OPEN_OFFSET 0x1e5b090
#define SQLITE3_BACKUP_STEP_OFFSET 0x1DEC500
#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1DECC40
#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1DECC50
#define SQLITE3_BACKUP_FINISH_OFFSET 0x1DECB40
#define SQLITE3_SLEEP_OFFSET 0x1e5b8d0
#define SQLITE3_ERRCODE_OFFSET 0x1e59d30
#define SQLITE3_CLOSE_OFFSET 0x1e584b0
#define SQLITE3_STEP_OFFSET 0x1df4f70
#define SQLITE3_COLUMN_COUNT_OFFSET 0x1df5480
#define SQLITE3_COLUMN_NAME_OFFSET 0x1df5d70
#define SQLITE3_COLUMN_TYPE_OFFSET 0x1df5c10
#define SQLITE3_COLUMN_BLOB_OFFSET 0x1df54c0
#define SQLITE3_COLUMN_BYTES_OFFSET 0x1df55a0
#define SQLITE3_FINALIZE_OFFSET 0x1df3f40
#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**);
@@ -794,4 +812,30 @@ struct ContactProfile{
std::wstring nickname;
std::wstring head_image;
};
struct WeChatStr{
char * ptr;
DWORD field1;
DWORD field2;
DWORD field3;
DWORD len;
DWORD maxlen;
WeChatStr(const char* p) {
ptr = (char *)p;
field1 = 0;
field2 = 0;
field3 = 0;
len = strlen(p);
maxlen = len | 0xF;
}
WeChatStr() {
ptr = NULL;
field1 = 0;
field2 = 0;
field3 = 0;
len = 0;
maxlen = 0xF;
}
};
#endif
Binary file not shown.