示例#1
0
        public IStorage OpenDecryptedHeaderStorage()
        {
            long firstSectionOffset = long.MaxValue;
            bool hasEnabledSection  = false;

            // Encrypted portion continues until the first section
            for (int i = 0; i < NcaHeader.SectionCount; i++)
            {
                if (Header.IsSectionEnabled(i))
                {
                    hasEnabledSection  = true;
                    firstSectionOffset = Math.Min(firstSectionOffset, Header.GetSectionStartOffset(i));
                }
            }

            long headerSize = hasEnabledSection ? NcaHeader.HeaderSize : firstSectionOffset;

            IStorage header  = new CachedStorage(new Aes128XtsStorage(BaseStorage.Slice(0, headerSize), Keyset.HeaderKey, NcaHeader.HeaderSectorSize, true), 1, true);
            int      version = ReadHeaderVersion(header);

            if (version == 2)
            {
                header = OpenNca2Header(headerSize);
            }

            return(header);
        }
示例#2
0
        public void Open()
        {
            DiskInfo disk    = SelectedDisk;
            var      storage = new CachedStorage(new DeviceStream(disk.PhysicalName, disk.Length).AsStorage(), disk.SectorSize * 100, 4, true);

            storage.SetReadOnly();
            Stream stream = storage.AsStream();

            Keyset keyset = OpenKeyset();
            var    nand   = new Nand(stream, keyset);

            Stream prodinfo    = nand.OpenProdInfo();
            var    calibration = new Calibration(prodinfo);

            keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(calibration.EticketExtKeyRsa, keyset.EticketRsaKek);
            Ticket[] tickets = GetTickets(keyset, nand);

            using (var outStream = new StreamWriter("titlekeys.txt"))
            {
                foreach (Ticket ticket in tickets)
                {
                    byte[] key = ticket.GetTitleKey(keyset);
                    outStream.WriteLine($"{ticket.RightsId.ToHexString()},{key.ToHexString()}");
                }
            }
        }
示例#3
0
        private static void Refresh()
        {
            ManagementObjectCollection disks = GetDisks();

            foreach (ManagementObject disk in disks)
            {
                if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering?
                {
                    try
                    {
                        DiskInfo info = CreateDiskInfo(disk);
                        IEnumerable <PartitionInfo> partitions = CreatePartitionInfos(GetPartitions()).Where((p) => info.Index == p.DiskIndex).OrderBy((p) => p.Index);
                        PartitionInfo lastPartition            = partitions.Last();
                        long          length        = (long)(lastPartition.Size + lastPartition.StartingOffset);
                        long          missingLength = (0x747BFFE00 - 0x727800000) + 0x200; // (start of GPT backup - end of USER) + length of GPT backup
                        length += missingLength;
                        IStorage diskStorage = new CachedStorage(new DeviceStream(info.PhysicalName, length).AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true);
                        if (InsertNAND(diskStorage, true))
                        {
                            CurrentDisk = info;
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.WriteLine("Cannot direct access drive due to lack of permissions.");
                    }
                }
            }
        }
示例#4
0
文件: Nca.cs 项目: garoxas/LibHac
        private IStorage OpenNca0BodyStorage(bool openEncrypted)
        {
            // NCA0 encrypts the entire NCA body using AES-XTS instead of
            // using different encryption types and IVs for each section.
            Assert.SdkEqual(0, Header.Version);

            if (openEncrypted == IsEncrypted)
            {
                return(GetRawStorage());
            }

            if (Nca0TransformedBody != null)
            {
                return(Nca0TransformedBody);
            }

            byte[] key0 = GetContentKey(NcaKeyType.AesXts0);
            byte[] key1 = GetContentKey(NcaKeyType.AesXts1);

            Nca0TransformedBody = new CachedStorage(new Aes128XtsStorage(GetRawStorage(), key0, key1, NcaHeader.HeaderSectorSize, true, !openEncrypted), 1, true);
            return(Nca0TransformedBody);

            IStorage GetRawStorage()
            {
                BaseStorage.GetSize(out long ncaSize).ThrowIfFailure();
                return(BaseStorage.Slice(0x400, ncaSize - 0x400));
            }
        }
示例#5
0
        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));
        }
示例#6
0
        public Stream OpenProdInfo()
        {
            IStorage encStorage = ProdInfo.Open().AsStorage();
            var      decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[0], 0x4000, true), 0x4000, 4, true);

            return(decStorage.AsStream(FileAccess.Read));
        }
示例#7
0
        public IStorage OpenDecryptedWarmBootStorage()
        {
            if (!IsDecrypted)
            {
                return(null);
            }

            IStorage warmBootStorage = OpenWarmBootStorage();

            // Only Mariko warmboot storage is encrypted
            if (!IsMariko)
            {
                return(warmBootStorage);
            }

            int size = GetSectionSize(Package1Section.WarmBoot);
            int encryptedSectionSize = size - MarikoWarmBootPlainTextSectionSize;

            var plainTextSection    = new SubStorage(warmBootStorage, 0, MarikoWarmBootPlainTextSectionSize);
            var encryptedSubStorage =
                new SubStorage(warmBootStorage, MarikoWarmBootPlainTextSectionSize, encryptedSectionSize);

            var      zeroIv           = new Buffer16();
            IStorage decryptedSection = new AesCbcStorage(encryptedSubStorage, KeySet.MarikoBek, zeroIv.Bytes, true);

            decryptedSection = new CachedStorage(decryptedSection, 0x200, 1, true);

            return(new ConcatenationStorage(new List <IStorage> {
                plainTextSection, decryptedSection
            }, true));
        }
示例#8
0
        public FatFileSystemProvider OpenUserPartition()
        {
            IStorage encStorage = User.Open().AsStorage();
            var      decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[3], 0x4000, true), 0x4000, 4, true);
            var      fat        = new FatFileSystem(decStorage.AsStream(FileAccess.Read), Ownership.None);

            return(new FatFileSystemProvider(fat));
        }
示例#9
0
文件: Nax0.cs 项目: tiliarou/LibHac
        public Nax0(Keyset keyset, IStorage storage, string sdPath, bool leaveOpen)
        {
            LeaveOpen = leaveOpen;
            ReadHeader(storage.AsStream());
            DeriveKeys(keyset, sdPath, storage);

            BaseStorage = new CachedStorage(new Aes128XtsStorage(storage.Slice(SectorSize), Key, SectorSize, leaveOpen), 4, leaveOpen);
        }
示例#10
0
        public NandPartition OpenUserPartition()
        {
            IStorage encStorage = User.Open().AsStorage();
            var      decStorage = new CachedStorage(new Aes128XtsStorage(encStorage, Keyset.BisKeys[3], 0x4000, true), 0x4000, 4, true);

            decStorage.SetReadOnly();
            var fat = new FatFileSystem(decStorage.AsStream(), Ownership.None);

            return(new NandPartition(fat));
        }
示例#11
0
文件: CacheTests.cs 项目: tomyqg/ULA
        public void PostNullIfnformationToCacheStorage()
        {
            var cache = new CachedStorage();

            cache.SetValueById("1", null);
            object result;

            cache.TryGetValueById("1", out result);
            result.Should().BeNull();
        }
示例#12
0
文件: CacheTests.cs 项目: tomyqg/ULA
        public void GetfnformationFromEmptyCacheStorage()
        {
            var cache = new CachedStorage();


            object result;

            cache.TryGetValueById("1", out result);
            result.Should().BeNull();
        }
示例#13
0
文件: CacheTests.cs 项目: tomyqg/ULA
        public void PostInformationWithNullKeyToCacheStorage()
        {
            var cache = new CachedStorage();

            cache.SetValueById(null, null);
            object result;

            cache.TryGetValueById(null, out result);
            result.Should().BeNull();
        }
示例#14
0
文件: CacheTests.cs 项目: tomyqg/ULA
        public void PostInformationAndGetInformationWithDifferentKeys()
        {
            var cache = new CachedStorage();

            cache.SetValueById("1", null);
            object result;

            cache.TryGetValueById("2", out result);
            result.Should().BeNull();
        }
示例#15
0
文件: CacheTests.cs 项目: tomyqg/ULA
        public void PostIfnformationToCacheStorage()
        {
            var    cache = new CachedStorage();
            object inf   = new Byte[1, 3, 4, 5, 6];

            cache.SetValueById("1", inf);
            object result;

            cache.TryGetValueById("1", out result);
            result.Should().Be(inf);
        }
示例#16
0
        public static void Process(Context ctx)
        {
            switch (ctx.Options.BenchType?.ToLower())
            {
            case "aesctr":
            {
                IStorage decStorage = new MemoryStorage(new byte[Size]);
                IStorage encStorage = new Aes128CtrStorage(new MemoryStorage(new byte[Size]), new byte[0x10], new byte[0x10], true);

                CopyBenchmark(decStorage, encStorage, Iterations, "MemoryStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "MemoryStorage Decrypt: ", ctx.Logger);

                decStorage = new NullStorage(Size);
                encStorage = new Aes128CtrStorage(new NullStorage(Size), new byte[0x10], new byte[0x10], true);

                CopyBenchmark(decStorage, encStorage, Iterations, "NullStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "NullStorage Decrypt: ", ctx.Logger);

                decStorage = new MemoryStorage(new byte[Size]);
                encStorage = new CachedStorage(new Aes128CtrStorage(new MemoryStorage(new byte[Size]), new byte[0x10], new byte[0x10], true), 0x4000, 4, true);

                CopyBenchmark(decStorage, encStorage, Iterations, "CachedStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "CachedStorage Decrypt: ", ctx.Logger);

                break;
            }

            case "aesxts":
            {
                IStorage decStorage = new MemoryStorage(new byte[Size]);
                IStorage encStorage = new Aes128XtsStorage(new MemoryStorage(new byte[Size]), new byte[0x20], 81920, true);

                CopyBenchmark(decStorage, encStorage, Iterations, "MemoryStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "MemoryStorage Decrypt: ", ctx.Logger);

                decStorage = new NullStorage(Size);
                encStorage = new Aes128XtsStorage(new NullStorage(Size), new byte[0x20], 81920, true);

                CopyBenchmark(decStorage, encStorage, Iterations, "NullStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "NullStorage Decrypt: ", ctx.Logger);

                decStorage = new MemoryStorage(new byte[Size]);
                encStorage = new CachedStorage(new Aes128XtsStorage(new MemoryStorage(new byte[Size]), new byte[0x20], 0x4000, true), 4, true);

                CopyBenchmark(decStorage, encStorage, Iterations, "CachedStorage Encrypt: ", ctx.Logger);
                CopyBenchmark(encStorage, decStorage, Iterations, "CachedStorage Decrypt: ", ctx.Logger);
                break;
            }

            default:
                ctx.Logger.LogMessage("Unknown benchmark type.");
                return;
            }
        }
示例#17
0
        private Result SetPk11Storage()
        {
            // Read the PK11 header from the body storage
            int pk11Offset = IsModern ? ModernStage1Size : LegacyStage1Size;

            Result rc = BodyStorage.Read(pk11Offset, SpanHelpers.AsByteSpan(ref _pk11Header));

            if (rc.IsFailure())
            {
                return(rc);
            }

            // Check if PK11 is already decrypted, creating the PK11 storage if it is
            IsDecrypted = _pk11Header.Magic == Package1Pk11Header.ExpectedMagic;

            if (IsDecrypted)
            {
                Pk11Storage = new SubStorage(BodyStorage, pk11Offset, Pk11Size);
                return(Result.Success);
            }

            var encPk11Storage = new SubStorage(BodyStorage, pk11Offset, Pk11Size);

            // See if we have an Erista package1 key that can decrypt this PK11
            if (!IsMariko && TryFindEristaKeyRevision())
            {
                IsDecrypted = true;
                IStorage decPk11Storage;

                if (IsModern)
                {
                    decPk11Storage = new AesCbcStorage(encPk11Storage, KeySet.Package1Keys[KeyRevision],
                                                       _stage1Footer.Iv, true);
                }
                else
                {
                    decPk11Storage = new Aes128CtrStorage(encPk11Storage,
                                                          KeySet.Package1Keys[KeyRevision].DataRo.ToArray(), _stage1Footer.Iv.ToArray(), true);
                }

                Pk11Storage = new CachedStorage(decPk11Storage, 0x4000, 1, true);

                return(Result.Success);
            }

            // We can't decrypt the PK11. Set Pk11Storage to the encrypted PK11 storage
            Pk11Storage = encPk11Storage;
            return(Result.Success);
        }
示例#18
0
文件: Nca.cs 项目: garoxas/LibHac
        private IStorage OpenAesCtrExStorage(IStorage baseStorage, int index, bool decrypting)
        {
            NcaFsHeader    fsHeader = 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;
            IStorage outputBucketTreeData;

            if (decrypting)
            {
                bucketTreeData       = new CachedStorage(new Aes128CtrStorage(baseStorage.Slice(bktrOffset, bktrSize), key, counter, true), 4, true);
                outputBucketTreeData = bucketTreeData;
            }
            else
            {
                bucketTreeData       = baseStorage.Slice(bktrOffset, bktrSize);
                outputBucketTreeData = new CachedStorage(new Aes128CtrStorage(baseStorage.Slice(bktrOffset, bktrSize), key, counter, true), 4, true);
            }

            var encryptionBucketTreeData = new SubStorage(bucketTreeData,
                                                          info.EncryptionTreeOffset - bktrOffset, sectionSize - info.EncryptionTreeOffset);

            var cachedBucketTreeData = new CachedStorage(encryptionBucketTreeData, IndirectStorage.NodeSize, 6, true);

            var treeHeader = new BucketTree.Header();

            info.EncryptionTreeHeader.CopyTo(SpanHelpers.AsByteSpan(ref treeHeader));
            long nodeStorageSize  = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
            long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);

            var tableNodeStorage  = new SubStorage(cachedBucketTreeData, 0, nodeStorageSize);
            var tableEntryStorage = new SubStorage(cachedBucketTreeData, nodeStorageSize, entryStorageSize);

            IStorage decStorage = new Aes128CtrExStorage(baseStorage.Slice(0, dataSize), tableNodeStorage,
                                                         tableEntryStorage, treeHeader.EntryCount, key, counterEx, true);

            return(new ConcatenationStorage(new[] { decStorage, outputBucketTreeData }, true));
        }
示例#19
0
        public Package2Header(IStorage storage, Keyset keyset, int keyGeneration)
        {
            var reader = new BinaryReader(storage.AsStream());

            byte[] key = keyset.Package2Keys[keyGeneration];

            Signature = reader.ReadBytes(0x100);
            byte[] sigData = reader.ReadBytes(0x100);
            SignatureValidity = CryptoOld.Rsa2048PssVerify(sigData, Signature, keyset.Package2FixedKeyModulus);

            reader.BaseStream.Position -= 0x100;
            Counter = reader.ReadBytes(0x10);

            Stream headerStream = new CachedStorage(new Aes128CtrStorage(storage.Slice(0x100), key, Counter, true), 0x4000, 4, true).AsStream();

            headerStream.Position = 0x10;
            reader = new BinaryReader(headerStream);

            for (int i = 0; i < 4; i++)
            {
                SectionCounters[i] = reader.ReadBytes(0x10);
            }

            Magic      = reader.ReadAscii(4);
            BaseOffset = reader.ReadInt32();

            reader.BaseStream.Position += 4;
            VersionMax = reader.ReadByte();
            VersionMin = reader.ReadByte();

            reader.BaseStream.Position += 2;

            for (int i = 0; i < 4; i++)
            {
                SectionSizes[i] = reader.ReadInt32();
            }

            for (int i = 0; i < 4; i++)
            {
                SectionOffsets[i] = reader.ReadInt32();
            }

            for (int i = 0; i < 4; i++)
            {
                SectionHashes[i] = reader.ReadBytes(0x20);
            }
        }
示例#20
0
文件: Nca.cs 项目: garoxas/LibHac
        public IStorage OpenHeaderStorage(bool openEncrypted)
        {
            long firstSectionOffset = long.MaxValue;
            bool hasEnabledSection  = false;

            // Encrypted portion continues until the first section
            for (int i = 0; i < NcaHeader.SectionCount; i++)
            {
                if (Header.IsSectionEnabled(i))
                {
                    hasEnabledSection  = true;
                    firstSectionOffset = Math.Min(firstSectionOffset, Header.GetSectionStartOffset(i));
                }
            }

            long     headerSize       = hasEnabledSection ? firstSectionOffset : NcaHeader.HeaderSize;
            IStorage rawHeaderStorage = BaseStorage.Slice(0, headerSize);

            if (openEncrypted == IsEncrypted)
            {
                return(rawHeaderStorage);
            }

            IStorage header;

            switch (Header.Version)
            {
            case 3:
                header = new CachedStorage(new Aes128XtsStorage(rawHeaderStorage, KeySet.HeaderKey, NcaHeader.HeaderSectorSize, true, !openEncrypted), 1, true);
                break;

            case 2:
                header = OpenNca2Header(headerSize, !openEncrypted);
                break;

            case 0:
                header = new CachedStorage(new Aes128XtsStorage(BaseStorage.Slice(0, 0x400), KeySet.HeaderKey, NcaHeader.HeaderSectorSize, true, !openEncrypted), 1, true);
                break;

            default:
                throw new NotSupportedException("Unsupported NCA version");
            }

            return(header);
        }
示例#21
0
        public static void ProcessPk21(Context ctx)
        {
            using (var file = new CachedStorage(new LocalStorage(ctx.Options.InFile, FileAccess.Read), 0x4000, 4, false))
            {
                var package2 = new Package2(ctx.Keyset, file);

                ctx.Logger.LogMessage(package2.Print());

                string outDir = ctx.Options.OutDir;

                if (outDir != null)
                {
                    Directory.CreateDirectory(outDir);

                    package2.OpenKernel().WriteAllBytes(Path.Combine(outDir, "Kernel.bin"), ctx.Logger);
                    package2.OpenIni1().WriteAllBytes(Path.Combine(outDir, "INI1.bin"), ctx.Logger);
                    package2.OpenDecryptedPackage().WriteAllBytes(Path.Combine(outDir, "Decrypted.bin"), ctx.Logger);
                }
            }
        }
示例#22
0
        public static void ProcessPk21(Context ctx)
        {
            using (var file = new CachedStorage(new LocalStorage(ctx.Options.InFile, FileAccess.Read), 0x4000, 4, false))
            {
                var package2 = new Package2StorageReader();
                package2.Initialize(ctx.Keyset, file).ThrowIfFailure();

                ctx.Logger.LogMessage(package2.Print());

                string outDir = ctx.Options.OutDir;
                string iniDir = ctx.Options.Ini1OutDir;

                if (iniDir == null && ctx.Options.ExtractIni1)
                {
                    iniDir = Path.Combine(outDir, "INI1");
                }

                if (outDir != null)
                {
                    Directory.CreateDirectory(outDir);

                    package2.OpenPayload(out IStorage kernelStorage, 0).ThrowIfFailure();
                    kernelStorage.WriteAllBytes(Path.Combine(outDir, "Kernel.bin"), ctx.Logger);

                    package2.OpenIni(out IStorage ini1Storage).ThrowIfFailure();
                    ini1Storage.WriteAllBytes(Path.Combine(outDir, "INI1.bin"), ctx.Logger);

                    package2.OpenDecryptedPackage(out IStorage decPackageStorage).ThrowIfFailure();
                    decPackageStorage.WriteAllBytes(Path.Combine(outDir, "Decrypted.bin"), ctx.Logger);
                }

                if (iniDir != null)
                {
                    Directory.CreateDirectory(iniDir);

                    package2.OpenIni(out IStorage ini1Storage).ThrowIfFailure();

                    ProcessKip.ExtractIni1(ini1Storage, iniDir);
                }
            }
        }
示例#23
0
        public IStorage OpenRawStorageWithPatch(Nca patchNca, int index)
        {
            IStorage patchStorage = patchNca.OpenRawStorage(index);
            IStorage baseStorage  = SectionExists(index) ? OpenRawStorage(index) : new NullStorage();

            patchStorage.GetSize(out long patchSize).ThrowIfFailure();
            baseStorage.GetSize(out long baseSize).ThrowIfFailure();

            NcaFsHeader    header    = patchNca.Header.GetFsHeader(index);
            NcaFsPatchInfo patchInfo = header.GetPatchInfo();

            if (patchInfo.RelocationTreeSize == 0)
            {
                return(patchStorage);
            }

            var treeHeader = new BucketTree.Header();

            patchInfo.RelocationTreeHeader.CopyTo(SpanHelpers.AsByteSpan(ref treeHeader));
            long nodeStorageSize  = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
            long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);

            var relocationTableStorage = new SubStorage(patchStorage, patchInfo.RelocationTreeOffset, patchInfo.RelocationTreeSize);
            var cachedTableStorage     = new CachedStorage(relocationTableStorage, IndirectStorage.NodeSize, 4, true);

            var tableNodeStorage  = new SubStorage(cachedTableStorage, 0, nodeStorageSize);
            var tableEntryStorage = new SubStorage(cachedTableStorage, nodeStorageSize, entryStorageSize);

            var storage = new IndirectStorage();

            storage.Initialize(tableNodeStorage, tableEntryStorage, treeHeader.EntryCount).ThrowIfFailure();

            storage.SetStorage(0, baseStorage, 0, baseSize);
            storage.SetStorage(1, patchStorage, 0, patchSize);

            return(storage);
        }
示例#24
0
        private static void Refresh()
        {
            ManagementObjectCollection disks = GetDisks();

            foreach (ManagementObject disk in disks)
            {
                if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering?
                {
                    try
                    {
                        DiskInfo info        = CreateDiskInfo(disk);
                        IStorage diskStorage = new CachedStorage(new DeviceStream(info.PhysicalName, info.Length).AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true);
                        if (InsertNAND(diskStorage, true))
                        {
                            CurrentDisk = info;
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Console.WriteLine("Cannot direct access drive due to lack of permissions.");
                    }
                }
            }
        }
示例#25
0
 private static void Refresh()
 {
     foreach (DiskInfo info in CreateDiskInfos(GetDisks()))
     {
         if (info.Model == "Linux UMS disk 0 USB Device" && info.Partitions > 1) // probably a bad way of filtering?
         {
             try
             {
                 IEnumerable <PartitionInfo> partitions =
                     CreatePartitionInfos(GetPartitions())
                     .Where((p) => info.Index == p.DiskIndex)
                     .OrderBy((p) => p.Index);
                 if (!partitions.Any())
                 {
                     continue; // obv the NAND should have *some* partitions
                 }
                 PartitionInfo lastPartition = partitions.Last();
                 long          length        = (long)(lastPartition.Size + lastPartition.StartingOffset);
                 // thx windows for ignoring the GPT backup AND reporting the size of the disk incorrectly...
                 long missingLength = (0x747BFFE00 - 0x727800000) + 0x200; // (start of GPT backup - end of USER) + length of GPT backup
                 length += missingLength;
                 DeviceStream stream      = new DeviceStream(info.PhysicalName, length);
                 IStorage     diskStorage = new CachedStorage(stream.AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true);
                 if (InsertNAND(diskStorage, true))
                 {
                     CurrentDisk = info;
                     break;
                 }
             }
             catch (UnauthorizedAccessException)
             {
                 MessageBox.Show("Cannot get direct access drive due to lack of permissions.\nReopen HACGUI as administrator to use the plugged in NAND.");
             }
         }
     }
 }
示例#26
0
        /// <summary>
        /// Opens a decrypted <see cref="IStorage"/> of one of the payloads in the package.
        /// </summary>
        /// <param name="payloadStorage">If the method returns successfully, contains an <see cref="IStorage"/>
        /// of the specified payload.</param>
        /// <param name="index">The index of the payload to get. Must me less than <see cref="Package2Header.PayloadCount"/></param>
        /// <returns>The <see cref="Result"/> of the operation.</returns>
        public Result OpenPayload(out IStorage payloadStorage, int index)
        {
            UnsafeHelpers.SkipParamInit(out payloadStorage);

            if ((uint)index >= Package2Header.PayloadCount)
            {
                return(ResultLibHac.ArgumentOutOfRange.Log());
            }

            int offset = _header.Meta.GetPayloadFileOffset(index);
            int size   = (int)_header.Meta.PayloadSizes[index];

            var payloadSubStorage = new SubStorage(_storage, offset, size);

            if (size == 0)
            {
                payloadStorage = payloadSubStorage;
                return(Result.Success);
            }

            byte[] iv = _header.Meta.PayloadIvs[index].Bytes.ToArray();
            payloadStorage = new CachedStorage(new Aes128CtrStorage(payloadSubStorage, _key.DataRo.ToArray(), iv, true), 0x4000, 1, true);
            return(Result.Success);
        }
示例#27
0
        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);
        }