Example #1
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);
        }
Example #2
0
        private static byte[] getFSTEntryAsByte(String filename, WUDPartition partition, FST fst, WUDDiscReader discReader, byte[] key)
        {
            FSTEntry       entry = getEntryByName(fst.root, filename);
            ContentFSTInfo info  = fst.contentFSTInfos[((int)entry.contentFSTID)];

            // Calculating the IV
            ByteBuffer byteBuffer = ByteBuffer.allocate(0x10);

            byteBuffer.position(0x08);
            long l = entry.fileOffset >> 16;

            byte[] ar = BitConverter.GetBytes(l);
            byte[] IV = new byte[0x10];//= copybyteBuffer.putLong(entry.fileOffset >> 16).ToArray();
            Array.ConstrainedCopy(ar, 0, IV, 0x08, 0x08);

            return(discReader.readDecryptedToByteArray(Settings.WIIU_DECRYPTED_AREA_OFFSET + (long)partition.partitionOffset + (long)info.getOffset(),
                                                       entry.fileOffset, (int)entry.fileSize, key, IV));
        }