mirror of
https://github.com/ttttupup/wxhelper.git
synced 2024-11-22 18:29:23 +08:00
'feat:基础功能'
This commit is contained in:
parent
2eb798458c
commit
a90d667799
16
app/3rdparty/CMakeLists.txt
vendored
16
app/3rdparty/CMakeLists.txt
vendored
@ -5,3 +5,19 @@ add_subdirectory(lz4)
|
|||||||
add_subdirectory(mongoose)
|
add_subdirectory(mongoose)
|
||||||
add_subdirectory(spdlog)
|
add_subdirectory(spdlog)
|
||||||
add_subdirectory(tinyxml2)
|
add_subdirectory(tinyxml2)
|
||||||
|
|
||||||
|
|
||||||
|
if(USE_EXTERNAL_DETOURS)
|
||||||
|
find_path(DETOURS_INCLUDE_DIRS "detours/detours.h")
|
||||||
|
find_library(DETOURS_LIBRARY detours REQUIRED)
|
||||||
|
else()
|
||||||
|
add_subdirectory(Detours)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(USE_EXTERNAL_JSON)
|
||||||
|
find_package(nlohmann_json 3.2.0 REQUIRED)
|
||||||
|
else()
|
||||||
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
add_subdirectory(json)
|
||||||
|
endif()
|
@ -7,8 +7,4 @@ add_library(base ${BASE_SOURCE} ${BASE_HEADER_SOURCE})
|
|||||||
target_include_directories(base PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/include)
|
target_include_directories(base PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/include)
|
||||||
|
|
||||||
|
|
||||||
#target_include_directories(base PUBLIC C:/other/codeSource/windows/wxhelper/app/base/src/include)
|
|
||||||
|
|
||||||
#install(TARGETS base LIBRARY DESTINATION base)
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
namespace base {
|
namespace base {
|
||||||
namespace memory {
|
namespace memory {
|
||||||
std::vector<INT64> ScanAndMatchValue(INT64 value, INT64 start,int align);
|
std::vector<INT64> ScanAndMatchValue(INT64 value, INT64 start,int align);
|
||||||
int sunday(const byte* total, int tlen, const byte* part, int plen);
|
int Sunday(const byte* total, int tlen, const byte* part, int plen);
|
||||||
}
|
}
|
||||||
} // namespace base
|
} // namespace base
|
||||||
#endif
|
#endif
|
@ -40,7 +40,7 @@ std::vector<INT64> ScanAndMatchValue(INT64 value, INT64 start, int align) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sunday(const byte* total, int tlen, const byte* part, int plen) {
|
int Sunday(const byte* total, int tlen, const byte* part, int plen) {
|
||||||
byte move[128] = {0};
|
byte move[128] = {0};
|
||||||
for (int i = 0; i < plen; i++) {
|
for (int i = 0; i < plen; i++) {
|
||||||
move[part[i]] = plen - i;
|
move[part[i]] = plen - i;
|
||||||
|
@ -5,52 +5,52 @@ project(wxhelper VERSION 1.0.0)
|
|||||||
|
|
||||||
message(${CMAKE_VERSION})
|
message(${CMAKE_VERSION})
|
||||||
|
|
||||||
|
option(USE_EXTERNAL_JSON "Use an external JSON library" OFF)
|
||||||
|
option(USE_EXTERNAL_DETOURS "Use an external detours library" OFF)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17 /MD /EHsc ")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17 /MD /EHsc ")
|
||||||
|
|
||||||
|
|
||||||
file(GLOB CPP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c )
|
file(GLOB CPP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c )
|
||||||
|
|
||||||
file(GLOB ASM_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.asm )
|
file(GLOB ASM_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.asm )
|
||||||
|
|
||||||
|
if(USE_EXTERNAL_DETOURS)
|
||||||
include_directories(${VCPKG_INSTALLED_DIR}/x64-windows/include ${DETOURS_INCLUDE_DIRS})
|
include_directories(${VCPKG_INSTALLED_DIR}/x64-windows/include ${DETOURS_INCLUDE_DIRS})
|
||||||
|
else()
|
||||||
|
include_directories(${VCPKG_INSTALLED_DIR}/x64-windows/include )
|
||||||
|
endif()
|
||||||
add_subdirectory(../3rdparty 3rdparty)
|
add_subdirectory(../3rdparty 3rdparty)
|
||||||
|
|
||||||
add_subdirectory(../base base)
|
add_subdirectory(../base base)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
find_path(DETOURS_INCLUDE_DIRS "detours/detours.h")
|
|
||||||
find_library(DETOURS_LIBRARY detours REQUIRED)
|
|
||||||
|
|
||||||
find_package(nlohmann_json CONFIG REQUIRED)
|
|
||||||
|
|
||||||
add_library(wxhelper SHARED ${CPP_FILES} ${ASM_FILES})
|
add_library(wxhelper SHARED ${CPP_FILES} ${ASM_FILES})
|
||||||
message(11233)
|
|
||||||
message(${PROJECT_SOURCE_DIR})
|
target_compile_definitions(wxhelper PRIVATE WECHAT_VERSION=39825)
|
||||||
target_include_directories(wxhelper
|
|
||||||
PRIVATE ${DETOURS_INCLUDE_DIRS}
|
# target_include_directories(wxhelper
|
||||||
PRIVATE ../base/src/include
|
# PRIVATE ../base/src/include
|
||||||
PRIVATE ../3rdparty/spdlog/include
|
# PRIVATE ../3rdparty/spdlog/include
|
||||||
PRIVATE ../3rdparty/base64
|
# PRIVATE ../3rdparty/base64
|
||||||
PRIVATE ../3rdparty/lz4
|
# PRIVATE ../3rdparty/lz4
|
||||||
PRIVATE ../3rdparty/mongoose
|
# PRIVATE ../3rdparty/mongoose
|
||||||
PRIVATE ../3rdparty/tinyxml2
|
# PRIVATE ../3rdparty/tinyxml2
|
||||||
PRIVATE ../base/src/include
|
# PRIVATE ../3rdparty/Detours/src
|
||||||
)
|
# )
|
||||||
|
|
||||||
target_link_libraries(wxhelper
|
target_link_libraries(wxhelper
|
||||||
PRIVATE ${DETOURS_LIBRARY}
|
PRIVATE base
|
||||||
PRIVATE spdlog::spdlog
|
PRIVATE spdlog::spdlog
|
||||||
PRIVATE lz4
|
PRIVATE lz4
|
||||||
PRIVATE base64
|
PRIVATE base64
|
||||||
PRIVATE mongoose
|
PRIVATE mongoose
|
||||||
PRIVATE nlohmann_json::nlohmann_json
|
PRIVATE nlohmann_json::nlohmann_json
|
||||||
PRIVATE base
|
|
||||||
PRIVATE tinyxml2
|
PRIVATE tinyxml2
|
||||||
|
PRIVATE detours
|
||||||
)
|
)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(wxhelper PROPERTIES LINKER_LANGUAGE C
|
SET_TARGET_PROPERTIES(wxhelper PROPERTIES LINKER_LANGUAGE C
|
||||||
|
@ -1,30 +1,64 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
#include "spdlog/sinks/daily_file_sink.h"
|
#include "spdlog/sinks/daily_file_sink.h"
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "windows.h"
|
|
||||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
|
||||||
namespace wxhelper {
|
namespace wxhelper {
|
||||||
Config::Config(/* args */) {}
|
|
||||||
|
|
||||||
Config::~Config() {}
|
void Config::init() {
|
||||||
|
|
||||||
void Config::Initialize() {
|
|
||||||
port_ = GetPrivateProfileInt("config", "Port", 19088, "./config.ini");
|
|
||||||
hidden_dll_ =
|
|
||||||
GetPrivateProfileInt("config", "HiddenDll", 1, "./config.ini");
|
|
||||||
auto logger =
|
auto logger =
|
||||||
spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 23, 59);
|
spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 23, 59);
|
||||||
logger->flush_on(spdlog::level::err);
|
logger->flush_on(spdlog::level::err);
|
||||||
spdlog::set_default_logger(logger);
|
spdlog::set_default_logger(logger);
|
||||||
spdlog::flush_every(std::chrono::seconds(3));
|
spdlog::flush_every(std::chrono::seconds(3));
|
||||||
spdlog::set_level(spdlog::level::debug);
|
spdlog::set_level(spdlog::level::info);
|
||||||
spdlog::set_pattern("%Y-%m-%d %H:%M:%S [%l] [%t] - <%s>|<%#>|<%!>,%v");
|
spdlog::set_pattern("%Y-%m-%d %H:%M:%S [%l] [%t] - <%s>|<%#>|<%!>,%v");
|
||||||
|
http_server_port_ =
|
||||||
|
GetPrivateProfileInt("config", "HttpServerPort", 19088, "./config.ini");
|
||||||
|
hidden_dll_ = GetPrivateProfileInt("config", "HiddenDll", 1, "./config.ini");
|
||||||
|
TCHAR host[MAX_PATH];
|
||||||
|
GetPrivateProfileStringA("config", "HttpServerHost", "http://0.0.0.0", host,
|
||||||
|
sizeof(host), "./config.ini");
|
||||||
|
http_server_host_ = host;
|
||||||
|
TCHAR mode[MAX_PATH];
|
||||||
|
GetPrivateProfileString("config", "RecvMessageMode", "tcp", mode,
|
||||||
|
sizeof(mode), "./config.ini");
|
||||||
|
recv_message_mode_ = mode;
|
||||||
|
|
||||||
|
TCHAR tcp_ip[MAX_PATH];
|
||||||
|
GetPrivateProfileString("config", "RecvTcpIp", "127.0.0.1", tcp_ip,
|
||||||
|
sizeof(tcp_ip), "./config.ini");
|
||||||
|
recv_tcp_ip_ = tcp_ip;
|
||||||
|
recv_tcp_port_ =
|
||||||
|
GetPrivateProfileInt("config", "RecvTcpPort", 19099, "./config.ini");
|
||||||
|
TCHAR url[MAX_PATH];
|
||||||
|
GetPrivateProfileString("config", "RecvHttpUrl", "127.0.0.1", url,
|
||||||
|
sizeof(url), "./config.ini");
|
||||||
|
recv_http_url_ = url;
|
||||||
|
recv_http_timeout_ =
|
||||||
|
GetPrivateProfileInt("config", "RecvHttpTimeout", 3000, "./config.ini");
|
||||||
|
SPDLOG_INFO(
|
||||||
|
"wxhelper config:"
|
||||||
|
"HttpServerPort={},HttpServerHost={},RecvMessageMode={},RecvTcpIp="
|
||||||
|
"{},RecvTcpPort={},RecvHttpUrl={},RecvHttpTimeout={}",
|
||||||
|
http_server_port_, http_server_host_, recv_message_mode_, recv_tcp_ip_,
|
||||||
|
recv_tcp_port_, recv_http_url_, recv_http_timeout_);
|
||||||
}
|
}
|
||||||
int Config::GetPort() { return port_; }
|
|
||||||
|
|
||||||
int Config::GetHideDll() { return hidden_dll_; }
|
int Config::GetHideDll() { return hidden_dll_; }
|
||||||
|
std::string Config::GetHttpServerHost() { return http_server_host_; }
|
||||||
|
int Config::GetHttpServerPort() { return http_server_port_; }
|
||||||
|
std::string Config::GetRecvMessageMode() { return recv_message_mode_; }
|
||||||
|
|
||||||
|
std::string Config::GetRecvTcpIp() { return recv_tcp_ip_; }
|
||||||
|
int Config::GetRecvTcpPort() { return recv_tcp_port_; }
|
||||||
|
|
||||||
|
std::string Config::GetRecvHttpUrl() { return recv_http_url_; }
|
||||||
|
int Config::GetRecvHttpTimeout() { return recv_http_timeout_; }
|
||||||
|
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
||||||
|
@ -1,19 +1,34 @@
|
|||||||
#ifndef WXHELPER_CONFIG_H_
|
#ifndef WXHELPER_CONFIG_H_
|
||||||
#define WXHELPER_CONFIG_H_
|
#define WXHELPER_CONFIG_H_
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "singleton.h"
|
||||||
namespace wxhelper {
|
namespace wxhelper {
|
||||||
|
|
||||||
class Config {
|
|
||||||
|
class Config : public base::Singleton<Config> {
|
||||||
public:
|
public:
|
||||||
Config();
|
void init();
|
||||||
~Config();
|
|
||||||
void Initialize();
|
|
||||||
int GetPort();
|
|
||||||
int GetHideDll();
|
int GetHideDll();
|
||||||
|
std::string GetHttpServerHost();
|
||||||
|
int GetHttpServerPort();
|
||||||
|
std::string GetRecvMessageMode();
|
||||||
|
|
||||||
|
std::string GetRecvTcpIp();
|
||||||
|
int GetRecvTcpPort();
|
||||||
|
|
||||||
|
std::string GetRecvHttpUrl();
|
||||||
|
int GetRecvHttpTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int port_;
|
|
||||||
int hidden_dll_;
|
int hidden_dll_;
|
||||||
|
std::string http_server_host_;
|
||||||
|
int http_server_port_;
|
||||||
|
std::string recv_message_mode_;
|
||||||
|
std::string recv_tcp_ip_;
|
||||||
|
int recv_tcp_port_;
|
||||||
|
std::string recv_http_url_;
|
||||||
|
int recv_http_timeout_;
|
||||||
};
|
};
|
||||||
} // namespace wxhelper
|
} // namespace wxhelper
|
||||||
#endif
|
#endif
|
@ -1,513 +0,0 @@
|
|||||||
#include "db.h"
|
|
||||||
|
|
||||||
#include "base64.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
#include "utils.h"
|
|
||||||
namespace offset = wxhelper::V3_9_8_25::offset;
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
void FreeResult(std::vector<std::vector<common::SqlResult>> &data) {
|
|
||||||
if (data.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < data.size(); i++) {
|
|
||||||
for (unsigned j = 0; j < data[i].size(); j++) {
|
|
||||||
common::SqlResult *sr = (common::SqlResult *)&data[i][j];
|
|
||||||
if (sr->column_name) {
|
|
||||||
delete[] sr->column_name;
|
|
||||||
sr->column_name = NULL;
|
|
||||||
}
|
|
||||||
if (sr->content) {
|
|
||||||
delete[] sr->content;
|
|
||||||
sr->content = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data[i].clear();
|
|
||||||
}
|
|
||||||
data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int DB::ExecSelect(UINT64 db, const char *sql,
|
|
||||||
std::vector<std::vector<common::SqlResult>> &data) {
|
|
||||||
common::sqlite3_prepare p_sqlite3_prepare =
|
|
||||||
(common::sqlite3_prepare)(base_addr_ + offset::k_sqlite3_prepare);
|
|
||||||
common::sqlite3_step p_sqlite3_step =
|
|
||||||
(common::sqlite3_step)(base_addr_ + offset::k_sqlite3_step);
|
|
||||||
common::sqlite3_column_count p_sqlite3_column_count =
|
|
||||||
(common::sqlite3_column_count)(base_addr_ +
|
|
||||||
offset::k_sqlite3_column_count);
|
|
||||||
common::sqlite3_column_name p_sqlite3_column_name =
|
|
||||||
(common::sqlite3_column_name)(base_addr_ + offset::k_sqlite3_column_name);
|
|
||||||
common::sqlite3_column_type p_sqlite3_column_type =
|
|
||||||
(common::sqlite3_column_type)(base_addr_ + offset::k_sqlite3_column_type);
|
|
||||||
common::sqlite3_column_blob p_sqlite3_column_blob =
|
|
||||||
(common::sqlite3_column_blob)(base_addr_ + offset::k_sqlite3_column_blob);
|
|
||||||
common::sqlite3_column_bytes p_sqlite3_column_bytes =
|
|
||||||
(common::sqlite3_column_bytes)(base_addr_ +
|
|
||||||
offset::k_sqlite3_column_bytes);
|
|
||||||
common::sqlite3_finalize p_sqlite3_finalize =
|
|
||||||
(common::sqlite3_finalize)(base_addr_ + offset::k_sqlite3_finalize);
|
|
||||||
UINT64 *stmt;
|
|
||||||
int rc = p_sqlite3_prepare(db, sql, -1, &stmt, 0);
|
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
while (p_sqlite3_step(stmt) == SQLITE_ROW) {
|
|
||||||
int col_count = p_sqlite3_column_count(stmt);
|
|
||||||
std::vector<common::SqlResult> tempStruct;
|
|
||||||
for (int i = 0; i < col_count; i++) {
|
|
||||||
common::SqlResult temp = {0};
|
|
||||||
const char *ColName = p_sqlite3_column_name(stmt, i);
|
|
||||||
int nType = p_sqlite3_column_type(stmt, i);
|
|
||||||
const void *pReadBlobData = p_sqlite3_column_blob(stmt, i);
|
|
||||||
int nLength = p_sqlite3_column_bytes(stmt, i);
|
|
||||||
temp.column_name = new char[strlen(ColName) + 1];
|
|
||||||
memcpy(temp.column_name, ColName, strlen(ColName) + 1);
|
|
||||||
temp.column_name_len = strlen(ColName);
|
|
||||||
temp.content_len = nLength;
|
|
||||||
switch (nType) {
|
|
||||||
case SQLITE_BLOB: {
|
|
||||||
temp.content = new char[nLength];
|
|
||||||
memcpy(temp.content, pReadBlobData, nLength);
|
|
||||||
temp.is_blob = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
if (nLength != 0) {
|
|
||||||
temp.content = new char[nLength + 1];
|
|
||||||
memcpy(temp.content, pReadBlobData, nLength + 1);
|
|
||||||
} else {
|
|
||||||
temp.content = new char[2];
|
|
||||||
ZeroMemory(temp.content, 2);
|
|
||||||
}
|
|
||||||
temp.is_blob = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempStruct.push_back(temp);
|
|
||||||
}
|
|
||||||
data.push_back(tempStruct);
|
|
||||||
}
|
|
||||||
p_sqlite3_finalize(stmt);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DB::Select(UINT64 db_hanle, const char *sql,
|
|
||||||
std::vector<std::vector<std::string>> &query_result) {
|
|
||||||
std::vector<std::vector<common::SqlResult>> data;
|
|
||||||
int status = ExecSelect(db_hanle, sql, data);
|
|
||||||
if (status == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (data.size() == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
std::vector<std::string> index;
|
|
||||||
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) {
|
|
||||||
std::vector<std::string> item;
|
|
||||||
for (size_t i = 0; i < it.size(); i++) {
|
|
||||||
if (!it[i].is_blob) {
|
|
||||||
bool is_utf8 =
|
|
||||||
base::utils::IsTextUtf8(it[i].content, it[i].content_len);
|
|
||||||
if (is_utf8) {
|
|
||||||
std::string content(it[i].content);
|
|
||||||
item.push_back(content);
|
|
||||||
} else {
|
|
||||||
std::string base64_str =
|
|
||||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
|
||||||
item.push_back(base64_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
std::string b64_str =
|
|
||||||
base64_encode((BYTE *)it[i].content, it[i].content_len);
|
|
||||||
item.push_back(b64_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query_result.push_back(item);
|
|
||||||
}
|
|
||||||
FreeResult(data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetDbInfo(void *data, int argc, char **argv, char **name) {
|
|
||||||
common::DatabaseInfo *pdata = (common::DatabaseInfo *)data;
|
|
||||||
common::TableInfo tb = {0};
|
|
||||||
if (argv[1]) {
|
|
||||||
tb.name = new char[strlen(argv[1]) + 1];
|
|
||||||
memcpy(tb.name, argv[1], strlen(argv[1]) + 1);
|
|
||||||
} else {
|
|
||||||
tb.name = (char *)"NULL";
|
|
||||||
}
|
|
||||||
if (argv[2]) {
|
|
||||||
tb.table_name = new char[strlen(argv[2]) + 1];
|
|
||||||
memcpy(tb.table_name, argv[2], strlen(argv[2]) + 1);
|
|
||||||
} else {
|
|
||||||
tb.table_name = (char *)"NULL";
|
|
||||||
}
|
|
||||||
if (argv[3]) {
|
|
||||||
tb.rootpage = new char[strlen(argv[3]) + 1];
|
|
||||||
memcpy(tb.rootpage, argv[3], strlen(argv[3]) + 1);
|
|
||||||
} else {
|
|
||||||
tb.rootpage = (char *)"NULL";
|
|
||||||
}
|
|
||||||
if (argv[4]) {
|
|
||||||
tb.sql = new char[strlen(argv[4]) + 1];
|
|
||||||
memcpy(tb.sql, argv[4], strlen(argv[4]) + 1);
|
|
||||||
} else {
|
|
||||||
tb.sql = (char *)"NULL";
|
|
||||||
}
|
|
||||||
tb.name_len = strlen(tb.name);
|
|
||||||
tb.table_name_len = strlen(tb.table_name);
|
|
||||||
tb.sql_len = strlen(tb.sql);
|
|
||||||
tb.rootpage_len = strlen(tb.rootpage);
|
|
||||||
pdata->tables.push_back(tb);
|
|
||||||
pdata->count = pdata->tables.size();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DB::init(UINT64 base) {
|
|
||||||
base_addr_ = base;
|
|
||||||
dbmap_ = {};
|
|
||||||
dbs_ = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
int DB::ExecuteSQL(UINT64 db, const char *sql,
|
|
||||||
common::sqlite3_callback callback, void *data) {
|
|
||||||
UINT64 sqlite3_exec_addr = base_addr_ + offset::k_sqlite3_exec;
|
|
||||||
common::sqlite3_exec sqlite3_exec = (common::sqlite3_exec)sqlite3_exec_addr;
|
|
||||||
int status = sqlite3_exec(db, sql, callback, data, 0);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<void *> DB::GetWeChatDbHandles() {
|
|
||||||
dbs_.clear();
|
|
||||||
dbmap_.clear();
|
|
||||||
UINT64 p_contact_addr = *(UINT64 *)(base_addr_ + offset::kGPInstance);
|
|
||||||
UINT64 micro_msg_db_addr = *(UINT64 *)(p_contact_addr + offset::kMicroMsgDB);
|
|
||||||
UINT64 chat_msg_db_addr = *(UINT64 *)(p_contact_addr + offset::kChatMsgDB);
|
|
||||||
UINT64 misc_db_addr = *(UINT64 *)(p_contact_addr + offset::kMiscDB);
|
|
||||||
UINT64 emotion_db_addr = *(UINT64 *)(p_contact_addr + offset::kEmotionDB);
|
|
||||||
UINT64 media_db_addr = *(UINT64 *)(p_contact_addr + offset::kMediaDB);
|
|
||||||
UINT64 bizchat_msg_db_addr =
|
|
||||||
*(UINT64 *)(p_contact_addr + offset::kBizchatMsgDB);
|
|
||||||
UINT64 function_msg_db_addr =
|
|
||||||
*(UINT64 *)(p_contact_addr + offset::kFunctionMsgDB);
|
|
||||||
|
|
||||||
// microMsg.db
|
|
||||||
common::DatabaseInfo micro_msg_db{0};
|
|
||||||
micro_msg_db.db_name = (wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kMicroMsgDB + offset::kDBName));
|
|
||||||
micro_msg_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kMicroMsgDB + offset::kDBName + 0x8);
|
|
||||||
micro_msg_db.handle = micro_msg_db_addr;
|
|
||||||
ExecuteSQL(micro_msg_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
µ_msg_db);
|
|
||||||
dbs_.push_back(micro_msg_db);
|
|
||||||
std::wstring micro_msg_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kMicroMsgDB + offset::kDBName)));
|
|
||||||
dbmap_[micro_msg_name] = micro_msg_db;
|
|
||||||
|
|
||||||
// chatMsg.db
|
|
||||||
common::DatabaseInfo chat_msg_db{0};
|
|
||||||
chat_msg_db.db_name = (wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kChatMsgDB + offset::kDBName));
|
|
||||||
chat_msg_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kChatMsgDB + offset::kDBName + 0x8);
|
|
||||||
chat_msg_db.handle = chat_msg_db_addr;
|
|
||||||
ExecuteSQL(chat_msg_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&chat_msg_db);
|
|
||||||
dbs_.push_back(chat_msg_db);
|
|
||||||
std::wstring chat_msg_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kChatMsgDB + offset::kDBName)));
|
|
||||||
dbmap_[chat_msg_name] = chat_msg_db;
|
|
||||||
|
|
||||||
// misc.db
|
|
||||||
common::DatabaseInfo misc_db{0};
|
|
||||||
misc_db.db_name = (wchar_t *)(*(UINT64 *)(p_contact_addr + offset::kMiscDB +
|
|
||||||
offset::kDBName));
|
|
||||||
misc_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kMiscDB + offset::kDBName + 0x8);
|
|
||||||
misc_db.handle = misc_db_addr;
|
|
||||||
ExecuteSQL(misc_db_addr, "select * from sqlite_master where type=\"table\";",
|
|
||||||
GetDbInfo, &misc_db);
|
|
||||||
dbs_.push_back(misc_db);
|
|
||||||
std::wstring misc_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kMiscDB + offset::kDBName)));
|
|
||||||
dbmap_[misc_name] = misc_db;
|
|
||||||
|
|
||||||
// emotion.db
|
|
||||||
common::DatabaseInfo emotion_db{0};
|
|
||||||
emotion_db.db_name = (wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kEmotionDB + offset::kDBName));
|
|
||||||
emotion_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kEmotionDB + offset::kDBName + 0x8);
|
|
||||||
emotion_db.handle = emotion_db_addr;
|
|
||||||
ExecuteSQL(emotion_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&emotion_db);
|
|
||||||
dbs_.push_back(emotion_db);
|
|
||||||
std::wstring emotion_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kEmotionDB + offset::kDBName)));
|
|
||||||
dbmap_[emotion_name] = emotion_db;
|
|
||||||
|
|
||||||
// media.db
|
|
||||||
common::DatabaseInfo media_db{0};
|
|
||||||
media_db.db_name = (wchar_t *)(*(UINT64 *)(p_contact_addr + offset::kMediaDB +
|
|
||||||
offset::kDBName));
|
|
||||||
media_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kMediaDB + offset::kDBName + 0x8);
|
|
||||||
media_db.handle = media_db_addr;
|
|
||||||
ExecuteSQL(media_db_addr, "select * from sqlite_master where type=\"table\";",
|
|
||||||
GetDbInfo, &media_db);
|
|
||||||
dbs_.push_back(media_db);
|
|
||||||
std::wstring media_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kMediaDB + offset::kDBName)));
|
|
||||||
dbmap_[media_name] = media_db;
|
|
||||||
|
|
||||||
// functionMsg.db
|
|
||||||
common::DatabaseInfo function_msg_db{0};
|
|
||||||
function_msg_db.db_name = (wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName));
|
|
||||||
function_msg_db.db_name_len = *(
|
|
||||||
DWORD *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName + 0x8);
|
|
||||||
function_msg_db.handle = function_msg_db_addr;
|
|
||||||
ExecuteSQL(function_msg_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&function_msg_db);
|
|
||||||
dbs_.push_back(function_msg_db);
|
|
||||||
std::wstring function_msg_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName)));
|
|
||||||
dbmap_[function_msg_name] = function_msg_db;
|
|
||||||
|
|
||||||
if (bizchat_msg_db_addr) {
|
|
||||||
// functionMsg.db maybe null
|
|
||||||
common::DatabaseInfo bizchat_msg_db{0};
|
|
||||||
bizchat_msg_db.db_name = (wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName));
|
|
||||||
bizchat_msg_db.db_name_len =
|
|
||||||
*(DWORD *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName +
|
|
||||||
0x8);
|
|
||||||
bizchat_msg_db.handle = bizchat_msg_db_addr;
|
|
||||||
ExecuteSQL(bizchat_msg_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&bizchat_msg_db);
|
|
||||||
dbs_.push_back(bizchat_msg_db);
|
|
||||||
std::wstring bizchat_msg_name = std::wstring((wchar_t *)(*(
|
|
||||||
UINT64 *)(p_contact_addr + offset::kFunctionMsgDB + offset::kDBName)));
|
|
||||||
dbmap_[bizchat_msg_name] = bizchat_msg_db;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 multi_db_mgr_addr = base_addr_ + offset::kMultiDBMgr;
|
|
||||||
UINT64 public_msg_mgr_addr = base_addr_ + offset::kPublicMsgMgr;
|
|
||||||
UINT64 favorite_storage_mgr_addr = base_addr_ + offset::kFavoriteStorageMgr;
|
|
||||||
|
|
||||||
// MsgX.db
|
|
||||||
UINT64 wrap_ptr = *(UINT64 *)(multi_db_mgr_addr);
|
|
||||||
UINT64 current_db_num = *(UINT64 *)(wrap_ptr + 0x68);
|
|
||||||
UINT64 begin_ptr = *(UINT64 *)(wrap_ptr + 0x50);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < current_db_num; i++) {
|
|
||||||
UINT64 next_addr = begin_ptr + i * 0x8;
|
|
||||||
UINT64 db_addr = *(UINT64 *)next_addr;
|
|
||||||
if (db_addr) {
|
|
||||||
UINT64 msg0_db_addr = *(UINT64 *)(db_addr + 0x78);
|
|
||||||
common::DatabaseInfo msg0_db{0};
|
|
||||||
msg0_db.db_name = (wchar_t *)(*(UINT64 *)(db_addr));
|
|
||||||
msg0_db.db_name_len = *(DWORD *)(db_addr + 0x8);
|
|
||||||
msg0_db.handle = msg0_db_addr;
|
|
||||||
msg0_db.extrainfo = *(UINT64 *)(*(UINT64 *)(db_addr + 0x28) + 0x1E8);
|
|
||||||
ExecuteSQL(msg0_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&msg0_db);
|
|
||||||
dbs_.push_back(msg0_db);
|
|
||||||
std::wstring msg_db_name =
|
|
||||||
std::wstring(msg0_db.db_name, msg0_db.db_name_len);
|
|
||||||
dbmap_[msg_db_name] = msg0_db;
|
|
||||||
|
|
||||||
// BufInfoStorage
|
|
||||||
UINT64 buf_info_addr = *(UINT64 *)(db_addr + 0x20);
|
|
||||||
|
|
||||||
UINT64 buf_info_handle = *(UINT64 *)(buf_info_addr + 0x50);
|
|
||||||
common::DatabaseInfo media_msg0_db{0};
|
|
||||||
media_msg0_db.db_name = (wchar_t *)(*(UINT64 *)(buf_info_addr + 0x78));
|
|
||||||
media_msg0_db.db_name_len = *(DWORD *)(buf_info_addr + 0x80);
|
|
||||||
media_msg0_db.handle = buf_info_handle;
|
|
||||||
ExecuteSQL(buf_info_handle,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&media_msg0_db);
|
|
||||||
dbs_.push_back(media_msg0_db);
|
|
||||||
std::wstring media_msg_db_name =
|
|
||||||
std::wstring(media_msg0_db.db_name, media_msg0_db.db_name_len);
|
|
||||||
dbmap_[media_msg_db_name] = media_msg0_db;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// publicMsg.db
|
|
||||||
UINT64 public_msg_mgr_ptr = *(UINT64 *)(public_msg_mgr_addr);
|
|
||||||
for (unsigned int i = 1; i < 4; i++) {
|
|
||||||
UINT64 public_msg_ptr = *(UINT64 *)(public_msg_mgr_ptr + i * 0x8);
|
|
||||||
if (public_msg_ptr) {
|
|
||||||
UINT64 public_msg_db_addr = *(UINT64 *)(public_msg_ptr + 0x50);
|
|
||||||
common::DatabaseInfo public_msg_db{0};
|
|
||||||
public_msg_db.db_name = (wchar_t *)(*(UINT64 *)(public_msg_ptr + 0x78));
|
|
||||||
public_msg_db.db_name_len = *(DWORD *)(public_msg_ptr + 0x80);
|
|
||||||
public_msg_db.handle = public_msg_db_addr;
|
|
||||||
ExecuteSQL(public_msg_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&public_msg_db);
|
|
||||||
dbs_.push_back(public_msg_db);
|
|
||||||
std::wstring public_msg_db_name =
|
|
||||||
std::wstring(public_msg_db.db_name, public_msg_db.db_name_len);
|
|
||||||
dbmap_[public_msg_db_name] = public_msg_db;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Favorite.db
|
|
||||||
UINT64 favItems_ptr =
|
|
||||||
*(UINT64 *)(*(UINT64 *)(*(UINT64 *)(favorite_storage_mgr_addr) + 0x10) +
|
|
||||||
0x8);
|
|
||||||
if (favItems_ptr) {
|
|
||||||
UINT64 favorite_db_addr = *(UINT64 *)(favItems_ptr + 0x50);
|
|
||||||
common::DatabaseInfo favorite_db{0};
|
|
||||||
favorite_db.db_name = (wchar_t *)(*(UINT64 *)(favItems_ptr + 0x78));
|
|
||||||
favorite_db.db_name_len = *(DWORD *)(favItems_ptr + 0x80);
|
|
||||||
favorite_db.handle = favorite_db_addr;
|
|
||||||
ExecuteSQL(favorite_db_addr,
|
|
||||||
"select * from sqlite_master where type=\"table\";", GetDbInfo,
|
|
||||||
&favorite_db);
|
|
||||||
dbs_.push_back(favorite_db);
|
|
||||||
std::wstring public_msg_db_name =
|
|
||||||
std::wstring(favorite_db.db_name, favorite_db.db_name_len);
|
|
||||||
dbmap_[public_msg_db_name] = favorite_db;
|
|
||||||
}
|
|
||||||
common::DatabaseInfo db_end = {0};
|
|
||||||
dbs_.push_back(db_end);
|
|
||||||
std::vector<void *> ret_array;
|
|
||||||
for (unsigned int i = 0; i < dbs_.size() - 1; i++) {
|
|
||||||
ret_array.push_back(&dbs_[i]);
|
|
||||||
}
|
|
||||||
return ret_array;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 DB::GetDbHandleByDbName(wchar_t *dbname) {
|
|
||||||
if (dbmap_.size() == 0) {
|
|
||||||
GetWeChatDbHandles();
|
|
||||||
}
|
|
||||||
if (dbmap_.find(dbname) != dbmap_.end()) {
|
|
||||||
return dbmap_[dbname].handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 DB::GetLocalIdByMsgId(ULONG64 msgid, INT64 &dbIndex) {
|
|
||||||
char sql[260] = {0};
|
|
||||||
sprintf_s(sql, "select localId from MSG where MsgSvrID=%llu;", msgid);
|
|
||||||
wchar_t dbname[20] = {0};
|
|
||||||
for (int i = 0;; i++) {
|
|
||||||
swprintf_s(dbname, L"MSG%d.db", i);
|
|
||||||
UINT64 handle = GetDbHandleByDbName(dbname);
|
|
||||||
if (handle == 0) {
|
|
||||||
SPDLOG_INFO("MSG db handle is null");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
std::vector<std::vector<std::string>> result;
|
|
||||||
int ret = Select(handle, (const char *)sql, result);
|
|
||||||
if (result.size() == 0) continue;
|
|
||||||
dbIndex = dbmap_[dbname].extrainfo;
|
|
||||||
return stoi(result[1][0]);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> DB::GetChatMsgByMsgId(ULONG64 msgid) {
|
|
||||||
char sql[260] = {0};
|
|
||||||
sprintf_s(sql,
|
|
||||||
"select "
|
|
||||||
"localId,TalkerId,MsgSvrID,Type,SubType,IsSender,CreateTime,"
|
|
||||||
"Sequence,StatusEx,FlagEx,Status,MsgServerSeq,MsgSequence,"
|
|
||||||
"StrTalker,StrContent,BytesExtra from MSG where MsgSvrID=%llu;",
|
|
||||||
msgid);
|
|
||||||
wchar_t dbname[20] = {0};
|
|
||||||
for (int i = 0;; i++) {
|
|
||||||
swprintf_s(dbname, L"MSG%d.db", i);
|
|
||||||
UINT64 handle = GetDbHandleByDbName(dbname);
|
|
||||||
if (handle == 0) {
|
|
||||||
SPDLOG_INFO("MSG db handle is null");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
std::vector<std::vector<std::string>> result;
|
|
||||||
int ret = Select(handle, (const char *)sql, result);
|
|
||||||
if (result.size() == 0) continue;
|
|
||||||
return result[1];
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DB::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);
|
|
||||||
UINT64 handle = GetDbHandleByDbName(dbname);
|
|
||||||
if (handle == 0) {
|
|
||||||
SPDLOG_INFO("Media db handle is null");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::vector<std::vector<std::string>> result;
|
|
||||||
int ret = Select(handle, (const char *)sql, result);
|
|
||||||
if (result.size() == 0) continue;
|
|
||||||
return result[1][0];
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DB::GetPublicMsgCompressContentByMsgId(ULONG64 msgid) {
|
|
||||||
char sql[260] = {0};
|
|
||||||
sprintf_s(sql, "SELECT CompressContent from PublicMsg WHERE MsgSvrID=%llu;",
|
|
||||||
msgid);
|
|
||||||
wchar_t dbname[20] = {0};
|
|
||||||
swprintf_s(dbname, 20, L"%s", L"PublicMsg.db");
|
|
||||||
UINT64 handle = GetDbHandleByDbName(dbname);
|
|
||||||
if (handle == 0) {
|
|
||||||
SPDLOG_INFO("db handle not found,check msgid");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::vector<std::vector<std::string>> result;
|
|
||||||
int ret = Select(handle, (const char *)sql, result);
|
|
||||||
if (result.size() == 0) {
|
|
||||||
SPDLOG_INFO(
|
|
||||||
"this SQL statement executed normally, but the result was empty");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return result[1][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DB::GetChatMsgStrContentByMsgId(ULONG64 msgid) {
|
|
||||||
char sql[260] = {0};
|
|
||||||
sprintf_s(sql, "select StrContent from MSG where MsgSvrID=%llu;", msgid);
|
|
||||||
wchar_t dbname[20] = {0};
|
|
||||||
for (int i = 0;; i++) {
|
|
||||||
swprintf_s(dbname, L"MSG%d.db", i);
|
|
||||||
UINT64 handle = GetDbHandleByDbName(dbname);
|
|
||||||
if (handle == 0) {
|
|
||||||
SPDLOG_INFO("MSG db handle is null");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
std::vector<std::vector<std::string>> result;
|
|
||||||
int ret = Select(handle, (const char *)sql, result);
|
|
||||||
if (result.size() == 0) continue;
|
|
||||||
return result[1][0];
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
} // namespace wxhelper
|
|
@ -1,40 +0,0 @@
|
|||||||
#ifndef WXHELPER_DB_H_
|
|
||||||
#define WXHELPER_DB_H_
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "singleton.h"
|
|
||||||
#include "wechat_function.h"
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
class DB : public base::Singleton<DB> {
|
|
||||||
public:
|
|
||||||
void init(UINT64 base);
|
|
||||||
int ExecuteSQL(UINT64 db, const char *sql, common::sqlite3_callback callback,
|
|
||||||
void *data);
|
|
||||||
std::vector<void *> GetWeChatDbHandles();
|
|
||||||
int Select(UINT64 db_hanle, const char *sql,
|
|
||||||
std::vector<std::vector<std::string>> &query_result);
|
|
||||||
UINT64 GetDbHandleByDbName(wchar_t *dbname);
|
|
||||||
INT64 GetLocalIdByMsgId(ULONG64 msgid, INT64 &dbIndex);
|
|
||||||
std::vector<std::string> GetChatMsgByMsgId(ULONG64 msgid);
|
|
||||||
|
|
||||||
std::string GetVoiceBuffByMsgId(ULONG64 msgid);
|
|
||||||
|
|
||||||
std::string GetPublicMsgCompressContentByMsgId(ULONG64 msgid);
|
|
||||||
|
|
||||||
std::string GetChatMsgStrContentByMsgId(ULONG64 msgid);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int ExecSelect(UINT64 db, const char *sql,
|
|
||||||
std::vector<std::vector<common::SqlResult>> &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::wstring, common::DatabaseInfo> dbmap_;
|
|
||||||
std::vector<common::DatabaseInfo> dbs_;
|
|
||||||
UINT64 base_addr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace wxhelper
|
|
||||||
#endif
|
|
@ -1,11 +1,13 @@
|
|||||||
#include "global_manager.h"
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,
|
|
||||||
LPVOID lpReserved) {
|
#include "wxhelper.h"
|
||||||
|
BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call,
|
||||||
|
LPVOID reserved) {
|
||||||
switch (ul_reason_for_call) {
|
switch (ul_reason_for_call) {
|
||||||
case DLL_PROCESS_ATTACH: {
|
case DLL_PROCESS_ATTACH: {
|
||||||
DisableThreadLibraryCalls(hModule);
|
OutputDebugString("start\n");
|
||||||
wxhelper::GlobalManager::GetInstance().initialize(hModule);
|
DisableThreadLibraryCalls(module);
|
||||||
|
wxhelper::WxHelper::GetInstance().init(module);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DLL_THREAD_ATTACH: {
|
case DLL_THREAD_ATTACH: {
|
||||||
@ -15,6 +17,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DLL_PROCESS_DETACH: {
|
case DLL_PROCESS_DETACH: {
|
||||||
|
OutputDebugString("end\n");
|
||||||
|
wxhelper::WxHelper::GetInstance().finally();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
#include "global_manager.h"
|
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
#include "http_url_handler.h"
|
|
||||||
#include "thread_pool.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "wechat_service.h"
|
|
||||||
#include "wxutils.h"
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
GlobalManager::~GlobalManager() {}
|
|
||||||
|
|
||||||
void GlobalManager::initialize(HMODULE module) {
|
|
||||||
state = GlobalContextState::INITIALIZING;
|
|
||||||
module_ = module;
|
|
||||||
config = std::unique_ptr<Config>(new Config());
|
|
||||||
config->Initialize();
|
|
||||||
if (config->GetHideDll()) {
|
|
||||||
base::utils::HideModule(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 base = wxutils::GetWeChatWinBase();
|
|
||||||
DB::GetInstance().init(base);
|
|
||||||
WechatService::GetInstance().SetBaseAddr(base);
|
|
||||||
http_server = std::unique_ptr<http::HttpServer>(
|
|
||||||
new http::HttpServer(config->GetPort()));
|
|
||||||
http_server->AddHttpApiUrl("/api/sendTextMsg", SendTextMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/hookSyncMsg", HookSyncMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/getContactList", GetContacts);
|
|
||||||
http_server->AddHttpApiUrl("/api/unhookSyncMsg", UnHookSyncMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/checkLogin", CheckLogin);
|
|
||||||
http_server->AddHttpApiUrl("/api/userInfo", GetSelfInfo);
|
|
||||||
http_server->AddHttpApiUrl("/api/getDBInfo", GetDBInfo);
|
|
||||||
http_server->AddHttpApiUrl("/api/execSql", ExecSql);
|
|
||||||
http_server->AddHttpApiUrl("/api/lockWeChat", LockWeChat);
|
|
||||||
http_server->AddHttpApiUrl("/api/unlockWeChat", UnLockWeChat);
|
|
||||||
http_server->AddHttpApiUrl("/api/clickEnterWeChat", EnterWeChat);
|
|
||||||
http_server->AddHttpApiUrl("/api/forwardMsg", ForwardMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/sendImagesMsg", SendImageMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/sendFileMsg", SendFileMsg);
|
|
||||||
http_server->AddHttpApiUrl("/api/sendAtText", SendAtText);
|
|
||||||
http_server->AddHttpApiUrl("/api/sendMultiAtText", SendMultiAtText);
|
|
||||||
http_server->AddHttpApiUrl("/api/getLoginUrl", GetLoginUrl);
|
|
||||||
http_server->AddHttpApiUrl("/api/translateVoice", TranslateVoice);
|
|
||||||
http_server->AddHttpApiUrl("/api/getTranslateVoiceText", GetTranslateVoiceText);
|
|
||||||
http_server->AddHttpApiUrl("/api/openUrlByWeChat", OpenUrlByWeChat);
|
|
||||||
|
|
||||||
http_server->Start();
|
|
||||||
base::ThreadPool::GetInstance().Create(2, 8);
|
|
||||||
|
|
||||||
state = GlobalContextState::INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlobalManager::finally() {
|
|
||||||
if (http_server) {
|
|
||||||
http_server->Stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace wxhelper
|
|
@ -1,33 +0,0 @@
|
|||||||
#ifndef WXHELPER_GLOBAL_MANAGER_H_
|
|
||||||
#define WXHELPER_GLOBAL_MANAGER_H_
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "http_server.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
enum class GlobalContextState { NOT_INITIALIZED, INITIALIZING, INITIALIZED };
|
|
||||||
|
|
||||||
class GlobalManager : public base::Singleton<GlobalManager> {
|
|
||||||
friend class base::Singleton<GlobalManager>;
|
|
||||||
~GlobalManager();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void initialize(HMODULE module);
|
|
||||||
void finally();
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::unique_ptr<Config> config;
|
|
||||||
std::unique_ptr<http::HttpServer> http_server;
|
|
||||||
// std::unique_ptr<WechatService> service_;
|
|
||||||
|
|
||||||
GlobalContextState state = GlobalContextState::NOT_INITIALIZED;
|
|
||||||
|
|
||||||
private:
|
|
||||||
HMODULE module_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace wxhelper
|
|
||||||
#endif
|
|
@ -2,13 +2,18 @@
|
|||||||
|
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
|
HttpClient::HttpClient(std::string url, int timeout)
|
||||||
|
: url_(url), timeout_(timeout) {}
|
||||||
|
|
||||||
void HttpClient::SendRequest(const std::string &content) {
|
void HttpClient::SendRequest(const std::string &content) {
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
Data data;
|
Data data;
|
||||||
data.done = false;
|
data.done = false;
|
||||||
data.post_data = content;
|
data.post_data = content;
|
||||||
|
data.url = url_;
|
||||||
|
data.timeout = timeout_;
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
mg_http_connect(&mgr, kUrl.c_str(), OnHttpEvent, &data);
|
mg_http_connect(&mgr, url_.c_str(), &HttpClient::OnHttpEvent, &data);
|
||||||
while (!data.done) {
|
while (!data.done) {
|
||||||
mg_mgr_poll(&mgr, 500);
|
mg_mgr_poll(&mgr, 500);
|
||||||
}
|
}
|
||||||
@ -16,18 +21,15 @@ void HttpClient::SendRequest(const std::string &content) {
|
|||||||
data.done = false;
|
data.done = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpClient::SetConfig(std::string url, uint64_t timeout) {
|
|
||||||
kUrl = url;
|
|
||||||
kTimeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpClient::OnHttpEvent(struct mg_connection *c, int ev, void *ev_data,
|
void HttpClient::OnHttpEvent(struct mg_connection *c, int ev, void *ev_data,
|
||||||
void *fn_data) {
|
void *fn_data) {
|
||||||
const char *s_url = kUrl.c_str();
|
|
||||||
Data *data = (Data *)fn_data;
|
Data *data = (Data *)fn_data;
|
||||||
|
const char *s_url = data->url.c_str();
|
||||||
|
int timeout = data->timeout;
|
||||||
if (ev == MG_EV_OPEN) {
|
if (ev == MG_EV_OPEN) {
|
||||||
// Connection created. Store connect expiration time in c->data
|
// Connection created. Store connect expiration time in c->data
|
||||||
*(uint64_t *)c->data = mg_millis() + kTimeout;
|
*(uint64_t *)c->data = mg_millis() + timeout;
|
||||||
} else if (ev == MG_EV_POLL) {
|
} else if (ev == MG_EV_POLL) {
|
||||||
if (mg_millis() > *(uint64_t *)c->data &&
|
if (mg_millis() > *(uint64_t *)c->data &&
|
||||||
(c->is_connecting || c->is_resolving)) {
|
(c->is_connecting || c->is_resolving)) {
|
||||||
|
@ -3,23 +3,29 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
#include "noncopyable.h"
|
||||||
#include "singleton.h"
|
#include "singleton.h"
|
||||||
|
|
||||||
namespace http {
|
namespace http {
|
||||||
static std::string kUrl = "http://127.0.0.1:8000";
|
|
||||||
static uint64_t kTimeout = 3000;
|
|
||||||
struct Data {
|
struct Data {
|
||||||
bool done;
|
bool done;
|
||||||
|
int timeout;
|
||||||
|
std::string url;
|
||||||
std::string post_data;
|
std::string post_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HttpClient {
|
class HttpClient : public NonCopyable {
|
||||||
public:
|
public:
|
||||||
static void SendRequest(const std::string &content);
|
explicit HttpClient(std::string url, int timeout);
|
||||||
static void SetConfig(std::string url, uint64_t timeout);
|
void SendRequest(const std::string &content);
|
||||||
|
private:
|
||||||
static void OnHttpEvent(struct mg_connection *c, int ev, void *ev_data,
|
static void OnHttpEvent(struct mg_connection *c, int ev, void *ev_data,
|
||||||
void *fn_data);
|
void *fn_data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string url_;
|
||||||
|
int timeout_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
#include "http_server.h"
|
#include "http_server.h"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include "http_router.h"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
namespace http {
|
|
||||||
|
|
||||||
HttpServer::HttpServer(int port) {
|
namespace http {
|
||||||
port_ = port;
|
|
||||||
running_ = false;
|
|
||||||
mg_mgr_init(&mgr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpServer::~HttpServer() {
|
HttpServer::~HttpServer() {
|
||||||
if (thread_ != nullptr) {
|
if (thread_ != nullptr) {
|
||||||
@ -19,17 +14,29 @@ HttpServer::~HttpServer() {
|
|||||||
mg_mgr_free(&mgr_);
|
mg_mgr_free(&mgr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HttpServer::init(std::string &&host, int port) {
|
||||||
|
if (port < 1 || port > 65535) {
|
||||||
|
throw std::invalid_argument("Port number is out of range.");
|
||||||
|
}
|
||||||
|
mg_mgr_init(&mgr_);
|
||||||
|
host_ = std::move(host);
|
||||||
|
port_ = port;
|
||||||
|
SPDLOG_INFO("http init :host={},port={}",host_,port_);
|
||||||
|
}
|
||||||
|
|
||||||
bool HttpServer::Start() {
|
bool HttpServer::Start() {
|
||||||
if (running_) {
|
if (running_) {
|
||||||
|
SPDLOG_INFO("http server is already running");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
base::utils::CreateConsole();
|
base::utils::CreateConsole();
|
||||||
#endif
|
#endif
|
||||||
running_ = true;
|
running_.store(true);
|
||||||
thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartHttpServer, this,
|
thread_ = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)LaunchServer, this,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
return true;
|
SPDLOG_INFO("CreateThread for http server ,the result is {}",thread_ != NULL);
|
||||||
|
return thread_ != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HttpServer::Stop() {
|
bool HttpServer::Stop() {
|
||||||
@ -48,25 +55,18 @@ bool HttpServer::Stop() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HttpServer::GetPort() { return port_; }
|
void HttpServer::LaunchServer(HttpServer *server) {
|
||||||
bool HttpServer::GetRunning() { return running_; }
|
|
||||||
|
|
||||||
const mg_mgr *HttpServer::GetMgr() { return &mgr_; }
|
|
||||||
|
|
||||||
void HttpServer::AddHttpApiUrl(const std::string &uri, HttpCbFunc func) {
|
|
||||||
http_api_url_map_[uri] = func;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::StartHttpServer(HttpServer *server) {
|
|
||||||
int port = server->GetPort();
|
int port = server->GetPort();
|
||||||
std::string lsten_addr = "http://0.0.0.0:" + std::to_string(port);
|
std::string host = server->GetHost();
|
||||||
if (mg_http_listen(const_cast<mg_mgr *>(server->GetMgr()), lsten_addr.c_str(),
|
const mg_mgr * mgr = server->GetMgr();
|
||||||
EventHandler, server) == NULL) {
|
std::string listen_addr = host +":"+ std::to_string(port);
|
||||||
SPDLOG_INFO("http server listen fail.port:{}", port);
|
if (mg_http_listen(const_cast<mg_mgr *>(mgr), listen_addr.c_str(),
|
||||||
|
EventHandler, NULL) == NULL) {
|
||||||
|
SPDLOG_ERROR("http server listen fail.port:{}", port);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
mg_mgr_poll(const_cast<mg_mgr *>(server->GetMgr()), 100);
|
mg_mgr_poll(const_cast<mg_mgr *>(mgr), 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ void HttpServer::EventHandler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
if (ev == MG_EV_OPEN) {
|
if (ev == MG_EV_OPEN) {
|
||||||
} else if (ev == MG_EV_HTTP_MSG) {
|
} else if (ev == MG_EV_HTTP_MSG) {
|
||||||
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
||||||
if (mg_http_match_uri(hm, "/websocket")) {
|
if (mg_http_match_uri(hm, "/websocket/*")) {
|
||||||
mg_ws_upgrade(c, hm, NULL);
|
mg_ws_upgrade(c, hm, NULL);
|
||||||
} else if (mg_http_match_uri(hm, "/api/*")) {
|
} else if (mg_http_match_uri(hm, "/api/*")) {
|
||||||
HandleHttpRequest(c, hm, fn_data);
|
HandleHttpRequest(c, hm, fn_data);
|
||||||
@ -90,7 +90,6 @@ void HttpServer::EventHandler(struct mg_connection *c, int ev, void *ev_data,
|
|||||||
} else if (ev == MG_EV_WS_MSG) {
|
} else if (ev == MG_EV_WS_MSG) {
|
||||||
HandleWebsocketRequest(c, ev_data, fn_data);
|
HandleWebsocketRequest(c, ev_data, fn_data);
|
||||||
}
|
}
|
||||||
(void)fn_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HttpServer::HandleHttpRequest(struct mg_connection *c, void *ev_data,
|
void HttpServer::HandleHttpRequest(struct mg_connection *c, void *ev_data,
|
||||||
@ -98,51 +97,36 @@ void HttpServer::HandleHttpRequest(struct mg_connection *c, void *ev_data,
|
|||||||
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
||||||
std::string ret = R"({"code":200,"msg":"success"})";
|
std::string ret = R"({"code":200,"msg":"success"})";
|
||||||
try {
|
try {
|
||||||
ret = HttpDispatch(c, hm, fn_data);
|
|
||||||
} catch (nlohmann::json::exception &e) {
|
|
||||||
nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}};
|
|
||||||
ret = res.dump();
|
|
||||||
}
|
|
||||||
if (ret != "") {
|
|
||||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n",
|
|
||||||
ret.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HttpServer::HandleWebsocketRequest(struct mg_connection *c, void *ev_data,
|
|
||||||
void *fn_data) {
|
|
||||||
// Got websocket frame. Received data is wm->data. Echo it back!
|
|
||||||
struct mg_ws_message *wm = (struct mg_ws_message *)ev_data;
|
|
||||||
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string HttpServer::HttpDispatch(struct mg_connection *c,
|
|
||||||
struct mg_http_message *hm,
|
|
||||||
void *fn_data) {
|
|
||||||
std::string ret;
|
|
||||||
if (mg_vcasecmp(&hm->method, "GET") == 0) {
|
if (mg_vcasecmp(&hm->method, "GET") == 0) {
|
||||||
nlohmann::json ret_data = {
|
nlohmann::json ret_data = {
|
||||||
{"code", 200},
|
{"code", 200},
|
||||||
{"data", {}},
|
{"data", {}},
|
||||||
{"msg", "the get method is not supported.please use post method."}};
|
{"msg", "the get method is not supported.please use post method."}};
|
||||||
ret = ret_data.dump();
|
ret = ret_data.dump();
|
||||||
return ret;
|
} else if (mg_vcasecmp(&hm->method, "POST") == 0) {
|
||||||
|
std::string url(hm->uri.ptr, hm->uri.len);
|
||||||
|
nlohmann::json params =
|
||||||
|
nlohmann::json::parse(hm->body.ptr, hm->body.ptr + hm->body.len);
|
||||||
|
std::string p = params.dump();
|
||||||
|
ret = HttpRouter::GetInstance().HandleHttpRequest(url, p);
|
||||||
}
|
}
|
||||||
std::string api_uri(hm->uri.ptr,hm->uri.len);
|
} catch (nlohmann::json::exception &e) {
|
||||||
HttpServer *server = (HttpServer *)fn_data;
|
nlohmann::json res = {{"code", "500"}, {"msg", e.what()}, {"data", NULL}};
|
||||||
return server->ProcessHttpRequest(api_uri, hm);
|
ret = res.dump();
|
||||||
|
}
|
||||||
|
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "%s\n",
|
||||||
|
ret.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HttpServer::ProcessHttpRequest(const std::string &url,
|
void HttpServer::HandleWebsocketRequest(struct mg_connection *c, void *ev_data,
|
||||||
mg_http_message *hm) {
|
void *fn_data) {
|
||||||
SPDLOG_INFO("http server process request url :{}", url);
|
struct mg_ws_message *wm = (struct mg_ws_message *)ev_data;
|
||||||
if (http_api_url_map_.find(url) != http_api_url_map_.end()) {
|
nlohmann::json params =
|
||||||
return http_api_url_map_[url](hm);
|
nlohmann::json::parse(wm->data.ptr, wm->data.ptr + wm->data.len);
|
||||||
} else {
|
std::string cmd = params["cmd"];
|
||||||
nlohmann::json ret_data = {
|
std::string p = params.dump();
|
||||||
{"code", 200}, {"data", {}}, {"msg", "the url is not supported"}};
|
std::string ret = HttpRouter::GetInstance().HandleHttpRequest(cmd, p);
|
||||||
return ret_data.dump();
|
mg_ws_send(c, ret.c_str(), ret.size(), WEBSOCKET_OP_TEXT);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
@ -1,47 +1,39 @@
|
|||||||
#ifndef WXHELPER_HTTP_SERVER_H_
|
#ifndef WXHELPER_HTTP_SERVER_H_
|
||||||
#define WXHELPER_HTTP_SERVER_H_
|
#define WXHELPER_HTTP_SERVER_H_
|
||||||
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
#include "singleton.h"
|
||||||
namespace http {
|
namespace http {
|
||||||
typedef std::function<std::string(struct mg_http_message *)> HttpCbFunc;
|
|
||||||
class HttpServer {
|
|
||||||
public:
|
|
||||||
explicit HttpServer(int port);
|
|
||||||
HttpServer(const HttpServer &) = delete;
|
|
||||||
HttpServer(HttpServer &&) = delete;
|
|
||||||
HttpServer &operator=(const HttpServer &) = delete;
|
|
||||||
~HttpServer();
|
|
||||||
|
|
||||||
|
class HttpServer : public base::Singleton<HttpServer> {
|
||||||
|
public:
|
||||||
|
~HttpServer();
|
||||||
|
void init(std::string &&host, int port);
|
||||||
bool Start();
|
bool Start();
|
||||||
bool Stop();
|
bool Stop();
|
||||||
int GetPort();
|
const mg_mgr *GetMgr() { return &mgr_; }
|
||||||
bool GetRunning();
|
int GetPort() { return port_; }
|
||||||
const mg_mgr *GetMgr();
|
bool GetRunning() { return running_; }
|
||||||
void AddHttpApiUrl(const std::string &uri, HttpCbFunc func);
|
std::string GetHost() { return host_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int port_;
|
static void LaunchServer(HttpServer *server);
|
||||||
bool running_;
|
|
||||||
struct mg_mgr mgr_;
|
|
||||||
HANDLE thread_;
|
|
||||||
std::map<const std::string, HttpCbFunc> http_api_url_map_;
|
|
||||||
|
|
||||||
static void StartHttpServer(HttpServer *server);
|
|
||||||
static void EventHandler(struct mg_connection *c, int ev, void *ev_data,
|
static void EventHandler(struct mg_connection *c, int ev, void *ev_data,
|
||||||
void *fn_data);
|
void *fn_data);
|
||||||
|
|
||||||
static void HandleHttpRequest(struct mg_connection *c, void *ev_data,
|
static void HandleHttpRequest(struct mg_connection *c, void *ev_data,
|
||||||
void *fn_data);
|
void *fn_data);
|
||||||
static void HandleWebsocketRequest(struct mg_connection *c, void *ev_data,
|
static void HandleWebsocketRequest(struct mg_connection *c, void *ev_data,
|
||||||
void *fn_data);
|
void *fn_data);
|
||||||
static std::string HttpDispatch(struct mg_connection *c,
|
|
||||||
struct mg_http_message *hm, void *fn_data);
|
private:
|
||||||
std::string ProcessHttpRequest(const std::string &url,
|
struct mg_mgr mgr_;
|
||||||
struct mg_http_message *hm);
|
std::string host_;
|
||||||
|
int port_;
|
||||||
|
std::atomic<bool> running_{false};
|
||||||
|
HANDLE thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace http
|
} // namespace http
|
||||||
|
@ -1,340 +0,0 @@
|
|||||||
#include "http_url_handler.h"
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "wechat_hook.h"
|
|
||||||
#include "wechat_service.h"
|
|
||||||
|
|
||||||
#define STR2ULL(str) (base::utils::IsDigit(str) ? stoull(str) : 0)
|
|
||||||
#define STR2LL(str) (base::utils::IsDigit(str) ? stoll(str) : 0)
|
|
||||||
#define STR2I(str) (base::utils::IsDigit(str) ? stoi(str) : 0)
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
std::wstring GetWStringParam(nlohmann::json data, std::string key) {
|
|
||||||
return base::utils::Utf8ToWstring(data[key].get<std::string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::wstring> GetArrayParam(nlohmann::json data, std::string key) {
|
|
||||||
std::vector<std::wstring> result;
|
|
||||||
std::wstring param = GetWStringParam(data, key);
|
|
||||||
result = base::utils::split(param, L',');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetIntParam(nlohmann::json data, std::string key) {
|
|
||||||
int result;
|
|
||||||
try {
|
|
||||||
result = data[key].get<int>();
|
|
||||||
} catch (nlohmann::json::exception) {
|
|
||||||
result = STR2I(data[key].get<std::string>());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetBoolParam(nlohmann::json data, std::string key) {
|
|
||||||
return data[key].get<bool>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetStringParam(nlohmann::json data, std::string key) {
|
|
||||||
return data[key].get<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 GetInt64Param(nlohmann::json data, std::string key) {
|
|
||||||
INT64 result;
|
|
||||||
try {
|
|
||||||
result = data[key].get<INT64>();
|
|
||||||
} catch (nlohmann::json::exception) {
|
|
||||||
result = STR2LL(data[key].get<std::string>());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SendTextMsg(mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
|
||||||
std::wstring msg = GetWStringParam(j_param, "msg");
|
|
||||||
INT64 success = WechatService::GetInstance().SendTextMsg(wxid, msg);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
std::string ret = ret_data.dump();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string HookSyncMsg(mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
int port = GetIntParam(j_param, "port");
|
|
||||||
std::string ip = GetStringParam(j_param, "ip");
|
|
||||||
bool enable = GetBoolParam(j_param, "enableHttp");
|
|
||||||
std::string url = "http:://127.0.0.1:19088";
|
|
||||||
uint64_t timeout = 3000;
|
|
||||||
if (enable) {
|
|
||||||
url = GetStringParam(j_param, "url");
|
|
||||||
timeout = GetIntParam(j_param, "timeout");
|
|
||||||
}
|
|
||||||
hook::WechatHookParam param = {
|
|
||||||
ip, url, port, enable, timeout,
|
|
||||||
};
|
|
||||||
hook::WechatHook::GetInstance().Init(param);
|
|
||||||
INT64 success = hook::WechatHook::GetInstance().HookSyncMsg();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
std::string ret = ret_data.dump();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetContacts(mg_http_message* hm) {
|
|
||||||
std::vector<common::ContactInner> vec;
|
|
||||||
INT64 success = WechatService::GetInstance().GetContacts(vec);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
|
||||||
nlohmann::json item = {
|
|
||||||
{"customAccount", vec[i].custom_account},
|
|
||||||
{"encryptName", vec[i].encrypt_name},
|
|
||||||
{"type", vec[i].type},
|
|
||||||
{"verifyFlag", vec[i].verify_flag},
|
|
||||||
{"wxid", vec[i].wxid},
|
|
||||||
{"nickname", vec[i].nickname},
|
|
||||||
{"pinyin", vec[i].pinyin},
|
|
||||||
{"pinyinAll", vec[i].pinyin_all},
|
|
||||||
{"reserved1", vec[i].reserved1},
|
|
||||||
{"reserved2", vec[i].reserved2},
|
|
||||||
{"remark",vec[i].remark},
|
|
||||||
{"remarkPinyin",vec[i].remark_pinyin},
|
|
||||||
{"remarkPinyinAll",vec[i].remark_pinyin_all},
|
|
||||||
{"labelIds",vec[i].label_ids},
|
|
||||||
};
|
|
||||||
ret_data["data"].push_back(item);
|
|
||||||
}
|
|
||||||
std::string ret = ret_data.dump();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string UnHookSyncMsg(mg_http_message* hm) {
|
|
||||||
INT64 success = hook::WechatHook::GetInstance().UnHookSyncMsg();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string CheckLogin(mg_http_message* hm) {
|
|
||||||
INT64 success = WechatService::GetInstance().CheckLogin();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetSelfInfo(mg_http_message* hm) {
|
|
||||||
common::SelfInfoInner self_info;
|
|
||||||
INT64 success = WechatService::GetInstance().GetSelfInfo(self_info);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
if (success) {
|
|
||||||
nlohmann::json j_info = {
|
|
||||||
{"name", self_info.name},
|
|
||||||
{"city", self_info.city},
|
|
||||||
{"province", self_info.province},
|
|
||||||
{"country", self_info.country},
|
|
||||||
{"account", self_info.account},
|
|
||||||
{"wxid", self_info.wxid},
|
|
||||||
{"mobile", self_info.mobile},
|
|
||||||
{"headImage", self_info.head_img},
|
|
||||||
{"signature", self_info.signature},
|
|
||||||
{"dataSavePath", self_info.data_save_path},
|
|
||||||
{"currentDataPath", self_info.current_data_path},
|
|
||||||
{"dbKey", self_info.db_key},
|
|
||||||
{"publicKey", self_info.public_key},
|
|
||||||
{"privateKey", self_info.private_key},
|
|
||||||
};
|
|
||||||
ret_data["data"] = j_info;
|
|
||||||
}
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetDBInfo(mg_http_message* hm) {
|
|
||||||
std::vector<void*> v_ptr = wxhelper::DB::GetInstance().GetWeChatDbHandles();
|
|
||||||
nlohmann::json ret_data = {{"data", nlohmann::json::array()}};
|
|
||||||
for (unsigned int i = 0; i < v_ptr.size(); i++) {
|
|
||||||
nlohmann::json db_info;
|
|
||||||
db_info["tables"] = nlohmann::json::array();
|
|
||||||
common::DatabaseInfo* db =
|
|
||||||
reinterpret_cast<common::DatabaseInfo*>(v_ptr[i]);
|
|
||||||
db_info["handle"] = db->handle;
|
|
||||||
std::wstring dbname(db->db_name);
|
|
||||||
db_info["databaseName"] = base::utils::WstringToUtf8(dbname);
|
|
||||||
for (auto table : db->tables) {
|
|
||||||
nlohmann::json table_info = {{"name", table.name},
|
|
||||||
{"tableName", table.table_name},
|
|
||||||
{"sql", table.sql},
|
|
||||||
{"rootpage", table.rootpage}};
|
|
||||||
db_info["tables"].push_back(table_info);
|
|
||||||
}
|
|
||||||
ret_data["data"].push_back(db_info);
|
|
||||||
}
|
|
||||||
ret_data["code"] = 1;
|
|
||||||
ret_data["msg"] = "success";
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ExecSql(mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
UINT64 db_handle = GetInt64Param(j_param, "dbHandle");
|
|
||||||
std::string sql = GetStringParam(j_param, "sql");
|
|
||||||
std::vector<std::vector<std::string>> items;
|
|
||||||
int success =
|
|
||||||
wxhelper::DB::GetInstance().Select(db_handle, sql.c_str(), items);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"data", nlohmann::json::array()}, {"code", success}, {"msg", "success"}};
|
|
||||||
if (success == 0) {
|
|
||||||
ret_data["msg"] = "no data";
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
for (auto it : items) {
|
|
||||||
nlohmann::json temp_arr = nlohmann::json::array();
|
|
||||||
for (size_t i = 0; i < it.size(); i++) {
|
|
||||||
temp_arr.push_back(it[i]);
|
|
||||||
}
|
|
||||||
ret_data["data"].push_back(temp_arr);
|
|
||||||
}
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string LockWeChat(struct mg_http_message* hm) {
|
|
||||||
INT64 success = WechatService::GetInstance().LockWeChat();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string UnLockWeChat(struct mg_http_message* hm) {
|
|
||||||
INT64 success = WechatService::GetInstance().UnLockWeChat();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string EnterWeChat(struct mg_http_message* hm) {
|
|
||||||
INT64 success = WechatService::GetInstance().EnterWeChat();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ForwardMsg(struct mg_http_message* hm){
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
INT64 msg_id = GetInt64Param(j_param, "msgId");
|
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
|
||||||
INT64 success =
|
|
||||||
wxhelper::WechatService::GetInstance().ForwardMsg(msg_id, wxid);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SendImageMsg(struct mg_http_message* hm){
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
|
||||||
std::wstring path = GetWStringParam(j_param, "imagePath");
|
|
||||||
INT64 success =
|
|
||||||
wxhelper::WechatService::GetInstance().SendImageMsg(wxid, path);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SendFileMsg(struct mg_http_message* hm){
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
std::wstring wxid = GetWStringParam(j_param, "wxid");
|
|
||||||
std::wstring path = GetWStringParam(j_param, "filePath");
|
|
||||||
INT64 success =
|
|
||||||
wxhelper::WechatService::GetInstance().SendFileMsg(wxid, path);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"data", {}}, {"msg", "success"}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SendAtText(struct mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
|
||||||
std::vector<std::wstring> wxids = GetArrayParam(j_param, "wxids");
|
|
||||||
std::wstring msg = GetWStringParam(j_param, "msg");
|
|
||||||
std::vector<std::wstring> wxid_list;
|
|
||||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
|
||||||
wxid_list.push_back(wxids[i]);
|
|
||||||
}
|
|
||||||
INT64 success = wxhelper::WechatService::GetInstance().SendAtText(
|
|
||||||
chat_room_id, wxid_list, msg);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SendMultiAtText(struct mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
nlohmann::json array = j_param["at"];
|
|
||||||
std::vector<std::pair<std::wstring, std::wstring>> at_vector;
|
|
||||||
if (array.is_array()) {
|
|
||||||
for (const auto& item : array) {
|
|
||||||
at_vector.push_back(std::make_pair(GetWStringParam(item, "wxid"),
|
|
||||||
GetWStringParam(item, "msg")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::wstring chat_room_id = GetWStringParam(j_param, "chatRoomId");
|
|
||||||
INT64 success = wxhelper::WechatService::GetInstance().SendMultiAtText(
|
|
||||||
chat_room_id, at_vector);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetLoginUrl(struct mg_http_message* hm) {
|
|
||||||
std::string url = wxhelper::WechatService::GetInstance().GetLoginUrl();
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", 1}, {"msg", "success"}, {"data", {{"loginUrl", url}}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TranslateVoice(struct mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
INT64 msg_id = GetInt64Param(j_param, "msgId");
|
|
||||||
INT64 success = wxhelper::WechatService::GetInstance().TranslateVoice(msg_id);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetTranslateVoiceText(struct mg_http_message* hm) {
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
INT64 msg_id = GetInt64Param(j_param, "msgId");
|
|
||||||
std::string content =
|
|
||||||
wxhelper::WechatService::GetInstance().GetTranslateVoiceText(msg_id);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", 1}, {"msg", "success"}, {"data", {{"transtext", content}}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string OpenUrlByWeChat(struct mg_http_message* hm){
|
|
||||||
nlohmann::json j_param = nlohmann::json::parse(
|
|
||||||
hm->body.ptr, hm->body.ptr + hm->body.len, nullptr, false);
|
|
||||||
std::wstring url = GetWStringParam(j_param, "url");
|
|
||||||
int flag = GetIntParam(j_param, "flag");
|
|
||||||
INT64 success =
|
|
||||||
wxhelper::WechatService::GetInstance().OpenUrlByWeChatBrowser(url,flag);
|
|
||||||
nlohmann::json ret_data = {
|
|
||||||
{"code", success}, {"msg", "success"}, {"data", {}}};
|
|
||||||
return ret_data.dump();
|
|
||||||
}
|
|
||||||
} // namespace wxhelper
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef WXHELPER_HTTP_URL_HANDLER_H_
|
|
||||||
#define WXHELPER_HTTP_URL_HANDLER_H_
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "mongoose.h"
|
|
||||||
namespace wxhelper {
|
|
||||||
std::string SendTextMsg(struct mg_http_message *hm);
|
|
||||||
std::string HookSyncMsg(struct mg_http_message *hm);
|
|
||||||
std::string GetContacts(struct mg_http_message *hm);
|
|
||||||
std::string UnHookSyncMsg(struct mg_http_message *hm);
|
|
||||||
std::string CheckLogin(struct mg_http_message *hm);
|
|
||||||
std::string GetSelfInfo(struct mg_http_message *hm);
|
|
||||||
std::string GetDBInfo(struct mg_http_message *hm);
|
|
||||||
std::string ExecSql(struct mg_http_message *hm);
|
|
||||||
std::string LockWeChat(struct mg_http_message *hm);
|
|
||||||
std::string UnLockWeChat(struct mg_http_message *hm);
|
|
||||||
std::string EnterWeChat(struct mg_http_message* hm);
|
|
||||||
std::string ForwardMsg(struct mg_http_message* hm);
|
|
||||||
std::string SendImageMsg(struct mg_http_message* hm);
|
|
||||||
std::string SendFileMsg(struct mg_http_message* hm);
|
|
||||||
std::string SendAtText(struct mg_http_message* hm);
|
|
||||||
std::string SendMultiAtText(struct mg_http_message* hm);
|
|
||||||
std::string GetLoginUrl(struct mg_http_message* hm);
|
|
||||||
std::string TranslateVoice(struct mg_http_message* hm);
|
|
||||||
std::string GetTranslateVoiceText(struct mg_http_message* hm);
|
|
||||||
std::string OpenUrlByWeChat(struct mg_http_message* hm);
|
|
||||||
} // namespace wxhelper
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,493 +0,0 @@
|
|||||||
#ifndef WXHELPER_WECHAT_FUNCTION_H_
|
|
||||||
#define WXHELPER_WECHAT_FUNCTION_H_
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
namespace wxhelper {
|
|
||||||
namespace common {
|
|
||||||
/***************************sqlite3***************************************/
|
|
||||||
#define SQLITE_OK 0 /* Successful result */
|
|
||||||
/* beginning-of-error-codes */
|
|
||||||
#define SQLITE_ERROR 1 /* Generic error */
|
|
||||||
#define SQLITE_INTERNAL 2 /* Internal logic error in SQLite */
|
|
||||||
#define SQLITE_PERM 3 /* Access permission denied */
|
|
||||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
|
||||||
#define SQLITE_BUSY 5 /* The database file is locked */
|
|
||||||
#define SQLITE_LOCKED 6 /* A table in the database is locked */
|
|
||||||
#define SQLITE_NOMEM 7 /* A malloc() failed */
|
|
||||||
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
|
|
||||||
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
|
|
||||||
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
|
||||||
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
|
||||||
#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */
|
|
||||||
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
|
||||||
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
|
||||||
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
|
|
||||||
#define SQLITE_EMPTY 16 /* Internal use only */
|
|
||||||
#define SQLITE_SCHEMA 17 /* The database schema changed */
|
|
||||||
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
|
|
||||||
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
|
|
||||||
#define SQLITE_MISMATCH 20 /* Data type mismatch */
|
|
||||||
#define SQLITE_MISUSE 21 /* Library used incorrectly */
|
|
||||||
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
|
|
||||||
#define SQLITE_AUTH 23 /* Authorization denied */
|
|
||||||
#define SQLITE_FORMAT 24 /* Not used */
|
|
||||||
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
|
|
||||||
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
|
|
||||||
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
|
|
||||||
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
|
|
||||||
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
|
|
||||||
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
|
|
||||||
/* end-of-error-codes */
|
|
||||||
|
|
||||||
#define SQLITE_INTEGER 1
|
|
||||||
#define SQLITE_FLOAT 2
|
|
||||||
#define SQLITE_BLOB 4
|
|
||||||
#define SQLITE_NULL 5
|
|
||||||
#define SQLITE_TEXT 3
|
|
||||||
|
|
||||||
typedef int (*sqlite3_callback)(void *, int, char **, char **);
|
|
||||||
|
|
||||||
typedef int(__cdecl *sqlite3_exec)(UINT64, /* An open database */
|
|
||||||
const char *sql, /* SQL to be evaluated */
|
|
||||||
sqlite3_callback, /* Callback function */
|
|
||||||
void *, /* 1st argument to callback */
|
|
||||||
char **errmsg /* Error msg written here */
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef int(__cdecl *sqlite3_prepare)(
|
|
||||||
UINT64 db, /* Database handle */
|
|
||||||
const char *zSql, /* SQL statement, UTF-8 encoded */
|
|
||||||
int nByte, /* Maximum length of zSql in bytes. */
|
|
||||||
UINT64 **ppStmt, /* OUT: Statement handle */
|
|
||||||
const char **pzTail /* OUT: Pointer to unused portion of zSql */
|
|
||||||
);
|
|
||||||
typedef int(__cdecl *sqlite3_open)(const char *filename, UINT64 **ppDb);
|
|
||||||
|
|
||||||
typedef int(__cdecl *sqlite3_sleep)(int);
|
|
||||||
typedef int(__cdecl *sqlite3_errcode)(UINT64 *db);
|
|
||||||
typedef int(__cdecl *sqlite3_close)(UINT64 *);
|
|
||||||
|
|
||||||
typedef int(__cdecl *sqlite3_step)(UINT64 *);
|
|
||||||
typedef int(__cdecl *sqlite3_column_count)(UINT64 *pStmt);
|
|
||||||
typedef const char *(__cdecl *sqlite3_column_name)(UINT64 *, int N);
|
|
||||||
typedef int(__cdecl *sqlite3_column_type)(UINT64 *, int iCol);
|
|
||||||
typedef const void *(__cdecl *sqlite3_column_blob)(UINT64 *, int iCol);
|
|
||||||
typedef int(__cdecl *sqlite3_column_bytes)(UINT64 *, int iCol);
|
|
||||||
typedef int(__cdecl *sqlite3_finalize)(UINT64 *pStmt);
|
|
||||||
|
|
||||||
/***************************sqlite3 end*************************************/
|
|
||||||
|
|
||||||
struct TableInfo {
|
|
||||||
char *name;
|
|
||||||
INT64 name_len;
|
|
||||||
char *table_name;
|
|
||||||
INT64 table_name_len;
|
|
||||||
char *sql;
|
|
||||||
INT64 sql_len;
|
|
||||||
char *rootpage;
|
|
||||||
INT64 rootpage_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DatabaseInfo {
|
|
||||||
UINT64 handle = 0;
|
|
||||||
wchar_t *db_name = NULL;
|
|
||||||
INT64 db_name_len = 0;
|
|
||||||
std::vector<TableInfo> tables;
|
|
||||||
INT64 count = 0;
|
|
||||||
INT64 extrainfo = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SqlResult {
|
|
||||||
char *column_name;
|
|
||||||
INT64 column_name_len;
|
|
||||||
char *content;
|
|
||||||
INT64 content_len;
|
|
||||||
BOOL is_blob;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct InnerMessageStruct {
|
|
||||||
char *buffer;
|
|
||||||
INT64 length;
|
|
||||||
~InnerMessageStruct() {
|
|
||||||
if (this->buffer != NULL) {
|
|
||||||
delete[] this->buffer;
|
|
||||||
this->buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SelfInfoInner {
|
|
||||||
std::string name;
|
|
||||||
std::string city;
|
|
||||||
std::string province;
|
|
||||||
std::string country;
|
|
||||||
std::string account;
|
|
||||||
std::string wxid;
|
|
||||||
std::string mobile;
|
|
||||||
std::string head_img;
|
|
||||||
std::string data_save_path;
|
|
||||||
std::string signature;
|
|
||||||
std::string current_data_path;
|
|
||||||
std::string db_key;
|
|
||||||
std::string public_key;
|
|
||||||
std::string private_key;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContactInner {
|
|
||||||
std::string wxid;
|
|
||||||
std::string custom_account;
|
|
||||||
std::string encrypt_name;
|
|
||||||
std::string nickname;
|
|
||||||
std::string pinyin;
|
|
||||||
std::string pinyin_all;
|
|
||||||
std::string remark;
|
|
||||||
std::string remark_pinyin;
|
|
||||||
std::string remark_pinyin_all;
|
|
||||||
std::string label_ids;
|
|
||||||
DWORD type;
|
|
||||||
DWORD verify_flag;
|
|
||||||
DWORD reserved1;
|
|
||||||
DWORD reserved2;
|
|
||||||
ContactInner() {
|
|
||||||
wxid = "";
|
|
||||||
custom_account = "";
|
|
||||||
encrypt_name = "";
|
|
||||||
nickname = "";
|
|
||||||
pinyin = "";
|
|
||||||
pinyin_all = "";
|
|
||||||
remark = "";
|
|
||||||
remark_pinyin = "";
|
|
||||||
remark_pinyin_all = "";
|
|
||||||
label_ids = "";
|
|
||||||
type = -1;
|
|
||||||
verify_flag = -1;
|
|
||||||
reserved1 = -1;
|
|
||||||
reserved2 = -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ChatRoomInfoInner {
|
|
||||||
std::string chat_room_id;
|
|
||||||
std::string notice;
|
|
||||||
std::string admin;
|
|
||||||
std::string xml;
|
|
||||||
ChatRoomInfoInner() {
|
|
||||||
chat_room_id = "";
|
|
||||||
notice = "";
|
|
||||||
admin = "";
|
|
||||||
xml = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VectorInner {
|
|
||||||
#ifdef _DEBUG
|
|
||||||
INT64 head;
|
|
||||||
#endif
|
|
||||||
INT64 start;
|
|
||||||
INT64 finsh;
|
|
||||||
INT64 end;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ChatRoomMemberInner {
|
|
||||||
std::string chat_room_id;
|
|
||||||
std::string admin;
|
|
||||||
std::string admin_nickname;
|
|
||||||
std::string member_nickname;
|
|
||||||
std::string member;
|
|
||||||
ChatRoomMemberInner()
|
|
||||||
: chat_room_id(""),
|
|
||||||
admin(""),
|
|
||||||
admin_nickname(""),
|
|
||||||
member_nickname(""),
|
|
||||||
member("") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContactProfileInner {
|
|
||||||
std::string wxid;
|
|
||||||
std::string account;
|
|
||||||
std::string v3;
|
|
||||||
std::string nickname;
|
|
||||||
std::string head_image;
|
|
||||||
ContactProfileInner()
|
|
||||||
: wxid(""), account(""), v3(""), nickname(""), head_image("") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace common
|
|
||||||
namespace V3_9_8_25 {
|
|
||||||
namespace function {
|
|
||||||
|
|
||||||
typedef UINT64 (*__GetAccountService)();
|
|
||||||
typedef UINT64 (*__GetDataSavePath)(UINT64);
|
|
||||||
typedef UINT64 (*__GetCurrentDataPath)(UINT64);
|
|
||||||
typedef UINT64 (*__GetSendMessageMgr)();
|
|
||||||
typedef UINT64 (*__SendTextMsg)(UINT64, UINT64, UINT64, UINT64, UINT64, UINT64,
|
|
||||||
UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__FreeChatMsg)(UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__SendImageMsg)(UINT64, UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__NewChatMsg)(UINT64);
|
|
||||||
typedef UINT64 (*__SendFile)(UINT64, UINT64, UINT64, UINT64, UINT64, UINT64,
|
|
||||||
UINT64, UINT64, UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetAppMsgMgr)();
|
|
||||||
typedef UINT64 (*__OperatorNew)(UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__Free)();
|
|
||||||
typedef UINT64 (*__GetContactMgr)();
|
|
||||||
typedef UINT64 (*__GetContactList)(UINT64, UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__GetChatRoomMgr)();
|
|
||||||
typedef UINT64 (*__NewChatRoomInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeChatRoomInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__GetChatRoomDetailInfo)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__DoAddMemberToChatRoom)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__DoModChatRoomMemberNickName)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__DoDelMemberFromChatRoom)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetMemberFromChatRoom)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__NewChatRoom)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeChatRoom)(UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__DoTopMsg)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__RemoveTopMsg)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__InviteMemberToChatRoom)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__CreateChatRoom)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__QuitChatRoom)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__ForwardMsg)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__GetSNSFirstPage)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetSNSNextPageScene)(UINT64, UINT64);
|
|
||||||
|
|
||||||
typedef UINT64 (*__GetSNSDataMgr)();
|
|
||||||
typedef UINT64 (*__GetSnsTimeLineMgr)();
|
|
||||||
typedef UINT64 (*__GetMgrByPrefixLocalId)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__AddFavFromMsg)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetChatMgr)();
|
|
||||||
typedef UINT64 (*__GetFavoriteMgr)();
|
|
||||||
typedef UINT64 (*__AddFavFromImage)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetContact)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__NewContact)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeContact)(UINT64);
|
|
||||||
typedef UINT64 (*__NewMMReaderItem)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeMMReaderItem)(UINT64);
|
|
||||||
typedef UINT64 (*__ForwordPublicMsg)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__NewAppMsgInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeAppMsgInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__ParseAppMsgXml)(UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetPreDownLoadMgr)();
|
|
||||||
typedef UINT64 (*__PushAttachTask)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetCustomSmileyMgr)();
|
|
||||||
typedef UINT64 (*__SendCustomEmotion)(UINT64, UINT64, UINT64, UINT64, UINT64,
|
|
||||||
UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__JsApiShareAppMessage)(UINT64);
|
|
||||||
typedef UINT64 (*__InitJsConfig)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__SendApplet)(UINT64, UINT64, UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__SendAppletSecond)(UINT64, UINT64, UINT64, UINT64, UINT64,
|
|
||||||
UINT64);
|
|
||||||
typedef UINT64 (*__GetAppInfoByWaid)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__CopyShareAppMessageRequest)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__NewWAUpdatableMsgInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeWAUpdatableMsgInfo)(UINT64);
|
|
||||||
typedef UINT64 (*__SendPatMsg)(UINT64, UINT64);
|
|
||||||
typedef UINT64 (*__GetOCRManager)();
|
|
||||||
typedef UINT64 (*__DoOCRTask)(UINT64, UINT64, UINT64, UINT64, UINT64);
|
|
||||||
|
|
||||||
|
|
||||||
typedef UINT64 (*__GetLockWechatMgr)();
|
|
||||||
typedef UINT64 (*__RequestLockWechat)(UINT64);
|
|
||||||
typedef UINT64 (*__RequestUnLockWechat)(UINT64);
|
|
||||||
typedef UINT64 (*__OnLoginBtnClick)(UINT64);
|
|
||||||
typedef UINT64 (*__GetQRCodeLoginMgr)();
|
|
||||||
typedef UINT64 (*__UpdateMsg)(UINT64,UINT64,UINT64);
|
|
||||||
typedef UINT64 (*__GetVoiceMgr)();
|
|
||||||
typedef UINT64 (*__ChatMsg2NetSceneSendMsg)(UINT64,UINT64);
|
|
||||||
typedef UINT64 (*__TranslateVoice)(UINT64,UINT64,UINT64);
|
|
||||||
typedef UINT64 (*__ShowWebView)(UINT64,UINT64,UINT64,UINT64,UINT64,UINT64);
|
|
||||||
typedef UINT64 (*__NewWebViewPageConfig)(UINT64);
|
|
||||||
typedef UINT64 (*__FreeWebViewPageConfig)(UINT64);
|
|
||||||
typedef UINT64 (*__GetWebViewMgr)();
|
|
||||||
typedef UINT64 (*__SetUrl)(UINT64,UINT64,UINT64);
|
|
||||||
|
|
||||||
} // namespace function
|
|
||||||
namespace prototype {
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct WeChatString {
|
|
||||||
wchar_t *ptr;
|
|
||||||
DWORD length;
|
|
||||||
DWORD max_length;
|
|
||||||
INT64 c_ptr = 0;
|
|
||||||
DWORD c_len = 0;
|
|
||||||
WeChatString() { WeChatString(NULL); }
|
|
||||||
|
|
||||||
WeChatString(const std::wstring &s) {
|
|
||||||
ptr = (wchar_t *)(s.c_str());
|
|
||||||
length = static_cast<DWORD>(s.length());
|
|
||||||
max_length = static_cast<DWORD>(s.length());
|
|
||||||
}
|
|
||||||
WeChatString(const wchar_t *pStr) { WeChatString((wchar_t *)pStr); }
|
|
||||||
WeChatString(int tmp) {
|
|
||||||
ptr = NULL;
|
|
||||||
length = 0x0;
|
|
||||||
max_length = 0x0;
|
|
||||||
}
|
|
||||||
WeChatString(wchar_t *pStr) {
|
|
||||||
ptr = pStr;
|
|
||||||
length = static_cast<DWORD>(wcslen(pStr));
|
|
||||||
max_length = static_cast<DWORD>(wcslen(pStr));
|
|
||||||
}
|
|
||||||
void set_value(const wchar_t *pStr) {
|
|
||||||
ptr = (wchar_t *)pStr;
|
|
||||||
length = static_cast<DWORD>(wcslen(pStr));
|
|
||||||
max_length = static_cast<DWORD>(wcslen(pStr) * 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WeChatStr {
|
|
||||||
char *ptr;
|
|
||||||
INT64 buf;
|
|
||||||
INT64 len;
|
|
||||||
INT64 maxlen;
|
|
||||||
|
|
||||||
WeChatStr(const char *p) {
|
|
||||||
ptr = (char *)p;
|
|
||||||
buf = 0;
|
|
||||||
len = strlen(p);
|
|
||||||
maxlen = len | 0xF;
|
|
||||||
}
|
|
||||||
WeChatStr() {
|
|
||||||
ptr = NULL;
|
|
||||||
buf = 0;
|
|
||||||
len = 0;
|
|
||||||
maxlen = 0xF;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace prototype
|
|
||||||
namespace offset {
|
|
||||||
const UINT64 kGetAccountServiceMgr = 0x94e510;
|
|
||||||
const UINT64 kSyncMsg = 0xc39680;
|
|
||||||
const UINT64 kSyncMsgNext = 0xc39680;
|
|
||||||
const UINT64 kGetCurrentDataPath = 0x101a920;
|
|
||||||
const UINT64 kGetAppDataSavePath = 0x13a5b90;
|
|
||||||
const UINT64 kGetSendMessageMgr = 0x94cd10;
|
|
||||||
const UINT64 kSendTextMsg = 0x1091F70;
|
|
||||||
const UINT64 kFreeChatMsg = 0x94e590;
|
|
||||||
|
|
||||||
const UINT64 kDoAddMsg = 0x10d9450;
|
|
||||||
const UINT64 kSendImageMsg = 0x1087950;
|
|
||||||
const UINT64 kChatMsgInstanceCounter = 0x956e00;
|
|
||||||
const UINT64 kSendFileMsg = 0xea0850;
|
|
||||||
const UINT64 kGetAppMsgMgr = 0x951cb0;
|
|
||||||
const UINT64 kGetContactMgr = 0x93a570;
|
|
||||||
const UINT64 kGetContactList = 0xf6cb70;
|
|
||||||
|
|
||||||
const UINT64 k_sqlite3_exec = 0x26e4f20;
|
|
||||||
const UINT64 k_sqlite3_prepare = 0x26ecaa0;
|
|
||||||
const UINT64 k_sqlite3_open = 0x27242a0;
|
|
||||||
const UINT64 k_sqlite3_step = 0x26a8f30;
|
|
||||||
const UINT64 k_sqlite3_column_count = 0x26a9750;
|
|
||||||
const UINT64 k_sqlite3_column_name = 0x26aa150;
|
|
||||||
const UINT64 k_sqlite3_column_type = 0x26a9fa0;
|
|
||||||
const UINT64 k_sqlite3_column_blob = 0x26a9780;
|
|
||||||
const UINT64 k_sqlite3_column_bytes = 0x26a9870;
|
|
||||||
const UINT64 k_sqlite3_finalize = 0x26a7fe0;
|
|
||||||
|
|
||||||
const UINT64 kGPInstance = 0x3d8b4f8;
|
|
||||||
const UINT64 kMicroMsgDB = 0xb8;
|
|
||||||
const UINT64 kChatMsgDB = 0x2c8;
|
|
||||||
const UINT64 kMiscDB = 0x5f0;
|
|
||||||
const UINT64 kEmotionDB = 0x888;
|
|
||||||
const UINT64 kMediaDB = 0xF48;
|
|
||||||
const UINT64 kBizchatMsgDB = 0x1AC0;
|
|
||||||
const UINT64 kFunctionMsgDB = 0x1b98;
|
|
||||||
const UINT64 kDBName = 0x28;
|
|
||||||
const UINT64 kStorageStart = 0x0;
|
|
||||||
const UINT64 kStorageEnd = 0x0;
|
|
||||||
const UINT64 kMultiDBMgr = 0x3e00910;
|
|
||||||
const UINT64 kPublicMsgMgr = 0x3dfe098;
|
|
||||||
const UINT64 kFavoriteStorageMgr = 0x3e01478;
|
|
||||||
|
|
||||||
const UINT64 kChatRoomMgr = 0x8e9d30;
|
|
||||||
const UINT64 kGetChatRoomDetailInfo = 0xe73590;
|
|
||||||
const UINT64 kNewChatRoomInfo = 0x12006b0;
|
|
||||||
const UINT64 kFreeChatRoomInfo = 0x1200890;
|
|
||||||
const UINT64 kDoAddMemberToChatRoom = 0xe63c70;
|
|
||||||
const UINT64 kDoModChatRoomMemberNickName = 0xe6db00;
|
|
||||||
const UINT64 kDelMemberFromChatRoom = 0xe64290;
|
|
||||||
const UINT64 kGetMemberFromChatRoom = 0xe74de0;
|
|
||||||
const UINT64 kNewChatRoom = 0x11fde50;
|
|
||||||
const UINT64 kFreeChatRoom = 0x11fe030;
|
|
||||||
|
|
||||||
const UINT64 kTopMsg = 0xa5e4f0;
|
|
||||||
const UINT64 kRemoveTopMsg = 0xe787b0;
|
|
||||||
const UINT64 kInviteMember = 0xe63650;
|
|
||||||
const UINT64 kHookLog = 0x1304e60;
|
|
||||||
|
|
||||||
const UINT64 kCreateChatRoom = 0xe63340;
|
|
||||||
const UINT64 kQuitChatRoom = 0xe6e3b0;
|
|
||||||
const UINT64 kForwardMsg = 0x1091660;
|
|
||||||
|
|
||||||
const UINT64 kOnSnsTimeLineSceneFinish = 0x1a73150;
|
|
||||||
const UINT64 kSNSGetFirstPage = 0x1a51dd0;
|
|
||||||
const UINT64 kSNSGetNextPageScene = 0x1a77240;
|
|
||||||
const UINT64 kSNSDataMgr = 0xeebda0;
|
|
||||||
const UINT64 kSNSTimeLineMgr = 0x19e83a0;
|
|
||||||
const UINT64 kGetMgrByPrefixLocalId = 0xf0ea60;
|
|
||||||
const UINT64 kAddFavFromMsg = 0x1601520;
|
|
||||||
const UINT64 kGetChatMgr = 0x97e4d0;
|
|
||||||
const UINT64 kGetFavoriteMgr = 0x8c69b0;
|
|
||||||
const UINT64 kAddFavFromImage = 0x160b920;
|
|
||||||
const UINT64 kGetContact = 0xf67060;
|
|
||||||
const UINT64 kNewContact = 0x12e01f0;
|
|
||||||
const UINT64 kFreeContact = 0x12e08a0;
|
|
||||||
const UINT64 kNewMMReaderItem = 0x8c79a0;
|
|
||||||
const UINT64 kFreeMMReaderItem = 0x8c6da0;
|
|
||||||
const UINT64 kForwordPublicMsg = 0xddc6c0;
|
|
||||||
const UINT64 kParseAppMsgXml = 0x11b0a70;
|
|
||||||
const UINT64 kNewAppMsgInfo = 0x91a550;
|
|
||||||
const UINT64 kFreeAppMsgInfo = 0x8fd1a0;
|
|
||||||
const UINT64 kGetPreDownLoadMgr = 0x9996f0;
|
|
||||||
const UINT64 kPushAttachTask = 0x9c0080;
|
|
||||||
const UINT64 kGetCustomSmileyMgr = 0x915c00;
|
|
||||||
const UINT64 kSendCustomEmotion = 0xec0a40;
|
|
||||||
const UINT64 kNewJsApiShareAppMessage = 0x13be1a0;
|
|
||||||
const UINT64 kInitJsConfig = 0x137bc00;
|
|
||||||
const UINT64 kSendApplet = 0x13c0920;
|
|
||||||
const UINT64 kSendAppletSecond = 0x13c1150;
|
|
||||||
const UINT64 kGetAppInfoByWaid = 0x13c5790;
|
|
||||||
const UINT64 kCopyShareAppMessageRequest = 0x13c0670;
|
|
||||||
const UINT64 kNewWAUpdatableMsgInfo = 0x919ca0;
|
|
||||||
const UINT64 kFreeWAUpdatableMsgInfo = 0x8fc230;
|
|
||||||
const UINT64 kSendPatMsg = 0x195f340;
|
|
||||||
const UINT64 kGetOCRManager = 0x999780;
|
|
||||||
const UINT64 kDoOCRTask = 0x190b2a0;
|
|
||||||
|
|
||||||
const UINT64 kGetLockWechatMgr = 0xa727b0;
|
|
||||||
const UINT64 kRequestLockWechat = 0xa2cc70;
|
|
||||||
const UINT64 kRequestUnLockWechat = 0xa2cf10;
|
|
||||||
|
|
||||||
const UINT64 kOnLoginBtnClick = 0xe0cf70;
|
|
||||||
|
|
||||||
const UINT64 kGetQRCodeLoginMgr = 0xdff6d0;
|
|
||||||
|
|
||||||
const UINT64 kUpdateMsg = 0xf15c40;
|
|
||||||
const UINT64 kGetVoiceMgr = 0xbf78f0;
|
|
||||||
const UINT64 kChatMsg2NetSceneSendMsg = 0x96e8d0;
|
|
||||||
const UINT64 kTranslateVoice = 0x11217e0;
|
|
||||||
const UINT64 kNewWebViewPageConfig = 0x9512f0;
|
|
||||||
const UINT64 kFreeWebViewPageConfig = 0x951520;
|
|
||||||
const UINT64 kGetWebViewMgr = 0x9412d0;
|
|
||||||
const UINT64 kShowWebView = 0x1d236b0;
|
|
||||||
const UINT64 kSetUrl = 0x13dd410;
|
|
||||||
|
|
||||||
} // namespace offset
|
|
||||||
} // namespace V3_9_8_15
|
|
||||||
|
|
||||||
} // namespace wxhelper
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,205 +0,0 @@
|
|||||||
#include <WS2tcpip.h>
|
|
||||||
#include "wechat_hook.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <detours/detours.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
|
|
||||||
#include "base64.h"
|
|
||||||
#include "http_client.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
#include "thread_pool.h"
|
|
||||||
#include "wxutils.h"
|
|
||||||
namespace offset = wxhelper::V3_9_8_25::offset;
|
|
||||||
namespace common = wxhelper::common;
|
|
||||||
|
|
||||||
namespace hook {
|
|
||||||
static bool kEnableHttp = false;
|
|
||||||
static bool kLogHookFlag = false;
|
|
||||||
static char kServerIp[20] = "127.0.0.1";
|
|
||||||
static int kServerPort = 19099;
|
|
||||||
|
|
||||||
UINT64(*RealDoAddMsg)
|
|
||||||
(UINT64, UINT64, UINT64) = (UINT64(*)(UINT64, UINT64, UINT64))(
|
|
||||||
wxhelper::wxutils::GetWeChatWinBase() + offset::kDoAddMsg);
|
|
||||||
|
|
||||||
VOID SendMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
|
||||||
PTP_WORK Work) {
|
|
||||||
common::InnerMessageStruct *msg = (common::InnerMessageStruct *)context;
|
|
||||||
if (msg == NULL) {
|
|
||||||
SPDLOG_INFO("add work:msg is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::unique_ptr<common::InnerMessageStruct> sms(msg);
|
|
||||||
nlohmann::json j_msg = nlohmann::json::parse(
|
|
||||||
msg->buffer, msg->buffer + msg->length, nullptr, false);
|
|
||||||
if (j_msg.is_discarded() == true) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string jstr = j_msg.dump() + "\n";
|
|
||||||
|
|
||||||
WSADATA was_data = {0};
|
|
||||||
int ret = WSAStartup(MAKEWORD(2, 2), &was_data);
|
|
||||||
if (ret != 0) {
|
|
||||||
SPDLOG_ERROR("WSAStartup failed:{}", ret);
|
|
||||||
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)kServerPort);
|
|
||||||
InetPtonA(AF_INET, kServerIp, &client_addr.sin_addr.s_addr);
|
|
||||||
if (connect(client_socket, reinterpret_cast<sockaddr *>(&client_addr),
|
|
||||||
sizeof(sockaddr)) < 0) {
|
|
||||||
SPDLOG_ERROR("socket connect fail. host:{} , port:{},",kServerIp,kServerPort);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
char recv_buf[1024] = {0};
|
|
||||||
ret = send(client_socket, jstr.c_str(), static_cast<int>(jstr.size()), 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
SPDLOG_ERROR("socket send fail ,ret:{}", ret);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
ret = shutdown(client_socket, SD_SEND);
|
|
||||||
if (ret == SOCKET_ERROR) {
|
|
||||||
SPDLOG_ERROR("shutdown failed with erro:{}", ret);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
ret = recv(client_socket, recv_buf, sizeof(recv_buf), 0);
|
|
||||||
if (ret < 0) {
|
|
||||||
SPDLOG_ERROR("socket recv fail ,ret:{}", ret);
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
clean:
|
|
||||||
closesocket(client_socket);
|
|
||||||
WSACleanup();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID SendHttpMsgCallback(PTP_CALLBACK_INSTANCE instance, PVOID context,
|
|
||||||
PTP_WORK Work) {
|
|
||||||
common::InnerMessageStruct *msg = (common::InnerMessageStruct *)context;
|
|
||||||
if (msg == NULL) {
|
|
||||||
SPDLOG_INFO("http msg is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<common::InnerMessageStruct> sms(msg);
|
|
||||||
nlohmann::json j_msg = nlohmann::json::parse(
|
|
||||||
msg->buffer, msg->buffer + msg->length, nullptr, false);
|
|
||||||
if (j_msg.is_discarded() == true) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string jstr = j_msg.dump() + "\n";
|
|
||||||
http::HttpClient::SendRequest(jstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleSyncMsg(INT64 param1, INT64 param2, INT64 param3) {
|
|
||||||
nlohmann::json msg;
|
|
||||||
|
|
||||||
msg["pid"] = GetCurrentProcessId();
|
|
||||||
msg["fromUser"] =
|
|
||||||
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x18));
|
|
||||||
msg["toUser"] =
|
|
||||||
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x28));
|
|
||||||
msg["content"] =
|
|
||||||
wxhelper::wxutils::ReadSKBuiltinString(*(INT64 *)(param2 + 0x30));
|
|
||||||
msg["signature"] =
|
|
||||||
wxhelper::wxutils::ReadWeChatStr(*(INT64 *)(param2 + 0x48));
|
|
||||||
msg["msgId"] = *(INT64 *)(param2 + 0x60);
|
|
||||||
msg["msgSequence"] = *(DWORD *)(param2 + 0x5C);
|
|
||||||
msg["createTime"] = *(DWORD *)(param2 + 0x58);
|
|
||||||
msg["displayFullContent"] =
|
|
||||||
wxhelper::wxutils::ReadWeChatStr(*(INT64 *)(param2 + 0x50));
|
|
||||||
DWORD type = *(DWORD *)(param2 + 0x24);
|
|
||||||
msg["type"] = type;
|
|
||||||
if (type == 3) {
|
|
||||||
int a = 1;
|
|
||||||
std::string img =
|
|
||||||
wxhelper::wxutils::ReadSKBuiltinBuffer(*(INT64 *)(param2 + 0x40));
|
|
||||||
SPDLOG_INFO("encode size:{}", img.size());
|
|
||||||
msg["base64Img"] = base64_encode(img);
|
|
||||||
a = 2;
|
|
||||||
}
|
|
||||||
std::string jstr = msg.dump() + '\n';
|
|
||||||
common::InnerMessageStruct *inner_msg = new common::InnerMessageStruct;
|
|
||||||
inner_msg->buffer = new char[jstr.size() + 1];
|
|
||||||
memcpy(inner_msg->buffer, jstr.c_str(), jstr.size() + 1);
|
|
||||||
inner_msg->length = jstr.size();
|
|
||||||
if (kEnableHttp) {
|
|
||||||
bool add =
|
|
||||||
base::ThreadPool::GetInstance().AddWork(SendHttpMsgCallback, inner_msg);
|
|
||||||
SPDLOG_INFO("add http msg work:{}", add);
|
|
||||||
} else {
|
|
||||||
bool add =
|
|
||||||
base::ThreadPool::GetInstance().AddWork(SendMsgCallback, inner_msg);
|
|
||||||
SPDLOG_INFO("add msg work:{}", add);
|
|
||||||
}
|
|
||||||
RealDoAddMsg(param1, param2, param3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WechatHook::Init(WechatHookParam param) {
|
|
||||||
if(!init_){
|
|
||||||
param_ = param;
|
|
||||||
kEnableHttp = param.enable_http;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int WechatHook::HookSyncMsg() {
|
|
||||||
if (sync_msg_flag_) {
|
|
||||||
SPDLOG_INFO("recv msg hook already called");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param_.server_ip.size() < 1) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
UINT64 base = wxhelper::wxutils::GetWeChatWinBase();
|
|
||||||
if (!base) {
|
|
||||||
SPDLOG_INFO("base addr is null");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (param_.enable_http) {
|
|
||||||
http::HttpClient::SetConfig(param_.http_url,param_.http_time_out);
|
|
||||||
}else{
|
|
||||||
const char* charPtr = param_.server_ip.c_str();
|
|
||||||
std::strcpy(kServerIp, charPtr);
|
|
||||||
kServerPort = param_.server_port;
|
|
||||||
}
|
|
||||||
DetourTransactionBegin();
|
|
||||||
DetourUpdateThread(GetCurrentThread());
|
|
||||||
DetourAttach(&(PVOID &)RealDoAddMsg, &HandleSyncMsg);
|
|
||||||
LONG ret = DetourTransactionCommit();
|
|
||||||
if (ret == NO_ERROR) {
|
|
||||||
sync_msg_flag_ = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
int WechatHook::UnHookSyncMsg() {
|
|
||||||
if (!sync_msg_flag_) {
|
|
||||||
SPDLOG_INFO("call UnHookSyncMsg but no hooked ");
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
UINT64 base = wxhelper::wxutils::GetWeChatWinBase();
|
|
||||||
DetourTransactionBegin();
|
|
||||||
DetourUpdateThread(GetCurrentThread());
|
|
||||||
DetourDetach(&(PVOID &)RealDoAddMsg, &HandleSyncMsg);
|
|
||||||
LONG ret = DetourTransactionCommit();
|
|
||||||
if (ret == NO_ERROR) {
|
|
||||||
sync_msg_flag_ = false;
|
|
||||||
strcpy_s(kServerIp, "127.0.0.1");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
int WechatHook::HookLog() { return 0; }
|
|
||||||
int WechatHook::UnHookLog() { return 0; }
|
|
||||||
} // namespace hook
|
|
@ -1,34 +0,0 @@
|
|||||||
#ifndef WXHELPER_WECHAT_HOOK_H_
|
|
||||||
#define WXHELPER_WECHAT_HOOK_H_
|
|
||||||
#include "wechat_function.h"
|
|
||||||
#include "singleton.h"
|
|
||||||
|
|
||||||
namespace hook {
|
|
||||||
struct WechatHookParam {
|
|
||||||
std::string server_ip = "127.0.0.1";
|
|
||||||
std::string http_url = "http:://127.0.0.1:19088";
|
|
||||||
int server_port = 19099;
|
|
||||||
bool enable_http = false;
|
|
||||||
uint64_t http_time_out = 3000;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WechatHook :public base::Singleton<WechatHook>{
|
|
||||||
public:
|
|
||||||
void Init(WechatHookParam param);
|
|
||||||
|
|
||||||
int HookSyncMsg();
|
|
||||||
int UnHookSyncMsg();
|
|
||||||
|
|
||||||
int HookLog();
|
|
||||||
|
|
||||||
int UnHookLog();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WechatHookParam param_;
|
|
||||||
bool sync_msg_flag_;
|
|
||||||
bool init_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace hook
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,786 +0,0 @@
|
|||||||
#include "wechat_service.h"
|
|
||||||
#include "wxutils.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "memory.h"
|
|
||||||
#include "db.h"
|
|
||||||
#include "tinyxml2.h"
|
|
||||||
#include "spdlog/spdlog.h"
|
|
||||||
namespace offset = wxhelper::V3_9_8_25::offset;
|
|
||||||
namespace prototype = wxhelper::V3_9_8_25::prototype;
|
|
||||||
namespace func = wxhelper::V3_9_8_25::function;
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
prototype::WeChatString *BuildWechatString(const std::wstring &ws) {
|
|
||||||
prototype::WeChatString *p =
|
|
||||||
base::utils::WxHeapAlloc<prototype::WeChatString>(
|
|
||||||
sizeof(prototype::WeChatString));
|
|
||||||
wchar_t *p_chat_room_id =
|
|
||||||
base::utils::WxHeapAlloc<wchar_t>((ws.size() + 1) * 2);
|
|
||||||
wmemcpy(p_chat_room_id, ws.c_str(), ws.size() + 1);
|
|
||||||
p->ptr = p_chat_room_id;
|
|
||||||
p->length = static_cast<DWORD>(ws.size());
|
|
||||||
p->max_length = static_cast<DWORD>(ws.size());
|
|
||||||
p->c_len = 0;
|
|
||||||
p->c_ptr = 0;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
WechatService::~WechatService() {}
|
|
||||||
|
|
||||||
INT64 WechatService::CheckLogin() {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 accout_service_addr = base_addr_ + offset::kGetAccountServiceMgr;
|
|
||||||
func::__GetAccountService GetSevice =
|
|
||||||
(func::__GetAccountService)accout_service_addr;
|
|
||||||
UINT64 service_addr = GetSevice();
|
|
||||||
if (service_addr) {
|
|
||||||
success = *(UINT64*)(service_addr + 0x7F8);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetSelfInfo(common::SelfInfoInner& out) {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 accout_service_addr = base_addr_ + offset::kGetAccountServiceMgr;
|
|
||||||
UINT64 get_app_data_save_path_addr = base_addr_ + offset::kGetAppDataSavePath;
|
|
||||||
UINT64 get_current_data_path_addr = base_addr_ + offset::kGetCurrentDataPath;
|
|
||||||
func::__GetAccountService GetSevice = (func::__GetAccountService)accout_service_addr;
|
|
||||||
func::__GetDataSavePath GetDataSavePath = (func::__GetDataSavePath)get_app_data_save_path_addr;
|
|
||||||
func::__GetCurrentDataPath GetCurrentDataPath = (func::__GetCurrentDataPath)get_current_data_path_addr;
|
|
||||||
|
|
||||||
UINT64 service_addr = GetSevice();
|
|
||||||
if (service_addr) {
|
|
||||||
if (*(INT64 *)(service_addr + 0x80) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x80 + 0x10) == 0) {
|
|
||||||
out.wxid = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x80 + 0x18) == 0xF) {
|
|
||||||
out.wxid = std::string((char *)(service_addr + 0x80),
|
|
||||||
*(INT64 *)(service_addr + 0x80 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.wxid = std::string(*(char **)(service_addr + 0x80),
|
|
||||||
*(INT64 *)(service_addr + 0x80 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x108) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x108 + 0x10) == 0) {
|
|
||||||
out.account = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x108 + 0x18) == 0xF) {
|
|
||||||
out.account = std::string((char *)(service_addr + 0x108),
|
|
||||||
*(INT64 *)(service_addr + 0x108 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.account = std::string(*(char **)(service_addr + 0x108),
|
|
||||||
*(INT64 *)(service_addr + 0x108 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x128) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x128 + 0x10) == 0) {
|
|
||||||
out.mobile = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x128 + 0x18) == 0xF) {
|
|
||||||
out.mobile = std::string((char *)(service_addr + 0x128),
|
|
||||||
*(INT64 *)(service_addr + 0x128 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.mobile = std::string(*(char **)(service_addr + 0x128),
|
|
||||||
*(INT64 *)(service_addr + 0x128 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x148) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x148 + 0x10) == 0) {
|
|
||||||
out.signature = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x148 + 0x18) == 0xF) {
|
|
||||||
out.signature = std::string((char *)(service_addr + 0x148),
|
|
||||||
*(INT64 *)(service_addr + 0x148 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.signature = std::string(*(char **)(service_addr + 0x148),
|
|
||||||
*(INT64 *)(service_addr + 0x148 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x168) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x168 + 0x10) == 0) {
|
|
||||||
out.country = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x168 + 0x18) == 0xF) {
|
|
||||||
out.country = std::string((char *)(service_addr + 0x168),
|
|
||||||
*(INT64 *)(service_addr + 0x168 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.country = std::string(*(char **)(service_addr + 0x168),
|
|
||||||
*(INT64 *)(service_addr + 0x168 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x188) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x188 + 0x10) == 0) {
|
|
||||||
out.province = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x188 + 0x18) == 0xF) {
|
|
||||||
out.province = std::string((char *)(service_addr + 0x188),
|
|
||||||
*(INT64 *)(service_addr + 0x188 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.province = std::string(*(char **)(service_addr + 0x188),
|
|
||||||
*(INT64 *)(service_addr + 0x188 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x1A8) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x1A8 + 0x10) == 0) {
|
|
||||||
out.city = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x1A8 + 0x18) == 0xF) {
|
|
||||||
out.city = std::string((char *)(service_addr + 0x1A8),
|
|
||||||
*(INT64 *)(service_addr + 0x1A8 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.city = std::string(*(char **)(service_addr + 0x1A8),
|
|
||||||
*(INT64 *)(service_addr + 0x1A8 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x1E8) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x1E8 + 0x10) == 0) {
|
|
||||||
out.name = std::string();
|
|
||||||
} else {
|
|
||||||
if (*(INT64 *)(service_addr + 0x1E8 + 0x18) == 0xF) {
|
|
||||||
out.name = std::string((char *)(service_addr + 0x1E8),
|
|
||||||
*(INT64 *)(service_addr + 0x1E8 + 0x10));
|
|
||||||
} else {
|
|
||||||
out.name = std::string(*(char **)(service_addr + 0x1E8),
|
|
||||||
*(INT64 *)(service_addr + 0x1E8 + 0x10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x450) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x450 + 0x10) == 0) {
|
|
||||||
out.head_img = std::string();
|
|
||||||
} else {
|
|
||||||
out.head_img = std::string(*(char **)(service_addr + 0x450),
|
|
||||||
*(INT64 *)(service_addr + 0x450 + 0x10));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x7B8) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x7B8 + 0x10) == 0) {
|
|
||||||
out.public_key = std::string();
|
|
||||||
} else {
|
|
||||||
out.public_key = std::string(*(char **)(service_addr + 0x7B8),
|
|
||||||
*(INT64 *)(service_addr + 0x7B8 + 0x10));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x7D8) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x7D8 + 0x10) == 0) {
|
|
||||||
out.private_key = std::string();
|
|
||||||
} else {
|
|
||||||
out.private_key = std::string(*(char **)(service_addr + 0x7D8),
|
|
||||||
*(INT64 *)(service_addr + 0x7D8 + 0x10));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(INT64 *)(service_addr + 0x6E0) == 0 ||
|
|
||||||
*(INT64 *)(service_addr + 0x6E8) == 0) {
|
|
||||||
out.db_key = std::string();
|
|
||||||
} else {
|
|
||||||
INT64 byte_addr = *(INT64 *)(service_addr + 0x6E0);
|
|
||||||
INT64 len = *(INT64 *)(service_addr + 0x6E8);
|
|
||||||
out.db_key = base::utils::Bytes2Hex((BYTE *)byte_addr, static_cast<int>(len));
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT64 flag = *(UINT64 *)(service_addr + 0x7F8);
|
|
||||||
if (flag == 1) {
|
|
||||||
prototype::WeChatString current_data_path;
|
|
||||||
// _GetCurrentDataPath(get_current_data_path_addr,
|
|
||||||
// reinterpret_cast<ULONG_PTR>(¤t_data_path));
|
|
||||||
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(¤t_data_path));
|
|
||||||
if (current_data_path.ptr) {
|
|
||||||
out.current_data_path = base::utils::WstringToUtf8(
|
|
||||||
std::wstring(current_data_path.ptr, current_data_path.length));
|
|
||||||
} else {
|
|
||||||
out.current_data_path = std::string();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prototype::WeChatString data_save_path;
|
|
||||||
// _GetDataSavePath(get_app_data_save_path_addr,
|
|
||||||
// reinterpret_cast<ULONG_PTR>(&data_save_path));
|
|
||||||
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(&data_save_path));
|
|
||||||
if (data_save_path.ptr) {
|
|
||||||
out.data_save_path = base::utils::WstringToUtf8(
|
|
||||||
std::wstring(data_save_path.ptr, data_save_path.length));
|
|
||||||
} else {
|
|
||||||
out.data_save_path = std::string();
|
|
||||||
}
|
|
||||||
|
|
||||||
success = 1;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendTextMsg(const std::wstring& wxid,
|
|
||||||
const std::wstring& msg) {
|
|
||||||
INT64 success = -1;
|
|
||||||
prototype::WeChatString to_user(wxid);
|
|
||||||
prototype::WeChatString text_msg(msg);
|
|
||||||
UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr;
|
|
||||||
UINT64 send_text_msg_addr = base_addr_ + offset::kSendTextMsg;
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
char chat_msg[0x460] = {0};
|
|
||||||
UINT64 temp[3] = {0};
|
|
||||||
func::__GetSendMessageMgr mgr;
|
|
||||||
mgr = (func::__GetSendMessageMgr)send_message_mgr_addr;
|
|
||||||
func::__SendTextMsg send;
|
|
||||||
send = (func::__SendTextMsg)send_text_msg_addr;
|
|
||||||
func::__FreeChatMsg free;
|
|
||||||
free = (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
mgr();
|
|
||||||
send(reinterpret_cast<UINT64>(&chat_msg), reinterpret_cast<UINT64>(&to_user),
|
|
||||||
reinterpret_cast<UINT64>(&text_msg), reinterpret_cast<UINT64>(&temp), 1,
|
|
||||||
1, 0, 0);
|
|
||||||
free(reinterpret_cast<UINT64>(&chat_msg));
|
|
||||||
success = 1;
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendImageMsg(const std::wstring& wxid,
|
|
||||||
const std::wstring& image_path) {
|
|
||||||
INT64 success = -1;
|
|
||||||
prototype::WeChatString to_user(wxid);
|
|
||||||
prototype::WeChatString image_full_path(image_path);
|
|
||||||
UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr;
|
|
||||||
UINT64 send_img_addr = base_addr_ + offset::kSendImageMsg;
|
|
||||||
UINT64 new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter;
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
|
||||||
func::__GetSendMessageMgr mgr =
|
|
||||||
(func::__GetSendMessageMgr)send_message_mgr_addr;
|
|
||||||
func::__SendImageMsg send_img = (func::__SendImageMsg)send_img_addr;
|
|
||||||
func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
|
|
||||||
char chat_msg[0x460] = {0};
|
|
||||||
char chat_msg_temp[0x460] = {0};
|
|
||||||
|
|
||||||
UINT64 p_chat_msg_temp = new_chat_msg(reinterpret_cast<UINT64>(&chat_msg_temp));
|
|
||||||
UINT64 temp1 =0;
|
|
||||||
UINT64 temp2 =0;
|
|
||||||
UINT64* flag[10] = {};
|
|
||||||
flag[8] = &temp1;
|
|
||||||
flag[9] = &temp2;
|
|
||||||
flag[1] = reinterpret_cast<UINT64*>(p_chat_msg_temp);
|
|
||||||
|
|
||||||
UINT64 p_chat_msg = new_chat_msg(reinterpret_cast<UINT64>(&chat_msg));
|
|
||||||
UINT64 send_mgr = mgr();
|
|
||||||
send_img(send_mgr, p_chat_msg,
|
|
||||||
reinterpret_cast<UINT64>(&to_user),
|
|
||||||
reinterpret_cast<UINT64>(&image_full_path),
|
|
||||||
reinterpret_cast<UINT64>(&flag));
|
|
||||||
free(p_chat_msg);
|
|
||||||
free(p_chat_msg_temp);
|
|
||||||
success = 1;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendFileMsg(const std::wstring& wxid,
|
|
||||||
const std::wstring& file_path) {
|
|
||||||
INT64 success = -1;
|
|
||||||
prototype::WeChatString* to_user= (prototype::WeChatString*)HeapAlloc(GetProcessHeap(),0,sizeof(prototype::WeChatString));
|
|
||||||
wchar_t * ptr_wxid = (wchar_t*)HeapAlloc(GetProcessHeap(),0,(wxid.length()+1)*2);
|
|
||||||
wmemcpy(ptr_wxid,wxid.c_str(),wxid.length()+1);
|
|
||||||
to_user->ptr = ptr_wxid;
|
|
||||||
to_user->length = static_cast<DWORD>(wxid.length());
|
|
||||||
to_user->max_length = static_cast<DWORD>(wxid.length());
|
|
||||||
to_user->c_len=0;
|
|
||||||
to_user->c_ptr=0;
|
|
||||||
prototype::WeChatString* file_full_path= (prototype::WeChatString*)HeapAlloc(GetProcessHeap(),0,sizeof(prototype::WeChatString));
|
|
||||||
wchar_t * ptr_path = (wchar_t*)HeapAlloc(GetProcessHeap(),0,(file_path.length()+1)*2);
|
|
||||||
wmemcpy(ptr_path,file_path.c_str(),file_path.length()+1);
|
|
||||||
file_full_path->ptr = ptr_path;
|
|
||||||
file_full_path->length = static_cast<DWORD>(file_path.length());
|
|
||||||
file_full_path->max_length = static_cast<DWORD>(file_path.length());
|
|
||||||
file_full_path->c_len = 0;
|
|
||||||
file_full_path->c_ptr = 0;
|
|
||||||
|
|
||||||
UINT64 get_app_msg_mgr_addr = base_addr_ + offset::kGetAppMsgMgr;
|
|
||||||
UINT64 send_file_addr = base_addr_ + offset::kSendFileMsg;
|
|
||||||
UINT64 new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter;
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
|
||||||
func::__GetAppMsgMgr get_app_mgr =
|
|
||||||
(func::__GetAppMsgMgr)get_app_msg_mgr_addr;
|
|
||||||
func::__SendFile send_file = (func::__SendFile)send_file_addr;
|
|
||||||
func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
|
|
||||||
|
|
||||||
char* chat_msg= (char*)HeapAlloc(GetProcessHeap(),0,0x460);
|
|
||||||
|
|
||||||
UINT64* temp1 = (UINT64*)HeapAlloc(GetProcessHeap(),0,sizeof(UINT64)*4);
|
|
||||||
UINT64* temp2 = (UINT64*)HeapAlloc(GetProcessHeap(),0,sizeof(UINT64)*4);
|
|
||||||
UINT64* temp3 = (UINT64*)HeapAlloc(GetProcessHeap(),0,sizeof(UINT64)*4);
|
|
||||||
UINT64* temp4 = (UINT64*)HeapAlloc(GetProcessHeap(),0,sizeof(UINT64)*4);
|
|
||||||
ZeroMemory(temp1,sizeof(UINT64)*4);
|
|
||||||
ZeroMemory(temp2,sizeof(UINT64)*4);
|
|
||||||
ZeroMemory(temp3,sizeof(UINT64)*4);
|
|
||||||
ZeroMemory(temp4,sizeof(UINT64)*4);
|
|
||||||
*temp4=0x1F;
|
|
||||||
UINT64 app_mgr = get_app_mgr();
|
|
||||||
send_file(app_mgr, reinterpret_cast<UINT64>(chat_msg),
|
|
||||||
reinterpret_cast<UINT64>(to_user),
|
|
||||||
reinterpret_cast<UINT64>(file_full_path), 1,
|
|
||||||
reinterpret_cast<UINT64>(temp1), 0, reinterpret_cast<UINT64>(temp2),
|
|
||||||
0, reinterpret_cast<UINT64>(temp3), 0, 0);
|
|
||||||
free(reinterpret_cast<UINT64>(chat_msg));
|
|
||||||
HeapFree(GetProcessHeap(),0,to_user);
|
|
||||||
HeapFree(GetProcessHeap(),0,file_full_path);
|
|
||||||
HeapFree(GetProcessHeap(),0,temp1);
|
|
||||||
HeapFree(GetProcessHeap(),0,temp2);
|
|
||||||
HeapFree(GetProcessHeap(),0,temp3);
|
|
||||||
HeapFree(GetProcessHeap(),0,temp4);
|
|
||||||
success = 1;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetContacts(std::vector<common::ContactInner>& vec) {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr;
|
|
||||||
UINT64 get_contact_list_addr = base_addr_ + offset::kGetContactList;
|
|
||||||
func::__GetContactMgr get_contact_mgr =
|
|
||||||
(func::__GetContactMgr)get_contact_mgr_addr;
|
|
||||||
func::__GetContactList get_contact_list =
|
|
||||||
(func::__GetContactList)get_contact_list_addr;
|
|
||||||
UINT64 mgr = get_contact_mgr();
|
|
||||||
UINT64 contact_vec[3] = {0, 0, 0};
|
|
||||||
success = get_contact_list(mgr, reinterpret_cast<UINT64>(&contact_vec));
|
|
||||||
|
|
||||||
UINT64 start = contact_vec[0];
|
|
||||||
UINT64 end = contact_vec[2];
|
|
||||||
while (start < end) {
|
|
||||||
common::ContactInner temp;
|
|
||||||
temp.wxid = wxutils::ReadWstringThenConvert(start + 0x10);
|
|
||||||
temp.custom_account = wxutils::ReadWstringThenConvert(start + 0x30);
|
|
||||||
temp.encrypt_name = wxutils::ReadWstringThenConvert(start + 0x50);
|
|
||||||
temp.remark = wxutils::ReadWstringThenConvert(start + 0x80);
|
|
||||||
temp.remark_pinyin = wxutils::ReadWstringThenConvert(start + 0x148);
|
|
||||||
temp.remark_pinyin_all = wxutils::ReadWstringThenConvert(start + 0x168);
|
|
||||||
temp.label_ids = wxutils::ReadWstringThenConvert(start + 0xc0);
|
|
||||||
temp.nickname = wxutils::ReadWstringThenConvert(start + 0xA0);
|
|
||||||
temp.pinyin = wxutils::ReadWstringThenConvert(start + 0x108);
|
|
||||||
temp.pinyin_all = wxutils::ReadWstringThenConvert(start + 0x128);
|
|
||||||
temp.verify_flag = *(DWORD *)(start + 0x70);
|
|
||||||
temp.type = *(DWORD *)(start + 0x74);
|
|
||||||
temp.reserved1 = *(DWORD *)(start + 0x1F0);
|
|
||||||
temp.reserved2 = *(DWORD *)(start + 0x1F4);
|
|
||||||
vec.push_back(temp);
|
|
||||||
start += 0x6A8;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetChatRoomDetailInfo(
|
|
||||||
const std::wstring& room_id, common::ChatRoomInfoInner& room_info) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::AddMemberToChatRoom(
|
|
||||||
const std::wstring& room_id, const std::vector<std::wstring>& members) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::ModChatRoomMemberNickName(const std::wstring& room_id,
|
|
||||||
const std::wstring& wxid,
|
|
||||||
const std::wstring& nickname) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::DelMemberFromChatRoom(
|
|
||||||
const std::wstring& room_id, const std::vector<std::wstring>& members) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetMemberFromChatRoom(
|
|
||||||
const std::wstring& room_id, common::ChatRoomMemberInner& member) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SetTopMsg(ULONG64 msg_id) { return INT64(); }
|
|
||||||
|
|
||||||
INT64 WechatService::RemoveTopMsg(const std::wstring& room_id, ULONG64 msg_id) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::InviteMemberToChatRoom(
|
|
||||||
const std::wstring& room_id, const std::vector<std::wstring>& wxids) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::CreateChatRoom(const std::vector<std::wstring>& wxids) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::QuitChatRoom(const std::wstring& room_id) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::ForwardMsg(UINT64 msg_id, const std::wstring& wxid) {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 forward_addr = base_addr_ + offset::kForwardMsg;
|
|
||||||
func::__ForwardMsg forward_msg = (func::__ForwardMsg)forward_addr;
|
|
||||||
INT64 index = 0;
|
|
||||||
INT64 local_id = wxhelper::DB::GetInstance().GetLocalIdByMsgId(msg_id, index);
|
|
||||||
if (local_id <= 0 || index >> 32 == 0) {
|
|
||||||
success = -2;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
LARGE_INTEGER l;
|
|
||||||
l.HighPart = index >> 32;
|
|
||||||
l.LowPart = (DWORD)local_id;
|
|
||||||
prototype::WeChatString *recv = BuildWechatString(wxid);
|
|
||||||
success = forward_msg(reinterpret_cast<UINT64>(recv), l.QuadPart, 0x4, 0x0);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetSNSFirstPage() { return INT64(); }
|
|
||||||
|
|
||||||
INT64 WechatService::GetSNSNextPage(UINT64 sns_id) { return INT64(); }
|
|
||||||
|
|
||||||
INT64 WechatService::AddFavFromMsg(UINT64 msg_id) { return INT64(); }
|
|
||||||
|
|
||||||
INT64 WechatService::AddFavFromImage(const std::wstring& wxid,
|
|
||||||
const std::wstring& image_path) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendAtText(const std::wstring& room_id,
|
|
||||||
const std::vector<std::wstring>& wxids,
|
|
||||||
const std::wstring& msg) {
|
|
||||||
INT64 success = -1;
|
|
||||||
std::vector<prototype::WeChatString> wxid_list;
|
|
||||||
common::VectorInner *list = (common::VectorInner *)&wxid_list;
|
|
||||||
std::wstring at_msg = L"";
|
|
||||||
int number = 0;
|
|
||||||
for (unsigned int i = 0; i < wxids.size(); i++) {
|
|
||||||
std::wstring nickname;
|
|
||||||
std::wstring at_all = L"notify@all";
|
|
||||||
if (at_all.compare(wxids[i]) == 0) {
|
|
||||||
nickname = L"\u6240\u6709\u4eba";
|
|
||||||
} else {
|
|
||||||
nickname = GetContactOrChatRoomNickname(wxids[i]);
|
|
||||||
}
|
|
||||||
if (nickname.length() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
prototype::WeChatString id(wxids[i]);
|
|
||||||
wxid_list.push_back(id);
|
|
||||||
at_msg = at_msg + L"@" + nickname + L" ";
|
|
||||||
number++;
|
|
||||||
}
|
|
||||||
if (number < 1) {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
at_msg += msg;
|
|
||||||
|
|
||||||
INT64 head = (INT64)&list->start;
|
|
||||||
prototype::WeChatString to_user(room_id);
|
|
||||||
prototype::WeChatString text_msg(at_msg);
|
|
||||||
UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr;
|
|
||||||
UINT64 send_text_msg_addr = base_addr_ + offset::kSendTextMsg;
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
char chat_msg[0x460] = {0};
|
|
||||||
func::__GetSendMessageMgr mgr= (func::__GetSendMessageMgr)send_message_mgr_addr;
|
|
||||||
func::__SendTextMsg send= (func::__SendTextMsg)send_text_msg_addr;
|
|
||||||
func::__FreeChatMsg free= (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
mgr();
|
|
||||||
success = send(reinterpret_cast<UINT64>(&chat_msg),
|
|
||||||
reinterpret_cast<UINT64>(&to_user),
|
|
||||||
reinterpret_cast<UINT64>(&text_msg), head, 1, 1, 0, 0);
|
|
||||||
free(reinterpret_cast<UINT64>(&chat_msg));
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring WechatService::GetContactOrChatRoomNickname(
|
|
||||||
const std::wstring& wxid) {
|
|
||||||
prototype::WeChatString to_user(wxid);
|
|
||||||
UINT64 get_contact_mgr_addr = base_addr_ + offset::kGetContactMgr;
|
|
||||||
UINT64 new_contact_addr = base_addr_ + offset::kNewContact;
|
|
||||||
UINT64 get_contact_addr = base_addr_ + offset::kGetContact;
|
|
||||||
UINT64 free_contact_addr = base_addr_ + offset::kFreeContact;
|
|
||||||
func::__GetContactMgr get_contact_mgr =
|
|
||||||
(func::__GetContactMgr)get_contact_mgr_addr;
|
|
||||||
func::__GetContact get_contact = (func::__GetContact)get_contact_addr;
|
|
||||||
func::__NewContact new_contact = (func::__NewContact)new_contact_addr;
|
|
||||||
func::__FreeContact free_contact = (func::__FreeContact)free_contact_addr;
|
|
||||||
char buff[0x6A9] = {0};
|
|
||||||
UINT64 contact = new_contact(reinterpret_cast<UINT64>(&buff));
|
|
||||||
UINT64 mgr = get_contact_mgr();
|
|
||||||
INT64 success = get_contact(mgr, reinterpret_cast<UINT64>(&to_user), contact);
|
|
||||||
if (success == 1) {
|
|
||||||
std::wstring nickname = wxutils::ReadWstring(contact + 0xA0);
|
|
||||||
free_contact(contact);
|
|
||||||
return nickname;
|
|
||||||
} else {
|
|
||||||
free_contact(contact);
|
|
||||||
return L"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetContactByWxid(const std::wstring& wxid,
|
|
||||||
common::ContactProfileInner& profile) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::DoDownloadTask(UINT64 msg_id) { return INT64(); }
|
|
||||||
|
|
||||||
INT64 WechatService::ForwardPublicMsg(const std::wstring& wxid,
|
|
||||||
const std::wstring& title,
|
|
||||||
const std::wstring& url,
|
|
||||||
const std::wstring& thumb_url,
|
|
||||||
const std::wstring& sender_id,
|
|
||||||
const std::wstring& sender_name,
|
|
||||||
const std::wstring& digest) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::ForwardPublicMsgByMsgId(const std::wstring& wxid,
|
|
||||||
UINT64 msg_id) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::DecodeImage(const std::wstring& file_path,
|
|
||||||
const std::wstring& save_dir) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::GetVoiceByDB(ULONG64 msg_id, const std::wstring& dir) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendCustomEmotion(const std::wstring& file_path,
|
|
||||||
const std::wstring& wxid) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendApplet(
|
|
||||||
const std::wstring& recv_wxid, const std::wstring& waid_suff,
|
|
||||||
const std::wstring& waid_w, const std::string& waid_s,
|
|
||||||
const std::string& wa_wxid, const std::string& json_param,
|
|
||||||
const std::string& head_image, const std::string& big_image,
|
|
||||||
const std::string& index_page) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendPatMsg(const std::wstring& room_id,
|
|
||||||
const std::wstring& wxid) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::DoOCRTask(const std::wstring& img_path,
|
|
||||||
std::string& result) {
|
|
||||||
return INT64();
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::LockWeChat() {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 lock_mgr_addr = base_addr_ + offset::kGetLockWechatMgr;
|
|
||||||
UINT64 request_lock_addr = base_addr_ + offset::kRequestLockWechat;
|
|
||||||
func::__GetLockWechatMgr GetLockMgr = (func::__GetLockWechatMgr)lock_mgr_addr;
|
|
||||||
func::__RequestLockWechat request_lock =
|
|
||||||
(func::__RequestLockWechat)request_lock_addr;
|
|
||||||
UINT64 mgr = GetLockMgr();
|
|
||||||
success = request_lock(mgr);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::UnLockWeChat() {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 lock_mgr_addr = base_addr_ + offset::kGetLockWechatMgr;
|
|
||||||
UINT64 request_unlock_addr = base_addr_ + offset::kRequestUnLockWechat;
|
|
||||||
func::__GetLockWechatMgr GetLockMgr = (func::__GetLockWechatMgr)lock_mgr_addr;
|
|
||||||
func::__RequestUnLockWechat request_unlock =
|
|
||||||
(func::__RequestUnLockWechat)request_unlock_addr;
|
|
||||||
UINT64 mgr = GetLockMgr();
|
|
||||||
success = request_unlock(mgr);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::EnterWeChat() {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 click_cb_addr = base_addr_ + offset::kOnLoginBtnClick;
|
|
||||||
func::__OnLoginBtnClick cb = (func::__OnLoginBtnClick)click_cb_addr;
|
|
||||||
auto vec =
|
|
||||||
base::memory::ScanAndMatchValue(base_addr_ + 0x34e0c18, 0x1000, 0x8);
|
|
||||||
for (int i = 0; i < vec.size(); i++) {
|
|
||||||
INT64 ptr = vec.at(i);
|
|
||||||
if (*(INT64 *)ptr == base_addr_ + 0x34e0c18) {
|
|
||||||
INT64 login_wnd = ptr;
|
|
||||||
success = cb(ptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
INT64 WechatService::SendMultiAtText(
|
|
||||||
const std::wstring &room_id,
|
|
||||||
const std::vector<std::pair<std::wstring, std::wstring>> &at) {
|
|
||||||
INT64 success = -1;
|
|
||||||
std::vector<prototype::WeChatString> wxid_list;
|
|
||||||
common::VectorInner *list = (common::VectorInner *)&wxid_list;
|
|
||||||
std::wstring at_msg = L"";
|
|
||||||
int number = 0;
|
|
||||||
for (unsigned int i = 0; i < at.size(); i++) {
|
|
||||||
std::wstring nickname;
|
|
||||||
std::wstring at_all = L"notify@all";
|
|
||||||
if (at_all.compare(at[i].first) == 0) {
|
|
||||||
nickname = L"\u6240\u6709\u4eba";
|
|
||||||
} else {
|
|
||||||
nickname = GetContactOrChatRoomNickname(at[i].first);
|
|
||||||
}
|
|
||||||
if (nickname.length() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
prototype::WeChatString id(at[i].first);
|
|
||||||
wxid_list.push_back(id);
|
|
||||||
at_msg = at_msg + L"@" + nickname + L" "+ at[i].second + L" ";
|
|
||||||
number++;
|
|
||||||
}
|
|
||||||
if (number < 1) {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
INT64 head = (INT64)&list->start;
|
|
||||||
prototype::WeChatString to_user(room_id);
|
|
||||||
prototype::WeChatString text_msg(at_msg);
|
|
||||||
UINT64 send_message_mgr_addr = base_addr_ + offset::kGetSendMessageMgr;
|
|
||||||
UINT64 send_text_msg_addr = base_addr_ + offset::kSendTextMsg;
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
char chat_msg[0x460] = {0};
|
|
||||||
func::__GetSendMessageMgr mgr =
|
|
||||||
(func::__GetSendMessageMgr)send_message_mgr_addr;
|
|
||||||
func::__SendTextMsg send = (func::__SendTextMsg)send_text_msg_addr;
|
|
||||||
func::__FreeChatMsg free = (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
mgr();
|
|
||||||
success = send(reinterpret_cast<UINT64>(&chat_msg),
|
|
||||||
reinterpret_cast<UINT64>(&to_user),
|
|
||||||
reinterpret_cast<UINT64>(&text_msg), head, 1, 1, 0, 0);
|
|
||||||
free(reinterpret_cast<UINT64>(&chat_msg));
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string WechatService::GetLoginUrl(){
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 login_mgr_addr = base_addr_ + offset::kGetQRCodeLoginMgr;
|
|
||||||
func::__GetQRCodeLoginMgr get = (func::__GetQRCodeLoginMgr)login_mgr_addr;
|
|
||||||
UINT64 addr = get();
|
|
||||||
std::string login_url = wxutils::ReadWeChatStr(addr + 0x68);
|
|
||||||
return "http://weixin.qq.com/x/" + login_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WechatService::SetBaseAddr(UINT64 addr) { base_addr_ = addr; }
|
|
||||||
|
|
||||||
void WechatService::SetJsApiAddr(UINT64 addr) { js_api_addr_ = addr; }
|
|
||||||
|
|
||||||
INT64 WechatService::TranslateVoice(UINT64 msg_id){
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 get_by_local_id_addr = base_addr_ + offset::kGetMgrByPrefixLocalId;
|
|
||||||
func::__GetMgrByPrefixLocalId get_by_local_id =
|
|
||||||
(func::__GetMgrByPrefixLocalId)get_by_local_id_addr;
|
|
||||||
|
|
||||||
UINT64 get_chat_mgr_addr = base_addr_ + offset::kGetChatMgr;
|
|
||||||
func::__GetChatMgr get_chat_mgr = (func::__GetChatMgr)get_chat_mgr_addr;
|
|
||||||
|
|
||||||
UINT64 free_chat_msg_addr = base_addr_ + offset::kFreeChatMsg;
|
|
||||||
func::__FreeChatMsg free_chat_msg = (func::__FreeChatMsg)free_chat_msg_addr;
|
|
||||||
|
|
||||||
UINT64 new_chat_msg_addr = base_addr_ + offset::kChatMsgInstanceCounter;
|
|
||||||
func::__NewChatMsg new_chat_msg = (func::__NewChatMsg)new_chat_msg_addr;
|
|
||||||
|
|
||||||
UINT64 update_addr = base_addr_ + offset::kUpdateMsg;
|
|
||||||
func::__UpdateMsg update = (func::__UpdateMsg)update_addr;
|
|
||||||
|
|
||||||
UINT64 get_voice_mgr_addr = base_addr_ + offset::kGetVoiceMgr;
|
|
||||||
func::__GetVoiceMgr get_voice_mgr = (func::__GetVoiceMgr)get_voice_mgr_addr;
|
|
||||||
|
|
||||||
UINT64 to_msg_addr = base_addr_ + offset::kChatMsg2NetSceneSendMsg;
|
|
||||||
func::__ChatMsg2NetSceneSendMsg to_msg =
|
|
||||||
(func::__ChatMsg2NetSceneSendMsg)to_msg_addr;
|
|
||||||
|
|
||||||
UINT64 trans_addr = base_addr_ + offset::kTranslateVoice;
|
|
||||||
func::__TranslateVoice translate_voice = (func::__TranslateVoice)trans_addr;
|
|
||||||
|
|
||||||
char temp_msg[0x460] = {0};
|
|
||||||
|
|
||||||
char *chat_msg = base::utils::WxHeapAlloc<char>(0x460);
|
|
||||||
INT64 index = 0;
|
|
||||||
INT64 local_id = DB::GetInstance().GetLocalIdByMsgId(msg_id, index);
|
|
||||||
if (local_id <= 0 || index >> 32 == 0) {
|
|
||||||
success = -2;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
LARGE_INTEGER l;
|
|
||||||
l.HighPart = index >> 32;
|
|
||||||
l.LowPart = (DWORD)local_id;
|
|
||||||
UINT64 p_chat_msg = new_chat_msg(reinterpret_cast<UINT64>(chat_msg));
|
|
||||||
get_chat_mgr();
|
|
||||||
get_by_local_id(l.QuadPart, p_chat_msg);
|
|
||||||
UINT64 mgr = get_chat_mgr();
|
|
||||||
update(mgr, p_chat_msg, 0);
|
|
||||||
|
|
||||||
UINT64 voice_mgr = get_voice_mgr();
|
|
||||||
UINT64 msg = to_msg(reinterpret_cast<UINT64>(&temp_msg), p_chat_msg);
|
|
||||||
|
|
||||||
success = translate_voice(voice_mgr, msg, 0);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string WechatService::GetTranslateVoiceText(UINT64 msg_id) {
|
|
||||||
std::string content = DB::GetInstance().GetChatMsgStrContentByMsgId(msg_id);
|
|
||||||
if (content.empty()) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
tinyxml2::XMLDocument doc;
|
|
||||||
if (doc.Parse(content.c_str(), content.size()) != 0) {
|
|
||||||
SPDLOG_INFO("tinyxml2 parse error");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
tinyxml2::XMLElement *msg = doc.FirstChildElement("msg");
|
|
||||||
if (msg != nullptr) {
|
|
||||||
tinyxml2::XMLElement *voicetrans = msg->FirstChildElement("voicetrans");
|
|
||||||
if (voicetrans != nullptr) {
|
|
||||||
const char *value = voicetrans->Attribute("transtext",nullptr);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
INT64 WechatService::OpenUrlByWeChatBrowser(const std::wstring &url, int flag) {
|
|
||||||
INT64 success = -1;
|
|
||||||
UINT64 config_addr = base_addr_ + offset::kNewWebViewPageConfig;
|
|
||||||
func::__NewWebViewPageConfig config =(func::__NewWebViewPageConfig)config_addr;
|
|
||||||
|
|
||||||
UINT64 free_config_addr = base_addr_ + offset::kFreeWebViewPageConfig;
|
|
||||||
func::__FreeWebViewPageConfig free_config =(func::__FreeWebViewPageConfig)free_config_addr;
|
|
||||||
|
|
||||||
UINT64 web_view_mgr_addr = base_addr_ + offset::kGetWebViewMgr;
|
|
||||||
func::__GetWebViewMgr web_view_mgr = (func::__GetWebViewMgr)web_view_mgr_addr;
|
|
||||||
|
|
||||||
UINT64 show_addr = base_addr_ + offset::kShowWebView;
|
|
||||||
func::__ShowWebView show_web_view = (func::__ShowWebView)show_addr;
|
|
||||||
|
|
||||||
UINT64 set_url_addr = base_addr_ + offset::kSetUrl;
|
|
||||||
func::__SetUrl set_url = (func::__SetUrl)set_url_addr;
|
|
||||||
|
|
||||||
int a = flag >> 4;
|
|
||||||
int b = flag & 0x1;
|
|
||||||
int c = flag & 0x2;
|
|
||||||
int d = flag & 0x4;
|
|
||||||
int e = flag & 0x8;
|
|
||||||
char* web_config= (char*)HeapAlloc(GetProcessHeap(),0,0xA20);
|
|
||||||
|
|
||||||
UINT64 ptr = config(reinterpret_cast<UINT64>(web_config));
|
|
||||||
set_url( ptr + 0x868,reinterpret_cast<UINT64>(url.c_str()),url.size());
|
|
||||||
web_view_mgr();
|
|
||||||
success = show_web_view(ptr,a,b,c,d,e);
|
|
||||||
free_config(ptr);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
} // namespace wxhelper
|
|
@ -1,93 +0,0 @@
|
|||||||
#ifndef WXHELPER_WECHAT_SERVICE_H_
|
|
||||||
#define WXHELPER_WECHAT_SERVICE_H_
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "singleton.h"
|
|
||||||
#include "wechat_function.h"
|
|
||||||
namespace wxhelper {
|
|
||||||
|
|
||||||
class WechatService : public base::Singleton<WechatService> {
|
|
||||||
friend class base::Singleton<WechatService>;
|
|
||||||
~WechatService();
|
|
||||||
|
|
||||||
public:
|
|
||||||
INT64 CheckLogin();
|
|
||||||
INT64 GetSelfInfo(common::SelfInfoInner& out);
|
|
||||||
INT64 SendTextMsg(const std::wstring& wxid, const std::wstring& msg);
|
|
||||||
INT64 SendImageMsg(const std::wstring& wxid, const std::wstring& image_path);
|
|
||||||
INT64 SendFileMsg(const std::wstring& wxid, const std::wstring& file_path);
|
|
||||||
INT64 GetContacts(std::vector<common::ContactInner>& vec);
|
|
||||||
INT64 GetChatRoomDetailInfo(const std::wstring& room_id,
|
|
||||||
common::ChatRoomInfoInner& room_info);
|
|
||||||
INT64 AddMemberToChatRoom(const std::wstring& room_id,
|
|
||||||
const std::vector<std::wstring>& members);
|
|
||||||
|
|
||||||
INT64 ModChatRoomMemberNickName(const std::wstring& room_id,
|
|
||||||
const std::wstring& wxid,
|
|
||||||
const std::wstring& nickname);
|
|
||||||
INT64 DelMemberFromChatRoom(const std::wstring& room_id,
|
|
||||||
const std::vector<std::wstring>& members);
|
|
||||||
INT64 GetMemberFromChatRoom(const std::wstring& room_id,
|
|
||||||
common::ChatRoomMemberInner& member);
|
|
||||||
INT64 SetTopMsg(ULONG64 msg_id);
|
|
||||||
INT64 RemoveTopMsg(const std::wstring& room_id, ULONG64 msg_id);
|
|
||||||
INT64 InviteMemberToChatRoom(const std::wstring& room_id,
|
|
||||||
const std::vector<std::wstring>& wxids);
|
|
||||||
INT64 CreateChatRoom(const std::vector<std::wstring>& wxids);
|
|
||||||
INT64 QuitChatRoom(const std::wstring& room_id);
|
|
||||||
INT64 ForwardMsg(UINT64 msg_id, const std::wstring& wxid);
|
|
||||||
INT64 GetSNSFirstPage();
|
|
||||||
INT64 GetSNSNextPage(UINT64 sns_id);
|
|
||||||
INT64 AddFavFromMsg(UINT64 msg_id);
|
|
||||||
INT64 AddFavFromImage(const std::wstring& wxid,
|
|
||||||
const std::wstring& image_path);
|
|
||||||
INT64 SendAtText(const std::wstring& room_id,
|
|
||||||
const std::vector<std::wstring>& wxids,
|
|
||||||
const std::wstring& msg);
|
|
||||||
std::wstring GetContactOrChatRoomNickname(const std::wstring& wxid);
|
|
||||||
INT64 GetContactByWxid(const std::wstring& wxid,
|
|
||||||
common::ContactProfileInner& profile);
|
|
||||||
INT64 DoDownloadTask(UINT64 msg_id);
|
|
||||||
INT64 ForwardPublicMsg(const std::wstring& wxid, const std::wstring& title,
|
|
||||||
const std::wstring& url, const std::wstring& thumb_url,
|
|
||||||
const std::wstring& sender_id,
|
|
||||||
const std::wstring& sender_name,
|
|
||||||
const std::wstring& digest);
|
|
||||||
INT64 ForwardPublicMsgByMsgId(const std::wstring& wxid, UINT64 msg_id);
|
|
||||||
|
|
||||||
INT64 DecodeImage(const std::wstring& file_path,
|
|
||||||
const std::wstring& save_dir);
|
|
||||||
INT64 GetVoiceByDB(ULONG64 msg_id, const std::wstring& dir);
|
|
||||||
INT64 SendCustomEmotion(const std::wstring& file_path,
|
|
||||||
const std::wstring& wxid);
|
|
||||||
INT64 SendApplet(const std::wstring& recv_wxid, const std::wstring& waid_suff,
|
|
||||||
const std::wstring& waid_w, const std::string& waid_s,
|
|
||||||
const std::string& wa_wxid, const std::string& json_param,
|
|
||||||
const std::string& head_image, const std::string& big_image,
|
|
||||||
const std::string& index_page);
|
|
||||||
INT64 SendPatMsg(const std::wstring& room_id, const std::wstring& wxid);
|
|
||||||
INT64 DoOCRTask(const std::wstring& img_path, std::string& result);
|
|
||||||
INT64 LockWeChat();
|
|
||||||
INT64 UnLockWeChat();
|
|
||||||
INT64 EnterWeChat();
|
|
||||||
INT64 SendMultiAtText(
|
|
||||||
const std::wstring& room_id,
|
|
||||||
const std::vector<std::pair<std::wstring, std::wstring>>& at);
|
|
||||||
std::string GetLoginUrl();
|
|
||||||
void SetBaseAddr(UINT64 addr);
|
|
||||||
void SetJsApiAddr(UINT64 addr);
|
|
||||||
INT64 TranslateVoice(UINT64 msg_id);
|
|
||||||
std::string GetTranslateVoiceText(UINT64 msg_id);
|
|
||||||
INT64 OpenUrlByWeChatBrowser(const std::wstring& url, int flag);
|
|
||||||
|
|
||||||
private:
|
|
||||||
UINT64 base_addr_;
|
|
||||||
UINT64 js_api_addr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace wxhelper
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue
Block a user