diff --git a/app/base/src/include/utils.h b/app/base/src/include/utils.h index 5b83ff5..88134ad 100644 --- a/app/base/src/include/utils.h +++ b/app/base/src/include/utils.h @@ -60,6 +60,8 @@ void HideModule(HMODULE module); bool IsDigit(const std::string &str); std::string Bytes2Hex(const BYTE *bytes, const int length); + +bool IsTextUtf8(const char *str, INT64 length); } // namespace utils } // namespace base #endif \ No newline at end of file diff --git a/app/base/src/utils.cc b/app/base/src/utils.cc index af605a2..427256a 100644 --- a/app/base/src/utils.cc +++ b/app/base/src/utils.cc @@ -181,5 +181,45 @@ std::string Bytes2Hex(const BYTE *bytes, const int length) { return buff; } +bool IsTextUtf8(const char *str, INT64 length) { + char endian = 1; + bool littlen_endian = (*(char *)&endian == 1); + + size_t i; + int bytes_num; + unsigned char chr; + + i = 0; + bytes_num = 0; + while (i < length) { + if (littlen_endian) { + chr = *(str + i); + } else { // Big Endian + chr = (*(str + i) << 8) | *(str + i + 1); + i++; + } + + if (bytes_num == 0) { + if ((chr & 0x80) != 0) { + while ((chr & 0x80) != 0) { + chr <<= 1; + bytes_num++; + } + if ((bytes_num < 2) || (bytes_num > 6)) { + return false; + } + bytes_num--; + } + } else { + if ((chr & 0xC0) != 0x80) { + return false; + } + bytes_num--; + } + i++; + } + return (bytes_num == 0); +} + } // namespace utils } // namespace base diff --git a/app/wxhelper/src/global_manager.cc b/app/wxhelper/src/global_manager.cc index 585694b..c8da1d4 100644 --- a/app/wxhelper/src/global_manager.cc +++ b/app/wxhelper/src/global_manager.cc @@ -1,5 +1,6 @@ #include "global_manager.h" +#include "db.h" #include "http_url_handler.h" #include "thread_pool.h" #include "utils.h" @@ -19,6 +20,7 @@ void GlobalManager::initialize(HMODULE module) { } UINT64 base = wxutils::GetWeChatWinBase(); + DB::GetInstance().init(base); WechatService::GetInstance().SetBaseAddr(base); http_server = std::unique_ptr( new http::HttpServer(config->GetPort())); @@ -28,6 +30,8 @@ void GlobalManager::initialize(HMODULE module) { 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->Start(); base::ThreadPool::GetInstance().Create(2, 8); diff --git a/app/wxhelper/src/http_url_handler.cc b/app/wxhelper/src/http_url_handler.cc index baa9121..87d7cba 100644 --- a/app/wxhelper/src/http_url_handler.cc +++ b/app/wxhelper/src/http_url_handler.cc @@ -2,6 +2,7 @@ #include +#include "db.h" #include "utils.h" #include "wechat_hook.h" #include "wechat_service.h" @@ -32,6 +33,16 @@ std::string GetStringParam(nlohmann::json data, std::string key) { return data[key].get(); } +INT64 GetInt64Param(nlohmann::json data, std::string key) { + INT64 result; + try { + result = data[key].get(); + } catch (nlohmann::json::exception) { + result = STR2LL(data[key].get()); + } + 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); @@ -129,4 +140,54 @@ std::string GetSelfInfo(mg_http_message* hm) { } return ret_data.dump(); } + +std::string GetDBInfo(mg_http_message* hm) { + std::vector 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(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> 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(); +} + } // namespace wxhelper \ No newline at end of file diff --git a/app/wxhelper/src/http_url_handler.h b/app/wxhelper/src/http_url_handler.h index 7b4ef20..ed09d6a 100644 --- a/app/wxhelper/src/http_url_handler.h +++ b/app/wxhelper/src/http_url_handler.h @@ -10,6 +10,8 @@ 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); } // namespace wxhelper #endif \ No newline at end of file diff --git a/app/wxhelper/src/wechat_function.h b/app/wxhelper/src/wechat_function.h index 5e0c5fe..77172ee 100644 --- a/app/wxhelper/src/wechat_function.h +++ b/app/wxhelper/src/wechat_function.h @@ -484,6 +484,35 @@ struct WeChatString { } // namespace prototype namespace offset { +const UINT64 k_sqlite3_exec = 0x2654db0; +const UINT64 k_sqlite3_prepare = 0x265c920; +const UINT64 k_sqlite3_open = 0x2694120; +const UINT64 k_sqlite3_backup_init = 0x260eec0; +const UINT64 k_sqlite3_errcode = 0x2692a20; +const UINT64 k_sqlite3_close = 0x2690b80; +const UINT64 k_sqlite3_step = 0x2618dc0; +const UINT64 k_sqlite3_column_count = 0x26195e0; +const UINT64 k_sqlite3_column_name = 0x2619fe0; +const UINT64 k_sqlite3_column_type = 0x2619e30; +const UINT64 k_sqlite3_column_blob = 0x2619610; +const UINT64 k_sqlite3_column_bytes = 0x2619700; +const UINT64 k_sqlite3_finalize = 0x2617e70; + +const UINT64 kGPInstance = 0x3c19fe8; +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 = 0x3c8ef40; +const UINT64 kPublicMsgMgr = 0x3c8c6c8; +const UINT64 kFavoriteStorageMgr = 0x3c8fac0; + const UINT64 kGetSendMessageMgr = 0x8fe740; const UINT64 kFreeChatMsg = 0x8fffc0; const UINT64 kSendTextMsg = 0x1024370;