public Segment(SimpleEndianessAwareReader reader, Stream stream, MachO machO) : base(reader, stream) { this.is64 = machO.Is64; Name = ReadSectionOrSegmentName(); Address = ReadUInt32OrUInt64(); Size = ReadUInt32OrUInt64(); FileOffset = ReadUInt32OrUInt64(); var fileSize = ReadUInt32OrUInt64(); MaximalProtection = ReadProtection(); InitialProtection = ReadProtection(); var numberOfSections = Reader.ReadInt32(); Reader.ReadInt32(); // we ignore flags for now if (fileSize > 0) { var streamPosition = Stream.Position; Stream.Seek((long)FileOffset, SeekOrigin.Begin); data = new byte[Size]; var buffer = stream.ReadBytesOrThrow(checked ((int)fileSize)); Array.Copy(buffer, data, buffer.Length); Stream.Position = streamPosition; } var sections = new List <Section>(); for (var i = 0; i < numberOfSections; i++) { var sectionName = ReadSectionOrSegmentName(); var segmentName = ReadSectionOrSegmentName(); // An intermediate object file contains only one segment. // This segment name is empty, its sections segment names are not empty. if (machO.FileType != FileType.Object && segmentName != Name) { throw new InvalidOperationException("Unexpected name of the section's segment."); } var sectionAddress = ReadUInt32OrUInt64(); var sectionSize = ReadUInt32OrUInt64(); var offset = Reader.ReadUInt32(); var alignExponent = Reader.ReadUInt32(); var relocOffset = Reader.ReadUInt32(); var numberOfReloc = Reader.ReadUInt32(); var flags = Reader.ReadUInt32(); _ = Reader.ReadUInt32(); // reserved1 _ = Reader.ReadUInt32(); // reserved2 _ = is64 ? Reader.ReadUInt32() : 0; // reserved3 var section = new Section(sectionName, segmentName, sectionAddress, sectionSize, offset, alignExponent, relocOffset, numberOfReloc, flags, this); sections.Add(section); } Sections = new ReadOnlyCollection <Section>(sections); }
public static MachOResult TryLoad(string fileName, out MachO machO) { machO = null; uint magic; using (var reader = new BinaryReader(File.OpenRead(fileName))) { magic = reader.ReadUInt32(); if (magic != Magic64 && magic != Magic32) { return(MachOResult.NotMachO); } } machO = new MachO(fileName, magic == Magic64); return(MachOResult.OK); }