public RelocationBucket(BinaryReader reader) { long start = reader.BaseStream.Position; BucketNum = reader.ReadInt32(); EntryCount = reader.ReadInt32(); VirtualOffsetEnd = reader.ReadInt64(); Entries = new RelocationEntry[EntryCount]; for (int i = 0; i < EntryCount; i++) { Entries[i] = new RelocationEntry(reader); } reader.BaseStream.Position = start + 0x4000; }
public Bktr(Stream patchRomfs, Stream baseRomfs, NcaSection section) { if (section.Header.EncryptionType != NcaEncryptionType.AesCtrEx) { throw new ArgumentException("Section is not of type BKTR"); } Patch = patchRomfs ?? throw new NullReferenceException($"{nameof(patchRomfs)} cannot be null"); Base = baseRomfs ?? throw new NullReferenceException($"{nameof(baseRomfs)} cannot be null"); IvfcLevelHeader level5 = section.Header.IvfcInfo.LevelHeaders[5]; Length = level5.LogicalOffset + level5.HashDataSize; using (var reader = new BinaryReader(patchRomfs, Encoding.Default, true)) { patchRomfs.Position = section.Header.BktrInfo.RelocationHeader.Offset; RelocationBlock = new RelocationBlock(reader); } foreach (RelocationBucket bucket in RelocationBlock.Buckets) { RelocationEntries.AddRange(bucket.Entries); } for (int i = 0; i < RelocationEntries.Count - 1; i++) { RelocationEntries[i].Next = RelocationEntries[i + 1]; RelocationEntries[i].VirtOffsetEnd = RelocationEntries[i + 1].VirtOffset; } RelocationEntries[RelocationEntries.Count - 1].VirtOffsetEnd = level5.LogicalOffset + level5.HashDataSize; RelocationOffsets = RelocationEntries.Select(x => x.VirtOffset).ToList(); CurrentEntry = GetRelocationEntry(0); UpdateSourceStreamPositions(); }