Ejemplo n.º 1
0
 public override ISearchData CreateSearchData(IEnumerable <uint> values)
 {
     return(Buffer32.CreateSearchData(values.Select(a => new ValueTuple <byte, byte, byte, byte>(
                                                        (byte)((a >> 24) & 0xFF),
                                                        (byte)((a >> 16) & 0xFF),
                                                        (byte)((a >> 8) & 0xFF),
                                                        (byte)(a & 0xFF))).ToArray()));
 }
Ejemplo n.º 2
0
        private Result ReadSegmentImpl(ref NsoHeader.SegmentHeader segment, uint fileSize, Buffer32 fileHash,
                                       bool isCompressed, bool checkHash, Span <byte> buffer)
        {
            // Select read size based on compression.
            if (!isCompressed)
            {
                fileSize = segment.Size;
            }

            // Validate size.
            if (fileSize > segment.Size)
            {
                return(ResultLoader.InvalidNso.Log());
            }

            // Load data from file.
            uint loadAddress = isCompressed ? (uint)buffer.Length - fileSize : 0;

            Result rc = NsoFile.Read(out long bytesRead, segment.FileOffset, buffer.Slice((int)loadAddress), ReadOption.None);

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

            if (bytesRead != fileSize)
            {
                return(ResultLoader.InvalidNso.Log());
            }

            // Uncompress if necessary.
            if (isCompressed)
            {
                // todo: Fix in-place decompression
                // Lz4.Decompress(buffer.Slice((int)loadAddress), buffer);
                byte[] decomp = Lz4.Decompress(buffer.Slice((int)loadAddress).ToArray(), buffer.Length);
                decomp.CopyTo(buffer);
            }

            // Check hash if necessary.
            if (checkHash)
            {
                Buffer32 hash = default;
                Crypto.Sha256.GenerateSha256Hash(buffer.Slice(0, (int)segment.Size), hash.Bytes);

                if (hash.Bytes.SequenceCompareTo(fileHash.Bytes) != 0)
                {
                    return(ResultLoader.InvalidNso.Log());
                }
            }

            return(Result.Success);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Verifies the hashes of all the payloads in the metadata.
        /// </summary>
        /// <returns>The <see cref="Result"/> of the operation.
        /// <see cref="Result.Success"/> if all the hashes are valid.</returns>
        public Result VerifyPayloads()
        {
            using (var buffer = new RentedArray <byte>(0x10000))
            {
                byte[] array      = buffer.Array;
                var    hashBuffer = new Buffer32();
                var    sha        = new Sha256Generator();

                // Verify hashes match for all payloads.
                for (int i = 0; i < Package2Header.PayloadCount; i++)
                {
                    if (_header.Meta.PayloadSizes[i] == 0)
                    {
                        continue;
                    }

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

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

                    offset = 0;
                    sha.Initialize();

                    while (size > 0)
                    {
                        int         toRead = Math.Min(array.Length, size);
                        Span <byte> span   = array.AsSpan(0, toRead);

                        Result rc = payloadSubStorage.Read(offset, span);
                        if (rc.IsFailure())
                        {
                            return(rc);
                        }

                        sha.Update(span);

                        offset += toRead;
                        size   -= toRead;
                    }

                    sha.GetHash(hashBuffer);

                    if (!CryptoUtil.IsSameBytes(hashBuffer, _header.Meta.PayloadHashes[i], 0x20))
                    {
                        return(ResultLibHac.InvalidPackage2PayloadCorrupted.Log());
                    }
                }
            }

            return(Result.Success);
        }
Ejemplo n.º 4
0
        public NsoExecutable(IStorage inStorage, string name = null)
        {
            NsoReader reader = new NsoReader();

            reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure();

            TextOffset = (int)reader.Header.Segments[0].MemoryOffset;
            RoOffset   = (int)reader.Header.Segments[1].MemoryOffset;
            DataOffset = (int)reader.Header.Segments[2].MemoryOffset;
            BssSize    = (int)reader.Header.BssSize;

            reader.GetSegmentSize(NsoReader.SegmentType.Data, out uint uncompressedSize).ThrowIfFailure();
            Program = new byte[DataOffset + uncompressedSize];

            TextSize = DecompressSection(reader, NsoReader.SegmentType.Text, TextOffset, Program);
            RoSize   = DecompressSection(reader, NsoReader.SegmentType.Ro, RoOffset, Program);
            DataSize = DecompressSection(reader, NsoReader.SegmentType.Data, DataOffset, Program);

            Name    = name;
            BuildId = reader.Header.ModuleId;
        }
Ejemplo n.º 5
0
 public void MoveIn32(short bar, long barOffset, int[] data, int numToRead)
 {
     // A buffer takes priority over individual memory values
     if (Buffer32.ContainsKey(barOffset))
     {
         int[] contents = Buffer32[barOffset];
         Array.Copy(contents, data, Math.Min(contents.Length, numToRead));
     }
     else
     {
         // return individual memory values that fall in the range
         long finalOffset = barOffset + (numToRead - 1) * sizeof(int);
         foreach (var key in mMemory.Keys)
         {
             if (barOffset <= key && key <= finalOffset)
             {
                 int index = (int)(key - barOffset) / sizeof(int);
                 data[index] = mMemory[key];
             }
         }
     }
 }
Ejemplo n.º 6
0
 public long FindBackward(long start, ValueTuple <byte, byte, byte, byte>[] values)
 {
     return(FindBackward(start, Buffer32.CreateSearchData(values)));
 }