public NUSDataProviderWUD(NUSTitle title, WUDInfo wudinfo) : base(title) { //super(title); this.WUDInfo = wudinfo; this.tmd = TMD.parseTMD(getRawTMD()); }
public static WUDInfo createAndLoad(WUDDiscReader discReader, byte[] titleKey) { WUDInfo result = new WUDInfo(titleKey, discReader); byte[] PartitionTocBlock = discReader.readDecryptedToByteArray(Settings.WIIU_DECRYPTED_AREA_OFFSET, 0, 0x8000, titleKey, null); // verify DiscKey before proceeding byte[] copy = new byte[4]; Array.ConstrainedCopy(PartitionTocBlock, 0, copy, 0, 4); if (!ArraysEqual(copy, DECRYPTED_AREA_SIGNATURE)) { //MessageBox.Show("Decryption of PartitionTocBlock failed"); return(null); } Dictionary <string, WUDPartition> partitions = readPartitions(result, PartitionTocBlock); result.partitions.Clear(); foreach (var v in partitions) { result.partitions.Add(v.Key, v.Value); } return(result); }
public static NUSTitle loadNUSTitle(String WUDPath, byte[] titleKey) { NUSTitleLoader loader = new NUSTitleLoaderWUD(); NUSTitleConfig config = new NUSTitleConfig(); byte[] usedTitleKey = titleKey; FileInfo wudFile = new FileInfo(WUDPath); if (!wudFile.Exists) { //MessageBox.Show(WUDPath + " does not exist."); //System.exit(1); } WUDImage image = new WUDImage(wudFile); if (usedTitleKey == null) { FileInfo keyFile = new FileInfo(Path.GetDirectoryName(wudFile.FullName) + Path.DirectorySeparatorChar + Settings.WUD_KEY_FILENAME); if (!keyFile.Exists) { //MessageBox.Show(keyFile.FullName + " does not exist and no title key was provided."); return(null); } usedTitleKey = File.ReadAllBytes(keyFile.FullName); } WUDInfo wudInfo = WUDInfoParser.createAndLoad(image.WUDDiscReader, usedTitleKey); if (wudInfo == null) { return(null); } config.WUDInfo = (wudInfo); return(loader.loadNusTitle(config)); }
private static Dictionary <string, WUDPartition> readPartitions(WUDInfo wudInfo, byte[] partitionTocBlock) { byte[] buffer = new byte[partitionTocBlock.Length]; int partitionCount = (int)SwapEndianness(BitConverter.ToUInt32(partitionTocBlock, 0x1C)); Dictionary <string, WUDPartition> partitions = new Dictionary <string, WUDPartition>(); byte[] gamePartitionTMD = new byte[0]; byte[] gamePartitionTicket = new byte[0]; byte[] gamePartitionCert = new byte[0]; String realGamePartitionName = ""; // populate partition information from decrypted TOC for (int i = 0; i < partitionCount; i++) { int offset = (PARTITION_TOC_OFFSET + (i * PARTITION_TOC_ENTRY_SIZE)); byte[] partitionIdentifier = new byte[0x19]; Array.ConstrainedCopy(partitionTocBlock, offset, partitionIdentifier, 0, 0x19); int j = 0; for (j = 0; j < partitionIdentifier.Length; j++) { if (partitionIdentifier[j] == 0) { break; } } byte[] partitionNameArray = new byte[j]; Array.ConstrainedCopy(partitionIdentifier, 0, partitionNameArray, 0, j); String partitionName = Encoding.ASCII.GetString(partitionNameArray); // calculate partition offset (relative from WIIU_DECRYPTED_AREA_OFFSET) from decrypted TOC long tmp = SwapEndianness(BitConverter.ToUInt32(partitionTocBlock, (PARTITION_TOC_OFFSET + (i * PARTITION_TOC_ENTRY_SIZE) + 0x20))); long partitionOffset = ((tmp * (long)0x8000) - 0x10000); WUDPartition partition = new WUDPartition(partitionName, partitionOffset); if (partitionName.StartsWith("SI")) { byte[] fileTableBlock = wudInfo.WUDDiscReader.readDecryptedToByteArray(Settings.WIIU_DECRYPTED_AREA_OFFSET + partitionOffset, 0, 0x8000, wudInfo.titleKey, null); byte[] copy = new byte[4]; Array.ConstrainedCopy(fileTableBlock, 0, copy, 0, 4); if (!ArraysEqual(copy, PARTITION_FILE_TABLE_SIGNATURE)) { //MessageBox.Show("FST Decrpytion failed"); continue; } //if (!Arrays.equals(Arrays.copyOfRange(fileTableBlock, 0, 4), PARTITION_FILE_TABLE_SIGNATURE)) //{ // log.info("FST Decrpytion failed"); // continue; //} FST fst = FST.parseFST(fileTableBlock, null); byte[] rawTIK = getFSTEntryAsByte(WUD_TICKET_FILENAME, partition, fst, wudInfo.WUDDiscReader, wudInfo.titleKey); byte[] rawTMD = getFSTEntryAsByte(WUD_TMD_FILENAME, partition, fst, wudInfo.WUDDiscReader, wudInfo.titleKey); byte[] rawCert = getFSTEntryAsByte(WUD_CERT_FILENAME, partition, fst, wudInfo.WUDDiscReader, wudInfo.titleKey); gamePartitionTMD = rawTMD; gamePartitionTicket = rawTIK; gamePartitionCert = rawCert; // We want to use the real game partition realGamePartitionName = partitionName = "GM" + Utils.ByteArrayToString(Arrays.copyOfRange(rawTIK, 0x1DC, 0x1DC + 0x08)); } else if (partitionName.StartsWith(realGamePartitionName)) { wudInfo.gamePartitionName = partitionName; partition = new WUDGamePartition(partitionName, partitionOffset, gamePartitionTMD, gamePartitionCert, gamePartitionTicket); } byte[] header = wudInfo.WUDDiscReader.readEncryptedToByteArray(partition.partitionOffset + 0x10000, 0, 0x8000); WUDPartitionHeader partitionHeader = WUDPartitionHeader.parseHeader(header); partition.partitionHeader = (partitionHeader); partitions.Add(partitionName, partition); } return(partitions); }