Esempio n. 1
0
        internal NoteData(ulong sectionOffset, ulong sectionSize, SimpleEndianessAwareReader reader)
        {
            this.reader = reader;
            var sectionEnd = (long)(sectionOffset + sectionSize);

            reader.BaseStream.Seek((long)sectionOffset, SeekOrigin.Begin);
            var nameSize        = ReadSize();
            var descriptionSize = ReadSize();

            Type = ReadField();
            int remainder;
            var fields          = Math.DivRem(nameSize, FieldSize, out remainder);
            var alignedNameSize = FieldSize * (remainder > 0 ? fields + 1 : fields);

            // We encountered binaries where nameSize and descriptionSize are
            // invalid (i.e. significantly larger than the size of the binary itself).
            // To avoid throwing on such binaries, we only read in name and description
            // if the sizes are within range of the containing section.
            if (reader.BaseStream.Position + alignedNameSize <= sectionEnd)
            {
                var name = reader.ReadBytes(alignedNameSize);
                if (nameSize > 0)
                {
                    Name = Encoding.UTF8.GetString(name, 0, nameSize - 1); // minus one to omit terminating NUL
                }
                if (reader.BaseStream.Position + descriptionSize <= sectionEnd)
                {
                    Description = descriptionSize > 0 ? reader.ReadBytes(descriptionSize) : new byte[0];
                }
            }
        }
Esempio n. 2
0
 internal Segment(long headerOffset, Class elfClass, SimpleEndianessAwareReader reader)
 {
     this.reader       = reader;
     this.headerOffset = headerOffset;
     this.elfClass     = elfClass;
     ReadHeader();
 }
        private void _disassemble()
        {
            Records = new List <InstructionRecord>();
            var sectionsToLoad = _elf.GetSections <ProgBitsSection <uint> >()
                                 .Where(x => x.Type == SectionType.ProgBits && x.Flags.HasFlag(SectionFlags.Executable));

            foreach (var s in sectionsToLoad)
            {
                var  stream   = new MemoryStream(s.GetContents());
                var  reader   = new SimpleEndianessAwareReader(stream, _elf.Endianess);
                uint position = 0;

                while (position < s.Size)
                {
                    var address = s.LoadAddress + position;
                    var chunk   = BitArrayFactory.FromUnsignedInt(
                        reader.ReadUInt32(), InstructionSize * 8
                        );
                    var instruction = _instructionSet.Resolve(chunk) ?? new Instruction("UNKNOWN");
                    instruction.Position = address;
                    instruction.Data     = chunk;

                    Records.Add(
                        new InstructionRecord(s.Name, address, instruction)
                        );
                    position += InstructionSize;
                }
            }
        }
Esempio n. 4
0
        private void ReadCommands(int noOfCommands, Stream stream, SimpleEndianessAwareReader reader)
        {
            for (var i = 0; i < noOfCommands; i++)
            {
                var loadCommandType = reader.ReadUInt32();
                var commandSize     = reader.ReadUInt32();
                switch ((CommandType)loadCommandType)
                {
                case CommandType.SymbolTable:
                    commands[i] = new SymbolTable(reader, stream, is64);
                    break;

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

                case CommandType.Segment:
                case CommandType.Segment64:
                    commands[i] = new Segment(reader, stream, is64);
                    break;

                default:
                    reader.ReadBytes((int)commandSize - 8); // 8 bytes is the size of the common command header
                    break;
                }
            }
        }
 // TODO: make elf consts file with things like SHT_LOUSER
 internal SectionHeader(SimpleEndianessAwareReader reader, Class elfClass, IStringTable table = null)
 {
     this.reader   = reader;
     this.table    = table;
     this.elfClass = elfClass;
     ReadSectionHeader();
 }
Esempio n. 6
0
 internal StringTable(SectionHeader header, SimpleEndianessAwareReader reader) : base(header, reader)
 {
     stringCache = new Dictionary <long, string>
     {
         { 0, string.Empty }
     };
     stringBlob = ReadStringData();
 }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        internal Dylib(SimpleEndianessAwareReader reader, Stream stream, uint commandSize) : base(reader, stream)
        {
            var offset               = reader.ReadUInt32();
            var timestamp            = reader.ReadInt32();
            var currentVersion       = reader.ReadUInt32();
            var compatibilityVersion = reader.ReadUInt32();

            Timestamp            = DateTimeOffset.FromUnixTimeSeconds(timestamp).UtcDateTime;
            CurrentVersion       = GetVersion(currentVersion);
            CompatibilityVersion = GetVersion(compatibilityVersion);
            Name = GetString(reader.ReadBytes((int)(commandSize - offset)));
        }
Esempio n. 9
0
        public Segment(SimpleEndianessAwareReader reader, Stream stream, bool is64) : base(reader, stream)
        {
            this.is64  = 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();
                if (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();
                Reader.ReadBytes(is64 ? 24 : 20);
                var section = new Section(sectionName, sectionAddress, sectionSize, offset, alignExponent, this);
                sections.Add(section);
            }

            Sections = new ReadOnlyCollection <Section>(sections);
        }
Esempio n. 10
0
        internal MachO(Stream stream, bool is64, Endianess endianess, bool ownsStream)
        {
            this.is64 = is64;

            using var reader = new SimpleEndianessAwareReader(stream, endianess, ownsStream);

            Machine = (Machine)reader.ReadInt32();
            reader.ReadBytes(4); // we don't support the cpu subtype now
            FileType = (FileType)reader.ReadUInt32();
            var noOfCommands = reader.ReadInt32();

            reader.ReadInt32();  // size of commands
            reader.ReadBytes(4); // we don't support flags now
            if (is64)
            {
                reader.ReadBytes(4); // reserved
            }
            commands = new Command[noOfCommands];
            ReadCommands(noOfCommands, stream, reader);
        }
Esempio n. 11
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++;
            }
        }
Esempio n. 12
0
 internal ProgBitsSection(SectionHeader header, SimpleEndianessAwareReader reader) : base(header, reader)
 {
 }
Esempio n. 13
0
 public SymbolTable(SimpleEndianessAwareReader reader, Stream stream, bool is64) : base(reader, stream)
 {
     this.is64 = is64;
     ReadSymbols();
 }
Esempio n. 14
0
 public static SegmentType ProbeType(SimpleEndianessAwareReader reader)
 {
     return((SegmentType)reader.ReadUInt32());
 }
Esempio n. 15
0
 public EntryPoint(SimpleEndianessAwareReader reader, Stream stream) : base(reader, stream)
 {
     Value     = Reader.ReadInt64();
     StackSize = Reader.ReadInt64();
 }
Esempio n. 16
0
 internal Command(SimpleEndianessAwareReader reader, Stream stream)
 {
     Stream = stream;
     Reader = reader;
 }
Esempio n. 17
0
 public IdDylib(SimpleEndianessAwareReader reader, Stream stream, uint commandSize) : base(reader, stream, commandSize)
 {
 }
Esempio n. 18
0
 internal NoteSegment(long headerOffset, Class elfClass, SimpleEndianessAwareReader reader)
     : base(headerOffset, elfClass, reader)
 {
     data = new NoteData((ulong)base.Offset, (ulong)base.FileSize, reader);
 }
Esempio n. 19
0
 internal SymbolTable(SectionHeader header, SimpleEndianessAwareReader Reader, IStringTable table, ELF <T> elf) : base(header, Reader)
 {
     this.table = table;
     this.elf   = elf;
     ReadSymbols();
 }
Esempio n. 20
0
 internal Section(SectionHeader header, SimpleEndianessAwareReader reader)
 {
     Header      = header;
     this.Reader = reader;
 }
Esempio n. 21
0
 internal DynamicSection(SectionHeader header, SimpleEndianessAwareReader reader, ELF <T> elf) : base(header, reader)
 {
     this.elf = elf;
     ReadEntries();
 }
Esempio n. 22
0
 internal NoteSection(SectionHeader header, SimpleEndianessAwareReader reader) : base(header, reader)
 {
     data = new NoteData(header.Offset, header.Size, reader);
 }