From a4f4500585e86b48c452cd077180ad83da2a4a96 Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 14 Mar 2017 17:34:47 +0700 Subject: [PATCH] Welcome HonokaMiku v5.0.0 Some cleanup and some new documentation. --- VersionInfo.rc | 13 ++++---- src/CN_Decrypter.cc | 6 ++-- src/DecrypterContext.h | 71 ++++++++++++++++++------------------------ src/EN_Decrypter.cc | 6 ++-- src/HonokaMiku.cc | 5 ++- src/JP_Decrypter.cc | 6 ++-- src/TW_Decrypter.cc | 6 ++-- src/V2_Decrypter.cc | 2 +- 8 files changed, 52 insertions(+), 63 deletions(-) diff --git a/VersionInfo.rc b/VersionInfo.rc index 33e6b9b..1933b5b 100644 --- a/VersionInfo.rc +++ b/VersionInfo.rc @@ -3,12 +3,11 @@ #define _DEPSTR1(x) #x #define _STR2(x) _DEPSTR1(x) -#define HONOKAMIKU_VERSION_MAJOR 4 -#define HONOKAMIKU_VERSION_MINOR 3 -#define HONOKAMIKU_VERSION_PATCH 1 -//#define HONOKAMIKU_VERSION_STRING "" _STR2(HONOKAMIKU_VERSION_MAJOR) "." _STR2(HONOKAMIKU_VERSION_MINOR) "." _STR2(HONOKAMIKU_VERSION_PATCH) "" -#define HONOKAMIKU_VERSION_STRING "5.0.0 beta-2" -#define HONOKAMIKU_VERSION_STRING_RC "5.0.0 beta-2" +#define HONOKAMIKU_VERSION_MAJOR 5 +#define HONOKAMIKU_VERSION_MINOR 0 +#define HONOKAMIKU_VERSION_PATCH 0 +#define HONOKAMIKU_VERSION_STRING "" _STR2(HONOKAMIKU_VERSION_MAJOR) "." _STR2(HONOKAMIKU_VERSION_MINOR) "." _STR2(HONOKAMIKU_VERSION_PATCH) "" +#define HONOKAMIKU_VERSION_STRING_RC "5.0.0" #define HONOKAMIKU_VERSION ((HONOKAMIKU_VERSION_MAJOR*100000000)+(HONOKAMIKU_VERSION_MINOR*100000)+(HONOKAMIKU_VERSION_PATCH)) #ifdef RC_INVOKED @@ -29,7 +28,7 @@ BEGIN VALUE "FileDescription", "Universal LL!SIF game files decrypter" VALUE "FileVersion", HONOKAMIKU_VERSION_STRING_RC VALUE "InternalName", "HonokaMiku" - VALUE "LegalCopyright", "Copyright © 2037 Dark Energy Processor Corporation" + VALUE "LegalCopyright", "Copyright © 2038 Dark Energy Processor Corporation" VALUE "OriginalFilename", "HonokaMiku.exe" VALUE "ProductName", "HonokaMiku" VALUE "ProductVersion", HONOKAMIKU_VERSION_STRING_RC diff --git a/src/CN_Decrypter.cc b/src/CN_Decrypter.cc index c5c665e..5ae9c0c 100644 --- a/src/CN_Decrypter.cc +++ b/src/CN_Decrypter.cc @@ -28,7 +28,7 @@ static const uint32_t cn_key_tables[64] = { // Version 2 code // //////////////////// -HonokaMiku::CN2_Dctx::CN2_Dctx(const void* header, const char* filename):V2_Dctx(GetPrefixFromGameId(5), header, filename) {} +HonokaMiku::CN2_Dctx::CN2_Dctx(const void* header, const char* filename): V2_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_CN), header, filename) {} uint32_t HonokaMiku::CN2_Dctx::get_id() { @@ -39,7 +39,7 @@ uint32_t HonokaMiku::CN2_Dctx::get_id() // Version 3 code // //////////////////// -HonokaMiku::CN3_Dctx::CN3_Dctx(const void* header, const char* filename):V3_Dctx(GetPrefixFromGameId(7), header, filename) {} +HonokaMiku::CN3_Dctx::CN3_Dctx(const void* header, const char* filename): V3_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_CN), header, filename) {} const uint32_t* HonokaMiku::CN3_Dctx::_getKeyTables() { return cn_key_tables; } @@ -56,6 +56,6 @@ void HonokaMiku::CN3_Dctx::final_setup(const char* filename, const void* block_r HonokaMiku::CN3_Dctx* HonokaMiku::CN3_Dctx::encrypt_setup(const char* filename, void* hdr_out, int32_t fv) { CN3_Dctx* dctx = new CN3_Dctx; - setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(7), 1847, filename, hdr_out, fv); + setupEncryptV3(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_CN), 1847, filename, hdr_out, fv); return dctx; } diff --git a/src/DecrypterContext.h b/src/DecrypterContext.h index 5517b15..5550c53 100644 --- a/src/DecrypterContext.h +++ b/src/DecrypterContext.h @@ -1,6 +1,10 @@ /** * \file DecrypterContext.h -* Base header of SIF game files decrypter +* \brief Base header of SIF game files decrypter +* \author Dark Energy Processor Corporation +* \author AuahDark +* \version 5.0.0 +* \copyright MIT License **/ #ifndef _HONOKAMIKU_DECRYPTERCONTEXT @@ -13,14 +17,22 @@ #include +/// Japanese game type #define HONOKAMIKU_GAMETYPE_JP 0x0000 +/// International game type #define HONOKAMIKU_GAMETYPE_EN 0x0001 +/// Taiwanese game type #define HONOKAMIKU_GAMETYPE_TW 0x0002 +/// Simplified Chinese game type #define HONOKAMIKU_GAMETYPE_CN 0x0003 +/// Version 1 decrypt/encrypt #define HONOKAMIKU_DECRYPT_V1 0x00010000 +/// Version 2 decrypt/encrypt #define HONOKAMIKU_DECRYPT_V2 0x00020000 +/// Version 3 decrypt/encrypt #define HONOKAMIKU_DECRYPT_V3 0x00030000 +/// Version 4 decrypt/encrypt #define HONOKAMIKU_DECRYPT_V4 0x00040000 #define HONOKAMIKU_DECRYPT_V5 0x00050000 #define HONOKAMIKU_DECRYPT_V6 0x00060000 @@ -28,38 +40,16 @@ namespace HonokaMiku { - /// \brief Gets game key prefix for specificed game id. - /// \param game_id The game ID. Valid game IDs are - /// 1. EN/WW Version 2 - /// 2. JP Version 2/KR - /// 3. TW Version 2 - /// 4. JP Version 3 - /// 5. CN Version 2 - /// 6. EN/WW Version 3 - /// 7. CN Version 3 - /// 8. TW Version 3 - /// \returns prefix key of specificed game ID or NULL if game ID is invalid - /// \note If you just want to get prefix key, the version doesn't matter. - inline const char* GetPrefixFromGameId(char game_id) - { - switch(game_id) - { - case 1: - case 6: return "BFd3EnkcKa"; - case 2: - case 4: return "Hello"; - case 3: - case 8: return "M2o2B7i3M6o6N88"; - case 5: - case 7: return "iLbs0LpvJrXm3zjdhAr4"; - default: return NULL; - } - } - - /// \brief same as GetPrefixFromGameId() except this one operates on `HONOKAMIKU_GAMETYPE_*` constants + /// \brief Gets game key prefix for specificed game types. + /// \param gt The game type. Valid game types are + /// 1. #HONOKAMIKU_GAMETYPE_JP + /// 2. #HONOKAMIKU_GAMETYPE_EN + /// 3. #HONOKAMIKU_GAMETYPE_TW + /// 4. #HONOKAMIKU_GAMETYPE_CN + /// \returns Prefix key of specificed game type or NULL if invalid game types specificed. inline const char* GetPrefixFromGameType(uint32_t gt) { - switch(gt) + switch(gt & 0xFFFF) { case HONOKAMIKU_GAMETYPE_JP: return "Hello"; case HONOKAMIKU_GAMETYPE_EN: return "BFd3EnkcKa"; @@ -109,7 +99,9 @@ namespace HonokaMiku /// \param filename File name that want to be decrypted. This affects the key calculation. /// \param block_rest The next 12-bytes header of Version 3 encrypted file. virtual void final_setup(const char* filename, const void* block_rest, int32_t fv = 0) = 0; - /// \brief Function to get the decrypter filename + /// \brief Gets the game property of the current decrypter context. + /// \returns Game property. The low 16-bit is the game type, and the upper 16-bit is the + /// decrypter version virtual uint32_t get_id() = 0; protected: inline DecrypterContext() {} @@ -296,7 +288,7 @@ namespace HonokaMiku inline static EN2_Dctx* encrypt_setup(const char* filename, void* hdr_out) { EN2_Dctx* dctx = new EN2_Dctx(); - setupEncryptV2(dctx, GetPrefixFromGameId(1), filename, hdr_out); + setupEncryptV2(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_EN), filename, hdr_out); return dctx; } }; @@ -319,7 +311,7 @@ namespace HonokaMiku inline static TW2_Dctx* encrypt_setup(const char* filename, void* hdr_out) { TW2_Dctx* dctx = new TW2_Dctx(); - setupEncryptV2(dctx, GetPrefixFromGameId(3), filename, hdr_out); + setupEncryptV2(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_TW), filename, hdr_out); return dctx; } }; @@ -342,7 +334,7 @@ namespace HonokaMiku inline static JP2_Dctx* encrypt_setup(const char* filename, void* hdr_out) { JP2_Dctx* dctx = new JP2_Dctx(); - setupEncryptV2(dctx, GetPrefixFromGameId(2), filename, hdr_out); + setupEncryptV2(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_JP), filename, hdr_out); return dctx; } }; @@ -366,7 +358,7 @@ namespace HonokaMiku inline static CN2_Dctx* encrypt_setup(const char* filename, void* hdr_out) { CN2_Dctx* dctx = new CN2_Dctx(); - setupEncryptV2(dctx, GetPrefixFromGameId(5), filename, hdr_out); + setupEncryptV2(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_CN), filename, hdr_out); return dctx; } }; @@ -385,12 +377,11 @@ namespace HonokaMiku /// \brief Creates decrypter context based from the given headers. Auto detect /// \param filename File name that want to be decrypted. This affects the key calculation. /// \param header The first 4-bytes contents of the file - /// \param game_type Pointer to store the game ID. See GetPrefixFromGameId() for valid game IDs. /// \returns DecrypterContext or NULL if no suitable decryption method is available. DecrypterContext* FindSuitable(const char* filename, const void* header); /// \brief Creates decrypter context based the game ID. - /// \param game_prop The game ID. Valid game IDs can be seen in HonokaMiku.cc Line 86 + /// \param game_prop The game property. See DecrypterContext::get_id() for more information. /// \param header The first 4-bytes contents of the file /// \param filename File name that want to be decrypted. This affects the key calculation. /// \returns DecrypterContext or NULL if specificed game ID is invalid @@ -398,14 +389,14 @@ namespace HonokaMiku DecrypterContext* RequestDecrypter(uint32_t game_prop, const void* header, const char* filename); /// \brief Creates decrypter context for encryption based the game ID. - /// \param game_id The game ID. See GetPrefixFromGameId() for valid game IDs. + /// \param game_prop The game property. See DecrypterContext::get_id() for more information. /// \param filename File name that want to be decrypted. This affects the key calculation. /// \param header_out Pointer to store the file header. The memory size should be 16-bytes /// to reserve space for Version 3 decrypter. /// \returns DecrypterContext ready for encryption DecrypterContext* RequestEncrypter(uint32_t game_prop, const char* filename, void* header_out); - /// \brief Get header size for specific decryption types + /// \brief Get header size for specific decryption modes. /// \param dectype `HONOAMIKU_DECRYPT_*` constants /// \returns header size (or -1 if unknown) inline int32_t GetHeaderSize(uint32_t dectype) diff --git a/src/EN_Decrypter.cc b/src/EN_Decrypter.cc index da0191e..46d35a6 100644 --- a/src/EN_Decrypter.cc +++ b/src/EN_Decrypter.cc @@ -28,7 +28,7 @@ static const uint32_t en_key_tables[64] = { // Version 2 code // //////////////////// -HonokaMiku::EN2_Dctx::EN2_Dctx(const void* header, const char* filename):V2_Dctx(GetPrefixFromGameId(1), header, filename) {} +HonokaMiku::EN2_Dctx::EN2_Dctx(const void* header, const char* filename): V2_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_EN), header, filename) {} uint32_t HonokaMiku::EN2_Dctx::get_id() { @@ -39,7 +39,7 @@ uint32_t HonokaMiku::EN2_Dctx::get_id() // Version 3 code // //////////////////// -HonokaMiku::EN3_Dctx::EN3_Dctx(const void* header, const char* filename): V3_Dctx(GetPrefixFromGameId(1), header, filename) {} +HonokaMiku::EN3_Dctx::EN3_Dctx(const void* header, const char* filename): V3_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_EN), header, filename) {} const uint32_t* HonokaMiku::EN3_Dctx::_getKeyTables() { return en_key_tables; } @@ -56,6 +56,6 @@ void HonokaMiku::EN3_Dctx::final_setup(const char* filename, const void* block_r HonokaMiku::EN3_Dctx* HonokaMiku::EN3_Dctx::encrypt_setup(const char* filename, void* hdr_out, int force_version) { EN3_Dctx* dctx = new EN3_Dctx; - setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(1), 844, filename, hdr_out, force_version); + setupEncryptV3(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_EN), 844, filename, hdr_out, force_version); return dctx; } diff --git a/src/HonokaMiku.cc b/src/HonokaMiku.cc index 148197a..b3e8762 100644 --- a/src/HonokaMiku.cc +++ b/src/HonokaMiku.cc @@ -266,10 +266,9 @@ void parse_args(int argc, char* argv[]) msvcr110_strnicmp("cross-encrypt", arg, 14) == 0 ) { - if((g_XEncryptGame = GetGameProp(argv[i + 1])) == (-1)) - fprintf(stderr, "Cross-encrypt: Invalid game '%s'", argv[i + 1]); + if((g_XEncryptGame = GetGameProp(argv[i++])) == (-1)) + fprintf(stderr, "Cross-encrypt: Invalid game '%s'\n", argv[i]); - i++; arg_f = true; } } diff --git a/src/JP_Decrypter.cc b/src/JP_Decrypter.cc index be497f6..d8a5fcb 100644 --- a/src/JP_Decrypter.cc +++ b/src/JP_Decrypter.cc @@ -34,7 +34,7 @@ static const uint32_t jp_lng_key_tables[12] = { // Version 2 code // //////////////////// -HonokaMiku::JP2_Dctx::JP2_Dctx(const void* header, const char* filename):V2_Dctx(GetPrefixFromGameId(2), header, filename) {} +HonokaMiku::JP2_Dctx::JP2_Dctx(const void* header, const char* filename): V2_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_JP), header, filename) {} uint32_t HonokaMiku::JP2_Dctx::get_id() { @@ -45,7 +45,7 @@ uint32_t HonokaMiku::JP2_Dctx::get_id() // Version 3 code // //////////////////// -HonokaMiku::JP3_Dctx::JP3_Dctx(const void* header, const char* filename):V3_Dctx(GetPrefixFromGameId(2), header, filename) {} +HonokaMiku::JP3_Dctx::JP3_Dctx(const void* header, const char* filename): V3_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_JP), header, filename) {} const uint32_t* HonokaMiku::JP3_Dctx::_getKeyTables() { return jp_key_tables; } const uint32_t* HonokaMiku::JP3_Dctx::_getLngKeyTables() { return jp_lng_key_tables; } @@ -63,6 +63,6 @@ void HonokaMiku::JP3_Dctx::final_setup(const char* filename, const void* block_r HonokaMiku::JP3_Dctx* HonokaMiku::JP3_Dctx::encrypt_setup(const char* filename,void* hdr_out, int32_t fv) { JP3_Dctx* dctx = new JP3_Dctx; - setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(2), 500, filename, hdr_out, fv); + setupEncryptV3(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_JP), 500, filename, hdr_out, fv); return dctx; } diff --git a/src/TW_Decrypter.cc b/src/TW_Decrypter.cc index bac9eed..377a593 100644 --- a/src/TW_Decrypter.cc +++ b/src/TW_Decrypter.cc @@ -28,7 +28,7 @@ static const uint32_t tw_key_tables[64] = { // Version 2 code // //////////////////// -HonokaMiku::TW2_Dctx::TW2_Dctx(const void* header, const char* filename):V2_Dctx(HonokaMiku::GetPrefixFromGameId(3), header, filename) {} +HonokaMiku::TW2_Dctx::TW2_Dctx(const void* header, const char* filename): V2_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_TW), header, filename) {} uint32_t HonokaMiku::TW2_Dctx::get_id() { @@ -39,7 +39,7 @@ uint32_t HonokaMiku::TW2_Dctx::get_id() // Version 3 code // //////////////////// -HonokaMiku::TW3_Dctx::TW3_Dctx(const void* header, const char* filename): HonokaMiku::V3_Dctx(HonokaMiku::GetPrefixFromGameId(3), header, filename) {} +HonokaMiku::TW3_Dctx::TW3_Dctx(const void* header, const char* filename): V3_Dctx(GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_TW), header, filename) {} const uint32_t* HonokaMiku::TW3_Dctx::_getKeyTables() { return tw_key_tables; } @@ -56,6 +56,6 @@ void HonokaMiku::TW3_Dctx::final_setup(const char* filename, const void* block_r HonokaMiku::TW3_Dctx* HonokaMiku::TW3_Dctx::encrypt_setup(const char* filename, void* hdr_out, int force_version) { TW3_Dctx* dctx = new TW3_Dctx; - setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(3), 1051, filename, hdr_out, force_version); + setupEncryptV3(dctx, GetPrefixFromGameType(HONOKAMIKU_GAMETYPE_TW), 1051, filename, hdr_out, force_version); return dctx; } diff --git a/src/V2_Decrypter.cc b/src/V2_Decrypter.cc index 8d1fd8e..930c3f1 100644 --- a/src/V2_Decrypter.cc +++ b/src/V2_Decrypter.cc @@ -172,7 +172,7 @@ void HonokaMiku::setupEncryptV2(V2_Dctx* dctx,const char* prefix,const char* fil mctx.Update(reinterpret_cast(basename), strlen(basename)); mctx.Final(); - memcpy(hdr_out,mctx.digestRaw+4,4); + memcpy(hdr_out,mctx.digestRaw + 4,4); dctx->init_key = ((mctx.digestRaw[0] & 0x7F) << 24) | (mctx.digestRaw[1] << 16) |