diff --git a/src/infra/infra.cpp b/src/infra/infra.cpp index 0f9bab3..30d3aba 100644 --- a/src/infra/infra.cpp +++ b/src/infra/infra.cpp @@ -4,7 +4,11 @@ #include #include #include + +#include +#include #include +#include namespace Infra { @@ -18,15 +22,15 @@ inline bool is_valid_page_1_header(const uint8_t* page1) { } void derive_page_key(uint8_t* aes_key, uint8_t* aes_iv, const uint8_t* p_master_key, const uint32_t page_no) { - uint8_t buffer[0x18]; + std::array buffer{}; // Setup buffer - memcpy(buffer, p_master_key, 0x10); + std::copy_n(p_master_key, 0x10, buffer.begin()); Endian::le_write(&buffer[0x10], page_no); Endian::le_write(&buffer[0x14], 0x546C4173); // Derive Key - md5(aes_key, buffer, 24); + md5(aes_key, buffer.data(), buffer.size()); // Derive IV for (uint32_t ebx{page_no + 1}, i = 0; i < 16; i += 4) { @@ -38,10 +42,10 @@ void derive_page_key(uint8_t* aes_key, uint8_t* aes_iv, const uint8_t* p_master_ ebx = ecx; Endian::le_write(&buffer[i], ebx); } - md5(aes_iv, buffer, 16); + md5(aes_iv, buffer.data(), 0x10); // Cleanup - memset(buffer, 0xCC, sizeof(buffer)); + std::ranges::fill(buffer, 0xcc); } static const uint8_t kDefaultMasterKey[0x10] = { @@ -49,8 +53,8 @@ static const uint8_t kDefaultMasterKey[0x10] = { 0x3d, 0x18, 0x96, 0x72, 0x14, 0x4f, 0xe4, 0xbf, // }; -static constexpr uint8_t kSQLiteDatabaseHeader[0x10] = {'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', - 'o', 'r', 'm', 'a', 't', ' ', '3', 0}; +static constexpr std::array kSQLiteDatabaseHeader = { // + 'S', 'Q', 'L', 'i', 't', 'e', ' ', 'f', 'o', 'r', 'm', 'a', 't', ' ', '3', 0}; int load_db(std::vector& db_data, const std::filesystem::path& db_path) { using namespace AES; @@ -87,25 +91,25 @@ int load_db(std::vector& db_data, const std::filesystem::path& db_path) } if (page_no == 1) [[unlikely]] { - if (memcmp(p_page, kSQLiteDatabaseHeader, 0x10) == 0) { + if (std::equal(kSQLiteDatabaseHeader.cbegin(), kSQLiteDatabaseHeader.cend(), p_page)) { ifs_db.read(reinterpret_cast(p_page + kPageSize), static_cast(db_size - kPageSize)); return SQLITE_OK; // no encryption } - if (!is_valid_page_1_header(p_page)) [[unlikely]] { + if (!is_valid_page_1_header(p_page)) { db_data.clear(); return SQLITE_CORRUPT; // header validation failed } - uint8_t backup[0x08]; // backup magic numbers - memcpy(&backup, &p_page[0x10], 0x08); - memcpy(&p_page[0x10], &p_page[0x08], 0x08); + std::array backup{}; // backup magic numbers + std::copy_n(&p_page[0x10], 0x08, backup.begin()); + std::copy_n(&p_page[0x08], 0x08, &p_page[0x10]); AES_CBC_decrypt_buffer(&ctx_aes, p_page + 0x10, kPageSize - 0x10); - if (memcmp(backup, &p_page[0x10], 0x08) != 0) { + if (!std::equal(backup.cbegin(), backup.cend(), &p_page[0x10])) { db_data.clear(); return SQLITE_CORRUPT; // header validation failed } - memcpy(p_page, kSQLiteDatabaseHeader, 0x10); + std::ranges::copy(kSQLiteDatabaseHeader, p_page); } else { AES_CBC_decrypt_buffer(&ctx_aes, p_page, kPageSize); } diff --git a/src/jobs.hpp b/src/jobs.hpp index 2c23728..01832b7 100644 --- a/src/jobs.hpp +++ b/src/jobs.hpp @@ -1,31 +1,35 @@ #pragma once -#include +#include "qmc2/qmc2.h" +#include #include +#include #include +#include #include #include #include #include #include +#include #include #include -#include "qmc2/qmc2.h" - class KggTask { public: explicit KggTask(std::filesystem::path kgg_path, std::filesystem::path out_dir) : kgg_path_(std::move(kgg_path)), out_dir_(std::move(out_dir)) {} - void warning(const wchar_t* msg) const { fwprintf(stderr, L"[WARN] %s (%s)\n", msg, kgg_path_.filename().c_str()); } - void warning(const std::wstring& msg) const { warning(msg.c_str()); } - - void error(const wchar_t* msg) const { fwprintf(stderr, L"[ERR ] %s (%s)\n", msg, kgg_path_.filename().c_str()); } - void error(const std::wstring& msg) const { error(msg.c_str()); } - - void info(const wchar_t* msg) const { fwprintf(stderr, L"[INFO] %s (%s)\n", msg, kgg_path_.filename().c_str()); } - void info(const std::wstring& msg) const { info(msg.c_str()); } + static void log(const std::wstring& msg) { fputws(msg.c_str(), stderr); } + void warning(const std::wstring& msg) const { + log(std::format(L"[WARN] {} ({})\n", msg, kgg_path_.filename().wstring())); + } + void error(const std::wstring& msg) const { + log(std::format(L"[ERR ] {} ({})\n", msg, kgg_path_.filename().wstring())); + } + void info(const std::wstring& msg) const { + log(std::format(L"[INFO] {} ({})\n", msg, kgg_path_.filename().wstring())); + } void Execute(const Infra::kgm_ekey_db_t& ekey_db, const std::wstring_view suffix) const { constexpr static std::array kMagicHeader{0x7C, 0xD5, 0x32, 0xEB, 0x86, 0x02, 0x7F, 0x4B, diff --git a/src/main.cpp b/src/main.cpp index 6a1d4d8..c4a3ae4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ void WalkFileOrDir(KggTaskQueue& queue, const std::filesystem::path& input_path, continue; } - fwprintf(stderr, L"[WARN] invalid path: %s\n", target_path.c_str()); + fputws(std::format(L"[WARN] invalid path: {}\n", target_path.wstring()).c_str(), stderr); } }