mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add partial NSO support
This commit is contained in:
parent
34c3ffd37e
commit
73b472befa
2 changed files with 114 additions and 0 deletions
|
@ -27,6 +27,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" Condition=" '$(TargetFramework)' == 'net46' " />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
113
libhac/Nso.cs
Normal file
113
libhac/Nso.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
using LibHac.Streams;
|
||||
using LZ4;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace LibHac
|
||||
{
|
||||
public class Nso
|
||||
{
|
||||
public NsoSection[] Sections;
|
||||
public RodataRelativeExtent[] RodataRelativeExtents;
|
||||
public uint BssSize;
|
||||
public byte[] BuildID = new byte[0x20];
|
||||
|
||||
private BinaryReader reader;
|
||||
|
||||
public Nso(Stream stream)
|
||||
{
|
||||
reader = new BinaryReader(stream);
|
||||
if (reader.ReadAscii(4) != "NSO0")
|
||||
throw new InvalidDataException("NSO magic is incorrect!");
|
||||
reader.ReadUInt32(); // Version
|
||||
reader.ReadUInt32(); // Reserved/Unused
|
||||
BitArray flags = new BitArray(new int[] { (int) reader.ReadUInt32() });
|
||||
NsoSection textSection = new NsoSection(stream);
|
||||
NsoSection rodataSection = new NsoSection(stream);
|
||||
NsoSection dataSection = new NsoSection(stream);
|
||||
textSection.IsCompressed = flags[0];
|
||||
textSection.CheckHash = flags[3];
|
||||
rodataSection.IsCompressed = flags[1];
|
||||
rodataSection.CheckHash = flags[4];
|
||||
dataSection.IsCompressed = flags[2];
|
||||
dataSection.CheckHash = flags[5];
|
||||
|
||||
ReadSegmentHeader(textSection);
|
||||
reader.ReadUInt32(); // Module offset (TODO)
|
||||
ReadSegmentHeader(rodataSection);
|
||||
reader.ReadUInt32(); // Module file size
|
||||
ReadSegmentHeader(dataSection);
|
||||
BssSize = reader.ReadUInt32();
|
||||
reader.Read(BuildID, 0, 0x20);
|
||||
textSection.CompressedSize = reader.ReadUInt32();
|
||||
rodataSection.CompressedSize = reader.ReadUInt32();
|
||||
dataSection.CompressedSize = reader.ReadUInt32();
|
||||
reader.ReadBytes(0x1C); // Padding
|
||||
RodataRelativeExtents = new RodataRelativeExtent[]
|
||||
{
|
||||
ReadRodataRelativeExtent(), ReadRodataRelativeExtent(), ReadRodataRelativeExtent()
|
||||
};
|
||||
|
||||
reader.Read(textSection.Hash, 0, 0x20);
|
||||
reader.Read(rodataSection.Hash, 0, 0x20);
|
||||
reader.Read(dataSection.Hash, 0, 0x20);
|
||||
|
||||
Sections = new NsoSection[] {textSection, rodataSection, dataSection };
|
||||
}
|
||||
|
||||
public void ReadSegmentHeader(NsoSection section)
|
||||
{
|
||||
section.FileOffset = reader.ReadUInt32();
|
||||
section.MemoryOffset = reader.ReadUInt32();
|
||||
section.DecompressedSize = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
public RodataRelativeExtent ReadRodataRelativeExtent()
|
||||
{
|
||||
RodataRelativeExtent extent = new RodataRelativeExtent();
|
||||
extent.RegionRodataOffset = reader.ReadUInt32();
|
||||
extent.RegionSize = reader.ReadUInt32();
|
||||
return extent;
|
||||
}
|
||||
|
||||
public class NsoSection
|
||||
{
|
||||
private Stream Stream;
|
||||
|
||||
public bool IsCompressed,
|
||||
CheckHash;
|
||||
public uint FileOffset,
|
||||
MemoryOffset,
|
||||
DecompressedSize,
|
||||
CompressedSize;
|
||||
public byte[] Hash = new byte[0x20];
|
||||
|
||||
public NsoSection(Stream stream)
|
||||
{
|
||||
Stream = stream;
|
||||
}
|
||||
|
||||
public Stream OpenCompressedStream()
|
||||
{
|
||||
return new SubStream(Stream, FileOffset, CompressedSize);
|
||||
}
|
||||
|
||||
public Stream OpenDecompressedStream()
|
||||
{
|
||||
return new LZ4Stream(OpenCompressedStream(), LZ4StreamMode.Decompress);
|
||||
}
|
||||
}
|
||||
|
||||
public class RodataRelativeExtent
|
||||
{
|
||||
public uint
|
||||
RegionRodataOffset,
|
||||
RegionSize;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue