Ejemplo n.º 1
0
        private void ReadSymbols(Dictionary <string, long> exceptions)
        {
            var symbolTableOffset = Reader.ReadInt32();
            var numberOfSymbols   = Reader.ReadInt32();

            symbols = new Symbol[numberOfSymbols];
            var stringTableOffset = Reader.ReadInt32();

            Reader.ReadInt32(); // string table size

            var symbolStream   = ProvideStream();
            var headerPosition = symbolStream.Position; // location before seeking to symbol table

            symbolStream.Seek(symbolTableOffset, SeekOrigin.Begin);
            using (var symbolReader = new BinaryReader(symbolStream, Encoding.UTF8, true))
            {
                var stringTableStream = ProvideStream();
                for (var i = 0; i < numberOfSymbols; i++)
                {
                    try
                    {
                        var nameOffset          = symbolReader.ReadInt32();
                        var symbolTablePosition = stringTableStream.Position; // location before reading from string table
                        var name = ReadStringFromOffset(stringTableStream, stringTableOffset + nameOffset);
                        stringTableStream.Position = symbolTablePosition;
                        symbolReader.ReadBytes(4); // ignoring for now
                        long value = is64 ? symbolReader.ReadInt64() : symbolReader.ReadInt32();
                        symbols[i] = new Symbol(name, value);
                    }
                    catch (Exception e)
                    {
                        if (exceptions != null)
                        {
                            MachOReader.AddException(exceptions, e.Message);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
            symbolStream.Position = headerPosition;
        }
Ejemplo n.º 2
0
        public static IEnumerable <MachO> Enumerate(Stream stream, bool shouldOwnStream)
        {
            // Fat header is always big endian.
            var reader = new SimpleEndianessAwareReader(stream, Endianess.BigEndian, !shouldOwnStream);

            // We assume that fat magic has been already read.
            var machOCount      = reader.ReadInt32();
            var alreadyRead     = 0;
            var fatEntriesBegin = stream.Position;

            while (alreadyRead < machOCount)
            {
                // We're only interested in offset and size.
                stream.Seek(fatEntriesBegin + 20 * alreadyRead + 8, SeekOrigin.Begin);
                var offset    = reader.ReadInt32();
                var size      = reader.ReadInt32();
                var substream = new SubStream(stream, offset, size);
                yield return(MachOReader.Load(substream, false));

                alreadyRead++;
            }
        }
Ejemplo n.º 3
0
        private void ReadCommands(int noOfCommands, BinaryReader reader)
        {
            for (var i = 0; i < noOfCommands; i++)
            {
                try
                {
                    var loadCommandType = reader.ReadUInt32();
                    var commandSize     = reader.ReadUInt32();
                    switch ((CommandType)loadCommandType)
                    {
                    case CommandType.SymbolTable:
                        commands[i] = new SymbolTable(reader, OpenStream, is64, throwExceptions ? null : Exceptions);
                        break;

                    case CommandType.Main:
                        commands[i] = new EntryPoint(reader, OpenStream);
                        break;

                    case CommandType.Segment:
                    case CommandType.Segment64:
                        commands[i] = new Segment(reader, OpenStream, is64, throwExceptions ? null : Exceptions);
                        break;

                    default:
                        reader.ReadBytes((int)commandSize - 8);     // 8 bytes is the size of the common command header
                        break;
                    }
                }
                catch (Exception e)
                {
                    if (!throwExceptions)
                    {
                        MachOReader.AddException(Exceptions, e.Message);
                    }
                    throw;
                }
            }
        }
Ejemplo n.º 4
0
        public Segment(BinaryReader reader, Func <Stream> streamProvider, bool is64, Dictionary <String, long> exceptionsToQueue = null) : base(reader, streamProvider)
        {
            this.is64 = is64;
            Name      = ReadSectionOrSegmentName();
            Address   = ReadInt32OrInt64();
            Size      = ReadInt32OrInt64();
            var fileOffset = ReadInt32OrInt64();
            var fileSize   = ReadInt32OrInt64();

            MaximalProtection = ReadProtection();
            InitialProtection = ReadProtection();
            var numberOfSections = Reader.ReadInt32();

            Reader.ReadInt32(); // we ignore flags for now
            if (fileSize > 0)
            {
                data = new byte[Size];
                var stream           = streamProvider();
                var previousPosition = stream.Position;
                stream.Seek(fileOffset, SeekOrigin.Begin);
                var buffer = stream.ReadBytesOrThrow(checked ((int)fileSize), exceptionsToQueue);
                Array.Copy(buffer, data, buffer.Length);
                stream.Position = previousPosition;
            }
            var sections = new List <Section>();

            try
            {
                for (var i = 0; i < numberOfSections; i++)
                {
                    var sectionName = ReadSectionOrSegmentName();
                    var segmentName = ReadSectionOrSegmentName();
                    // set name to segment name in edge case where name is empty string
                    if (string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(segmentName))
                    {
                        Name = segmentName;
                    }
                    if (segmentName != Name)
                    {
                        if (exceptionsToQueue == null)
                        {
                            throw new InvalidOperationException(UNEXPECTED_SEGMENT_NAME);
                        }
                        else
                        {
                            MachOReader.AddException(exceptionsToQueue, UNEXPECTED_SEGMENT_NAME);
                        }
                    }
                    var sectionAddress  = ReadInt32OrInt64();
                    var sectionSize     = ReadInt32OrInt64();
                    var offsetInSegment = ReadInt32OrInt64() - fileOffset;
                    if (offsetInSegment < 0)
                    {
                        if (exceptionsToQueue == null)
                        {
                            throw new InvalidOperationException(UNEXPECTED_SECTION_OFFSET);
                        }
                        else
                        {
                            MachOReader.AddException(exceptionsToQueue, UNEXPECTED_SECTION_OFFSET);
                        }
                    }
                    var alignExponent = Reader.ReadInt32();
                    Reader.ReadBytes(20);
                    var section = new Section(sectionName, sectionAddress, sectionSize, offsetInSegment, alignExponent, this);
                    sections.Add(section);
                }
            }
            finally
            {
                Sections = new ReadOnlyCollection <Section>(sections);
            }
        }