diff --git a/WeChatFerry/spy/database_executor.cpp b/WeChatFerry/spy/database_executor.cpp index bd5a7f8..50c24fa 100644 --- a/WeChatFerry/spy/database_executor.cpp +++ b/WeChatFerry/spy/database_executor.cpp @@ -4,6 +4,7 @@ #include #include "log.hpp" +#include "offsets.h" #include "pb_util.h" #include "rpc_helper.h" #include "sqlite3.h" @@ -13,23 +14,14 @@ extern UINT64 g_WeChatWinDllAddr; namespace db { -#define OFFSET_DB_INSTANCE 0x5902000 -#define OFFSET_DB_MICROMSG 0xB8 -#define OFFSET_DB_CHAT_MSG 0x2C8 -#define OFFSET_DB_MISC 0x5F0 -#define OFFSET_DB_EMOTION 0x15F0 -#define OFFSET_DB_MEDIA 0xF48 -#define OFFSET_DB_BIZCHAT_MSG 0x1A70 -#define OFFSET_DB_FUNCTION_MSG 0x1B98 -#define OFFSET_DB_NAME 0x28 -#define OFFSET_DB_MSG_MGR 0x595F900 +namespace OsDb = Offsets::Db; using db_map_t = std::map; static db_map_t db_map; static void get_db_handle(QWORD base, QWORD offset) { - auto *wsp = reinterpret_cast(*(QWORD *)(base + offset + OFFSET_DB_NAME)); + auto *wsp = reinterpret_cast(*(QWORD *)(base + offset + OsDb::NAME)); std::string dbname = util::w2s(std::wstring(wsp)); db_map[dbname] = util::get_qword(base + offset); } @@ -56,17 +48,16 @@ static void get_msg_db_handle(QWORD msg_mgr_addr) db_map_t get_db_handles() { db_map.clear(); - QWORD db_instance_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_INSTANCE); + QWORD db_instance_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::INSTANCE); - get_db_handle(db_instance_addr, OFFSET_DB_MICROMSG); // MicroMsg.db - get_db_handle(db_instance_addr, OFFSET_DB_CHAT_MSG); // ChatMsg.db - get_db_handle(db_instance_addr, OFFSET_DB_MISC); // Misc.db - get_db_handle(db_instance_addr, OFFSET_DB_EMOTION); // Emotion.db - get_db_handle(db_instance_addr, OFFSET_DB_MEDIA); // Media.db - get_db_handle(db_instance_addr, OFFSET_DB_FUNCTION_MSG); // Function.db - - get_msg_db_handle(util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR)); // MSGi.db & MediaMsgi.db + get_db_handle(db_instance_addr, OsDb::MICROMSG); // MicroMsg.db + get_db_handle(db_instance_addr, OsDb::CHAT_MSG); // ChatMsg.db + get_db_handle(db_instance_addr, OsDb::MISC); // Misc.db + get_db_handle(db_instance_addr, OsDb::EMOTION); // Emotion.db + get_db_handle(db_instance_addr, OsDb::MEDIA); // Media.db + get_db_handle(db_instance_addr, OsDb::FUNCTION_MSG); // Function.db + get_msg_db_handle(util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I)); // MSGi.db & MediaMsgi.db return db_map; } @@ -113,7 +104,7 @@ DbTables_t get_db_tables(const std::string &db) } constexpr const char *sql = "SELECT name FROM sqlite_master WHERE type='table';"; - Sqlite3_exec p_sqlite3_exec = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_EXEC_OFFSET); + Sqlite3_exec p_sqlite3_exec = reinterpret_cast(g_WeChatWinDllAddr + OsDb::EXEC); p_sqlite3_exec(it->second, sql, (Sqlite3_callback)cb_get_tables, (void *)&tables, nullptr); return tables; @@ -123,19 +114,19 @@ DbRows_t exec_db_query(const std::string &db, const std::string &sql) { DbRows_t rows; - Sqlite3_prepare func_prepare = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_PREPARE_OFFSET); - Sqlite3_step func_step = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_STEP_OFFSET); + Sqlite3_prepare func_prepare = reinterpret_cast(g_WeChatWinDllAddr + OsDb::PREPARE); + Sqlite3_step func_step = reinterpret_cast(g_WeChatWinDllAddr + OsDb::STEP); Sqlite3_column_count func_column_count - = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_COLUMN_COUNT_OFFSET); + = reinterpret_cast(g_WeChatWinDllAddr + OsDb::COLUMN_COUNT); Sqlite3_column_name func_column_name - = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_COLUMN_NAME_OFFSET); + = reinterpret_cast(g_WeChatWinDllAddr + OsDb::COLUMN_NAME); Sqlite3_column_type func_column_type - = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_COLUMN_TYPE_OFFSET); + = reinterpret_cast(g_WeChatWinDllAddr + OsDb::COLUMN_TYPE); Sqlite3_column_blob func_column_blob - = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_COLUMN_BLOB_OFFSET); + = reinterpret_cast(g_WeChatWinDllAddr + OsDb::COLUMN_BLOB); Sqlite3_column_bytes func_column_bytes - = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_COLUMN_BYTES_OFFSET); - Sqlite3_finalize func_finalize = reinterpret_cast(g_WeChatWinDllAddr + SQLITE3_FINALIZE_OFFSET); + = reinterpret_cast(g_WeChatWinDllAddr + OsDb::COLUMN_BYTES); + Sqlite3_finalize func_finalize = reinterpret_cast(g_WeChatWinDllAddr + OsDb::FINALIZE); if (db_map.empty()) { db_map = get_db_handles(); @@ -189,7 +180,7 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx) return -1; } - QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); + QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I); int db_index = static_cast(util::get_qword(msg_mgr_addr + 0x68)); // 总不能 int 还不够吧? QWORD p_start = util::get_qword(msg_mgr_addr + 0x50); @@ -232,7 +223,7 @@ int get_local_id_and_dbidx(uint64_t id, uint64_t *local_id, uint32_t *db_idx) std::vector get_audio_data(uint64_t id) { - QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OFFSET_DB_MSG_MGR); + QWORD msg_mgr_addr = util::get_qword(g_WeChatWinDllAddr + OsDb::MSG_I); int db_index = static_cast(util::get_qword(msg_mgr_addr + 0x68)); std::string sql = "SELECT Buf FROM Media WHERE Reserved0=" + std::to_string(id) + ";"; @@ -262,8 +253,8 @@ std::vector get_audio_data(uint64_t id) bool rpc_get_db_names(uint8_t *out, size_t *len) { + DbNames_t names = get_db_names(); return fill_response(out, len, [&](Response &rsp) { - DbNames_t names = get_db_names(); rsp.msg.dbs.names.funcs.encode = encode_dbnames; rsp.msg.dbs.names.arg = &names; }); diff --git a/WeChatFerry/spy/rpc_server.cpp b/WeChatFerry/spy/rpc_server.cpp index 0c5224c..6a082fa 100644 --- a/WeChatFerry/spy/rpc_server.cpp +++ b/WeChatFerry/spy/rpc_server.cpp @@ -245,7 +245,7 @@ const std::unordered_map RpcServer::rpcFu { Functions_FUNC_ENABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().start_message_listener(r.msg.flag, out, len); } }, { Functions_FUNC_DISABLE_RECV_TXT, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().stop_message_listener(out, len); } }, // { Functions_FUNC_GET_CONTACTS, [](const Request &r, uint8_t *out, size_t *len) { return contact::rpc_get_contacts(out, len); } }, - // { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } }, + { Functions_FUNC_GET_DB_NAMES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_names(out, len); } }, // { Functions_FUNC_GET_DB_TABLES, [](const Request &r, uint8_t *out, size_t *len) { return db::rpc_get_db_tables(r.msg.str, out, len); } }, // { Functions_FUNC_GET_AUDIO_MSG, [](const Request &r, uint8_t *out, size_t *len) { return misc::rpc_get_audio(r.msg.am, out, len); } }, { Functions_FUNC_SEND_TXT, [](const Request &r, uint8_t *out, size_t *len) { return RpcServer::getInstance().sender_.rpc_send_text(r.msg.txt, out, len); } }, diff --git a/WeChatFerry/spy/sqlite3.h b/WeChatFerry/spy/sqlite3.h index b50ec2a..a680be7 100644 --- a/WeChatFerry/spy/sqlite3.h +++ b/WeChatFerry/spy/sqlite3.h @@ -138,25 +138,6 @@ #define SQLITE_NULL 5 #define SQLITE_TEXT 3 -#define SQLITE3_EXEC_OFFSET 0x3A5EDA0 -#define SQLITE3_BACKUP_INIT_OFFSET 0x3A18EA0 -#define SQLITE3_PREPARE_OFFSET 0x3A66A20 -#define SQLITE3_OPEN_OFFSET 0x3A9E210 -#define SQLITE3_BACKUP_STEP_OFFSET 0x3A193F0 -#define SQLITE3_BACKUP_REMAINING_OFFSET 0x1B26EB0 -#define SQLITE3_BACKUP_PAGECOUNT_OFFSET 0x1B26EE0 -#define SQLITE3_BACKUP_FINISH_OFFSET 0x3A19AF0 -#define SQLITE3_SLEEP_OFFSET 0x3A9EE70 -#define SQLITE3_ERRCODE_OFFSET 0x3A9CB10 -#define SQLITE3_CLOSE_OFFSET 0x3A9AC70 -#define SQLITE3_STEP_OFFSET 0x3A22DA0 -#define SQLITE3_COLUMN_COUNT_OFFSET 0x3A235C0 -#define SQLITE3_COLUMN_NAME_OFFSET 0x3A23FC0 -#define SQLITE3_COLUMN_TYPE_OFFSET 0x3A23E10 -#define SQLITE3_COLUMN_BLOB_OFFSET 0x3A235F0 -#define SQLITE3_COLUMN_BYTES_OFFSET 0x3A236E0 -#define SQLITE3_FINALIZE_OFFSET 0x3A21E50 - typedef int (*Sqlite3_callback)(void *, int, char **, char **); typedef int(__cdecl *Sqlite3_exec)(QWORD, /* An open database */