diff --git a/NDecrypt/DSTool.cs b/NDecrypt/DSTool.cs index 5187e32..8a0183f 100644 --- a/NDecrypt/DSTool.cs +++ b/NDecrypt/DSTool.cs @@ -16,10 +16,16 @@ namespace NDecrypt /// private readonly bool encrypt; - public DSTool(string filename, bool encrypt) + /// + /// Flag to determine if forcing operations + /// + private readonly bool force; + + public DSTool(string filename, bool encrypt, bool force) { this.filename = filename; this.encrypt = encrypt; + this.force = force; } /// @@ -44,7 +50,7 @@ namespace NDecrypt } // Process the secure area - header.ProcessSecureArea(reader, writer, encrypt); + header.ProcessSecureArea(reader, writer, encrypt, force); } return true; diff --git a/NDecrypt/Headers/NCCHHeader.cs b/NDecrypt/Headers/NCCHHeader.cs index 4df4471..08e4b5e 100644 --- a/NDecrypt/Headers/NCCHHeader.cs +++ b/NDecrypt/Headers/NCCHHeader.cs @@ -255,10 +255,16 @@ namespace NDecrypt.Headers /// NCSD header representing the 3DS file /// True if we want to encrypt the partitions, false otherwise /// True if development keys should be used, false otherwise - public void ProcessPartition(BinaryReader reader, BinaryWriter writer, NCSDHeader header, bool encrypt, bool development) + /// True if we want to force the operation, false otherwise + public void ProcessPartition(BinaryReader reader, BinaryWriter writer, NCSDHeader header, bool encrypt, bool development, bool force) { - // Check if the 'NoCrypto' bit is set - if (Flags.PossblyDecrypted ^ encrypt) + // If we're forcing the operation, tell the user + if (force) + { + Console.WriteLine($"Partition {PartitionNumber} is not verified due to force flag being set."); + } + // If we're not forcing the operation, check if the 'NoCrypto' bit is set + else if (Flags.PossblyDecrypted ^ encrypt) { Console.WriteLine($"Partition {PartitionNumber}: Already " + (encrypt ? "Encrypted" : "Decrypted") + "?..."); return; diff --git a/NDecrypt/Headers/NCSDHeader.cs b/NDecrypt/Headers/NCSDHeader.cs index 3cf236d..8a0e81e 100644 --- a/NDecrypt/Headers/NCSDHeader.cs +++ b/NDecrypt/Headers/NCSDHeader.cs @@ -330,7 +330,8 @@ namespace NDecrypt.Headers /// BinaryWriter representing the output stream /// True if we want to encrypt the partitions, false otherwise /// True if development keys should be used, false otherwise - public void ProcessAllPartitions(BinaryReader reader, BinaryWriter writer, bool encrypt, bool development) + /// True if we want to force the operation, false otherwise + public void ProcessAllPartitions(BinaryReader reader, BinaryWriter writer, bool encrypt, bool development, bool force) { // Iterate over all 8 NCCH partitions for (int p = 0; p < 8; p++) @@ -339,7 +340,7 @@ namespace NDecrypt.Headers if (partitionHeader == null) continue; - partitionHeader.ProcessPartition(reader, writer, this, encrypt, development); + partitionHeader.ProcessPartition(reader, writer, this, encrypt, development, force); } } diff --git a/NDecrypt/Headers/NDSHeader.cs b/NDecrypt/Headers/NDSHeader.cs index c3a0a52..d231027 100644 --- a/NDecrypt/Headers/NDSHeader.cs +++ b/NDecrypt/Headers/NDSHeader.cs @@ -591,18 +591,28 @@ namespace NDecrypt.Headers /// BinaryReader representing the input stream /// BinaryWriter representing the output stream /// True if we want to encrypt the partitions, false otherwise - public void ProcessSecureArea(BinaryReader reader, BinaryWriter writer, bool encrypt) + /// True if we want to force the operation, false otherwise + public void ProcessSecureArea(BinaryReader reader, BinaryWriter writer, bool encrypt, bool force) { - bool? isDecrypted = CheckIfDecrypted(reader); - if (isDecrypted == null) + // If we're forcing the operation, tell the user + if (force) { - Console.WriteLine("File has an empty secure area, cannot proceed"); - return; + Console.WriteLine("File is not verified due to force flag being set."); } - else if (encrypt ^ isDecrypted.Value) + // If we're not forcing the operation, check to see if we should be proceeding + else { - Console.WriteLine("File is already " + (encrypt ? "encrypted" : "decrypted")); - return; + bool? isDecrypted = CheckIfDecrypted(reader); + if (isDecrypted == null) + { + Console.WriteLine("File has an empty secure area, cannot proceed"); + return; + } + else if (encrypt ^ isDecrypted.Value) + { + Console.WriteLine("File is already " + (encrypt ? "encrypted" : "decrypted")); + return; + } } ProcessARM9(reader, writer, encrypt); diff --git a/NDecrypt/Program.cs b/NDecrypt/Program.cs index ade24bb..545656f 100644 --- a/NDecrypt/Program.cs +++ b/NDecrypt/Program.cs @@ -29,12 +29,18 @@ namespace NDecrypt return; } - bool development = false; + bool development = false, force = false; int start = 1; - if (args[1] == "-dev") + for ( ; start < args.Length; start++) { - development = true; - start = 2; + if (args[start] == "-dev" || args[start] == "--development") + development = true; + + else if (args[start] == "-f" || args[start] == "--force") + force = true; + + else + break; } // Ensure the constants are all set @@ -49,7 +55,7 @@ namespace NDecrypt { if (File.Exists(args[i])) { - ITool tool = DeriveTool(args[i], encrypt.Value, development); + ITool tool = DeriveTool(args[i], encrypt.Value, development, force); if (tool?.ProcessFile() != true) Console.WriteLine("Processing failed!"); } @@ -57,7 +63,7 @@ namespace NDecrypt { foreach (string file in Directory.EnumerateFiles(args[i], "*", SearchOption.AllDirectories)) { - ITool tool = DeriveTool(file, encrypt.Value, development); + ITool tool = DeriveTool(file, encrypt.Value, development, force); if (tool?.ProcessFile() != true) Console.WriteLine("Processing failed!"); } @@ -77,7 +83,7 @@ namespace NDecrypt if (!string.IsNullOrWhiteSpace(err)) Console.WriteLine($"Error: {err}"); - Console.WriteLine("Usage: NDecrypt.exe (decrypt|encrypt) [-dev] ..."); + Console.WriteLine("Usage: NDecrypt.exe (decrypt|encrypt) [-dev] [-f] ..."); } private enum RomType @@ -93,18 +99,19 @@ namespace NDecrypt /// /// Filename to derive the tool from /// True if we are encrypting the file, false otherwise - /// rue if we are using development keys, false otherwise + /// True if we are using development keys, false otherwise + /// True if operations should be forced, false otherwise /// - private static ITool DeriveTool(string filename, bool encrypt, bool development) + private static ITool DeriveTool(string filename, bool encrypt, bool development, bool force) { RomType type = DetermineRomType(filename); switch(type) { case RomType.NDS: case RomType.NDSi: - return new DSTool(filename, encrypt); + return new DSTool(filename, encrypt, force); case RomType.N3DS: - return new ThreeDSTool(filename, development, encrypt); + return new ThreeDSTool(filename, development, encrypt, force); case RomType.NULL: default: Console.WriteLine($"Unrecognized file format for {filename}. Expected *.nds, *.srl, *.dsi, *.3ds"); diff --git a/NDecrypt/ThreeDSTool.cs b/NDecrypt/ThreeDSTool.cs index fb1c793..981b9b2 100644 --- a/NDecrypt/ThreeDSTool.cs +++ b/NDecrypt/ThreeDSTool.cs @@ -21,11 +21,17 @@ namespace NDecrypt /// private readonly bool encrypt; - public ThreeDSTool(string filename, bool development, bool encrypt) + /// + /// Flag to determine if forcing operations + /// + private readonly bool force; + + public ThreeDSTool(string filename, bool development, bool encrypt, bool force) { this.filename = filename; this.development = development; this.encrypt = encrypt; + this.force = force; } /// @@ -50,7 +56,7 @@ namespace NDecrypt } // Process all 8 NCCH partitions - header.ProcessAllPartitions(reader, writer, encrypt, development); + header.ProcessAllPartitions(reader, writer, encrypt, development, force); } return true;