Skip to content

Commit

Permalink
Added CN3 encryption
Browse files Browse the repository at this point in the history
- Source: iebb@9f904b7

- It's unknown if it works for real SIF CNv3 assets file
  • Loading branch information
MikuAuahDark committed Nov 14, 2016
1 parent 2dc508c commit c70db96
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 23 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ DEBUG_MSV_CMD :=
NDK_DEBUG :=

# Files
GCC_FILES=V1_Decrypter.o V2_Decrypter.o V3_Decrypter.o EN_Decrypter.o JP_Decrypter.o Helper.o HonokaMiku.o
MSVC_FILES=V1_Decrypter.obj V2_Decrypter.obj V3_Decrypter.obj EN_Decrypter.obj JP_Decrypter.obj Helper.obj HonokaMiku.obj VersionInfo.res
GCC_FILES=V1_Decrypter.o V2_Decrypter.o V3_Decrypter.o EN_Decrypter.o JP_Decrypter.o CN_Decrypter.o Helper.o HonokaMiku.o
MSVC_FILES=V1_Decrypter.obj V2_Decrypter.obj V3_Decrypter.obj EN_Decrypter.obj JP_Decrypter.obj CN_Decrypter.obj Helper.obj HonokaMiku.obj VersionInfo.res

# Rules
all: honokamiku
Expand Down Expand Up @@ -96,6 +96,12 @@ clean:
# Object files
# .o for GCC
# .obj for MSVC
CN_Decrypter.o:
$(xPREFIX)g++ -c $(RELEASE_GCC_CMD) $(DEBUG_GCC_CMD) $(CXXFLAGS) src/CN_Decrypter.cc

CN_Decrypter.obj:
cl -nologo -W3 -Zc:wchar_t -Za $(RELEASE_MSV_CMD) -wd"4996" -D"WIN32" -D"_CONSOLE" -EHsc -c $(CFLAGS) src/CN_Decrypter.cc

EN_Decrypter.o:
$(xPREFIX)g++ -c $(RELEASE_GCC_CMD) $(DEBUG_GCC_CMD) $(CXXFLAGS) src/EN_Decrypter.cc

Expand Down
6 changes: 3 additions & 3 deletions VersionInfo.rc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#define _STR2(x) _DEPSTR1(x)

#define HONOKAMIKU_VERSION_MAJOR 4
#define HONOKAMIKU_VERSION_MINOR 0
#define HONOKAMIKU_VERSION_PATCH 2
#define HONOKAMIKU_VERSION_MINOR 1
#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 "4.0.2.0"
#define HONOKAMIKU_VERSION_STRING_RC "4.1.0.0"
#define HONOKAMIKU_VERSION ((HONOKAMIKU_VERSION_MAJOR*100000000)+(HONOKAMIKU_VERSION_MINOR*100000)+(HONOKAMIKU_VERSION_PATCH))

#ifdef RC_INVOKED
Expand Down
1 change: 1 addition & 0 deletions sln/HonokaMiku.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\CN_Decrypter.cc" />
<ClCompile Include="..\src\EN_Decrypter.cc" />
<ClCompile Include="..\src\Helper.cc" />
<ClCompile Include="..\src\HonokaMiku.cc" />
Expand Down
3 changes: 3 additions & 0 deletions sln/HonokaMiku.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<ClCompile Include="..\src\EN_Decrypter.cc">
<Filter>Decrypter</Filter>
</ClCompile>
<ClCompile Include="..\src\CN_Decrypter.cc">
<Filter>Decrypter</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\VersionInfo.rc" />
Expand Down
39 changes: 39 additions & 0 deletions src/CN_Decrypter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* CN_Decrypter.cc
* SIF CN game files related things
**/

#include "DecrypterContext.h"
static const unsigned int cn_key_tables[64] = {
0x1b695658u, 0x0a43a213u, 0x0ead0863u, 0x1400056du,
0xd470461du, 0xb6152300u, 0xfbe054bcu, 0x9ac9f112u,
0x23d3cab6u, 0xcd8fe028u, 0x6905bd74u, 0x01a3a612u,
0x6e96a579u, 0x333d7ad1u, 0xb6688bffu, 0x29160495u,
0xd7743bcfu, 0x8ede97bbu, 0xcacb7e8du, 0x24d81c23u,
0xdbfc6947u, 0xb07521c8u, 0xf506e2aeu, 0x3f48df2fu,
0x52beb172u, 0x695935e8u, 0x13e2a0a9u, 0xe2edf409u,
0x96cba5c1u, 0xdbb1e890u, 0x4c2af968u, 0x17fd17c6u,
0x1b9af5a8u, 0x97c0bc25u, 0x8413c879u, 0xd9b13fe1u,
0x4066a948u, 0x9662023au, 0x74a4feeeu, 0x1f24b4f6u,
0x637688c8u, 0x7a7ccf70u, 0x91042eecu, 0x57edd02cu,
0x666da2ddu, 0x92839de9u, 0x43baa9edu, 0x024a8e2cu,
0xd4ee7b72u, 0x34c18b72u, 0x13b275c4u, 0xed506a6eu,
0xbc1c29b9u, 0xfa66a220u, 0xc2364de3u, 0x767e52b2u,
0xe2d32439u, 0xe6f0cef5u, 0xd18c8687u, 0x14bba295u,
0xcd84d15bu, 0xa0290f82u, 0xd3e95afcu, 0x9c6a97b4u
};

HonokaMiku::CN3_Dctx::CN3_Dctx(const void* header, const char* filename): HonokaMiku::V3_Dctx(HonokaMiku::GetPrefixFromGameId(7), cn_key_tables, header, filename) {}


void HonokaMiku::CN3_Dctx::final_setup(const char* filename, const void* block_rest)
{
finalDecryptV3(this, 1847, filename, block_rest);
}

HonokaMiku::CN3_Dctx* HonokaMiku::CN3_Dctx::encrypt_setup(const char* filename,void* hdr_out)
{
CN3_Dctx* dctx = new CN3_Dctx;
setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(7), cn_key_tables, 1847, filename, hdr_out);
return dctx;
}
31 changes: 25 additions & 6 deletions src/DecrypterContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,24 @@ namespace HonokaMiku
void final_setup(const char* filename, const void* block_rest);
};

/// Chinese SIF decrypter context (Version 3)
class CN3_Dctx: public V3_Dctx
{
protected:
inline CN3_Dctx() {}
public:
/// \brief Initialize SIF CN decrypter context (version 3)
/// \param header The first 4-bytes contents of the file
/// \param filename File name that want to be decrypted. This affects the key calculation.
/// \exception std::runtime_error The header does not match and this decrypter context can't decrypt it.
CN3_Dctx(const void* header, const char* filename);
/// \brief Creates SIF CN decrypter context specialized for encryption. (version 3)
/// \param filename File name that want to be encrypted. This affects the key calculation.
/// \param hdr_out Pointer with size of 16-bytes to store the file header.
static CN3_Dctx* encrypt_setup(const char* filename, void* hdr_out);
void final_setup(const char* filename, const void* block_rest);
};

/// International SIF decrypter context
class EN2_Dctx:public V2_Dctx
{
Expand Down Expand Up @@ -229,22 +247,22 @@ namespace HonokaMiku

/// Simplified Chinese SIF decrypter context.
/// It has longest prefix key currently
class CN_Dctx: public V2_Dctx
class CN2_Dctx: public V2_Dctx
{
protected:
CN_Dctx():V2_Dctx() {}
CN2_Dctx():V2_Dctx() {}
public:
/// \brief Initialize SIF CN decrypter context
/// \param header The first 4-bytes contents of the file
/// \param filename File name that want to be decrypted. This affects the key calculation.
/// \exception std::runtime_error The header does not match and this decrypter context can't decrypt it.
CN_Dctx(const void* header, const char* filename):V2_Dctx("iLbs0LpvJrXm3zjdhAr4", header, filename) {}
CN2_Dctx(const void* header, const char* filename):V2_Dctx("iLbs0LpvJrXm3zjdhAr4", header, filename) {}
/// \brief Creates SIF CN decrypter context specialized for encryption.
/// \param filename File name that want to be encrypted. This affects the key calculation.
/// \param hdr_out Pointer with size of 16-bytes to store the file header.
inline static CN_Dctx* encrypt_setup(const char* filename, void* hdr_out)
inline static CN2_Dctx* encrypt_setup(const char* filename, void* hdr_out)
{
CN_Dctx* dctx=new CN_Dctx();
CN2_Dctx* dctx=new CN2_Dctx();
setupEncryptV2(dctx, "iLbs0LpvJrXm3zjdhAr4", filename,hdr_out);
return dctx;
}
Expand Down Expand Up @@ -288,7 +306,8 @@ namespace HonokaMiku
case 2:
case 4: return "Hello";
case 3: return "M2o2B7i3M6o6N88";
case 5: return "iLbs0LpvJrXm3zjdhAr4";
case 5:
case 7: return "iLbs0LpvJrXm3zjdhAr4";
default: return NULL;
}
}
Expand Down
18 changes: 15 additions & 3 deletions src/Helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,19 @@ HonokaMiku::DecrypterContext* HonokaMiku::FindSuitable(const char* filename, con
{
try
{
dctx = new CN_Dctx(header, filename);
dctx = new CN2_Dctx(header, filename);
*game_type = 5;
}
catch(std::runtime_error)
{
try
{
dctx = new CN3_Dctx(header, filename);
*game_type = 7;
}
catch(std::runtime_error)
{
}
}
}
}
Expand All @@ -83,9 +91,11 @@ HonokaMiku::DecrypterContext* HonokaMiku::CreateFrom(char game_id, const void* h
case 4:
return new JP2_Dctx(header, filename);
case 5:
return new CN_Dctx(header, filename);
return new CN2_Dctx(header, filename);
case 6:
return new EN3_Dctx(header, filename);
case 7:
return new CN3_Dctx(header, filename);
default:
return NULL;
}
Expand All @@ -109,9 +119,11 @@ HonokaMiku::DecrypterContext* HonokaMiku::EncryptPrepare(char game_id, const cha
case 4:
return JP2_Dctx::encrypt_setup(filename, header_out);
case 5:
return CN_Dctx::encrypt_setup(filename, header_out);
return CN2_Dctx::encrypt_setup(filename, header_out);
case 6:
return EN3_Dctx::encrypt_setup(filename, header_out);
case 7:
return CN3_Dctx::encrypt_setup(filename, header_out);
default:
return NULL;
}
Expand Down
25 changes: 16 additions & 9 deletions src/HonokaMiku.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
#include "CompilerName.h"
#include "../VersionInfo.rc"

// Actually this is `strnicmp` implementation in MSVCRT v110
// Copyright Microsoft Corporation.
// Copied from MSVC strnicmp.c
int msvcr110_strnicmp (const char * first, const char * last, size_t count)
{
if(count)
Expand Down Expand Up @@ -62,8 +61,8 @@ static char usage_string[] =
" -b<name> Use basename <name> as decrypt/encrypt\n"
" --basename<name> key. Required if reading from stdin.\n"
"\n"
" -c Assume <input file> is SIF CN game file.\n"
" --sif-cn\n"
" -c[3] Assume <input file> is SIF CN game file.\n"
" --sif-cn[-v3]"
"\n"
" -d Detect game file type only. [output file]\n"
" --detect and the other parameters is omitted.\n"
Expand Down Expand Up @@ -116,10 +115,12 @@ char get_gametype(const char* a)
return 4;
else if(msvcr110_strnicmp(a, "j3", 3) == 0 || msvcr110_strnicmp(a, "sif-jp-v3", 10) == 0)
return 2;
else if(msvcr110_strnicmp(a,"t",2)==0 || msvcr110_strnicmp(a,"sif-tw",7)==0)
else if(msvcr110_strnicmp(a, "t", 2) == 0 || msvcr110_strnicmp(a, "sif-tw", 7) == 0)
return 3;
else if(msvcr110_strnicmp(a,"c",2)==0 || msvcr110_strnicmp(a,"sif-cn",7)==0)
else if(msvcr110_strnicmp(a, "c", 2) == 0 || msvcr110_strnicmp(a, "sif-cn", 7) == 0)
return 5;
else if(msvcr110_strnicmp(a, "c3", 3) == 0 || msvcr110_strnicmp(a, "sif-cn-v3", 10) == 0)
return 7;
return 0;
}

Expand All @@ -136,9 +137,11 @@ const char* gameid_to_string(char gameid)
case 4:
return "JP (Version 2) game file";
case 5:
return "CN game file";
return "CN (Version 2) game file";
case 6:
return "EN (Version 3) game file";
case 7:
return "CN (Version 3) game file";
default:
return "Unknown";
}
Expand All @@ -157,6 +160,7 @@ const char* gameid_to_string_v1(char gameid)
case 3:
return "TW game file";
case 5:
case 7:
return "CN game file";
default:
return "Unknown";
Expand Down Expand Up @@ -244,7 +248,10 @@ void parse_args(int argc,char* argv[])
g_Basename = argv[i] + 2;
}
else if(s == 'c')
g_DecryptGame = 5;
if(argv[i][2] == '3')
g_DecryptGame = 7;
else
g_DecryptGame = 5;

else if(s == 'd')
g_TestMode = true;
Expand Down Expand Up @@ -681,4 +688,4 @@ int main(int argc, char* argv[])
delete dctx;

return 0;
}
}
5 changes: 5 additions & 0 deletions src/V1_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

#include <stdint.h>

// Mac OS fix
#include <string>
#include <sstream>
#include <iostream>

#include "DecrypterContext.h"
#include "md5.h"

Expand Down
5 changes: 5 additions & 0 deletions src/V2_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#include <stdexcept>
#include <cstring>

// Mac OS fix
#include <string>
#include <sstream>
#include <iostream>

#include "DecrypterContext.h"
#include "md5.h"

Expand Down
5 changes: 5 additions & 0 deletions src/V3_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include <stdexcept>
#include <cstring>

// Mac OS fix
#include <string>
#include <sstream>
#include <iostream>

#include "DecrypterContext.h"
#include "md5.h"

Expand Down

0 comments on commit c70db96

Please sign in to comment.