Compare commits

..
Author SHA1 Message Date
hugy e7a460ad25 新增确认收款 close #12 2023-02-06 17:56:37 +08:00
hugy ebde430aec 修复一些内存泄漏 2023-02-06 11:21:13 +08:00
hugy 1216733b82 完善接口文档 close #10 2023-02-04 16:42:57 +08:00
hugy 6dca99474b 修改转发消息接口文档 2023-02-04 16:28:34 +08:00
hugy d818c826e5 使用微信内部函数释放内存 2023-02-04 15:07:01 +08:00
14 changed files with 216 additions and 50 deletions
+108 -1
View File
@@ -91,9 +91,40 @@ vcpkg
2023-02-01 : 新增拍一拍(仅支持3.8.1.26)。
2023-02-04 : 新增群消息置顶和取消置顶。
2023-02-04 : 新增群消息置顶和取消置顶。
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.退出登录
45.确认收款
46.联系人列表
47.获取群详情
48.获取解密图片
49.图片提取文字ocr
50.拍一拍
51.群消息置顶消息
52.群消息取消置顶
### 接口文档:
#### 0.检查微信登录**
###### 接口功能
> 检查微信是否登录
@@ -721,6 +752,43 @@ 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.退出登录**
###### 接口功能
@@ -758,6 +826,45 @@ vcpkg
```
#### 45.确认收款**
###### 接口功能
> 收到转账消息后,自动收款确认。type=49 即是转账消息。
###### 接口地址
> [/api/?type=45](/api/?type=45)
###### 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"}
```
#### 46.联系人列表**
###### 接口功能
+7
View File
@@ -20,6 +20,7 @@
#include "hook_img.h"
#include "ocr.h"
#include "pat.h"
#include "confirm_receipt.h"
#pragma comment(lib, "ws2_32.lib")
using namespace std;
@@ -478,6 +479,12 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
break;
}
case WECHAT_GET_TRANSFER: {
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);
BOOL response = DoConfirmReceipt(WS2LW(wxid), WS2LW(transcationid), WS2LW(transferid));
json ret_data = {{"msg", response}, {"result", "OK"}};
ret = ret_data.dump();
break;
}
case WECHAT_GET_CONTACT_ALL: {
+50 -14
View File
@@ -5,6 +5,8 @@
#include "get_db_handle.h"
#include "wechat_data.h"
#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
@@ -45,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
@@ -231,6 +266,7 @@ int SetTopMsg(wchar_t* wxid,ULONG64 msg_id){
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;
@@ -276,6 +312,8 @@ int SetTopMsg(wchar_t* wxid,ULONG64 msg_id){
PUSH EAX
CALL handle_top_msg_addr
MOV success,EAX
LEA ECX,chat_msg
CALL free_addr
POPAD
}
return success;
@@ -285,8 +323,6 @@ int SetTopMsg(wchar_t* wxid,ULONG64 msg_id){
int RemoveTopMsg(wchar_t* chat_room_id,ULONG64 msg_id){
int success = -1;
DWORD left = (DWORD)(&msg_id);
DWORD right = (DWORD)(&msg_id+4);
WeChatString chat_room(chat_room_id);
DWORD base = GetWeChatWinBase();
DWORD get_chat_room_mgr_addr = base + WX_CHAT_ROOM_MGR_OFFSET;
+1 -1
View File
@@ -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
View File
@@ -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) {
+1 -1
View File
@@ -3,7 +3,7 @@
#include "common.h"
#include "wechat_data.h"
using namespace std;
#define WX_CONTACT_MGR_INSTANCE_OFFSET 0x64dc30
#define WX_CONTACT_GET_LIST_OFFSET 0xa9b000
#define WX_CONTACT_DEL_OFFSET 0xa9ef40
+1 -1
View File
@@ -3,7 +3,7 @@
#include <vector>
#include "wechat_data.h"
int GetAllContact(vector<Contact> &vec);
int GetAllContact(std::vector<Contact> &vec);
+3 -3
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -2,7 +2,7 @@
#include "hook_img.h"
#include "common.h"
using namespace std;
// #define WX_HOOK_IMG_OFFSET 0xd7eaa5
// #define WX_HOOK_IMG_NEXT_OFFSET 0xda56e0
+1 -2
View File
@@ -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);
+1 -1
View File
@@ -7,7 +7,7 @@
#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);
+1
View File
@@ -4,6 +4,7 @@
#include "common.h"
#include "wechat_data.h"
using namespace std;
#define WX_SELF_NAME_OFFSET 0x2C426E8
#define WX_SELF_MOBILE_OFFSET 0x2C42658
+33 -15
View File
@@ -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