1
0
forked from um/kgg-dec

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 { namespace Infra {
HMODULE g_mod_infra_dll; SqliteDB::SqliteDB(const std::filesystem::path& infra_dll_path) {
sqlite3_open_v2_t sqlite3_open_v2; ok_ = InitInfraDll(infra_dll_path);
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;
bool g_init_sqlite_ok = []() { bool SqliteDB::Open(const std::filesystem::path& db_path, std::string_view key) {
g_mod_infra_dll = LoadLibraryA("infra.dll"); if (infra_ == nullptr) {
if (g_mod_infra_dll == nullptr) {
return false; 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(); 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) { 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; return;
} }
rc = sqlite3_key(db_, "7777B48756BA491BB4CEE771A3E2727E", 0x20); Open(db_path);
if (rc != SQLITE_OK) {
return;
} }
ok_ = true; kgm_ekey_db_t KugouDb::dump_ekey(int& error) {
} if (!IsOpen()) {
kgm_ekey_db_t SQLite::dump_ekey(int& error) {
if (ok_ == false) {
error = SQLITE_ERROR; error = SQLITE_ERROR;
return {}; return {};
} }
@ -64,7 +98,7 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
int rc{-1}; int rc{-1};
sqlite3_stmt* stmt{nullptr}; sqlite3_stmt* stmt{nullptr};
rc = sqlite3_prepare_v2(db_, rc = sqlite3_prepare_v2_(db_,
"select EncryptionKeyId, EncryptionKey from ShareFileItems" "select EncryptionKeyId, EncryptionKey from ShareFileItems"
" where EncryptionKey != ''", " where EncryptionKey != ''",
-1, &stmt, nullptr); -1, &stmt, nullptr);
@ -74,9 +108,9 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
} }
kgm_ekey_db_t result{}; kgm_ekey_db_t result{};
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) { while ((rc = sqlite3_step_(stmt)) == SQLITE_ROW) {
const auto* ekey_id = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)); 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)); const auto* ekey = reinterpret_cast<const char*>(sqlite3_column_text_(stmt, 1));
result[ekey_id] = ekey; result[ekey_id] = ekey;
} }
@ -84,16 +118,20 @@ kgm_ekey_db_t SQLite::dump_ekey(int& error) {
error = rc; error = rc;
} }
sqlite3_finalize(stmt); sqlite3_finalize_(stmt);
error = 0; error = 0;
return result; return result;
} }
SQLite::~SQLite() { KugouDb::~KugouDb() {
if (db_ != nullptr) { if (db_ != nullptr) {
sqlite3_close_v2(db_); sqlite3_close_v2_(db_);
db_ = nullptr; db_ = nullptr;
} }
} }
bool KugouDb::Open(const std::filesystem::path& db_path) {
return SqliteDB::Open(db_path, {"7777B48756BA491BB4CEE771A3E2727E"});
}
} // namespace Infra } // namespace Infra

View File

@ -4,23 +4,46 @@
#include <unordered_map> #include <unordered_map>
#include "sqlite_base.h" #include "sqlite_base.h"
#include "sqlite_fn.h"
namespace Infra { namespace Infra {
typedef std::unordered_map<std::string, std::string> kgm_ekey_db_t; typedef std::unordered_map<std::string, std::string> kgm_ekey_db_t;
extern bool g_init_sqlite_ok; extern bool g_init_sqlite_ok;
class SQLite { class SqliteDB {
public: public:
explicit SQLite(const std::filesystem::path& db_path); explicit SqliteDB(const std::filesystem::path& infra_dll_path);
~SQLite(); bool Open(const std::filesystem::path& db_path, std::string_view key);
void Close();
[[nodiscard]] bool is_ok() const { return ok_; } [[nodiscard]] bool IsInfraOk() const { return ok_; }
kgm_ekey_db_t dump_ekey(int& error); [[nodiscard]] bool IsOpen() const { return db_ != nullptr; }
private: 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}; 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 } // namespace Infra

View File

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