Skip to content

Commit

Permalink
Make parameter handling much more intuitive
Browse files Browse the repository at this point in the history
Now a single file or a directory can be provided, and the
application does its best to locate the required content.
  • Loading branch information
VitaSmith committed Dec 5, 2020
1 parent c541dae commit bb02703
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
8 changes: 4 additions & 4 deletions .vs/cdecrypt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;AES_ROM_TABLES;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;AES_ROM_TABLES;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4200;4201</DisableSpecificWarnings>
Expand All @@ -132,7 +132,7 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;AES_ROM_TABLES;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;AES_ROM_TABLES;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DisableSpecificWarnings>4200;4201</DisableSpecificWarnings>
Expand All @@ -151,7 +151,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;AES_ROM_TABLES;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;AES_ROM_TABLES;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4200;4201</DisableSpecificWarnings>
Expand All @@ -172,7 +172,7 @@
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;AES_ROM_TABLES;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;AES_ROM_TABLES;WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<DisableSpecificWarnings>4200;4201</DisableSpecificWarnings>
Expand Down
78 changes: 69 additions & 9 deletions cdecrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@

#define MAX_ENTRIES 90000
#define MAX_LEVELS 16
#define FST_MAGIC ((uint32_t)'FST\0')
#define FST_MAGIC 0x46535400 // 'FST\0'
// We use part of the root cert name used by TMD/TIK to identify them
#define TMD_MAGIC 0x4350303030303030ULL // 'CP000000'
#define TIK_MAGIC 0x5853303030303030ULL // 'XS000000'
#define T_MAGIC_OFFSET 0x0150
#define HASH_BLOCK_SIZE 0xFC00
#define HASHES_SIZE 0x0400

Expand All @@ -51,7 +55,7 @@ uint64_t h0_fail = 0;

enum ContentType
{
CONTENT_REQUIRED = (1 << 0), // not sure
CONTENT_REQUIRED = (1 << 0), // Not sure
CONTENT_SHARED = (1 << 15),
CONTENT_OPTIONAL = (1 << 14),
};
Expand Down Expand Up @@ -348,24 +352,78 @@ static bool extract_file(FILE* src, uint64_t part_data_offset, uint64_t file_off
int main_utf8(int argc, char** argv)
{
int r = EXIT_FAILURE;
char str[1024];
char str[MAX_PATH], *tmd_path = NULL, *tik_path = NULL;
FILE* src = NULL;
TitleMetaData* tmd = NULL;
uint8_t *tik = NULL, *cnt = NULL;

if (argc != 3) {
printf("%s %s (c) 2013-2015 crediar, (c) 2020 VitaSmith\n\n"
"Usage: %s <title.tmd> <title.tik>\n\n"
"Decrypt Wii U NUS content files.\n\n",
if (argc < 2) {
printf("%s %s - Wii U NUS content file decrypter\n"
"Copyright (c) 2013-2015 crediar, Copyright (c) 2020 VitaSmith\n"
"Visit https://github.com/VitaSmith/cdecrypt for official source and downloads.\n\n"
"Usage: %s <file or directory>\n\n"
"This program is free software; you can redistribute it and/or modify it under\n"
"the terms of the GNU General Public License as published by the Free Software\n"
"Foundation; either version 3 of the License or any later version.\n",
appname(argv[0]), APP_VERSION_STR, appname(argv[0]));
return EXIT_SUCCESS;
}

uint32_t tmd_len = read_file(argv[1], (uint8_t**)&tmd);
if (!is_directory(argv[1])) {
uint8_t* buf = NULL;
uint32_t size = read_file_max(argv[1], &buf, T_MAGIC_OFFSET + sizeof(uint64_t));
if (size == 0)
goto out;
if (size >= T_MAGIC_OFFSET + sizeof(uint64_t)) {
uint64_t magic = getbe64(&buf[T_MAGIC_OFFSET]);
free(buf);
if (magic == TMD_MAGIC) {
tmd_path = strdup(argv[1]);
if (argc < 3) {
tik_path = strdup(argv[1]);
tik_path[strlen(tik_path) - 2] = 'i';
tik_path[strlen(tik_path) - 1] = 'k';
}
else {
tik_path = strdup(argv[2]);
}
} else if (magic == TIK_MAGIC) {
tik_path = strdup(argv[1]);
if (argc < 3) {
tmd_path = strdup(argv[1]);
tmd_path[strlen(tik_path) - 2] = 'm';
tmd_path[strlen(tik_path) - 1] = 'd';
}
else {
tmd_path = strdup(argv[2]);
}
}
}

// File too small or without expected magic
if ((tmd_path == NULL) || (tik_path == NULL)) {
argv[1][get_trailing_slash(argv[1])] = 0;
if (argv[1][0] == 0) {
argv[1][0] = '.';
argv[1][1] = 0;
}
}
}

// If the condition below is true, argv[1] is a directory
if ((tmd_path == NULL) || (tik_path == NULL)) {
size_t size = strlen(argv[1]);
tmd_path = calloc(size + 10, 1);
tik_path = calloc(size + 10, 1);
sprintf(tmd_path, "%s%ctitle.tmd", argv[1], PATH_SEP);
sprintf(tik_path, "%s%ctitle.tik", argv[1], PATH_SEP);
}

uint32_t tmd_len = read_file(tmd_path, (uint8_t**)&tmd);
if (tmd_len == 0)
goto out;

uint32_t tik_len = read_file(argv[2], &tik);
uint32_t tik_len = read_file(tik_path, &tik);
if (tik_len == 0)
goto out;

Expand Down Expand Up @@ -512,6 +570,8 @@ int main_utf8(int argc, char** argv)
free(tmd);
free(tik);
free(cnt);
free(tmd_path);
free(tik_path);
if (src != NULL)
fclose(src);
return r;
Expand Down
18 changes: 17 additions & 1 deletion util.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ size_t get_trailing_slash(const char* path)
return (i == 0) ? 0: i + 1;
}

uint32_t read_file(const char* path, uint8_t** buf)
uint32_t read_file_max(const char* path, uint8_t** buf, uint32_t max_size)
{
FILE* file = fopen_utf8(path, "rb");
if (file == NULL) {
Expand All @@ -105,6 +105,8 @@ uint32_t read_file(const char* path, uint8_t** buf)
fseek(file, 0L, SEEK_END);
uint32_t size = (uint32_t)ftell(file);
fseek(file, 0L, SEEK_SET);
if (max_size != 0)
size = min(size, max_size);

*buf = calloc(size, 1);
if (*buf == NULL) {
Expand All @@ -124,6 +126,20 @@ uint32_t read_file(const char* path, uint8_t** buf)
return size;
}

uint64_t get_file_size(const char* path)
{
FILE* file = fopen_utf8(path, "rb");
if (file == NULL) {
fprintf(stderr, "ERROR: Can't open '%s'\n", path);
return 0;
}

fseek(file, 0L, SEEK_END);
uint64_t size = ftell64(file);
fclose(file);
return size;
}

void create_backup(const char* path)
{
struct stat64 st;
Expand Down
8 changes: 7 additions & 1 deletion util.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
#define PATH_SEP '/'
#endif

#ifndef MAX_PATH
#define MAX_PATH 256
#endif

#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
Expand Down Expand Up @@ -206,6 +210,8 @@ size_t get_trailing_slash(const char* path);
bool is_file(const char* path);
bool is_directory(const char* path);

uint32_t read_file(const char* path, uint8_t** buf);
uint32_t read_file_max(const char* path, uint8_t** buf, uint32_t max_size);
#define read_file(path, buf) read_file_max(path, buf, 0)
uint64_t get_file_size(const char* path);
void create_backup(const char* path);
bool write_file(const uint8_t* buf, const uint32_t size, const char* path, const bool backup);

0 comments on commit bb02703

Please sign in to comment.