public byte[] UncompressedData()
        {
            using (MemoryMappedFile file = MemoryMappedFile.CreateFromFile(Bundle.FileName, FileMode.Open))
            {
                using (MemoryMappedViewStream viewstream = file.CreateViewStream(PageOFfset, ZSize, MemoryMappedFileAccess.Read))
                {
                    switch (CompressionType)
                    {
                    case "None":
                    {
                        using (MemoryStream destination = new MemoryStream())
                        {
                            viewstream.CopyTo(destination);
                            return(destination.ToArray());
                        }
                    }

                    case "Lz4":
                    {
                        var buffer       = new byte[ZSize];
                        var c            = viewstream.Read(buffer, 0, buffer.Length);
                        var uncompressed = LZ4Codec.Decode(buffer, 0, c, (int)Size);
                        return(uncompressed);
                    }

                    case "Snappy":
                    {
                        var buffer       = new byte[ZSize];
                        var c            = viewstream.Read(buffer, 0, buffer.Length);
                        var uncompressed = SnappyCodec.Uncompress(buffer);
                        return(uncompressed);
                    }

                    case "Doboz":
                    {
                        var buffer       = new byte[ZSize];
                        var c            = viewstream.Read(buffer, 0, buffer.Length);
                        var uncompressed = DobozCodec.Decode(buffer, 0, c);
                        return(uncompressed);
                    }

                    case "Zlib":
                    {
                        using (MemoryStream destination = new MemoryStream())
                        {
                            var zlib = new ZlibStream(viewstream, CompressionMode.Decompress);
                            zlib.CopyTo(destination);
                            return(destination.ToArray());
                        }
                    }

                    default:
                        throw new MissingCompressionException("Unhandled compression algorithm.")
                              {
                                  Compression = Compression
                              };
                    }
                }
            }
        }
 public static void WriteToFile(this MemoryMappedFile mem, string path, long size)
 {
     Directory.CreateDirectory(Path.GetDirectoryName(path) ??
                               throw new InvalidOperationException("Path cannot be null."));
     using (var file = new FileStream(path, FileMode.Create, FileAccess.Write))
     {
         MemoryMappedViewStream m = mem.CreateViewStream(0, size);
         m.CopyTo(file);
     }
 }
Exemple #3
0
        private void ExtractExeFS(Stream output, NCCHRegion region, Keyslot secondaryKeyslot, bool close = true)
        {
            if (secondaryKeyslot == Keyslot.NCCH)
            {
                //if the secondary keyslot is also the original 0x2C NCCH Keyslot, don't bother decrypting anything in parts, and just shove the entire ExeFS through a CryptoStream
                Tools.CryptFileStreamPart(this.NCCHMemoryMappedFile, output, new AesCtrCryptoTransform(this.Cryptor.NormalKey[(int)Keyslot.NCCH], region.CTR), region.Offset, region.Size, close);
                return;
            }

            //here we go, i don't like this part

            byte[] header = new byte[0x200];

            using (MemoryMappedViewStream headerViewStream = this.NCCHMemoryMappedFile.CreateViewStream(region.Offset, 0x200))
            {
                header = Tools.CryptBytes(headerViewStream.ReadBytes(0x200), new AesCtrCryptoTransform(this.Cryptor.NormalKey[0x2C], region.CTR));
            }

            output.Write(header);

            //create dummy ExeFS class instance to figure out the locations of each file in the ExeFS
            ExeFS exefs = new ExeFS(header);

            //write decrypted header to output file
            foreach (ExeFSEntry entry in exefs.Entries)
            {
                byte[] CTR = (region.CTRInt + (entry.Offset / 16)).ToCTRBytes();

                AesCtrCryptoTransform transform = (NormalCryptoExeFSFiles.Contains(entry.Name)) ? new AesCtrCryptoTransform(this.Cryptor.NormalKey[(int)Keyslot.NCCH], CTR) : new AesCtrCryptoTransform(this.Cryptor.NormalKey[(int)secondaryKeyslot], CTR);

                using (MemoryMappedViewStream fileViewStream = this.NCCHMemoryMappedFile.CreateViewStream(region.Offset + entry.Offset, entry.Size))
                {
                    CryptoStream cs = new CryptoStream(output, transform, CryptoStreamMode.Write);

                    output.Seek(entry.Offset, SeekOrigin.Begin);

                    fileViewStream.CopyTo(cs);

                    cs.FlushFinalBlock();
                }
            }

            //sneaky way to make it gm9-like

            if (!(output.GetType() == typeof(MemoryMappedViewStream)))
            {
                output.SetLength(Tools.RoundUp(output.Length, 0x200));
            }

            if (close)
            {
                output.Dispose();
            }
        }
Exemple #4
0
        public static void ExtractFileStreamPart(MemoryMappedFile input, Stream output, long offset, long size, bool close = true)
        {
            using (MemoryMappedViewStream viewStream = input.CreateViewStream(offset, size))
            {
                viewStream.CopyTo(output);

                if (close)
                {
                    output.Dispose();
                }
            }
        }
Exemple #5
0
        public static void CryptFileStreamPart(MemoryMappedFile input, Stream output, ICryptoTransform transform, long offset, long size, bool closeOutputStream = true)
        {
            using (MemoryMappedViewStream viewStream = input.CreateViewStream(offset, size))
            {
                CryptoStream cs = new CryptoStream(output, transform, CryptoStreamMode.Write);
                viewStream.CopyTo(cs);
                cs.FlushFinalBlock();
            }

            if (closeOutputStream)
            {
                output.Dispose();
            }
        }
Exemple #6
0
        public void Decrypt(FileStream outputStream, bool trim = true)
        {
            if (this.Cryptor == null || this.SeedDatabase == null)
            {
                throw new ArgumentException("Cannot decrypt without seed database or crypto engine.");
            }

            long size;

            if (!trim)
            {
                outputStream.SetLength(this.Info.ImageSize);
            }
            else
            {
                size = this.Info.Partitions[0].Offset;

                foreach (NCSDPartition partition in this.Info.Partitions)
                {
                    size += partition.Size;
                }

                outputStream.SetLength(size);
            }

            outputStream.Seek(0, SeekOrigin.Begin);

            MemoryMappedFile outputFile = Tools.LoadFileMapped(outputStream);

            using (MemoryMappedViewStream srcHeaderViewStream = this.NCSDMemoryMappedFile.CreateViewStream(0x0, this.Info.Partitions[0].Offset))
            {
                using (MemoryMappedViewStream destHeaderViewStream = outputFile.CreateViewStream(0x0, this.Info.Partitions[0].Offset))
                {
                    srcHeaderViewStream.CopyTo(destHeaderViewStream);
                }
            }

            foreach (NCSDPartition partition in this.Info.Partitions)
            {
                using (MemoryMappedViewStream destPartitionViewStream = outputFile.CreateViewStream(partition.Offset, partition.Size))
                {
                    NCCH ncch = new NCCH(this.NCSDMemoryMappedFile, partition.Offset, this.Cryptor, this.SeedDatabase);

                    ncch.Decrypt(outputFile);
                }
            }

            if (!trim)
            {
                NCSDPartition lastPartition = this.Info.Partitions.Last();

                long lastPosition = lastPartition.Offset + lastPartition.Size;

                using (MemoryMappedViewStream viewStream = outputFile.CreateViewStream(lastPosition, this.Info.ImageSize - lastPosition))
                {
                    while (viewStream.Position / 64 < viewStream.Length / 64)
                    {
                        byte[] buffer = new byte[64];

                        for (int i = 0; i < buffer.Length; i++)
                        {
                            buffer[i] = 0xFF;
                        }

                        viewStream.Write(buffer, 0, buffer.Length);
                    }
                }
            }
        }