refactor: make infra.dll customizeable

This commit is contained in:
鲁树人 2024-10-18 05:17:10 +09:00
parent 2a462c2eff
commit db21f35b3f
3 changed files with 120 additions and 58 deletions

View File

@ -6,57 +6,91 @@
namespace Infra {
HMODULE g_mod_infra_dll;
sqlite3_open_v2_t sqlite3_open_v2;
sqlite3_key_t sqlite3_key;
sqlite3_prepare_v2_t sqlite3_prepare_v2;
sqlite3_step_t sqlite3_step;
sqlite3_column_text_t sqlite3_column_text;
sqlite3_close_v2_t sqlite3_close_v2;
sqlite3_finalize_t sqlite3_finalize;
SqliteDB::SqliteDB(const std::filesystem::path& infra_dll_path) {
ok_ = InitInfraDll(infra_dll_path);
}
bool g_init_sqlite_ok = []() {
g_mod_infra_dll = LoadLibraryA("infra.dll");
if (g_mod_infra_dll == nullptr) {
bool SqliteDB::Open(const std::filesystem::path& db_path, std::string_view key) {
if (infra_ == nullptr) {
return false;
}
sqlite3_open_v2 = reinterpret_cast<sqlite3_open_v2_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_open_v2"));
sqlite3_key = reinterpret_cast<sqlite3_key_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_key"));
sqlite3_prepare_v2 = reinterpret_cast<sqlite3_prepare_v2_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_prepare_v2"));
sqlite3_step = reinterpret_cast<sqlite3_step_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_step"));
sqlite3_column_text =
reinterpret_cast<sqlite3_column_text_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_column_text"));
sqlite3_close_v2 = reinterpret_cast<sqlite3_close_v2_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_close_v2"));
sqlite3_finalize = reinterpret_cast<sqlite3_finalize_t>(GetProcAddress(g_mod_infra_dll, "sqlite3_finalize"));
return sqlite3_open_v2 && sqlite3_key && sqlite3_prepare_v2 && sqlite3_step && sqlite3_column_text &&
sqlite3_close_v2 && sqlite3_finalize;
}();
SQLite::SQLite(const std::filesystem::path& db_path) {
ok_ = false;
int rc{-1};
if (!g_init_sqlite_ok) {
return;
}
auto db_path_u8 = db_path.generic_u8string();
rc = sqlite3_open_v2(reinterpret_cast<const char*>(db_path_u8.c_str()), &db_, SQLITE_OPEN_READONLY, nullptr);
int rc = sqlite3_open_v2_(reinterpret_cast<const char*>(db_path_u8.c_str()), &db_, SQLITE_OPEN_READONLY, nullptr);
if (rc != SQLITE_OK) {
return false;
}
if (!key.empty()) {
rc = sqlite3_key_(db_, key.data(), static_cast<int>(key.size()));
if (rc != SQLITE_OK) {
sqlite3_close_v2_(db_);
db_ = nullptr;
return false;
}
}
return true;
}
void SqliteDB::Close() {
if (db_) {
sqlite3_close_v2_(db_);
db_ = nullptr;
}
}
void SqliteDB::FreeInfraDll() {
if (infra_ != nullptr) {
FreeLibrary(reinterpret_cast<HMODULE>(infra_));
infra_ = nullptr;
}
sqlite3_open_v2_ = nullptr;
sqlite3_key_ = nullptr;
sqlite3_prepare_v2_ = nullptr;
sqlite3_step_ = nullptr;
sqlite3_column_text_ = nullptr;
sqlite3_close_v2_ = nullptr;
sqlite3_finalize_ = nullptr;
}
bool SqliteDB::InitInfraDll(const std::filesystem::path& infra_dll_path) {
auto path_unicode = infra_dll_path.wstring();
HMODULE hMod = LoadLibraryW(path_unicode.c_str());
infra_ = hMod;
if (hMod == nullptr) {
return false;
}
sqlite3_open_v2_ = reinterpret_cast<sqlite3_open_v2_t>(GetProcAddress(hMod, "sqlite3_open_v2"));
sqlite3_key_ = reinterpret_cast<sqlite3_key_t>(GetProcAddress(hMod, "sqlite3_key"));
sqlite3_prepare_v2_ = reinterpret_cast<sqlite3_prepare_v2_t>(GetProcAddress(hMod, "sqlite3_prepare_v2"));
sqlite3_step_ = reinterpret_cast<sqlite3_step_t>(GetProcAddress(hMod, "sqlite3_step"));
sqlite3_column_text_ = reinterpret_cast<sqlite3_column_text_t>(GetProcAddress(hMod, "sqlite3_column_text"));
sqlite3_close_v2_ = reinterpret_cast<sqlite3_close_v2_t>(GetProcAddress(hMod, "sqlite3_close_v2"));
sqlite3_finalize_ = reinterpret_cast<sqlite3_finalize_t>(GetProcAddress(hMod, "sqlite3_finalize"));
if (!sqlite3_open_v2_ || !sqlite3_key_ || !sqlite3_prepare_v2_ || !sqlite3_step_ || !sqlite3_column_text_ ||
!sqlite3_close_v2_ || !sqlite3_finalize_) {
infra_ = nullptr;
return false;
}
return true;
}
KugouDb::KugouDb(const std::filesystem::path& infra_dll_path, const std::filesystem::path& db_path)
: SqliteDB(infra_dll_path) {
int rc{-1};
if (!IsInfraOk()) {
return;
}
rc = sqlite3_key(db_, "7777B48756BA491BB4CEE771A3E2727E", 0x20);
if (rc != SQLITE_OK) {
return;
Open(db_path);
}
ok_ = true;
}
kgm_ekey_db_t SQLite::dump_ekey(int& error) {
if (ok_ == false) {
kgm_ekey_db_t KugouDb::dump_ekey(int& error) {
if (!IsOpen()) {
error = SQLITE_ERROR;
return {};
}
@ -64,7 +98,7 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
int rc{-1};
sqlite3_stmt* stmt{nullptr};
rc = sqlite3_prepare_v2(db_,
rc = sqlite3_prepare_v2_(db_,
"select EncryptionKeyId, EncryptionKey from ShareFileItems"
" where EncryptionKey != ''",
-1, &stmt, nullptr);
@ -74,9 +108,9 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
}
kgm_ekey_db_t result{};
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
const auto* ekey_id = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
const auto* ekey = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
while ((rc = sqlite3_step_(stmt)) == SQLITE_ROW) {
const auto* ekey_id = reinterpret_cast<const char*>(sqlite3_column_text_(stmt, 0));
const auto* ekey = reinterpret_cast<const char*>(sqlite3_column_text_(stmt, 1));
result[ekey_id] = ekey;
}
@ -84,16 +118,20 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
error = rc;
}
sqlite3_finalize(stmt);
sqlite3_finalize_(stmt);
error = 0;
return result;
}
SQLite::~SQLite() {
KugouDb::~KugouDb() {
if (db_ != nullptr) {
sqlite3_close_v2(db_);
sqlite3_close_v2_(db_);
db_ = nullptr;
}
}
bool KugouDb::Open(const std::filesystem::path& db_path) {
return SqliteDB::Open(db_path, {"7777B48756BA491BB4CEE771A3E2727E"});
}
} // namespace Infra

View File

@ -4,23 +4,46 @@
#include <unordered_map>
#include "sqlite_base.h"
#include "sqlite_fn.h"
namespace Infra {
typedef std::unordered_map<std::string, std::string> kgm_ekey_db_t;
extern bool g_init_sqlite_ok;
class SQLite {
class SqliteDB {
public:
explicit SQLite(const std::filesystem::path& db_path);
~SQLite();
[[nodiscard]] bool is_ok() const { return ok_; }
kgm_ekey_db_t dump_ekey(int& error);
explicit SqliteDB(const std::filesystem::path& infra_dll_path);
bool Open(const std::filesystem::path& db_path, std::string_view key);
void Close();
[[nodiscard]] bool IsInfraOk() const { return ok_; }
[[nodiscard]] bool IsOpen() const { return db_ != nullptr; }
private:
bool ok_ = false;
bool InitInfraDll(const std::filesystem::path& infra_dll_path);
bool ok_{false};
protected:
void FreeInfraDll();
void* infra_{nullptr};
sqlite3_open_v2_t sqlite3_open_v2_{nullptr};
sqlite3_key_t sqlite3_key_{nullptr};
sqlite3_prepare_v2_t sqlite3_prepare_v2_{nullptr};
sqlite3_step_t sqlite3_step_{nullptr};
sqlite3_column_text_t sqlite3_column_text_{nullptr};
sqlite3_close_v2_t sqlite3_close_v2_{nullptr};
sqlite3_finalize_t sqlite3_finalize_{nullptr};
sqlite3* db_{nullptr};
};
class KugouDb : public SqliteDB {
public:
explicit KugouDb(const std::filesystem::path& infra_dll_path, const std::filesystem::path& db_path);
~KugouDb();
bool Open(const std::filesystem::path& db_path);
kgm_ekey_db_t dump_ekey(int& error);
};
} // namespace Infra

View File

@ -116,8 +116,8 @@ int main() {
kgmPath = kgmPath / L"Kugou8" / L"KGMusicV3.db";
int error{-1};
Infra::SQLite db{kgmPath};
if (!db.is_ok()) {
Infra::KugouDb db{L"infra.dll", kgmPath};
if (!db.IsOpen()) {
fprintf(stderr, "[ERR ] db init error: is infra.dll ok?\n");
return 1;
}
@ -126,6 +126,7 @@ int main() {
fprintf(stderr, "[ERR ] dump ekey failed %d (%s)", error, sqlite_get_error(error));
return 1;
}
db.Close();
#ifdef _DEBUG
printf("ekey_db:\n");