Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4eab2a2414 | ||
|
|
b8dc032525 | ||
|
|
7e89c6ef2d | ||
|
|
82a5ca28db | ||
|
|
861a04e7a0 | ||
|
|
04e7967236 |
@@ -138,6 +138,7 @@ vcpkg
|
||||
53.朋友圈首页
|
||||
54.朋友圈下一页
|
||||
55.获取联系人或者群名称
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
### 接口文档:
|
||||
|
||||
|
||||
@@ -197,17 +198,16 @@ vcpkg
|
||||
|result|string|成功提示|
|
||||
|data|object|响应内容|
|
||||
|account|string|账号|
|
||||
|bigImage|string|头像大图|
|
||||
|headImage|string|头像|
|
||||
|city|string|城市|
|
||||
|country|string|国家|
|
||||
|currentDataPath|string|当前数据目录|
|
||||
|dataRootPath|string|根目录|
|
||||
|dataSavePath|string|保存目录|
|
||||
|currentDataPath|string|当前数据目录,登录的账号目录|
|
||||
|dataSavePath|string|微信保存目录|
|
||||
|mobile|string|手机|
|
||||
|name|string|昵称|
|
||||
|province|string|省|
|
||||
|smallImage|string|小头像|
|
||||
|wxid|string|wxid|
|
||||
|signature|string|个人签名|
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
@@ -215,7 +215,7 @@ vcpkg
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"data":{"account":"xx","bigImage":"https://wx.qlogo.cn/mmhead/ver_1xx","city":"xx","country":"CN","currentDataPath":"xxx","dataRootPath":"C:\\xx","dataSavePath":"C:\\xx","mobie":"13949175447","name":"xx","province":"xx","smallImage":"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"},"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
@@ -260,6 +260,47 @@ vcpkg
|
||||
|
||||
|
||||
|
||||
#### 3.发送@文本消息**
|
||||
###### 接口功能
|
||||
> 发送@文本消息
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=3](/api/?type=3)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|chatRoomId |true |string| 群id |
|
||||
|msg|true |string|消息文本内容|
|
||||
|wxids |true |string| @的用户微信id用,号分隔, @所有人 传 notify@all ,区分大小写 |
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,不为0成功, 0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
###### 接口示例
|
||||
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"chatRoomId": "123333@chatroom",
|
||||
"wxids":"notify@all,wxid_122221",
|
||||
"msg": "12333"
|
||||
}
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":345686720,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 5.发送图片消息**
|
||||
###### 接口功能
|
||||
> 发送图片消息
|
||||
@@ -1424,6 +1465,46 @@ vcpkg
|
||||
|
||||
|
||||
|
||||
#### 56.获取消息附件**
|
||||
###### 接口功能
|
||||
> 根据消息id,下载消息附件(图片,视频,文件)
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=56](/api/?type=56)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId |true |string| 消息id |
|
||||
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,0成功, 非0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"msgId": 3224560917391784099
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":0,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 感谢
|
||||
https://github.com/ljc545w/ComWeChatRobot
|
||||
|
||||
|
||||
+21
-4
@@ -23,6 +23,7 @@
|
||||
#include "confirm_receipt.h"
|
||||
#include "sns.h"
|
||||
#include "search_contact.h"
|
||||
#include "download.h"
|
||||
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
using namespace std;
|
||||
@@ -221,9 +222,8 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
{"account", self_info.account},
|
||||
{"wxid", self_info.wxid},
|
||||
{"mobile", self_info.mobile},
|
||||
{"smallImage", self_info.small_img},
|
||||
{"bigImage", self_info.big_img},
|
||||
{"dataRootPath",self_info.data_root_path},
|
||||
{"headImage", self_info.head_img},
|
||||
{"signature",self_info.signature},
|
||||
{"dataSavePath",self_info.data_save_path},
|
||||
{"currentDataPath",self_info.current_data_path},
|
||||
};
|
||||
@@ -241,6 +241,16 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_SEND_AT: {
|
||||
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);
|
||||
vector<wchar_t *> wxid_list;
|
||||
for (unsigned int i = 0; i < wxids.size(); i++){
|
||||
wxid_list.push_back(WS2LW(wxids[i]));
|
||||
}
|
||||
int success = SendAtText(WS2LW(chat_room_id), wxid_list.data(), wxid_list.size(),WS2LW(msg));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_MSG_SEND_CARD: {
|
||||
@@ -643,6 +653,13 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_ATTACH_DOWNLOAD:{
|
||||
ULONG64 msg_id = get_http_param_ulong64(hm, j_param, "msgId", is_post);
|
||||
int success = DoDownloadTask(msg_id);
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -701,7 +718,7 @@ int http_start(int port) {
|
||||
#endif
|
||||
kHttpRuning = true;
|
||||
kHttpThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)http_server,
|
||||
(LPVOID)port, NULL, 0);
|
||||
(LPVOID)port, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ typedef enum WECHAT_HTTP_APISTag
|
||||
WECHAT_SNS_GET_FIRST_PAGE,
|
||||
WECHAT_SNS_GET_NEXT_PAGE,
|
||||
WECHAT_CONTACT_NAME,
|
||||
WECHAT_ATTACH_DOWNLOAD,
|
||||
} WECHAT_HTTP_APIS,
|
||||
*PWECHAT_HTTP_APIS;
|
||||
|
||||
|
||||
+8
-1
@@ -126,7 +126,7 @@ string Wstring2String(wstring wstr) {
|
||||
BOOL FindOrCreateDirectoryW(const wchar_t *path) {
|
||||
WIN32_FIND_DATAW fd;
|
||||
HANDLE hFind = ::FindFirstFileW(path, &fd);
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
if (hFind != INVALID_HANDLE_VALUE && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
FindClose(hFind);
|
||||
return true;
|
||||
}
|
||||
@@ -135,4 +135,11 @@ BOOL FindOrCreateDirectoryW(const wchar_t *path) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CloseConsole(){
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
FreeConsole();
|
||||
}
|
||||
@@ -53,6 +53,7 @@ std::string Wstring2String(std::wstring wstr);
|
||||
/// @return
|
||||
BOOL FindOrCreateDirectoryW(const wchar_t *path);
|
||||
|
||||
void CloseConsole();
|
||||
|
||||
template <typename T1, typename T2>
|
||||
std::vector<T1> split(T1 str, T2 letter) {
|
||||
|
||||
+6
-1
@@ -97,10 +97,15 @@ int Select(DWORD db_hanle, const char *sql,
|
||||
if (status == 0) {
|
||||
return 0;
|
||||
}
|
||||
if(data.size() == 0){
|
||||
return 1;
|
||||
}
|
||||
vector<string> index;
|
||||
for (size_t i = 0; i < data[0].size(); i++)
|
||||
for (size_t i = 0; i < data[0].size(); i++){
|
||||
index.push_back(data[0][i].column_name);
|
||||
}
|
||||
query_result.push_back(index);
|
||||
|
||||
for (auto it : data) {
|
||||
vector<string> item;
|
||||
for (size_t i = 0; i < it.size(); i++) {
|
||||
|
||||
@@ -16,6 +16,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,
|
||||
break;
|
||||
}
|
||||
case DLL_PROCESS_DETACH: {
|
||||
CloseConsole();
|
||||
http_close();
|
||||
break;
|
||||
}
|
||||
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
#include "pch.h"
|
||||
#include "download.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "get_db_handle.h"
|
||||
|
||||
#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
|
||||
|
||||
using namespace std;
|
||||
|
||||
int DoDownloadTask(ULONG64 msg_id) {
|
||||
int success = -1;
|
||||
int db_index = 0;
|
||||
int local_id = GetLocalIdByMsgId(msg_id, db_index);
|
||||
if (local_id < 1) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
char chat_msg[0x2C4] = {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;
|
||||
DWORD pre_download_mgr_addr = base + WX_GET_PRE_DOWNLOAD_MGR_OFFSET;
|
||||
DWORD push_attach_task_addr = base + WX_PUSH_ATTACH_TASK_OFFSET;
|
||||
DWORD free_addr = base + WX_FREE_CHAT_MSG_INSTANCE_COUNTER_OFFSET;
|
||||
DWORD get_by_local_Id_addr = base + WX_GET_MGR_BY_PREFIX_LOCAL_ID_OFFSET;
|
||||
DWORD get_current_data_path_addr = base + WX_GET_CURRENT_DATA_PATH_OFFSET;
|
||||
DWORD free_app_msg_info_addr = base + WX_FREE_APP_MSG_INFO_OFFSET;
|
||||
DWORD push_thumb_task_addr = base + WX_PUSH_THUMB_TASK_OFFSET;
|
||||
DWORD video_mgr_addr = base + WX_VIDEO_MGR_OFFSET;
|
||||
DWORD download_video_image_addr = base + WX_VIDEO_MGR_OFFSET;
|
||||
|
||||
WeChatString current_data_path;
|
||||
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,current_data_path
|
||||
CALL get_current_data_path_addr
|
||||
|
||||
LEA ECX,chat_msg
|
||||
CALL new_chat_msg_addr
|
||||
|
||||
CALL get_chat_mgr_addr
|
||||
PUSH dword ptr [db_index]
|
||||
LEA ECX,chat_msg
|
||||
PUSH dword ptr [local_id]
|
||||
CALL get_by_local_Id_addr
|
||||
ADD ESP,0x8
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
wstring save_path = L"";
|
||||
wstring thumb_path = L"";
|
||||
if (current_data_path.length > 0) {
|
||||
save_path += current_data_path.ptr;
|
||||
save_path += L"wxhelper";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
DWORD type = *(DWORD *)(chat_msg + 0x38);
|
||||
wchar_t *content = *(wchar_t **)(chat_msg + 0x70);
|
||||
|
||||
switch (type) {
|
||||
case 0x3: {
|
||||
save_path += L"\\image";
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
save_path = save_path +L"\\"+ to_wstring(msg_id) + L".png";
|
||||
break;
|
||||
}
|
||||
case 0x3E:
|
||||
case 0x2B: {
|
||||
save_path += L"\\video";
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
thumb_path = save_path + L"\\"+ to_wstring(msg_id) + L".jpg";
|
||||
save_path = save_path + L"\\"+ to_wstring(msg_id) + L".mp4";
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x31: {
|
||||
save_path += L"\\file";
|
||||
wcout << save_path << endl;
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
return -3;
|
||||
}
|
||||
char xml_app_msg[0xC80] = {0};
|
||||
DWORD new_app_msg_addr = base + WX_APP_MSG_INFO_OFFSET;
|
||||
DWORD get_xml_addr = base + WX_GET_APP_MSG_XML_OFFSET;
|
||||
WeChatString w_content(content);
|
||||
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
LEA ECX,xml_app_msg
|
||||
CALL new_app_msg_addr
|
||||
PUSH 0x1
|
||||
LEA EAX,w_content
|
||||
PUSH EAX
|
||||
LEA ECX,xml_app_msg
|
||||
CALL get_xml_addr
|
||||
MOV success,EAX
|
||||
LEA ECX,xml_app_msg
|
||||
CALL free_app_msg_info_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
if (success != 1) {
|
||||
return -4;
|
||||
}
|
||||
WeChatString *file_name = (WeChatString *)((DWORD)xml_app_msg + 0x44);
|
||||
save_path = save_path +L"\\" + to_wstring(msg_id) + L"_" +
|
||||
wstring(file_name->ptr, file_name->length);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
WeChatString w_save_path(save_path);
|
||||
WeChatString w_thumb_path(thumb_path);
|
||||
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));
|
||||
// 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.
|
||||
// if (type == 0x3E || type == 0x2B){
|
||||
// __asm{
|
||||
// PUSHAD
|
||||
// PUSHFD
|
||||
// CALL video_mgr_addr
|
||||
// LEA ECX,chat_msg
|
||||
// PUSH ECX
|
||||
// MOV ECX,EAX
|
||||
// CALL download_video_image_addr
|
||||
// POPFD
|
||||
// POPAD
|
||||
// }
|
||||
// }
|
||||
|
||||
__asm {
|
||||
PUSHAD
|
||||
PUSHFD
|
||||
CALL pre_download_mgr_addr
|
||||
PUSH 0x1
|
||||
PUSH 0x0
|
||||
LEA ECX,chat_msg
|
||||
PUSH ECX
|
||||
MOV ECX,EAX
|
||||
CALL push_attach_task_addr
|
||||
MOV success,EAX
|
||||
LEA ECX,chat_msg
|
||||
PUSH 0x0
|
||||
CALL free_addr
|
||||
POPFD
|
||||
POPAD
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef DOWNLOAD_H_
|
||||
#define DOWNLOAD_H_
|
||||
|
||||
int DoDownloadTask(ULONG64 msg_id);
|
||||
#endif
|
||||
+169
-108
@@ -20,136 +20,197 @@ using namespace std;
|
||||
#define WX_APP_DATA_SAVE_PATH_OFFSET 0x2E52DB0
|
||||
#define WX_CURRENT_DATA_PATH_OFFSET 0x2E4F290
|
||||
|
||||
#define WX_LOGOUT_OFFSET 0xdd5c90
|
||||
#define WX_ACCOUT_SERVICE_OFFSET 0x707960
|
||||
|
||||
#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
|
||||
int GetSelfInfo(SelfInfoInner &out) {
|
||||
DWORD base = GetWeChatWinBase();
|
||||
#ifdef _DEBUG
|
||||
cout << "mobile:" << (char *)(base + WX_SELF_MOBILE_OFFSET) << endl;
|
||||
cout << "name:" << (char *)(base + WX_SELF_NAME_OFFSET) << endl;
|
||||
cout << "city:" << (char *)(base + WX_SELF_CITY_OFFSET) << endl;
|
||||
cout << "city:" << (char *)(base + WX_SELF_CITY_OFFSET) << endl;
|
||||
cout << "province:" << (char *)(base + WX_SELF_PROVINCE_OFFSET) << endl;
|
||||
cout << "country:" << (char *)(base + WX_SELF_COUNTRY_OFFSET) << endl;
|
||||
cout << "account:" << (char *)(base + WX_SELF_ACCOUNT_OFFSET) << endl;
|
||||
cout << "wxid:" << (char *)(base + WX_SELF_ID_OFFSET) << endl;
|
||||
cout << "small_img:" << (char *)(base + WX_SELF_SMALL_IMG_OFFSET) << endl;
|
||||
cout << "big_img:" << (char *)(base + WX_SELF_BIG_IMG_OFFSET) << endl;
|
||||
#endif
|
||||
if (*(DWORD *)(base + WX_SELF_NAME_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_NAME_OFFSET + 0x10) == 0) {
|
||||
out.name = string();
|
||||
} else {
|
||||
out.name = string((char *)(base + WX_SELF_NAME_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_NAME_OFFSET + 0x10));
|
||||
DWORD accout_service_addr = base + WX_ACCOUNT_SERVICE_OFFSET;
|
||||
DWORD get_app_save_addr = base + WX_GET_APP_DATA_SAVE_PATH_OFFSET;
|
||||
DWORD get_current_data_path_addr = base + WX_GET_CURRENT_DATA_PATH_OFFSET;
|
||||
DWORD service_addr = NULL;
|
||||
__asm {
|
||||
PUSHAD
|
||||
CALL accout_service_addr
|
||||
MOV service_addr,EAX
|
||||
POPAD
|
||||
}
|
||||
if (*(DWORD *)(base + WX_SELF_MOBILE_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_MOBILE_OFFSET + 0x10) == 0) {
|
||||
out.mobile = string();
|
||||
} else {
|
||||
out.mobile = string((char *)(base + WX_SELF_MOBILE_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_MOBILE_OFFSET + 0x10));
|
||||
if (service_addr) {
|
||||
if (*(DWORD *)(service_addr + 0x44) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x44 + 0x10) == 0) {
|
||||
out.wxid = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x44 + 0x14) == 0xF) {
|
||||
out.wxid = string((char *)(service_addr + 0x44),
|
||||
*(DWORD *)(service_addr + 0x44 + 0x10));
|
||||
} else {
|
||||
out.wxid = string(*(char **)(service_addr + 0x44),
|
||||
*(DWORD *)(service_addr + 0x44 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0xA8) == 0 ||
|
||||
*(DWORD *)(service_addr + 0xA8 + 0x10) == 0) {
|
||||
out.account = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0xA8 + 0x14) == 0xF) {
|
||||
out.account = string((char *)(service_addr + 0xA8),
|
||||
*(DWORD *)(service_addr + 0xA8 + 0x10));
|
||||
} else {
|
||||
out.account = string(*(char **)(service_addr + 0xA8),
|
||||
*(DWORD *)(service_addr + 0xA8 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0xC0) == 0 ||
|
||||
*(DWORD *)(service_addr + 0xC0 + 0x10) == 0) {
|
||||
out.mobile = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0xC0 + 0x14) == 0xF) {
|
||||
out.mobile = string((char *)(service_addr + 0xC0),
|
||||
*(DWORD *)(service_addr + 0xC0 + 0x10));
|
||||
} else {
|
||||
out.mobile = string(*(char **)(service_addr + 0xC0),
|
||||
*(DWORD *)(service_addr + 0xC0 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0xD8) == 0 ||
|
||||
*(DWORD *)(service_addr + 0xD8 + 0x10) == 0) {
|
||||
out.signature = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0xD8 + 0x14) == 0xF) {
|
||||
out.signature = string((char *)(service_addr + 0xD8),
|
||||
*(DWORD *)(service_addr + 0xD8 + 0x10));
|
||||
} else {
|
||||
out.signature = string(*(char **)(service_addr + 0xD8),
|
||||
*(DWORD *)(service_addr + 0xD8 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0xF0) == 0 ||
|
||||
*(DWORD *)(service_addr + 0xF0 + 0x10) == 0) {
|
||||
out.country = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0xF0 + 0x14) == 0xF) {
|
||||
out.country = string((char *)(service_addr + 0xF0),
|
||||
*(DWORD *)(service_addr + 0xF0 + 0x10));
|
||||
} else {
|
||||
out.country = string(*(char **)(service_addr + 0xF0),
|
||||
*(DWORD *)(service_addr + 0xF0 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x108) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x108 + 0x10) == 0) {
|
||||
out.province = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x108 + 0x14) == 0xF) {
|
||||
out.province = string((char *)(service_addr + 0x108),
|
||||
*(DWORD *)(service_addr + 0x108 + 0x10));
|
||||
} else {
|
||||
out.province = string(*(char **)(service_addr + 0x108),
|
||||
*(DWORD *)(service_addr + 0x108 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x120) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x120 + 0x10) == 0) {
|
||||
out.city = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x120 + 0x14) == 0xF) {
|
||||
out.city = string((char *)(service_addr + 0x120),
|
||||
*(DWORD *)(service_addr + 0x120 + 0x10));
|
||||
} else {
|
||||
out.city = string(*(char **)(service_addr + 0x120),
|
||||
*(DWORD *)(service_addr + 0x120 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x150) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x150 + 0x10) == 0) {
|
||||
out.name = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x150 + 0x14) == 0xF) {
|
||||
out.name = string((char *)(service_addr + 0x150),
|
||||
*(DWORD *)(service_addr + 0x150 + 0x10));
|
||||
} else {
|
||||
out.name = string(*(char **)(service_addr + 0x150),
|
||||
*(DWORD *)(service_addr + 0x150 + 0x10));
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(service_addr + 0x304) == 0 ||
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10) == 0) {
|
||||
out.head_img = string();
|
||||
} else {
|
||||
if (*(DWORD *)(service_addr + 0x304 + 0x14) == 0xF) {
|
||||
out.head_img = string((char *)(service_addr + 0x304),
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10));
|
||||
} else {
|
||||
out.head_img = string(*(char **)(service_addr + 0x304),
|
||||
*(DWORD *)(service_addr + 0x304 + 0x10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_CITY_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_CITY_OFFSET + 0x10) == 0) {
|
||||
out.city = string();
|
||||
} else {
|
||||
out.city = string((char *)(base + WX_SELF_CITY_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_CITY_OFFSET + 0x10));
|
||||
WeChatString data_save_path;
|
||||
WeChatString current_data_path;
|
||||
|
||||
__asm {
|
||||
PUSHAD
|
||||
LEA ECX,data_save_path
|
||||
CALL get_app_save_addr
|
||||
LEA ECX,current_data_path
|
||||
CALL get_current_data_path_addr
|
||||
POPAD
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_PROVINCE_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_PROVINCE_OFFSET + 0x10) == 0) {
|
||||
out.province = string();
|
||||
} else {
|
||||
out.province = string((char *)(base + WX_SELF_PROVINCE_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_PROVINCE_OFFSET + 0x10));
|
||||
if (data_save_path.ptr) {
|
||||
out.data_save_path =
|
||||
Wstring2String(wstring(data_save_path.ptr, data_save_path.length));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_COUNTRY_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_COUNTRY_OFFSET + 0x10) == 0) {
|
||||
out.country = string();
|
||||
} else {
|
||||
out.country = string((char *)(base + WX_SELF_COUNTRY_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_COUNTRY_OFFSET + 0x10));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET + 0x10) == 0) {
|
||||
out.account = string();
|
||||
} else {
|
||||
out.account = string(*(char **)(base + WX_SELF_ACCOUNT_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_ACCOUNT_OFFSET + 0x10));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_ID_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_ID_OFFSET + 0x10) == 0) {
|
||||
out.wxid = string();
|
||||
} else {
|
||||
out.wxid = string(*(char **)(base + WX_SELF_ID_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_ID_OFFSET + 0x10));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET + 0x10) == 0) {
|
||||
out.small_img = string();
|
||||
} else {
|
||||
out.small_img = string(*(char **)(base + WX_SELF_SMALL_IMG_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_SMALL_IMG_OFFSET + 0x10));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET + 0x10) == 0) {
|
||||
out.big_img = string();
|
||||
} else {
|
||||
out.big_img = string(*(char **)(base + WX_SELF_BIG_IMG_OFFSET),
|
||||
*(DWORD *)(base + WX_SELF_BIG_IMG_OFFSET + 0x10));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET + 0x4) == 0) {
|
||||
out.data_root_path = string();
|
||||
} else {
|
||||
out.data_root_path = Wstring2String(wstring(*(wchar_t **)(base + WX_APP_DATA_ROOT_PATH_OFFSET),
|
||||
*(DWORD *)(base + WX_APP_DATA_ROOT_PATH_OFFSET + 0x4)));
|
||||
}
|
||||
|
||||
if (*(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET + 0x4) == 0) {
|
||||
else {
|
||||
out.data_save_path = string();
|
||||
} else {
|
||||
out.data_save_path = Wstring2String(wstring(*(wchar_t **)(base + WX_APP_DATA_SAVE_PATH_OFFSET),
|
||||
*(DWORD *)(base + WX_APP_DATA_SAVE_PATH_OFFSET + 0x4)));
|
||||
}
|
||||
if (*(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET) == 0 ||
|
||||
*(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET + 0x4) == 0) {
|
||||
out.current_data_path = string();
|
||||
} else {
|
||||
out.current_data_path = Wstring2String(wstring(*(wchar_t **)(base + WX_CURRENT_DATA_PATH_OFFSET),
|
||||
*(DWORD *)(base + WX_CURRENT_DATA_PATH_OFFSET + 0x4)));
|
||||
}
|
||||
|
||||
if (current_data_path.ptr) {
|
||||
out.current_data_path = Wstring2String(
|
||||
wstring(current_data_path.ptr, current_data_path.length));
|
||||
} else {
|
||||
out.current_data_path = string();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int CheckLogin(){
|
||||
int CheckLogin() {
|
||||
DWORD base = GetWeChatWinBase();
|
||||
return *(DWORD*) (base + WX_LOGIN_STATUS_OFFSET);
|
||||
DWORD accout_service_addr = base + WX_ACCOUNT_SERVICE_OFFSET;
|
||||
DWORD service_addr = NULL;
|
||||
__asm {
|
||||
PUSHAD
|
||||
CALL accout_service_addr
|
||||
MOV service_addr,EAX
|
||||
POPAD
|
||||
}
|
||||
if (service_addr) {
|
||||
return *(DWORD *)(service_addr + 0x4C8);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Logout(){
|
||||
int Logout() {
|
||||
int success = 0;
|
||||
if(!CheckLogin()){
|
||||
if (!CheckLogin()) {
|
||||
return success;
|
||||
}
|
||||
DWORD base = GetWeChatWinBase();
|
||||
DWORD account_service_addr = base + WX_ACCOUT_SERVICE_OFFSET;
|
||||
DWORD account_service_addr = base + WX_ACCOUNT_SERVICE_OFFSET;
|
||||
DWORD logout_addr = base + WX_LOGOUT_OFFSET;
|
||||
__asm{
|
||||
__asm {
|
||||
PUSHAD
|
||||
CALL account_service_addr
|
||||
PUSH 0x0
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "wechat_data.h"
|
||||
#include "contact.h"
|
||||
|
||||
#define WX_SEND_TEXT_OFFSET 0xc71a60
|
||||
|
||||
#define WX_SEND_MESSAGE_MGR_OFFSET 0x706d30
|
||||
|
||||
#define WX_FREE_CHAT_MSG_OFFSET 0x6f4ea0
|
||||
using namespace std;
|
||||
/// @brief 鍙戠敓鏂囨湰娑堟伅
|
||||
/// @param wxid wxid
|
||||
/// @param msg 鏂囨湰娑堟伅
|
||||
@@ -45,4 +47,72 @@ int SendText(wchar_t* wxid, wchar_t* msg) {
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SendAtText(wchar_t* chat_room_id,wchar_t** wxids,int len,wchar_t* msg){
|
||||
int success = -1;
|
||||
WeChatString * at_users = new WeChatString[len+1];
|
||||
wstring at_msg = L"";
|
||||
int number =0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
wstring nickname;
|
||||
if (!lstrcmpiW((wchar_t *)wxids[i], (wchar_t *)L"notify@all")) {
|
||||
nickname = L"所有人";
|
||||
} else {
|
||||
nickname = GetContactOrChatRoomNickname(wxids[i]);
|
||||
}
|
||||
if (nickname.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WeChatString temp = {0};
|
||||
temp.ptr = (wchar_t *)wxids[i];
|
||||
temp.length = wcslen((wchar_t *)wxids[i]);
|
||||
temp.max_length = wcslen((wchar_t *)wxids[i]) * 2;
|
||||
memcpy(&at_users[number], &temp, sizeof(WeChatString));
|
||||
at_msg = at_msg + L"@" + nickname + L" ";
|
||||
number++;
|
||||
}
|
||||
if (number < 1){
|
||||
return success;
|
||||
}
|
||||
wstring origin(msg);
|
||||
at_msg += origin;
|
||||
AtInner at_list = {0};
|
||||
at_list.start = (DWORD)at_users;
|
||||
at_list.finsh = (DWORD)&at_users[number];
|
||||
at_list.end = (DWORD)&at_users[number];
|
||||
WeChatString to_user(chat_room_id);
|
||||
WeChatString text_msg((wchar_t *)at_msg.c_str());
|
||||
wchar_t **msg_pptr = &text_msg.ptr;
|
||||
|
||||
DWORD base = GetWeChatWinBase();
|
||||
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};
|
||||
|
||||
__asm{
|
||||
PUSHAD
|
||||
CALL send_message_mgr_addr
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x0
|
||||
PUSH 0x1
|
||||
LEA EAX,at_list
|
||||
PUSH EAX
|
||||
MOV EAX,msg_pptr
|
||||
PUSH EAX
|
||||
LEA EDX,to_user
|
||||
LEA ECX,chat_msg
|
||||
CALL send_text_msg_addr
|
||||
MOV success,EAX
|
||||
ADD ESP,0x18
|
||||
LEA ECX,chat_msg
|
||||
CALL free_chat_msg_addr
|
||||
POPAD
|
||||
}
|
||||
return success;
|
||||
}
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
#define SEND_TEXT_H_
|
||||
|
||||
int SendText(wchar_t* wxid, wchar_t* msg);
|
||||
|
||||
int SendAtText(wchar_t* chat_room_id,wchar_t** wxids,int len,wchar_t* msg);
|
||||
#endif
|
||||
+155
-3
@@ -149,10 +149,9 @@ struct SelfInfoInner{
|
||||
std::string account;
|
||||
std::string wxid;
|
||||
std::string mobile;
|
||||
std::string small_img;
|
||||
std::string big_img;
|
||||
std::string data_root_path;
|
||||
std::string head_img;
|
||||
std::string data_save_path;
|
||||
std::string signature;
|
||||
std::string current_data_path;
|
||||
};
|
||||
|
||||
@@ -181,4 +180,157 @@ struct UserInfo {
|
||||
DWORD sex;
|
||||
BOOL over;
|
||||
};
|
||||
|
||||
struct AtInner{
|
||||
DWORD start;
|
||||
DWORD finsh;
|
||||
DWORD end;
|
||||
};
|
||||
|
||||
struct ChatMsg {
|
||||
DWORD **field0_0x0;
|
||||
DWORD field1_0x4;
|
||||
ULONG64 sequence;
|
||||
DWORD field3_0x10;
|
||||
DWORD field4_0x14;
|
||||
ULONG64 msgSequence;
|
||||
DWORD localId;
|
||||
DWORD field7_0x24;
|
||||
DWORD field8_0x28;
|
||||
DWORD field9_0x2c;
|
||||
ULONG64 msgId;
|
||||
DWORD type;
|
||||
DWORD isSendMsg;
|
||||
DWORD msgStatus;
|
||||
DWORD timestamp;
|
||||
WeChatString talker;
|
||||
DWORD field16_0x5c;
|
||||
DWORD field17_0x60;
|
||||
DWORD field18_0x64;
|
||||
DWORD field19_0x68;
|
||||
DWORD field20_0x6c;
|
||||
WeChatString content;
|
||||
DWORD field22_0x84;
|
||||
DWORD field23_0x88;
|
||||
DWORD field24_0x8c;
|
||||
DWORD field25_0x90;
|
||||
DWORD field26_0x94;
|
||||
DWORD field27_0x98;
|
||||
DWORD field28_0x9c;
|
||||
DWORD field29_0xa0;
|
||||
DWORD field30_0xa4;
|
||||
DWORD field31_0xa8;
|
||||
DWORD field32_0xac;
|
||||
DWORD field33_0xb0;
|
||||
DWORD field34_0xb4;
|
||||
DWORD field35_0xb8;
|
||||
DWORD field36_0xbc;
|
||||
DWORD field37_0xc0;
|
||||
DWORD field38_0xc4;
|
||||
DWORD field39_0xc8;
|
||||
DWORD field40_0xcc;
|
||||
DWORD field41_0xd0;
|
||||
DWORD field42_0xd4;
|
||||
DWORD field43_0xd8;
|
||||
DWORD field44_0xdc;
|
||||
DWORD field45_0xe0;
|
||||
DWORD field46_0xe4;
|
||||
DWORD field47_0xe8;
|
||||
DWORD field48_0xec;
|
||||
DWORD field49_0xf0;
|
||||
DWORD field50_0xf4;
|
||||
DWORD field51_0xf8;
|
||||
DWORD field52_0xfc;
|
||||
DWORD field53_0x100;
|
||||
DWORD field54_0x104;
|
||||
DWORD field55_0x108;
|
||||
DWORD field56_0x10c;
|
||||
DWORD field57_0x110;
|
||||
DWORD field58_0x114;
|
||||
DWORD field59_0x118;
|
||||
DWORD field60_0x11c;
|
||||
DWORD field61_0x120;
|
||||
DWORD field62_0x124;
|
||||
DWORD field63_0x128;
|
||||
DWORD field64_0x12c;
|
||||
DWORD field65_0x130;
|
||||
DWORD field66_0x134;
|
||||
DWORD field67_0x138;
|
||||
DWORD field68_0x13c;
|
||||
DWORD field69_0x140;
|
||||
DWORD field70_0x144;
|
||||
DWORD field71_0x148;
|
||||
DWORD field72_0x14c;
|
||||
DWORD field73_0x150;
|
||||
DWORD field74_0x154;
|
||||
DWORD field75_0x158;
|
||||
DWORD field76_0x15c;
|
||||
DWORD field77_0x160;
|
||||
DWORD field78_0x164;
|
||||
DWORD field79_0x168;
|
||||
DWORD field80_0x16c;
|
||||
DWORD field81_0x170;
|
||||
WeChatString fromGroup;
|
||||
WeChatString sign;
|
||||
WeChatString thumbPath;
|
||||
WeChatString path;
|
||||
DWORD field86_0x1c4;
|
||||
DWORD field87_0x1c8;
|
||||
DWORD field88_0x1cc;
|
||||
DWORD field89_0x1d0;
|
||||
DWORD field90_0x1d4;
|
||||
DWORD field91_0x1d8;
|
||||
DWORD field92_0x1dc;
|
||||
DWORD field93_0x1e0;
|
||||
DWORD field94_0x1e4;
|
||||
DWORD field95_0x1e8;
|
||||
DWORD field96_0x1ec;
|
||||
WeChatString signature;
|
||||
DWORD field98_0x204;
|
||||
DWORD field99_0x208;
|
||||
DWORD field100_0x20c;
|
||||
DWORD field101_0x210;
|
||||
DWORD field102_0x214;
|
||||
DWORD field103_0x218;
|
||||
DWORD field104_0x21c;
|
||||
DWORD field105_0x220;
|
||||
DWORD field106_0x224;
|
||||
DWORD field107_0x228;
|
||||
DWORD field108_0x22c;
|
||||
DWORD field109_0x230;
|
||||
DWORD field110_0x234;
|
||||
DWORD field111_0x238;
|
||||
DWORD field112_0x23c;
|
||||
DWORD field113_0x240;
|
||||
DWORD field114_0x244;
|
||||
DWORD field115_0x248;
|
||||
DWORD field116_0x24c;
|
||||
DWORD field117_0x250;
|
||||
DWORD field118_0x254;
|
||||
DWORD field119_0x258;
|
||||
DWORD field120_0x25c;
|
||||
DWORD field121_0x260;
|
||||
DWORD field122_0x264;
|
||||
DWORD field123_0x268;
|
||||
DWORD field124_0x26c;
|
||||
DWORD field125_0x270;
|
||||
DWORD field126_0x274;
|
||||
DWORD field127_0x278;
|
||||
DWORD field128_0x27c;
|
||||
DWORD field129_0x280;
|
||||
DWORD field130_0x284;
|
||||
DWORD field131_0x288;
|
||||
DWORD field132_0x28c;
|
||||
DWORD field133_0x290;
|
||||
DWORD field134_0x294;
|
||||
DWORD field135_0x298;
|
||||
DWORD field136_0x29c;
|
||||
DWORD field137_0x2a0;
|
||||
DWORD field138_0x2a4;
|
||||
DWORD field139_0x2a8;
|
||||
DWORD field140_0x2ac;
|
||||
DWORD field141_0x2b0;
|
||||
int field142_0x2b4;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user