diff --git a/BuildIRD/BuildIRD.cs b/BuildIRD/BuildIRD.cs index 99d74f6..7bfa121 100644 --- a/BuildIRD/BuildIRD.cs +++ b/BuildIRD/BuildIRD.cs @@ -1,5 +1,7 @@ using LibIRD; using System; +using System.IO; +using System.IO.Enumeration; using System.Text; namespace BuildIRD @@ -12,15 +14,39 @@ namespace BuildIRD // Create new reproducible redump-style IRD with a key byte[] discKey = new byte[] { 0x1A, 0x2D, 0x88, 0xFC, 0x19, 0x37, 0x27, 0x44, 0x11, 0x5E, 0xE9, 0x83, 0xA0, 0x47, 0xE2, 0xD5 }; - IRD ird1 = new ReIRD("./game.iso", discKey); - ird1.Write("./test1.ird"); - Console.WriteLine("IRD for " + ird1.Title + " created"); + string fileName = "./game.iso"; + try + { + IRD ird1 = new ReIRD(fileName, discKey); + ird1.Write("./test1.ird"); + Console.WriteLine("IRD for " + fileName + " created"); - // Create new reproducible redump-style IRD with a GetKey log - string logPath = "./log.getkey.log"; - IRD ird2 = new ReIRD("./game.iso", logPath); - ird2.Write("./test2.ird"); - Console.WriteLine("IRD for " + ird2.Title + " created"); + // Create new reproducible redump-style IRD with a GetKey log + string logPath = "./log.getkey.log"; + try + { + IRD ird2 = new ReIRD(fileName, logPath); + ird2.Write("./test2.ird"); + Console.WriteLine("IRD for " + fileName + " created"); + } + catch (FileNotFoundException) + { + Console.WriteLine("File not found: " + logPath); + } + + // Read IRD and print details to console + IRD ird = IRD.Read("./test1.ird"); + Console.WriteLine("IRD Version: " + ird.Version); + Console.WriteLine("Title ID: " + ird.TitleID); + Console.WriteLine("Title: " + ird.Title); + Console.WriteLine("System Version: " + ird.SystemVersion); + Console.WriteLine("Game Version: " + ird.GameVersion); + Console.WriteLine("App Version: " + ird.AppVersion); + } + catch (FileNotFoundException) + { + Console.WriteLine("File not found: " + fileName); + } } } } diff --git a/LibIRD/IRD.cs b/LibIRD/IRD.cs index 42a20f7..a43ff61 100644 --- a/LibIRD/IRD.cs +++ b/LibIRD/IRD.cs @@ -152,12 +152,12 @@ namespace LibIRD byte[][] regionHashes, ulong[] fileKeys, byte[][] fileHashes, - uint uid, ushort extraConfig, ushort attachments, byte[] d1, byte[] d2, - byte[] pic) + byte[] pic, + uint uid) : base( titleID, title, @@ -171,12 +171,12 @@ namespace LibIRD fileHashes) { Version = version; - UID = uid; ExtraConfig = extraConfig; Attachments = attachments; Data1Key = d1; Data2Key = d2; PIC = pic; + UID = uid; } /// @@ -357,59 +357,6 @@ namespace LibIRD Data2Key = stream.ToArray(); } - /// - /// Read and store IRD data from an existing file - /// - /// Path to the IRD file - /// - /// - public static IRD Read(string irdPath) - { - // Validate irdPath - if (irdPath == null || irdPath.Length <= 0) - throw new ArgumentNullException(nameof(irdPath)); - if (!File.Exists(irdPath)) - throw new FileNotFoundException(nameof(irdPath)); - - byte version = 1; - string titleID = "BCES01234"; - string title = "R"; - string sysVersion = "0.00"; - string gameVersion = "00.00"; - string appVersion = "00.00"; - byte[] header = new byte[1]; - byte[] footer = new byte[1]; - byte[][] regionHashes = new byte[1][]; - regionHashes[0] = new byte[1]; - ulong[] fileKeys = new ulong[1]; - byte[][] fileHashes = new byte[1][]; - fileHashes[0] = new byte[1]; - uint uid = 1; - ushort extraConfig = 1; - ushort attachments = 1; - byte[] d1 = new byte[16]; - byte[] d2 = new byte[16]; - byte[] pic = new byte[115]; - - return new IRD(version, - titleID, - title, - sysVersion, - gameVersion, - appVersion, - header, - footer, - regionHashes, - fileKeys, - fileHashes, - uid, - extraConfig, - attachments, - d1, - d2, - pic); - } - /// /// Write IRD data to file /// @@ -527,6 +474,119 @@ namespace LibIRD stream.CopyTo(gzStream); } + /// + /// Read and store IRD data from an existing file + /// + /// Path to the IRD file + /// + /// + public static IRD Read(string irdPath) + { + // Validate irdPath + if (irdPath == null || irdPath.Length <= 0) + throw new ArgumentNullException(nameof(irdPath)); + if (!File.Exists(irdPath)) + throw new FileNotFoundException(nameof(irdPath)); + + // Open IRD for reading + using FileStream fs = new(irdPath, FileMode.Open, FileAccess.Read); + using GZipStream gzs = new(fs, CompressionMode.Decompress); + using BinaryReader br = new(gzs); + + // Check for IRD file signature + byte[] magic = br.ReadBytes(4); + if (!((ReadOnlySpan)Magic).SequenceEqual(magic)) + throw new InvalidDataException("IRD file not recognised"); + + // Read file version + byte version = br.ReadByte(); + if (version < 6 || version > 9) + throw new InvalidDataException("Unsupported IRD version detected"); + + // Read Title ID and Title + string titleID = Encoding.ASCII.GetString(br.ReadBytes(9)); + string title = br.ReadString(); + + // Read System, Game, and App Version + string sysVersion = Encoding.ASCII.GetString(br.ReadBytes(4)); + string gameVersion = Encoding.ASCII.GetString(br.ReadBytes(5)); + string appVersion = Encoding.ASCII.GetString(br.ReadBytes(5)); + + // Read UID (for Version 7) + uint uid = 0; + if (version == 7) + uid = br.ReadUInt32(); + + // Read Header + uint headerLength = br.ReadUInt32(); + byte[] header = new byte[headerLength]; + br.Read(header, 0, header.Length); + + // Read Footer + uint footerLength = br.ReadUInt32(); + byte[] footer = new byte[footerLength]; + br.Read(footer, 0, footer.Length); + + // Read region hashes + byte regionCount = br.ReadByte(); + byte[][] regionHashes = new byte[regionCount][]; + for (int i = 0; i < regionCount; i++) + regionHashes[i] = br.ReadBytes(16); + + // Read file hashes + uint fileCount = br.ReadUInt32(); + ulong[] fileKeys = new ulong[fileCount]; + byte[][] fileHashes = new byte[fileCount][]; + for (int i = 0; i < fileCount; i++) + { + fileKeys[i] = br.ReadUInt64(); + fileHashes[i] = br.ReadBytes(16); + } + + // Read extra config and number of attachments + ushort extraConfig = br.ReadUInt16(); + ushort attachments = br.ReadUInt16(); + + // Read PIC data (for Version 8 and prior) + byte[] pic = new byte[115]; + if (version >= 9) + pic = br.ReadBytes(115); + + // Read Data 1 Key, Data 2 Key + byte[] d1 = br.ReadBytes(16); + byte[] d2 = br.ReadBytes(16); + + // Read PIC data (for Version 8 and prior) + if (version < 9) + pic = br.ReadBytes(115); + + // Read UID (for Version 8 onwards) + if (version > 7) + uid = br.ReadUInt16(); + + // Read and CRC32 hash + byte[] crc = br.ReadBytes(4); + + // Create new IRD object with read parameters + return new IRD(version, + titleID, + title, + sysVersion, + gameVersion, + appVersion, + header, + footer, + regionHashes, + fileKeys, + fileHashes, + extraConfig, + attachments, + d1, + d2, + pic, + uid); + } + #endregion } } diff --git a/LibIRD/PS3ISO.cs b/LibIRD/PS3ISO.cs index 8156a9d..f90cde9 100644 --- a/LibIRD/PS3ISO.cs +++ b/LibIRD/PS3ISO.cs @@ -155,7 +155,9 @@ namespace LibIRD Header = header; FooterLength = (uint)footer.Length; Footer = footer; + RegionCount = (byte) regionHashes.Length; RegionHashes = regionHashes; + FileCount = (uint)fileKeys.Length; FileKeys = fileKeys; FileHashes = fileHashes; }