Skip to content

Commit

Permalink
Fixed SIF EN v3 encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
MikuAuahDark committed Sep 30, 2016
1 parent 40c04e3 commit 5d56b3e
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 84 deletions.
6 changes: 3 additions & 3 deletions VersionInfo.rc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

#define HONOKAMIKU_VERSION_MAJOR 4
#define HONOKAMIKU_VERSION_MINOR 0
#define HONOKAMIKU_VERSION_PATCH 0
#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_RC "4.0.0.0"
#define HONOKAMIKU_VERSION ((HONOKAMIKU_VERSION_MAJOR*10000)+(HONOKAMIKU_VERSION_MINOR*100)+(HONOKAMIKU_VERSION_PATCH))
#define HONOKAMIKU_VERSION_STRING_RC "4.0.1.0"
#define HONOKAMIKU_VERSION ((HONOKAMIKU_VERSION_MAJOR*100000000)+(HONOKAMIKU_VERSION_MINOR*100000)+(HONOKAMIKU_VERSION_PATCH))

#ifdef RC_INVOKED

Expand Down
12 changes: 6 additions & 6 deletions src/DecrypterContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace HonokaMiku
/// For encrypt_setup static members for SIF EN, TW, KR, and CN. Used internally
void setupEncryptV2(V2_Dctx* dctx, const char* prefix, const char* filename, void* hdr_out);
/// For encrypt_setup static members for SIF JP and EN (Version 3). Used internally
void setupEncryptV3(V3_Dctx* dctx, const char* prefix, const unsigned int* key_tables, const char* filename, void* hdr_out);
void setupEncryptV3(V3_Dctx* dctx, const char* prefix, const unsigned int* key_tables, unsigned short name_sum_base, const char* filename, void* hdr_out);
/// To finalize version 3 decrypter
void finalDecryptV3(V3_Dctx* dctx, unsigned int expected_sum_name, const char* filename, const void* block_rest);

Expand Down Expand Up @@ -121,8 +121,8 @@ namespace HonokaMiku
static V3_Dctx* encrypt_setup(const char* prefix, const unsigned int* key_tables, const char* filename, void* hdr_out);
virtual void final_setup(const char* , const void* ) = 0;

friend void setupEncryptV3(V3_Dctx* dctx, const char* prefix, const unsigned int* key_tables, const char* filename, void* hdr_out);
friend void finalDecryptV3(V3_Dctx* dctx, unsigned int expected_sum_name, const char* filename, const void* block_rest);
friend void setupEncryptV3(V3_Dctx* , const char* , const unsigned int* , unsigned short , const char* , void* );
friend void finalDecryptV3(V3_Dctx* , unsigned int , const char* , const void* );
};

/// Japanese SIF decrypter context
Expand Down Expand Up @@ -206,7 +206,7 @@ namespace HonokaMiku
};

/// SIF JP decrypter version 2
class JP2_Dctx:public V2_Dctx
class JP2_Dctx: public V2_Dctx
{
protected:
JP2_Dctx():V2_Dctx() {}
Expand All @@ -229,7 +229,7 @@ namespace HonokaMiku

/// Simplified Chinese SIF decrypter context.
/// It has longest prefix key currently
class CN_Dctx:public V2_Dctx
class CN_Dctx: public V2_Dctx
{
protected:
CN_Dctx():V2_Dctx() {}
Expand All @@ -255,7 +255,7 @@ namespace HonokaMiku
typedef EN3_Dctx WW3_Dctx;
typedef JP2_Dctx KR_Dctx;

// Helper functions. GameID is used for libhonoka backward compatibility
// Helper functions.

/// \brief Creates decrypter context based from the given headers.
/// Returns decrypter context or NULL if no suitable decryption method is available.
Expand Down
2 changes: 1 addition & 1 deletion src/EN_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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)
{
EN3_Dctx* dctx = new EN3_Dctx;
setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(1), en_key_tables, filename, hdr_out);
setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(1), en_key_tables, 844, filename, hdr_out);
return dctx;
}
114 changes: 43 additions & 71 deletions src/HonokaMiku.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ static char usage_string[] =
" New decrypt option can't be specificed\n"
" if this option is specificed.\n"
"\n"
" -3 Select version 3 algorithm to decrypt\n"
" --newdecrypt or encrypt SIF EN or JP game files\n"
" Old decrypt option can't be specificed\n"
" if this option is specificed.\n"
"\n"
" -b<name> Use basename <name> as decrypt/encrypt\n"
" --basename<name> key. Required if reading from stdin.\n"
"\n"
Expand All @@ -81,18 +76,18 @@ static char usage_string[] =
" -?\n"
" --help\n"
"\n"
" -j Assume <input file> is SIF JP game file.\n"
" --sif-jp Defaults to version 2 algorithm.\n"
" -j[3] Assume <input file> is SIF JP game file.\n"
" --sif-jp[-v3]\n"
"\n"
" -t Assume <input file> is SIF TW game file.\n"
" --sif-tw\n"
"\n"
" -v Show version information.\n"
" --version\n"
"\n"
" -w Assume <input file> is SIF EN game file.\n"
" --sif-en Defaults to version 2 algorithm.\n"
" --sif-ww\n"
" -w[3] Assume <input file> is SIF EN game file.\n"
" --sif-en[-v3]\n"
" --sif-ww[-v3]\n"
"\n"
" -x<game> Cross-encrypt to another game file.\n"
" --cross-encrypt<game> <game> can be w, j, t, or c\n"
Expand All @@ -110,24 +105,17 @@ char g_XEncryptGame = 0; // 0 = cross-encryption not specificed; 1 = ww/en; 2 =
bool g_Encrypt = false; // Encrypt mode?
bool g_TestMode = false; // Detect only.
bool g_Version1 = false; // Encrypt/decrypt version 1 game files (SIF v1.x)
bool g_Version3 = false; // Use version 3 algorithm

char get_gametype(const char* a)
{
if(a[0] == 'w')
if(a[1] == '3')
return 6;
else
return 1;
else if(msvcr110_strnicmp(a,"sif-ww",7)==0 || msvcr110_strnicmp(a,"sif-en",7)==0)
if(msvcr110_strnicmp(a, "w", 2) == 0 || msvcr110_strnicmp(a, "sif-en", 7) == 0 || msvcr110_strnicmp(a, "sif-ww", 7) == 0)
return 1;
else if(a[0] == 'j')
if(a[1] == '3')
return 2;
else
return 4;
else if(msvcr110_strnicmp(a,"sif-jp",7)==0)
else if(msvcr110_strnicmp(a, "w3", 3) == 0 || msvcr110_strnicmp(a, "sif-en-v3", 10) == 0 || msvcr110_strnicmp(a, "sif-ww-v3", 10) == 0)
return 6;
else if(msvcr110_strnicmp(a, "j", 2) == 0 || msvcr110_strnicmp(a, "sif-jp", 7) == 0)
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)
return 3;
else if(msvcr110_strnicmp(a,"c",2)==0 || msvcr110_strnicmp(a,"sif-cn",7)==0)
Expand Down Expand Up @@ -156,6 +144,25 @@ const char* gameid_to_string(char gameid)
}
}

const char* gameid_to_string_v1(char gameid)
{
switch(gameid)
{
case 1:
case 6:
return "EN game file";
case 2:
case 4:
return "JP game file";
case 3:
return "TW game file";
case 5:
return "CN game file";
default:
return "Unknown";
}
}

void parse_args(int argc,char* argv[])
{
int i = 1;
Expand Down Expand Up @@ -205,44 +212,24 @@ void parse_args(int argc,char* argv[])
exit(0);
}

else if(msvcr110_strnicmp(start_arg, "newdecrypt", 10) == 0)
g_Version3 = true;

else if(msvcr110_strnicmp(start_arg, "olddecrypt", 10) == 0)
g_Version1 = true;

else if(msvcr110_strnicmp(start_arg, "sif-cn", 7) == 0)
g_DecryptGame = 5;

else if(msvcr110_strnicmp(start_arg, "sif-en", 7) == 0 ||
msvcr110_strnicmp(start_arg, "sif-ww", 6) == 0)
g_DecryptGame = 1;

else if(msvcr110_strnicmp(start_arg, "sif-jp", 7) == 0)
g_DecryptGame = 2;

else if(msvcr110_strnicmp(start_arg, "sif-tw", 7) == 0)
g_DecryptGame = 3;

else if(msvcr110_strnicmp(start_arg, "version", 8) == 0)
{
fputs("Version " HONOKAMIKU_VERSION_STRING "\n", stderr);
fprintf(stderr, "Version " HONOKAMIKU_VERSION_STRING " (%d)\n", HONOKAMIKU_VERSION);
fputs("Build at " __DATE__ " " __TIME__ "\n", stderr);
fprintf(stderr, "Compiled using %s\n\n", CompilerName());

exit(0);
}

else
else if((g_DecryptGame = get_gametype(start_arg)) == 0)
fprintf(stderr, "Ignoring %s\n", argv[i]);
}
// Short argument name parse
else if(s == '1')
g_Version1 = true;

else if(s == '3')
g_Version3 = true;

else if(s == 'b')
{
if(argv[i][2] == 0)
Expand Down Expand Up @@ -272,22 +259,28 @@ void parse_args(int argc,char* argv[])
}

else if(s == 'j')
g_DecryptGame = 2;
if(argv[i][2] == '3')
g_DecryptGame = 2;
else
g_DecryptGame = 4;

else if(s == 't')
g_DecryptGame = 3;

else if(s == 'v')
{
fputs("Version " HONOKAMIKU_VERSION_STRING "\n", stderr);
fprintf(stderr, "Version " HONOKAMIKU_VERSION_STRING " (%d)\n", HONOKAMIKU_VERSION);
fputs("Build at " __DATE__ " " __TIME__ "\n", stderr);
fprintf(stderr, "Compiled using %s\n\n", CompilerName());

exit(0);
}

else if(s == 'w')
g_DecryptGame = 1;
if(argv[i][2] == '3')
g_DecryptGame = 6;
else
g_DecryptGame = 1;

else if(s == 'x')
{
Expand Down Expand Up @@ -346,20 +339,6 @@ void check_args(char* argv[])
g_Basename = __DctxGetBasename(argv[g_InPos]);
}

if(g_Version3)
{
if(g_DecryptGame == 1)
g_DecryptGame = 6;
else if(g_DecryptGame > 2)
{
fputs("Warning: specificed game file does not support version 3 algorithm\n", stderr);
g_Version3 = false;
}
}
else
if(g_DecryptGame == 2)
g_DecryptGame = 4;

if(g_Version1 && g_DecryptGame == 0)
{
fputs("Error: version 1 decryption requires game file switch\n\n", stderr);
Expand All @@ -381,17 +360,10 @@ void check_args(char* argv[])

exit(EINVAL);
}
else if(g_Version1 && g_Version3)
{
fputs("Error: --olddecrypt and --newdecrypt both can't be specificed\n\n", stderr);
fprintf(stderr, usage_string, g_ProgramName);

exit(EINVAL);
}

if(g_Encrypt && g_Version1)
{
fputs("Warning: encrypt mode option ignored\n", stderr);
fputs("Warning: encrypt mode option ignored for version 1\n", stderr);
g_Encrypt = false;
}
}
Expand Down Expand Up @@ -513,7 +485,7 @@ int main(int argc, char* argv[])
{
if(g_Version1)
{
fprintf(stderr, "Version 1 decrypt: %s\n", gameid_to_string(g_DecryptGame));
fprintf(stderr, "Version 1 decrypt: %s\n", gameid_to_string_v1(g_DecryptGame));

dctx = new HonokaMiku::V1_Dctx(HonokaMiku::GetPrefixFromGameId(g_DecryptGame), g_Basename);
}
Expand Down
2 changes: 1 addition & 1 deletion src/JP_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,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)
{
JP3_Dctx* dctx = new JP3_Dctx;
setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(2), jp_key_tables, filename, hdr_out);
setupEncryptV3(dctx, HonokaMiku::GetPrefixFromGameId(2), jp_key_tables, 500, filename, hdr_out);
return dctx;
}
4 changes: 2 additions & 2 deletions src/V3_Decrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ void HonokaMiku::finalDecryptV3(V3_Dctx* dctx, unsigned int expected_sum_name, c
}
}

void HonokaMiku::setupEncryptV3(HonokaMiku::V3_Dctx* dctx, const char* prefix, const unsigned int* key_tables, const char* filename, void* hdr_out)
void HonokaMiku::setupEncryptV3(HonokaMiku::V3_Dctx* dctx, const char* prefix, const unsigned int* key_tables, unsigned short name_sum_base, const char* filename, void* hdr_out)
{
MD5 mctx;
const char* basename=__DctxGetBasename(filename);
uint8_t hdr_create[16];
uint8_t digcopy[3];
uint16_t key_picker=500;
uint16_t key_picker=name_sum_base;

mctx.Init();
mctx.Update(reinterpret_cast<const uint8_t*>(prefix), strlen(prefix));
Expand Down

0 comments on commit 5d56b3e

Please sign in to comment.