예제 #1
0
 public NUSDataProviderWUD(NUSTitle title, WUDInfo wudinfo)
     : base(title)
 {
     //super(title);
     this.WUDInfo = wudinfo;
     this.tmd     = TMD.parseTMD(getRawTMD());
 }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        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);
        }