'feat:基础功能'

This commit is contained in:
ttttupup 2024-04-06 11:38:16 +08:00
parent 2eb798458c
commit a90d667799
23 changed files with 206 additions and 2782 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,
&micro_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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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>(&current_data_path));
GetCurrentDataPath(reinterpret_cast<ULONG_PTR>(&current_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

View File

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