From b83293e8c91f11f6ee2c766ea1c8e15a0a7f216d Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sun, 7 Apr 2019 03:04:05 -0700 Subject: [PATCH] Fix encrypt --- 3DSDecrypt/Headers/ExeFSFileHeader.cs | 10 +++++-- 3DSDecrypt/ThreeDSTool.cs | 43 ++++++++++++++------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/3DSDecrypt/Headers/ExeFSFileHeader.cs b/3DSDecrypt/Headers/ExeFSFileHeader.cs index 20a64f1..75b594f 100644 --- a/3DSDecrypt/Headers/ExeFSFileHeader.cs +++ b/3DSDecrypt/Headers/ExeFSFileHeader.cs @@ -1,13 +1,17 @@ using System.IO; +using System.Linq; +using System.Text; namespace ThreeDS.Headers { public class ExeFSFileHeader { private const string codeSegment = ".code\0\0\0"; + private readonly byte[] codeSegmentBytes = new byte[] { 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x00 }; - public string FileName; - public bool IsCodeBinary { get { return FileName == codeSegment; } } + public byte[] FileName = new byte[8]; + public string ReadableFileName { get { return Encoding.ASCII.GetString(FileName); } } + public bool IsCodeBinary { get { return Enumerable.SequenceEqual(FileName, codeSegmentBytes); } } public uint FileOffset; public uint FileSize; public byte[] FileHash = new byte[0x20]; @@ -18,7 +22,7 @@ namespace ThreeDS.Headers try { - header.FileName = new string(reader.ReadChars(8)); + header.FileName = reader.ReadBytes(8); header.FileOffset = reader.ReadUInt32(); header.FileSize = reader.ReadUInt32(); return header; diff --git a/3DSDecrypt/ThreeDSTool.cs b/3DSDecrypt/ThreeDSTool.cs index d0799c1..8d2ab0f 100644 --- a/3DSDecrypt/ThreeDSTool.cs +++ b/3DSDecrypt/ThreeDSTool.cs @@ -177,7 +177,7 @@ namespace ThreeDS { g.Write(exefsctrmode2C.ProcessBytes(exefsctrmode.ProcessBytes(f.ReadBytes(1024 * 1024)))); g.Flush(); - Console.Write("\rPartition {0} ExeFS: Decrypting: {1}... {2} / {3} mb...", p, fileHeader.FileName, i, datalenM + 1); + Console.Write("\rPartition {0} ExeFS: Decrypting: {1}... {2} / {3} mb...", p, fileHeader.ReadableFileName, i, datalenM + 1); } } @@ -187,7 +187,7 @@ namespace ThreeDS g.Flush(); } - Console.Write("\rPartition {0} ExeFS: Decrypting: {1}... {2} / {3} mb... Done!\r\n", p, fileHeader.FileName, datalenM + 1, datalenM + 1); + Console.Write("\rPartition {0} ExeFS: Decrypting: {1}... {2} / {3} mb... Done!\r\n", p, fileHeader.ReadableFileName, datalenM + 1, datalenM + 1); } } } @@ -395,17 +395,6 @@ namespace ThreeDS // Encrypt the ExeFS, if it exists if (partitionHeader.ExeFSSizeInBytes > 0) { - f.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) * header.SectorSize, SeekOrigin.Begin); - g.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) * header.SectorSize, SeekOrigin.Begin); - - var exefsctrmode2C = CipherUtilities.GetCipher("AES/CTR"); - exefsctrmode2C.Init(true, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey2C)), exefsIV)); - - g.Write(exefsctrmode2C.ProcessBytes(f.ReadBytes((int)header.SectorSize))); - g.Flush(); - - Console.WriteLine("Partition {0} ExeFS: Encrypting: ExeFS Filename Table", p); - if (backupFlags.CryptoMethod != CryptoMethod.Original) { f.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) * header.SectorSize, SeekOrigin.Begin); @@ -426,7 +415,7 @@ namespace ThreeDS var exefsctrmode = CipherUtilities.GetCipher("AES/CTR"); exefsctrmode.Init(true, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey)), exefsIVWithOffsetForHeader)); - exefsctrmode2C = CipherUtilities.GetCipher("AES/CTR"); + var exefsctrmode2C = CipherUtilities.GetCipher("AES/CTR"); exefsctrmode2C.Init(false, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey2C)), exefsIVWithOffsetForHeader)); f.BaseStream.Seek((((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) + 1) * header.SectorSize) + fileHeader.FileOffset, SeekOrigin.Begin); @@ -438,7 +427,7 @@ namespace ThreeDS { g.Write(exefsctrmode2C.ProcessBytes(exefsctrmode.ProcessBytes(f.ReadBytes(1024 * 1024)))); g.Flush(); - Console.Write("\rPartition {0} ExeFS: Encrypting: {1}... {2} / {3} mb...", p, fileHeader.FileName, i, datalenM + 1); + Console.Write("\rPartition {0} ExeFS: Encrypting: {1}... {2} / {3} mb...", p, fileHeader.ReadableFileName, i, datalenM + 1); } } @@ -448,20 +437,32 @@ namespace ThreeDS g.Flush(); } - Console.Write("\rPartition {0} ExeFS: Encrypting: {1}... {2} / {3} mb... Done!\r\n", p, fileHeader.FileName, datalenM + 1, datalenM + 1); + Console.Write("\rPartition {0} ExeFS: Encrypting: {1}... {2} / {3} mb... Done!\r\n", p, fileHeader.ReadableFileName, datalenM + 1, datalenM + 1); } } } - // decrypt exefs + // encrypt exefs filename table + f.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) * header.SectorSize, SeekOrigin.Begin); + g.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits) * header.SectorSize, SeekOrigin.Begin); + + var exefsctrmode2C_2 = CipherUtilities.GetCipher("AES/CTR"); + exefsctrmode2C_2.Init(true, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey2C)), exefsIV)); + + g.Write(exefsctrmode2C_2.ProcessBytes(f.ReadBytes((int)header.SectorSize))); + g.Flush(); + + Console.WriteLine("Partition {0} ExeFS: Encrypting: ExeFS Filename Table", p); + + // encrypt exefs int exefsSizeM = (int)((partitionHeader.ExeFSSizeInMediaUnits - 1) * header.SectorSize) / (1024 * 1024); int exefsSizeB = (int)((partitionHeader.ExeFSSizeInMediaUnits - 1) * header.SectorSize) % (1024 * 1024); int ctroffsetE = (int)(header.SectorSize / 0x10); byte[] exefsIVWithOffset = AddToByteArray(exefsIV, ctroffsetE); - exefsctrmode2C = CipherUtilities.GetCipher("AES/CTR"); - exefsctrmode2C.Init(true, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey2C)), exefsIVWithOffset)); + exefsctrmode2C_2 = CipherUtilities.GetCipher("AES/CTR"); + exefsctrmode2C_2.Init(true, new ParametersWithIV(new KeyParameter(TakeSixteen(NormalKey2C)), exefsIVWithOffset)); f.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits + 1) * header.SectorSize, SeekOrigin.Begin); g.BaseStream.Seek((header.PartitionsTable[p].Offset + partitionHeader.ExeFSOffsetInMediaUnits + 1) * header.SectorSize, SeekOrigin.Begin); @@ -469,14 +470,14 @@ namespace ThreeDS { for (int i = 0; i < exefsSizeM; i++) { - g.Write(exefsctrmode2C.ProcessBytes(f.ReadBytes(1024 * 1024))); + g.Write(exefsctrmode2C_2.ProcessBytes(f.ReadBytes(1024 * 1024))); g.Flush(); Console.Write("\rPartition {0} ExeFS: Encrypting: {1} / {2} mb", p, i, exefsSizeM + 1); } } if (exefsSizeB > 0) { - g.Write(exefsctrmode2C.DoFinal(f.ReadBytes(exefsSizeB))); + g.Write(exefsctrmode2C_2.DoFinal(f.ReadBytes(exefsSizeB))); g.Flush(); }