private IStorage OpenAesCtrExStorage(IStorage baseStorage, int index) { NcaFsHeader fsHeader = Header.GetFsHeader(index); NcaFsPatchInfo info = fsHeader.GetPatchInfo(); long sectionOffset = Header.GetSectionStartOffset(index); long sectionSize = Header.GetSectionSize(index); long bktrOffset = info.RelocationTreeOffset; long bktrSize = sectionSize - bktrOffset; long dataSize = info.RelocationTreeOffset; byte[] key = GetContentKey(NcaKeyType.AesCtr); byte[] counter = Aes128CtrStorage.CreateCounter(fsHeader.Counter, bktrOffset + sectionOffset); byte[] counterEx = Aes128CtrStorage.CreateCounter(fsHeader.Counter, sectionOffset); IStorage bucketTreeData = new CachedStorage(new Aes128CtrStorage(baseStorage.Slice(bktrOffset, bktrSize), key, counter, true), 4, true); IStorage encryptionBucketTreeData = bucketTreeData.Slice(info.EncryptionTreeOffset - bktrOffset); IStorage decStorage = new Aes128CtrExStorage(baseStorage.Slice(0, dataSize), encryptionBucketTreeData, key, counterEx, true); decStorage = new CachedStorage(decStorage, 0x4000, 4, true); return(new ConcatenationStorage(new[] { decStorage, bucketTreeData }, true)); }
private static bool FindEmuMMC(DriveInfo drive) { DirectoryInfo root = drive.RootDirectory; FileInfo emummcIni = root.GetFile("emuMMC/emummc.ini"); if (emummcIni.Exists) { // find the DiskDrive associated with this drive letter VolumeInfo volume = AllVolumes .Where(x => x.Caption == drive.Name).FirstOrDefault(); LogicalDiskInfo logicalDisk = AllLogicalDisks .Where(x => x.DeviceID == volume.DriveLetter).FirstOrDefault(); IEnumerable <PartitionInfo> partitionsFromLogicalDisk = ToDiskPartitions(logicalDisk); if (!partitionsFromLogicalDisk.Any()) { return(false); } DiskInfo disk = AllDisks.Where(x => x.Index == partitionsFromLogicalDisk.First().DiskIndex).FirstOrDefault(); IEnumerable <PartitionInfo> partitions = AllPartitions.Where(x => x.DiskIndex == disk.Index); // parse ini FileIniDataParser parser = new FileIniDataParser(); IniData ini = parser.ReadFile(emummcIni.FullName); ini.SectionKeySeparator = '/'; if (!ini.TryGetKey("emummc/sector", out string sectorStr)) { return(false); } ulong sector = ulong.Parse(sectorStr.Replace("0x", ""), System.Globalization.NumberStyles.HexNumber); PartitionInfo partition = partitions.Where(x => (sector * x.BlockSize) - 0x1000000 /* hekate's 16MB padding to protect the emuMMC */ == x.StartingOffset).FirstOrDefault(); bool usingEmummc = partition != null; if (usingEmummc) { MessageBoxResult r = MessageBox.Show("emuMMC was detected on this SD card. Do you want to open that instead of sysMMC content?", "emuMMC", MessageBoxButton.YesNo); if (r == MessageBoxResult.No) { usingEmummc = false; } } if (usingEmummc) { DeviceStream stream = new DeviceStream(disk.PhysicalName, disk.Length); IStorage diskStorage = new CachedStorage(stream.AsStorage().AsReadOnly(), disk.SectorSize * 100, 4, true); long offset = (long)partition.StartingOffset; offset += 0x1000000; // account for hekate's padding offset += 0x400000; // BOOT0 offset += 0x400000; // BOOT1 NANDService.InsertNAND(diskStorage.Slice(offset, (long)partition.Size), false); } return(usingEmummc); } return(false); }