From f26671db85d34578f6ad02f5b849d88120d18c95 Mon Sep 17 00:00:00 2001 From: n2460 Date: Wed, 19 Oct 2011 08:51:52 +0000 Subject: [PATCH] =?UTF-8?q?TwlBkpCheck/Windows:=E3=83=98=E3=83=83=E3=83=80?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=81=AE=E6=9B=B4=E6=96=B0(=E4=BB=8A?= =?UTF-8?q?=E3=81=BE=E3=81=A7=E3=81=AE=E3=81=AF=20Legacy=20=E3=81=A8?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=82=AF=E3=83=A9=E3=82=B9=E5=88=86=E3=81=91?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_test_tools@27 6b0af911-cb57-b745-895f-eec5701120e1 --- .../{Program.cs => FalsifyTwlBackup.cs} | 102 +++++----- .../FalsifyTwlBackup/FalsifyTwlBackup.csproj | 2 +- .../Windows/TWLBackupBlock/ExtBinaryReader.cs | 12 ++ .../Windows/TWLBackupBlock/HeaderBody.cs | 105 ++-------- .../TWLBackupBlock/LegacyHeaderBody.cs | 185 ++++++++++++++++++ .../Windows/TWLBackupBlock/SignatureBody.cs | 11 +- .../Windows/TWLBackupBlock/TmdReserved.cs | 82 ++++++++ .../TWLBackupBlock/TwlBackupBlock.csproj | 2 + TwlBkpCheck/Windows/TWLBackupBlock/Utility.cs | 49 +++-- 9 files changed, 394 insertions(+), 156 deletions(-) rename TwlBkpCheck/Windows/FalsifyTwlBackup/{Program.cs => FalsifyTwlBackup.cs} (93%) create mode 100644 TwlBkpCheck/Windows/TWLBackupBlock/LegacyHeaderBody.cs create mode 100644 TwlBkpCheck/Windows/TWLBackupBlock/TmdReserved.cs diff --git a/TwlBkpCheck/Windows/FalsifyTwlBackup/Program.cs b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.cs similarity index 93% rename from TwlBkpCheck/Windows/FalsifyTwlBackup/Program.cs rename to TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.cs index 5ba6a74..f20ac5d 100644 --- a/TwlBkpCheck/Windows/FalsifyTwlBackup/Program.cs +++ b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.cs @@ -49,6 +49,7 @@ namespace FalsifyTwlBackup private const int CAT300 = 3; private const int CAT400 = 4; private const int CAT500 = 5; + private const int VERIFY = 9; // TORIAEZU : 上記が Mode == Pattern なのが引っかかる・・・ // 各カテゴリでの最大番号 private const int MAX_OF_CAT100 = 118; @@ -90,8 +91,9 @@ namespace FalsifyTwlBackup Console.WriteLine(" -all (default) : output all falsifying pattern"); Console.WriteLine(" -cat CAT_NUM : output all pattern of CAT_NUM category"); Console.WriteLine(" ex) -cat 100 -> falsifying 100,101,102...."); - Console.WriteLine(" -each PAT_NUM : output PAT_NUM pattern "); + Console.WriteLine(" -each PAT_NUM : output PAT_NUM pattern"); Console.WriteLine(" ex) -each 204 -> falsifying 204 only"); + Console.WriteLine(" -verify : verify backup file"); Environment.Exit(-1); } @@ -178,7 +180,14 @@ namespace FalsifyTwlBackup return Convert.ToInt16(args[4]); } } + + // -verify + else if (args[3].ToUpper().TrimStart('-') == "VERIFY") + { + return VERIFY; + } } + // それ以外 return ALL; } @@ -257,19 +266,31 @@ namespace FalsifyTwlBackup switch (index) { case INDEX_BANNER: - hash.CopyTo(signature.digest.banner, 0); - break; + hash.CopyTo(signature.digest.banner, 0); + break; case INDEX_HEADER: - hash.CopyTo(signature.digest.header, 0); - break; + hash.CopyTo(signature.digest.header, 0); + break; case INDEX_TMD: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.TMD], 0); + break; + + // TODO : マルチコンテンツ対応 case INDEX_CONTENT: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.CONTENT], 0); + break; + case INDEX_PUBLIC_SAVE: + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.PUBLIC_SAVE], 0); + break; + case INDEX_SUB_BANNER: - hash.CopyTo(signature.digest.section[index - (INDEX_SIGNATURE + 1)], 0); - break; + hash.CopyTo(signature.digest.section[(int)Utility.SectionIndex.SUB_BANNER], 0); + break; + + // TODO : Private Save 追加 default: Debug.Assert(false); @@ -286,38 +307,6 @@ namespace FalsifyTwlBackup /// 連結後のbyte列 static byte[] MergeByteArray(byte[] front, byte[] rear) { - /* 私のコード(色々アレだよ;;) - byte[] merged = new byte[front.Length + rear.Length]; - for (int i = 0; i < (front.Length + rear.Length); i++) - { - if (i < front.Length) - { - merged[i] = front[i]; - } - else - { - merged[i] = rear[i - front.Length]; - } - } - */ - - /* 田中さん案1(中にifは使わないほうがいいよ) - for (int i = 0; i < front.Length; i++) - { - merged[i] = front[i]; - } - for (int i = 0; i < rear.Length; i++) - { - merged[i + front.Length] = rear[i]; - } - */ - - /* 田中さん案2(ライブラリを使うとコピーしてるのも分かりやすいよ^^) - Array.Copy(front, 0, merged, 0, front.Length); - Array.Copy(rear, 0, merged, front.Length, rear.Length); - */ - - // 田中さん案3(結局1行で出来ちゃったよ;;) return front.Concat(rear).ToArray(); } @@ -395,7 +384,7 @@ namespace FalsifyTwlBackup /// - /// 各ブロックを暗号化した後、1つのbute列に結合します。 + /// 各ブロックを暗号化した後、1つの byte 列に結合します。 /// /// 暗号化するデータ /// バックアップデータに関するインスタンス @@ -662,7 +651,10 @@ namespace FalsifyTwlBackup break; case 211: - header.contentId++; + for (int i = 0; i < header.contentId.Length; i++) + { + header.contentId[i]++; + } outData = MergeEncryptBody(blocksForFalsifying, prop, improperData, NONE, NC_MAC_AND_HASHSET); OutputFalsifiedData(improperNo, prop.outFolderPath, outData); break; @@ -1072,7 +1064,6 @@ namespace FalsifyTwlBackup Properties prop = new Properties(); // インスタンスの作成 byte[] twlBackupData = File.ReadAllBytes(twlBackupName); // バックアップデータの読み込み - prop.SetOutputFolderPath(twlBackupName); // 出力フォルダを作成 // 鍵データの読み込み string[] keyString = File.ReadAllLines(keyName); @@ -1092,14 +1083,25 @@ namespace FalsifyTwlBackup // ファイル名の出力 + 鍵データの dump Console.WriteLine("Twl Backup File : {0}", twlBackupName); - Console.Write("Block Key File : {0}, ", keyName); - dumpArray("", prop.keyData); - Console.Write("MAC Key Data : {0}, ", macKeyData); - dumpArray("", prop.macKeyData); + Console.WriteLine("Block Key File : {0} ({1})", keyName, dumpArray(prop.keyData)); + Console.WriteLine("MAC Key File : {0} ({1})", macKeyData, dumpArray(prop.macKeyData)); + + // TORIAEZU : ひとまず VERIFY だったら検証して終了 + if (falsifyingType == VERIFY) + { + if (Utility.Verify(twlBackupData, prop.keyData, prop.macKeyData)) + { + Console.WriteLine("{0} は検証に成功しました。", twlBackupName); + } + Environment.Exit(0); + } // バックアップデータを復号化 prop.decryptedBlocks = Utility.DecryptBackupData(twlBackupData, prop.keyData); + // 出力フォルダを作成 + prop.SetOutputFolderPath(twlBackupName); + //========================================== // 改ざん&ファイル出力 Console.WriteLine("Start ------------"); @@ -1111,14 +1113,14 @@ namespace FalsifyTwlBackup } // byte 配列の 16 進表示 - static void dumpArray(String msg, byte[] array) + static string dumpArray(byte[] array) { - Console.Write(msg); + string str = ""; foreach (byte b in array) { - Console.Write(String.Format("{0,0:X2} ", b)); + str += String.Format("{0,0:X2} ", b); } - Console.WriteLine(); + return str.TrimEnd(); } } diff --git a/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj index 9b0d4b3..c58ae29 100644 --- a/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj +++ b/TwlBkpCheck/Windows/FalsifyTwlBackup/FalsifyTwlBackup.csproj @@ -43,7 +43,7 @@ - + diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/ExtBinaryReader.cs b/TwlBkpCheck/Windows/TWLBackupBlock/ExtBinaryReader.cs index 9ec8b25..f182b25 100644 --- a/TwlBkpCheck/Windows/TWLBackupBlock/ExtBinaryReader.cs +++ b/TwlBkpCheck/Windows/TWLBackupBlock/ExtBinaryReader.cs @@ -123,6 +123,18 @@ namespace TwlBackupBlock br.Read(buffer, 0, buffer.Length); } + /// + /// 現在のストリームから指定した配列に2バイト符号なし整数を読み取り、ストリームの現在位置を指定した配列のバイト数だけ進めます。 + /// + /// データを読み取るバッファ + public void Read(UInt16[] buffer) + { + for (int i = 0; i < buffer.Length; i++) + { + Read(ref buffer[i]); + } + } + /// /// 現在のストリームから指定した配列に4バイト符号なし整数を読み取り、ストリームの現在位置を指定した配列のバイト数だけ進めます。 /// diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/HeaderBody.cs b/TwlBkpCheck/Windows/TWLBackupBlock/HeaderBody.cs index a84680e..2c9d556 100644 --- a/TwlBkpCheck/Windows/TWLBackupBlock/HeaderBody.cs +++ b/TwlBkpCheck/Windows/TWLBackupBlock/HeaderBody.cs @@ -9,13 +9,14 @@ namespace TwlBackupBlock /// public class HeaderBody : AbstractBody { - public const int HEADER_SIZE = 160; + public const int HEADER_SIZE = 240; public const int UNIQUE_ID_SIZE = 32; public const int HARDWARE_ID_SIZE = 16; - public const int NUM_OF_SECTION = 4; + public const int MAX_CONTENTS = 8; + public const int NUM_OF_SECTION = 11; public const int TMD_RESERVED_SIZE = 62; - public const int RESERVED_SIZE = 4; + public const int RESERVED_SIZE = 13; public UInt32 signature; public UInt16 companyCode; @@ -25,9 +26,10 @@ namespace TwlBackupBlock public UInt64 titleId; public Int64 requiredSize; public readonly UInt32[] fileSizes; - public UInt32 contentId; + public readonly UInt32[] contentId; + public readonly UInt16[] contentIndex; public readonly TmdReserved tmdReserved; - public UInt16 contentIndex; + public Byte headerVersion; public readonly Byte[] reserved; public HeaderBody(byte[] data) @@ -45,6 +47,8 @@ namespace TwlBackupBlock uniqueId = new Byte[UNIQUE_ID_SIZE]; hardwareId = new Byte[HARDWARE_ID_SIZE]; fileSizes = new UInt32[NUM_OF_SECTION]; + contentId = new UInt32[MAX_CONTENTS]; + contentIndex = new UInt16[MAX_CONTENTS]; tmdReserved = new TmdReserved(); reserved = new Byte[RESERVED_SIZE]; @@ -130,9 +134,16 @@ namespace TwlBackupBlock { bw.Write(e); } - bw.Write(contentId); + foreach (UInt32 e in contentId) + { + bw.Write(e); + } + foreach (UInt16 e in contentIndex) + { + bw.Write(e); + } bw.Write(tmdReserved.GetBytes()); - bw.Write(contentIndex); + bw.Write(headerVersion); bw.Write(reserved); Debug.Assert(ms.Position == HEADER_SIZE); @@ -164,13 +175,14 @@ namespace TwlBackupBlock br.Read(ref titleId); br.Read(ref requiredSize); br.Read(fileSizes); - br.Read(ref contentId); + br.Read(contentId); + br.Read(contentIndex); { byte[] tmdReservedBytes = new byte[TMD_RESERVED_SIZE]; br.Read(tmdReservedBytes); tmdReserved.SetBytes(tmdReservedBytes); } - br.Read(ref contentIndex); + br.Read(ref headerVersion); br.Read(reserved); Debug.Assert(ms.Position == HEADER_SIZE); @@ -182,79 +194,4 @@ namespace TwlBackupBlock return new HeaderBody(GetBytes()); } } - - /// - /// ヘッダブロック中のTMDReserved。 - /// - public class TmdReserved - { - private const int TMD_RESERVED_SIZE = 62; - - public const int RESERVED8_SIZE = 3; - public const int PARENTAL_CONTROL_SIZE = 16; - public const int RESERVED_SIZE = 30; - - public UInt32 publicSaveSize; - public UInt32 privateSaveSize; - public UInt32 reserved32; - public Byte flags; - public readonly Byte[] reserved8; - public readonly Byte[] parentalControl; - public readonly Byte[] reserved; - - public TmdReserved() - { - reserved8 = new Byte[RESERVED8_SIZE]; - parentalControl = new Byte[PARENTAL_CONTROL_SIZE]; - reserved = new Byte[RESERVED_SIZE]; - } - - public byte[] GetBytes() - { - byte[] bytes = new byte[TMD_RESERVED_SIZE]; - - using (var ms = new MemoryStream(bytes)) - using (var bw = new BinaryWriter(ms)) - { - bw.Write(publicSaveSize); - bw.Write(privateSaveSize); - bw.Write(reserved32); - bw.Write(flags); - bw.Write(reserved8); - bw.Write(parentalControl); - bw.Write(reserved); - - Debug.Assert(ms.Position == TMD_RESERVED_SIZE); - } - - return bytes; - } - - public void SetBytes(byte[] bytes) - { - if (bytes == null) - { - throw new ArgumentNullException("bytes"); - } - if (bytes.Length != TMD_RESERVED_SIZE) - { - string message = string.Format("bytes.Length != {0} (bytes.Length:{1})", TMD_RESERVED_SIZE, bytes.Length); - throw new ArgumentException("bytes", message); - } - - using (var ms = new MemoryStream(bytes)) - using (var br = new ExtBinaryReader(ms)) - { - br.Read(ref publicSaveSize); - br.Read(ref privateSaveSize); - br.Read(ref reserved32); - br.Read(ref flags); - br.Read(reserved8); - br.Read(parentalControl); - br.Read(reserved); - - Debug.Assert(ms.Position == TMD_RESERVED_SIZE); - } - } - } } diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/LegacyHeaderBody.cs b/TwlBkpCheck/Windows/TWLBackupBlock/LegacyHeaderBody.cs new file mode 100644 index 0000000..6c7f179 --- /dev/null +++ b/TwlBkpCheck/Windows/TWLBackupBlock/LegacyHeaderBody.cs @@ -0,0 +1,185 @@ +using System; +using System.IO; +using System.Diagnostics; + +namespace TwlBackupBlock +{ + /// + /// ヘッダブロックのデータ本体。 + /// + public class LegacyHeaderBody : AbstractBody + { + public const int HEADER_SIZE = 160; + + public const int UNIQUE_ID_SIZE = 32; + public const int HARDWARE_ID_SIZE = 16; + public const int NUM_OF_SECTION = 4; + public const int TMD_RESERVED_SIZE = 62; + public const int RESERVED_SIZE = 4; + + public UInt32 signature; + public UInt16 companyCode; + public UInt16 version; + public readonly Byte[] uniqueId; + public readonly Byte[] hardwareId; + public UInt64 titleId; + public Int64 requiredSize; + public readonly UInt32[] fileSizes; + public UInt32 contentId; + public readonly TmdReserved tmdReserved; + public UInt16 contentIndex; + public readonly Byte[] reserved; + + public LegacyHeaderBody(byte[] data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + if (data.Length != HEADER_SIZE) + { + string message = string.Format("data.Length % {0} != 0 (data.Length:{1})", HEADER_SIZE, data.Length); + throw new ArgumentException("data", message); + } + + uniqueId = new Byte[UNIQUE_ID_SIZE]; + hardwareId = new Byte[HARDWARE_ID_SIZE]; + fileSizes = new UInt32[NUM_OF_SECTION]; + tmdReserved = new TmdReserved(); + reserved = new Byte[RESERVED_SIZE]; + + SetBytes(data); + } + + public override byte this[int index] + { + get + { + if (index < 0 || index >= HEADER_SIZE) + { + throw new ArgumentException("index"); + } + return ReadByte(index); + } + set + { + if (index < 0 || index >= HEADER_SIZE) + { + throw new ArgumentException("index"); + } + WriteByte(index, value); + } + } + + public override int Length + { + get + { + return HEADER_SIZE; + } + } + + /// + /// 指定したバイトを取得します。 + /// + /// 取得したいバイトのインデックス。 + /// で指定したバイト + public byte ReadByte(int index) + { + if (index < 0 || index >= HEADER_SIZE) + { + throw new ArgumentException("index"); + } + // TODO 処理が遅ければ効率化 + byte[] bytes = GetBytes(); + return bytes[index]; + } + + /// + /// 指定したバイトを書き換えます。 + /// + /// 書き換えたいバイトのインデックス。 + /// 上書きに使うバイト。 + public void WriteByte(int index, byte b) + { + if (index < 0 || index >= HEADER_SIZE) + { + throw new ArgumentException("index"); + } + // TODO 処理が遅ければ効率化 + byte[] bytes = GetBytes(); + bytes[index] = b; + SetBytes(bytes); + } + + public override byte[] GetBytes() + { + byte[] bytes = new byte[HEADER_SIZE]; + + using (var ms = new MemoryStream(bytes)) + using (var bw = new BinaryWriter(ms)) + { + bw.Write(signature); + bw.Write(companyCode); + bw.Write(version); + bw.Write(uniqueId); + bw.Write(hardwareId); + bw.Write(titleId); + bw.Write(requiredSize); + foreach (UInt32 e in fileSizes) + { + bw.Write(e); + } + bw.Write(contentId); + bw.Write(tmdReserved.GetBytes()); + bw.Write(contentIndex); + bw.Write(reserved); + + Debug.Assert(ms.Position == HEADER_SIZE); + } + + return bytes; + } + + public override void SetBytes(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (bytes.Length != HEADER_SIZE) + { + string message = string.Format("bytes.Length != {0} (bytes.Length:{1})", HEADER_SIZE, bytes.Length); + throw new ArgumentException("bytes", message); + } + + using (var ms = new MemoryStream(bytes)) + using (var br = new ExtBinaryReader(ms)) + { + br.Read(ref signature); + br.Read(ref companyCode); + br.Read(ref version); + br.Read(uniqueId); + br.Read(hardwareId); + br.Read(ref titleId); + br.Read(ref requiredSize); + br.Read(fileSizes); + br.Read(ref contentId); + { + byte[] tmdReservedBytes = new byte[TMD_RESERVED_SIZE]; + br.Read(tmdReservedBytes); + tmdReserved.SetBytes(tmdReservedBytes); + } + br.Read(ref contentIndex); + br.Read(reserved); + + Debug.Assert(ms.Position == HEADER_SIZE); + } + } + + public override object Clone() + { + return new HeaderBody(GetBytes()); + } + } +} diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/SignatureBody.cs b/TwlBkpCheck/Windows/TWLBackupBlock/SignatureBody.cs index 69b6546..5a27d0d 100644 --- a/TwlBkpCheck/Windows/TWLBackupBlock/SignatureBody.cs +++ b/TwlBkpCheck/Windows/TWLBackupBlock/SignatureBody.cs @@ -10,7 +10,8 @@ namespace TwlBackupBlock public class TwlBackupHashSet { public const int HASH_SIZE = 32; - public const int NUM_OF_SECTION = 4; + public const int NUM_OF_SECTION = 11; + public const int NUM_OF_LEGACY_SECTION = 4; public readonly byte[] banner; public readonly byte[] header; @@ -19,11 +20,12 @@ namespace TwlBackupBlock /// /// コンストラクタ。 /// - public TwlBackupHashSet() + public TwlBackupHashSet(bool isLegacy = false) { banner = new byte[HASH_SIZE]; header = new byte[HASH_SIZE]; - section = new byte[NUM_OF_SECTION][]; + section = isLegacy ? + new byte[NUM_OF_LEGACY_SECTION][] : new byte[NUM_OF_SECTION][]; for (int i = 0; i < section.Length; i++) { section[i] = new byte[HASH_SIZE]; @@ -35,7 +37,8 @@ namespace TwlBackupBlock /// public class SignatureBody : AbstractBody { - public const int SIGNATURE_SIZE = 1024; + public const int SIGNATURE_SIZE = 1248; + public const int LEGACY_SIGNATURE_SIZE = 1024; public const int ECC_SIGN_SIZE = 60; public const int ECC_CERT_SIZE = 384; diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/TmdReserved.cs b/TwlBkpCheck/Windows/TWLBackupBlock/TmdReserved.cs new file mode 100644 index 0000000..257d04c --- /dev/null +++ b/TwlBkpCheck/Windows/TWLBackupBlock/TmdReserved.cs @@ -0,0 +1,82 @@ +using System; +using System.IO; +using System.Diagnostics; + +namespace TwlBackupBlock +{ + /// + /// ヘッダブロック中のTMDReserved。 + /// Normal, Legacy 共に共通。 + /// + public class TmdReserved + { + private const int TMD_RESERVED_SIZE = 62; + + public const int RESERVED8_SIZE = 3; + public const int PARENTAL_CONTROL_SIZE = 16; + public const int RESERVED_SIZE = 30; + + public UInt32 publicSaveSize; + public UInt32 privateSaveSize; + public UInt32 reserved32; + public Byte flags; + public readonly Byte[] reserved8; + public readonly Byte[] parentalControl; + public readonly Byte[] reserved; + + public TmdReserved() + { + reserved8 = new Byte[RESERVED8_SIZE]; + parentalControl = new Byte[PARENTAL_CONTROL_SIZE]; + reserved = new Byte[RESERVED_SIZE]; + } + + public byte[] GetBytes() + { + byte[] bytes = new byte[TMD_RESERVED_SIZE]; + + using (var ms = new MemoryStream(bytes)) + using (var bw = new BinaryWriter(ms)) + { + bw.Write(publicSaveSize); + bw.Write(privateSaveSize); + bw.Write(reserved32); + bw.Write(flags); + bw.Write(reserved8); + bw.Write(parentalControl); + bw.Write(reserved); + + Debug.Assert(ms.Position == TMD_RESERVED_SIZE); + } + + return bytes; + } + + public void SetBytes(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (bytes.Length != TMD_RESERVED_SIZE) + { + string message = string.Format("bytes.Length != {0} (bytes.Length:{1})", TMD_RESERVED_SIZE, bytes.Length); + throw new ArgumentException("bytes", message); + } + + using (var ms = new MemoryStream(bytes)) + using (var br = new ExtBinaryReader(ms)) + { + br.Read(ref publicSaveSize); + br.Read(ref privateSaveSize); + br.Read(ref reserved32); + br.Read(ref flags); + br.Read(reserved8); + br.Read(parentalControl); + br.Read(reserved); + + Debug.Assert(ms.Position == TMD_RESERVED_SIZE); + } + } + } +} diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/TwlBackupBlock.csproj b/TwlBkpCheck/Windows/TWLBackupBlock/TwlBackupBlock.csproj index e41b545..f803879 100644 --- a/TwlBkpCheck/Windows/TWLBackupBlock/TwlBackupBlock.csproj +++ b/TwlBkpCheck/Windows/TWLBackupBlock/TwlBackupBlock.csproj @@ -58,6 +58,7 @@ + True True @@ -68,6 +69,7 @@ True Settings.settings + diff --git a/TwlBkpCheck/Windows/TWLBackupBlock/Utility.cs b/TwlBkpCheck/Windows/TWLBackupBlock/Utility.cs index d12c4b3..40d1bc3 100644 --- a/TwlBkpCheck/Windows/TWLBackupBlock/Utility.cs +++ b/TwlBkpCheck/Windows/TWLBackupBlock/Utility.cs @@ -13,6 +13,16 @@ namespace TwlBackupBlock /// public class Utility { + public const int MAX_CONTENTS = 8; + public enum SectionIndex + { + TMD, + CONTENT, + PUBLIC_SAVE = CONTENT + MAX_CONTENTS, + SUB_BANNER, + PRIVATE_SAVE + }; + private const int KEY_SIZE = 16; private const int ROUND_SCALE = 16; @@ -21,8 +31,10 @@ namespace TwlBackupBlock private const int AES_SIGN_HEADER_SIZE = 32; private const int BANNER_SIZE = 16 * 1024; - private const int HEADER_SIZE = 160; - private const int SIGNATURE_SIZE = 1024; + private const int HEADER_SIZE = 240; + private const int SIGNATURE_SIZE = 1248; + private const int LEGACY_HEADER_SIZE = 160; + private const int LEGACY_SIGNATURE_SIZE = 1024; private const int ENCRYPT_BANNER_SIZE = BANNER_SIZE + AES_SIGN_HEADER_SIZE; private const int ENCRYPT_HEADER_SIZE = HEADER_SIZE + AES_SIGN_HEADER_SIZE; @@ -74,14 +86,16 @@ namespace TwlBackupBlock blocks.signature.body = new SignatureBody(DecryptBlock(br, SIGNATURE_SIZE, key, out blocks.signature.mac, out blocks.signature.iv)); - int TMD_SIZE = (int)headerBody.fileSizes[0]; - int CONTENT_SIZE = (int)headerBody.fileSizes[1]; - int SAVE_DATA_SIZE = (int)headerBody.fileSizes[2]; - int SUB_BANNER_SIZE = (int)headerBody.fileSizes[3]; + // TORIAEZU + // TODO : 複数コンテンツ対応 + int TMD_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.TMD]; + int CONTENT_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.CONTENT]; + int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.PUBLIC_SAVE]; + int SUB_BANNER_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.SUB_BANNER]; blocks.tmd.body = new Body(DecryptBlock(br, TMD_SIZE, key, out blocks.tmd.mac, out blocks.tmd.iv)); blocks.content.body = new Body(DecryptBlock(br, CONTENT_SIZE, key, out blocks.content.mac, out blocks.content.iv)); - blocks.saveData.body = new Body(DecryptBlock(br, SAVE_DATA_SIZE, key, out blocks.saveData.mac, out blocks.saveData.iv)); + blocks.saveData.body = new Body(DecryptBlock(br, PUBLIC_SAVE_SIZE, key, out blocks.saveData.mac, out blocks.saveData.iv)); blocks.subBanner.body = new Body(DecryptBlock(br, SUB_BANNER_SIZE, key, out blocks.subBanner.mac, out blocks.subBanner.iv)); Debug.Assert(ms.Position == data.Length); @@ -386,13 +400,14 @@ namespace TwlBackupBlock return false; } - int TMD_SIZE = (int)headerBody.fileSizes[0]; - int CONTENT_SIZE = (int)headerBody.fileSizes[1]; - int SAVE_DATA_SIZE = (int)headerBody.fileSizes[2]; - int SUB_BANNER_SIZE = (int)headerBody.fileSizes[3]; + // TODO : 複数コンテンツ対応 + int TMD_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.TMD]; + int CONTENT_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.CONTENT]; + int PUBLIC_SAVE_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.PUBLIC_SAVE]; + int SUB_BANNER_SIZE = (int)headerBody.fileSizes[(int)SectionIndex.SUB_BANNER]; int restSize = RoundUp(TMD_SIZE, ROUND_SCALE) + RoundUp(CONTENT_SIZE, ROUND_SCALE) + - RoundUp(SAVE_DATA_SIZE, ROUND_SCALE) + RoundUp(SUB_BANNER_SIZE, ROUND_SCALE) + + RoundUp(PUBLIC_SAVE_SIZE, ROUND_SCALE) + RoundUp(SUB_BANNER_SIZE, ROUND_SCALE) + AES_SIGN_HEADER_SIZE * 4; if (data.Length - ms.Position != restSize) { @@ -405,7 +420,7 @@ namespace TwlBackupBlock Console.WriteLine("TMDブロックのMACが一致しません"); return false; } - if (!CheckHash(blocks.tmd, signatureBody.digest.section[0])) + if (!CheckHash(blocks.tmd, signatureBody.digest.section[(int)SectionIndex.TMD])) { Console.WriteLine("TMDブロックのハッシュが一致しません"); return false; @@ -416,18 +431,18 @@ namespace TwlBackupBlock Console.WriteLine("コンテンツブロックのMACが一致しません"); return false; } - if (!CheckHash(blocks.content, signatureBody.digest.section[1])) + if (!CheckHash(blocks.content, signatureBody.digest.section[(int)SectionIndex.CONTENT])) { Console.WriteLine("コンテンツブロックのハッシュが一致しません"); return false; } - blocks.saveData.body = new Body(DecryptBlock(br, SAVE_DATA_SIZE, aesCbcKey, out blocks.saveData.mac, out blocks.saveData.iv)); + blocks.saveData.body = new Body(DecryptBlock(br, PUBLIC_SAVE_SIZE, aesCbcKey, out blocks.saveData.mac, out blocks.saveData.iv)); if (!CheckMac(blocks.saveData, aesCmacKey, blocks.saveData.mac)) { Console.WriteLine("publicセーブデータブロックのMACが一致しません"); return false; } - if (!CheckHash(blocks.saveData, signatureBody.digest.section[2])) + if (!CheckHash(blocks.saveData, signatureBody.digest.section[(int)SectionIndex.PUBLIC_SAVE])) { Console.WriteLine("publicセーブデータブロックのハッシュが一致しません"); return false; @@ -438,7 +453,7 @@ namespace TwlBackupBlock Console.WriteLine("サブバナーブロックの内容とMACが一致しません"); return false; } - if (!CheckHash(blocks.subBanner, signatureBody.digest.section[3])) + if (!CheckHash(blocks.subBanner, signatureBody.digest.section[(int)SectionIndex.SUB_BANNER])) { Console.WriteLine("サブバナーブロックのハッシュが一致しません"); return false;