diff --git a/NyaFs/Filesystem/Cpio/CpioFsReader.cs b/NyaFs/Filesystem/Cpio/CpioFsReader.cs index 8c537b1..bab486d 100644 --- a/NyaFs/Filesystem/Cpio/CpioFsReader.cs +++ b/NyaFs/Filesystem/Cpio/CpioFsReader.cs @@ -28,11 +28,11 @@ private void Init() var F = new Types.CpioNode(Raw); if (!FI.IsTrailer) - { Nodes.Add(F); + else + break; - Offset += FI.FullFileBlockSize; - } + Offset += FI.FullFileBlockSize; } else break; @@ -122,7 +122,7 @@ public FilesystemEntry[] ReadDir(string Path) if(Pos == 0) { Pos = Pos + Path.Length + 1; - if(UPath.IndexOf('/', Pos) < 0) + if((Pos < UPath.Length) && UPath.IndexOf('/', Pos) < 0) { Res.Add(new FilesystemEntry(N.FsType, UPath, N.UserId, N.GroupId, N.HexMode, Convert.ToUInt32(N.Content.Length))); } diff --git a/NyaFs/Filesystem/Universal/Items/SymLink.cs b/NyaFs/Filesystem/Universal/Items/SymLink.cs index 572a8b8..c9d6c9a 100644 --- a/NyaFs/Filesystem/Universal/Items/SymLink.cs +++ b/NyaFs/Filesystem/Universal/Items/SymLink.cs @@ -10,13 +10,13 @@ public class SymLink : FilesystemItem public SymLink(string Filename, uint User, uint Group, uint Mode, string Target) : base(Types.FilesystemItemType.SymLink, Filename, User, Group, Mode) { - this.Target = Target; + this.Target = (Target == null) ? "" : Target; } public override string ToString() { return $"LINK {Filename} {User}:{Group} {Mode:x03} => {Target}"; } - public override long Size => Target.Length; + public override long Size => Target?.Length ?? 0; } } diff --git a/NyaFs/ImageFormat/Composite/AndroidImageWriter.cs b/NyaFs/ImageFormat/Composite/AndroidImageWriter.cs new file mode 100644 index 0000000..3dc4dca --- /dev/null +++ b/NyaFs/ImageFormat/Composite/AndroidImageWriter.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NyaFs.ImageFormat.Composite +{ + class AndroidImageWriter + { + private readonly string Path; + + public AndroidImageWriter(string Path) + { + this.Path = Path; + } + + public bool Write(BaseImageBlob Blob) + { + + return false; + } + } +} diff --git a/NyaFs/ImageFormat/Elements/Dtb/Reader/AndroidReader.cs b/NyaFs/ImageFormat/Elements/Dtb/Reader/AndroidReader.cs index e733c8a..b4f5a84 100644 --- a/NyaFs/ImageFormat/Elements/Dtb/Reader/AndroidReader.cs +++ b/NyaFs/ImageFormat/Elements/Dtb/Reader/AndroidReader.cs @@ -23,6 +23,33 @@ public override void ReadToDevTree(DeviceTree Dst) if (Image.IsMagicCorrect) { // TODO: detect, is dtb present in image + if(Image.HeaderVersion == 2) + { + // v2 contains Dtb + var Imagev2 = new Types.Android.AndroidImagev2(Image.getPacket()); + + var Raw = Imagev2.Dtbo; + if(Raw.Length > 0) + { + var Dtb = new FlattenedDeviceTree.Reader.FDTReader(Raw); + if (Dtb.Correct) + { + var Reader = new DtbReader(Raw); + Reader.ReadToDevTree(Dst); + } + else + Log.Error(0, $"Unknown device tree format in android image."); + } + } + else if(Image.HeaderVersion < 2) + { + // No dtb... + } + else + { + // Different image format!.. + throw new NotImplementedException("Android image v3-4 are not supported now!"); + } } } } diff --git a/NyaFs/ImageFormat/Elements/Fs/Reader/AndroidReader.cs b/NyaFs/ImageFormat/Elements/Fs/Reader/AndroidReader.cs index 14d4b7f..2b2cf25 100644 --- a/NyaFs/ImageFormat/Elements/Fs/Reader/AndroidReader.cs +++ b/NyaFs/ImageFormat/Elements/Fs/Reader/AndroidReader.cs @@ -19,28 +19,42 @@ public override void ReadToFs(LinuxFilesystem Dst) { if (Image.IsMagicCorrect) { - // Is legacy image... - uint Magic = Image.Ramdisk.ReadUInt32(0); - if (Magic == 0x56190527) + var Version = Image.HeaderVersion; + if(Version < 3) { - // Parse as legacy - var Reader = new LegacyReader(Image.Ramdisk); - Reader.ReadToFs(Dst); + ReadToFsv0(Dst); } else { - var Comp = (Magic == 0x04224D18) - ? Types.CompressionType.IH_COMP_LZ4 - : Helper.FitHelper.DetectCompression(Image.Ramdisk); + // Different image format!.. + throw new NotImplementedException("Android image v3-4 are not supported now!"); + } + } + } + private void ReadToFsv0(LinuxFilesystem Dst) + { + var RD = Image.Ramdisk; + // Is legacy image... + uint Magic = RD.ReadUInt32(0); + if (Magic == 0x56190527) + { + // Parse as legacy + var Reader = new LegacyReader(RD); + Reader.ReadToFs(Dst); + } + else + { + var Comp = (Magic == 0x04224D18) + ? Types.CompressionType.IH_COMP_LZ4 + : Helper.FitHelper.DetectCompression(RD); - var Uncompressed = Helper.FitHelper.GetDecompressedData(Image.Ramdisk, Comp); + var Uncompressed = Helper.FitHelper.GetDecompressedData(RD, Comp); - Dst.Info.Compression = Comp; - Dst.Info.Type = Types.ImageType.IH_TYPE_RAMDISK; - Dst.Info.OperatingSystem = Types.OS.IH_OS_LINUX; - Dst.Info.DataLoadAddress = Image.RamdiskAddress; - DetectAndRead(Dst, Uncompressed); - } + Dst.Info.Compression = Comp; + Dst.Info.Type = Types.ImageType.IH_TYPE_RAMDISK; + Dst.Info.OperatingSystem = Types.OS.IH_OS_LINUX; + Dst.Info.DataLoadAddress = Image.RamdiskAddress; + DetectAndRead(Dst, Uncompressed); } } } diff --git a/NyaFs/ImageFormat/Elements/Kernel/Reader/AndroidReader.cs b/NyaFs/ImageFormat/Elements/Kernel/Reader/AndroidReader.cs index 7179824..47bf810 100644 --- a/NyaFs/ImageFormat/Elements/Kernel/Reader/AndroidReader.cs +++ b/NyaFs/ImageFormat/Elements/Kernel/Reader/AndroidReader.cs @@ -9,6 +9,7 @@ class AndroidReader : Reader Types.Android.LegacyAndroidImage Image; public AndroidReader(string Filename) : this(System.IO.File.ReadAllBytes(Filename)) { } + public AndroidReader(byte[] Raw) { Image = new Types.Android.LegacyAndroidImage(Raw); @@ -18,11 +19,28 @@ public override void ReadToKernel(LinuxKernel Dst) { if(Image.IsMagicCorrect) { - Dst.Image = Image.Kernel; - Dst.Info.Compression = Types.CompressionType.IH_COMP_NONE; - Dst.Info.DataLoadAddress = Image.KernelAddress; - Dst.Info.EntryPointAddress = Image.KernelAddress; + var Version = Image.HeaderVersion; + if (Version < 3) + { + ReadToKernelv0(Dst); + } + else + { + // Different image format!.. + throw new NotImplementedException("Android image v3-4 are not supported now!"); + } } } + + private void ReadToKernelv0(LinuxKernel Dst) + { + + + // TODO: detect image format... + Dst.Info.Compression = Types.CompressionType.IH_COMP_NONE; + Dst.Info.DataLoadAddress = Image.KernelAddress; + Dst.Info.EntryPointAddress = Image.KernelAddress; + Dst.Image = Image.Kernel; + } } } diff --git a/NyaFs/ImageFormat/Types/Android/AndroidImagev1.cs b/NyaFs/ImageFormat/Types/Android/AndroidImagev1.cs new file mode 100644 index 0000000..fac359d --- /dev/null +++ b/NyaFs/ImageFormat/Types/Android/AndroidImagev1.cs @@ -0,0 +1,41 @@ +using Extension.Array; +using Extension.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NyaFs.ImageFormat.Types.Android +{ + class AndroidImagev1 : LegacyAndroidImage + { + public AndroidImagev1(byte[] Raw) : base(Raw) + { + + } + + /// + /// Recovery dtb size in bytes + /// + public uint RecoveryDtboSize + { + get { return ReadUInt32(0x660); } + set { WriteUInt32(0x660, value); } + } + + /// + /// Recovery dtb address + /// + public ulong RecoveryDtboAddress + { + get { return ReadUInt64(0x664); } + set { WriteUInt64(0x664, value); } + } + + public override long HeaderSize => ReadUInt32(0x66C); + + protected long RecoveryDtboOffset => (SecondOffset + SecondSize).GetAligned(PageSize); + + public byte[] RecoveryDtbo => ReadArray(RecoveryDtboOffset, RecoveryDtboSize); + } +} diff --git a/NyaFs/ImageFormat/Types/Android/AndroidImagev2.cs b/NyaFs/ImageFormat/Types/Android/AndroidImagev2.cs new file mode 100644 index 0000000..1f67215 --- /dev/null +++ b/NyaFs/ImageFormat/Types/Android/AndroidImagev2.cs @@ -0,0 +1,39 @@ +using Extension.Array; +using Extension.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NyaFs.ImageFormat.Types.Android +{ + class AndroidImagev2 : AndroidImagev1 + { + public AndroidImagev2(byte[] Raw) : base(Raw) + { + + } + + /// + /// dtb size in bytes + /// + public uint DtboSize + { + get { return ReadUInt32(0x670); } + set { WriteUInt32(0x670, value); } + } + + /// + /// dtb address + /// + public ulong DtboAddress + { + get { return ReadUInt64(0x674); } + set { WriteUInt64(0x674, value); } + } + + protected long DtboOffset => (RecoveryDtboOffset + RecoveryDtboSize).GetAligned(PageSize); + + public byte[] Dtbo => ReadArray(DtboOffset, DtboSize); + } +} diff --git a/NyaFs/ImageFormat/Types/Android/LegacyAndroidImage.cs b/NyaFs/ImageFormat/Types/Android/LegacyAndroidImage.cs index d47c545..618f0b1 100644 --- a/NyaFs/ImageFormat/Types/Android/LegacyAndroidImage.cs +++ b/NyaFs/ImageFormat/Types/Android/LegacyAndroidImage.cs @@ -59,7 +59,7 @@ public uint RamdiskAddress } /// - /// Second size in bytes + /// Second bootloader size in bytes /// public uint SecondSize { @@ -68,7 +68,7 @@ public uint SecondSize } /// - /// Second address + /// Second bootloader address /// public uint SecondAddress { @@ -157,11 +157,13 @@ public string ExtraAgrs public uint KernelBase => KernelAddress - 0x8000; - private long KernelOffset => HeaderSize.GetAligned(PageSize); - private long RamdiskOffset => (KernelOffset + KernelSize).GetAligned(PageSize); + protected long KernelOffset => HeaderSize.GetAligned(PageSize); + protected long RamdiskOffset => (KernelOffset + KernelSize).GetAligned(PageSize); + protected long SecondOffset => (RamdiskOffset + RamdiskSize).GetAligned(PageSize); public byte[] Kernel => ReadArray(KernelOffset, KernelSize); public byte[] Ramdisk => ReadArray(RamdiskOffset, RamdiskSize); + public byte[] Second => ReadArray(SecondOffset, SecondSize); public HashType DetectedHashType {