获取语音文件

This commit is contained in:
hugy 2023-03-30 23:08:15 +08:00
parent c590a95425
commit 61c9e6f8c1
7 changed files with 206 additions and 1 deletions

View File

@ -38,6 +38,7 @@
54.朋友圈下一页
<!-- 55.获取联系人或者群名称 -->
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

View File

@ -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;
}

View File

@ -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;

View File

@ -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
@ -181,3 +182,32 @@ int DoDownloadTask(ULONG64 msg_id) {
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;
}

View File

@ -2,4 +2,6 @@
#define DOWNLOAD_H_
int DoDownloadTask(ULONG64 msg_id);
int GetVoice(ULONG64 msg_id,wchar_t * dir);
#endif

View File

@ -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;
}
}
@ -316,3 +414,25 @@ vector<string> GetChatMsgByMsgId(ULONG64 msgid){
}
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 "";
}

View File

@ -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