mirror of
https://github.com/ttttupup/wxhelper.git
synced 2024-11-21 17:59:24 +08:00
获取语音文件
This commit is contained in:
parent
c590a95425
commit
61c9e6f8c1
44
README.md
44
README.md
@ -37,7 +37,8 @@
|
||||
53.朋友圈首页
|
||||
54.朋友圈下一页
|
||||
<!-- 55.获取联系人或者群名称 -->
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
56.获取消息附件(图片,视频,文件)
|
||||
57.获取消息语音文件
|
||||
### 接口文档:
|
||||
|
||||
|
||||
@ -1542,6 +1543,47 @@
|
||||
```
|
||||
|
||||
|
||||
#### 57.获取语音文件**
|
||||
###### 接口功能
|
||||
> 根据消息id,获取该语音消息的语音文件,文件为silk3格式,可以自行转换mp3.
|
||||
|
||||
###### 接口地址
|
||||
> [/api/?type=57](/api/?type=57)
|
||||
|
||||
###### HTTP请求方式
|
||||
> POST JSON
|
||||
|
||||
###### 请求参数
|
||||
|参数|必选|类型|说明|
|
||||
|---|---|---|---|
|
||||
|msgId |true |string| 消息id |
|
||||
|voiceDir |true |string| 语音文件保存的目录,文件名称为 (msgid).amr |
|
||||
|
||||
|
||||
###### 返回字段
|
||||
|返回字段|字段类型|说明 |
|
||||
|---|---|---|
|
||||
|code|int|返回状态,1成功, 非0失败|
|
||||
|result|string|成功提示|
|
||||
|
||||
|
||||
|
||||
###### 接口示例
|
||||
入参:
|
||||
``` javascript
|
||||
{
|
||||
"msgId": 3224560917391784099,
|
||||
"voiceDir" : "c:\\voice"
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
响应:
|
||||
``` javascript
|
||||
{"code":1,"result":"OK"}
|
||||
```
|
||||
|
||||
|
||||
#### 感谢
|
||||
https://github.com/ljc545w/ComWeChatRobot
|
||||
|
||||
|
@ -694,6 +694,14 @@ void api_handle(mg_http_message *hm, struct mg_connection *c, string &ret) {
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
case WECHAT_GET_VOICE:{
|
||||
ULONG64 msg_id = get_http_param_ulong64(hm, j_param, "msgId", is_post);
|
||||
wstring voice_dir = get_http_req_param(hm, j_param, "voiceDir", is_post);
|
||||
int success = GetVoice(msg_id,WS2LW(voice_dir));
|
||||
json ret_data = {{"code", success}, {"result", "OK"}};
|
||||
ret = ret_data.dump();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ typedef enum WECHAT_HTTP_APISTag
|
||||
WECHAT_SNS_GET_NEXT_PAGE,
|
||||
WECHAT_CONTACT_NAME,
|
||||
WECHAT_ATTACH_DOWNLOAD,
|
||||
WECHAT_GET_VOICE,
|
||||
} WECHAT_HTTP_APIS,
|
||||
*PWECHAT_HTTP_APIS;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "get_db_handle.h"
|
||||
|
||||
#include "wechat_data.h"
|
||||
#include "base64.h"
|
||||
|
||||
#define WX_NEW_CHAT_MSG_OFFSET 0x76f010
|
||||
#define WX_GET_PRE_DOWNLOAD_MGR_OFFSET 0x80f110
|
||||
@ -179,5 +180,34 @@ int DoDownloadTask(ULONG64 msg_id) {
|
||||
POPAD
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int GetVoice(ULONG64 msg_id, wchar_t *dir) {
|
||||
int success = -1;
|
||||
string buff = GetVoiceBuffByMsgId(msg_id);
|
||||
if (buff.size() == 0) {
|
||||
success = 0;
|
||||
return success;
|
||||
}
|
||||
wstring save_path = wstring(dir);
|
||||
if (!FindOrCreateDirectoryW(save_path.c_str())) {
|
||||
success = -2;
|
||||
return success;
|
||||
}
|
||||
save_path = save_path + L"\\" + to_wstring(msg_id) + 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) {
|
||||
#ifdef _DEBUG
|
||||
wcout <<" save_path =" <<save_path<<endl;
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
DWORD bytes_write = 0;
|
||||
string decode = base64_decode(buff);
|
||||
WriteFile(file_handle, (LPCVOID)decode.c_str(), decode.size(), &bytes_write, 0);
|
||||
CloseHandle(file_handle);
|
||||
success = 1;
|
||||
return success;
|
||||
}
|
@ -2,4 +2,6 @@
|
||||
#define DOWNLOAD_H_
|
||||
|
||||
int DoDownloadTask(ULONG64 msg_id);
|
||||
|
||||
int GetVoice(ULONG64 msg_id,wchar_t * dir);
|
||||
#endif
|
@ -15,11 +15,40 @@
|
||||
#define DB_FUNCTION_MSG_OFFSET 0x11B0
|
||||
#define DB_NAME_OFFSET 0x14
|
||||
|
||||
#define STORAGE_START_OFFSET 0x13f8
|
||||
#define STORAGE_END_OFFSET 0x13fc
|
||||
|
||||
#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
|
||||
#define CHAT_CR_MSG_STORAGE_VFTABLE 0x2ABEF14
|
||||
#define SESSION_STORAGE_VFTABLE 0x2AD3578
|
||||
#define APP_INFO_STORAGE_VFTABLE 0x2ABCC58
|
||||
#define HEAD_IMG_STORAGE_VFTABLE 0x2ACD9DC
|
||||
#define HEAD_IMG_URL_STORAGE_VFTABLE 0x2ACDF70
|
||||
|
||||
#define BIZ_INFO_STORAGE_VFTABLE 0x2ABD718
|
||||
#define TICKET_INFO_STORAGE_VFTABLE 0x2AD5400
|
||||
#define CHAT_ROOM_STORAGE_VFTABLE 0x2AC299C
|
||||
#define CHAT_ROOM_INFO_STORAGE_VFTABLE 0x2AC245C
|
||||
#define MEDIA_STORAGE_VFTABLE 0x2ACE998
|
||||
#define NAME_2_ID_STORAGE_VFTABLE 0x2AD222C
|
||||
#define EMOTION_PACKAGE_STORAGE_VFTABLE 0x2AC6400
|
||||
|
||||
#define EMOTION_STORAGE_VFTABLE 0x2AC7018
|
||||
#define BUFINFO_STORAGE_VFTABLE 0x2AC3178
|
||||
|
||||
#define CUSTOM_EMOTION_STORAGE_VFTABLE 0x2AC4E90
|
||||
#define DEL_SESSIONINFO_STORAGE_VFTABLE 0x2AC5F98
|
||||
#define FUNCTION_MSG_STORAGE_VFTABLE 0x2ACD10C
|
||||
|
||||
#define FUNCTION_MSG_TASK_STORAGE_VFTABLE 0x2ACC5C8
|
||||
#define REVOKE_MSG_STORAGE_VFTABLE 0x2AD27BC
|
||||
|
||||
using namespace std;
|
||||
map<wstring, DatabaseInfo> dbmap;
|
||||
std::vector<DatabaseInfo> dbs;
|
||||
@ -180,6 +209,60 @@ std::vector<void *> GetDbHandles() {
|
||||
DWORD *)(p_contact_addr + DB_FUNCTION_MSG_OFFSET + DB_NAME_OFFSET)));
|
||||
dbmap[bizchat_msg_name] = bizchat_msg_db;
|
||||
}
|
||||
// Storage
|
||||
DWORD storage_start = *(DWORD *)(p_contact_addr + STORAGE_START_OFFSET);
|
||||
DWORD storage_end = *(DWORD *)(p_contact_addr + STORAGE_END_OFFSET);
|
||||
|
||||
// do {
|
||||
// DWORD vtable_ptr = *(DWORD *)(storage_start);
|
||||
|
||||
// if(vtable_ptr == base + OP_LOG_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + CHAT_MSG_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + CHAT_CR_MSG_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + SESSION_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + APP_INFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + HEAD_IMG_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + HEAD_IMG_URL_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + BIZ_INFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + TICKET_INFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + CHAT_ROOM_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + CHAT_ROOM_INFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + MEDIA_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + NAME_2_ID_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + EMOTION_PACKAGE_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + EMOTION_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + BUFINFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + CUSTOM_EMOTION_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + DEL_SESSIONINFO_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + FUNCTION_MSG_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + FUNCTION_MSG_TASK_STORAGE_VFTABLE){
|
||||
|
||||
// }else if(vtable_ptr == base + REVOKE_MSG_STORAGE_VFTABLE){
|
||||
|
||||
// }
|
||||
|
||||
// storage_start = storage_start + 0x4;
|
||||
// } while (storage_start != storage_end);
|
||||
|
||||
DWORD multi_db_mgr_addr = base + MULTI_DB_MSG_MGR_OFFSET;
|
||||
DWORD public_msg_mgr_addr = base + PUBLIC_MSG_MGR_OFFSET;
|
||||
DWORD favorite_storage_mgr_addr = base + FAVORITE_STORAGE_MGR_OFFSET;
|
||||
@ -207,6 +290,21 @@ std::vector<void *> GetDbHandles() {
|
||||
dbs.push_back(msg0_db);
|
||||
wstring msg_db_name = wstring((wchar_t *)(*(DWORD *)(db_addr)));
|
||||
dbmap[msg_db_name] = msg0_db;
|
||||
|
||||
// BufInfoStorage
|
||||
DWORD buf_info_addr = *(DWORD *)(db_addr + 0x14);
|
||||
|
||||
DWORD buf_info_handle = *(DWORD *)(buf_info_addr + 0x38);
|
||||
DatabaseInfo media_msg0_db{0};
|
||||
media_msg0_db.db_name = (wchar_t *)(*(DWORD *)(buf_info_addr + 0x4C));
|
||||
media_msg0_db.db_name_len = *(DWORD *)(buf_info_addr + 0x50);
|
||||
media_msg0_db.handle = buf_info_handle;
|
||||
ExecuteSQL(buf_info_handle,
|
||||
"select * from sqlite_master where type=\"table\";",
|
||||
(DWORD)GetDbInfo, &media_msg0_db);
|
||||
dbs.push_back(media_msg0_db);
|
||||
wstring media_msg_db_name = wstring((wchar_t *)(*(DWORD *)(buf_info_addr + 0x4C)));
|
||||
dbmap[media_msg_db_name] = media_msg0_db;
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,4 +413,26 @@ vector<string> GetChatMsgByMsgId(ULONG64 msgid){
|
||||
return result[1];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string GetVoiceBuffByMsgId(ULONG64 msgid) {
|
||||
char sql[260] = {0};
|
||||
sprintf_s(sql, "SELECT Buf from Media WHERE Reserved0=%llu;", msgid);
|
||||
wchar_t dbname[20] = {0};
|
||||
for (int i = 0;; i++) {
|
||||
swprintf_s(dbname, L"MediaMSG%d.db", i);
|
||||
DWORD handle = GetDbHandleByDbName(dbname);
|
||||
#ifdef _DEBUG
|
||||
cout <<" handle =" <<handle<<endl;
|
||||
#endif
|
||||
if (handle == 0) return "";
|
||||
vector<vector<string>> result;
|
||||
int ret = Select(handle, (const char *)sql, result);
|
||||
#ifdef _DEBUG
|
||||
cout <<" size =" <<result.size()<<endl;
|
||||
#endif
|
||||
if (result.size() == 0) continue;
|
||||
return result[1][0];
|
||||
}
|
||||
return "";
|
||||
}
|
@ -8,4 +8,6 @@ std::vector<void *> GetDbHandles();
|
||||
DWORD GetDbHandleByDbName(wchar_t *dbname);
|
||||
unsigned int GetLocalIdByMsgId(ULONG64 msgid, int &dbIndex);
|
||||
std::vector<std::string> GetChatMsgByMsgId(ULONG64 msgid);
|
||||
|
||||
std::string GetVoiceBuffByMsgId(ULONG64 msgid);
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user