// TODO: real processing. Currently we are ignoring everything except the hashes
        public static WUDPartitionHeader parseHeader(byte[] header)
        {
            WUDPartitionHeader result = new WUDPartitionHeader();

            result.rawData = (header);
            return(result);
        }
Esempio n. 2
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);
        }