Example #1
0
        public void ShouldChooseGoodClass32()
        {
            var elf = ELFReader.Load("hello32le");

            Assert.AreEqual(Class.Bit32, elf.Class);
        }
Example #2
0
 public void GithubIssueNo9()
 {
     ELFReader.Load(Utilities.GetBinary("stripped-all-binary"));
 }
Example #3
0
        public ElfRunner(string filename, long heapsize, long sealedheapsize, long invisibleheapsize)
        {
            using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                _elfhash = WaterboxUtils.Hash(fs);
            }

            // todo: hack up this baby to take Streams
            _elf = ELFReader.Load <long>(filename);

            var loadsegs = _elf.Segments.Where(s => s.Type == SegmentType.Load);

            long orig_start = loadsegs.Min(s => s.Address);

            orig_start &= ~(Environment.SystemPageSize - 1);
            long orig_end = loadsegs.Max(s => s.Address + s.Size);

            if (HasRelocations())
            {
                _base       = new MemoryBlock((ulong)(orig_end - orig_start));
                _loadoffset = (long)_base.Start - orig_start;
                Initialize(0);
            }
            else
            {
                Initialize((ulong)orig_start);
                _base       = new MemoryBlock((ulong)orig_start, (ulong)(orig_end - orig_start));
                _loadoffset = 0;
                Enter();
            }

            try
            {
                _disposeList.Add(_base);
                AddMemoryBlock(_base, "elf");
                _base.Activate();
                _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.RW);

                foreach (var seg in loadsegs)
                {
                    var data = seg.GetContents();
                    Marshal.Copy(data, 0, Z.SS(seg.Address + _loadoffset), data.Length);
                }
                RegisterSymbols();
                ProcessRelocations();

                _base.Protect(_base.Start, _base.Size, MemoryBlock.Protection.R);

                foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Allocatable) != 0))
                {
                    if ((sec.Flags & SectionFlags.Executable) != 0)
                    {
                        _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RX);
                    }
                    else if ((sec.Flags & SectionFlags.Writable) != 0)
                    {
                        _base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlock.Protection.RW);
                    }
                }

                ulong end = _base.End;

                if (heapsize > 0)
                {
                    _heap = new Heap(GetHeapStart(end), (ulong)heapsize, "sbrk-heap");
                    _heap.Memory.Activate();
                    end = _heap.Memory.End;
                    _disposeList.Add(_heap);
                    AddMemoryBlock(_heap.Memory, "sbrk - heap");
                }

                if (sealedheapsize > 0)
                {
                    _sealedheap = new Heap(GetHeapStart(end), (ulong)sealedheapsize, "sealed-heap");
                    _sealedheap.Memory.Activate();
                    end = _sealedheap.Memory.End;
                    _disposeList.Add(_sealedheap);
                    AddMemoryBlock(_sealedheap.Memory, "sealed-heap");
                }

                if (invisibleheapsize > 0)
                {
                    _invisibleheap = new Heap(GetHeapStart(end), (ulong)invisibleheapsize, "invisible-heap");
                    _invisibleheap.Memory.Activate();
                    end = _invisibleheap.Memory.End;
                    _disposeList.Add(_invisibleheap);
                    AddMemoryBlock(_invisibleheap.Memory, "invisible-heap");
                }

                ConnectAllClibPatches();
                Console.WriteLine("Loaded {0}@{1:X16}", filename, _base.Start);
                foreach (var sec in _elf.Sections.Where(s => s.LoadAddress != 0))
                {
                    Console.WriteLine("  {0}@{1:X16}, size {2}", sec.Name.PadLeft(20), sec.LoadAddress + _loadoffset, sec.Size.ToString().PadLeft(12));
                }

                PrintTopSavableSymbols();
            }
            catch
            {
                Dispose();
                throw;
            }
            finally
            {
                Exit();
            }
        }
Example #4
0
        public void ShouldProperlyParseClass64()
        {
            var elf64 = ELFReader.Load <ulong>(Utilities.GetBinary("hello64le"));

            Assert.AreEqual(Class.Bit64, elf64.Class);
        }
Example #5
0
 public void GithubIssueNo2()
 {
     ELFReader.Load(Utilities.GetBinary("mpuG890.axf"));
 }
Example #6
0
 public void ShouldHandleCorruptedNamesInDynSym()
 {
     ELFReader.Load(Utilities.GetBinaryStream("issue24.elf"), true);
 }
Example #7
0
 public void ShouldOpenHelloWorld64()
 {
     ELFReader.Load(Utilities.GetBinary("hello64le"));
 }
Example #8
0
        public ElfLoader(string moduleName, byte[] fileData, ulong assumedStart, bool skipCoreConsistencyCheck, bool skipMemoryConsistencyCheck)
        {
            ModuleName = moduleName;
            _skipCoreConsistencyCheck   = skipCoreConsistencyCheck;
            _skipMemoryConsistencyCheck = skipMemoryConsistencyCheck;

            _elfHash = WaterboxUtils.Hash(fileData);
            _elf     = ELFReader.Load <ulong>(new MemoryStream(fileData, false), true);

            var loadsegs = _elf.Segments.Where(s => s.Type == SegmentType.Load);
            var start    = loadsegs.Min(s => s.Address);

            start = WaterboxUtils.AlignDown(start);
            var end = loadsegs.Max(s => s.Address + s.Size);

            end = WaterboxUtils.AlignUp(end);
            var size = end - start;

            if (start != assumedStart)
            {
                throw new InvalidOperationException($"{nameof(assumedStart)} did not match actual origin in elf file");
            }

            if (_elf.Sections.Any(s => s.Name.StartsWith(".rel")))
            {
                throw new InvalidOperationException("Elf has relocations!");
            }

            _allSymbols = ((ISymbolTable)_elf.GetSection(".symtab"))
                          .Entries
                          .Cast <SymbolEntry <ulong> >()
                          .ToList();

            _sectionsByName = _elf.Sections
                              .ToDictionary(s => s.Name);

            _sectionsByName.TryGetValue(".wbxsyscall", out _imports);
            if (_imports == null)
            {
                // Likely cause:  This is a valid elf file, but it was not compiled by our toolchain at all
                throw new InvalidOperationException("Missing .wbxsyscall section!");
            }
            _sectionsByName.TryGetValue(".sealed", out _sealed);
            _sectionsByName.TryGetValue(".invis", out _invisible);

            _visibleSymbols = _allSymbols
                              .Where(s => s.Binding == SymbolBinding.Global && s.Visibility == SymbolVisibility.Default)
                              .ToDictionary(s => s.Name);

            _importSymbols = _allSymbols
                             // TODO: No matter what attributes I provide, I seem to end up with Local and/or Hidden symbols in
                             // .wbxsyscall a lot of the time on heavily optimized release builds.
                             // Fortunately, there's nothing else in .wbxsyscall so we can just not filter at all.
                             .Where(s => s.PointedSection == _imports)
                             .ToList();

            Memory = MemoryBlock.Create(start, size);
            Memory.Activate();
            Memory.Protect(Memory.Start, Memory.Size, MemoryBlock.Protection.RW);

            foreach (var seg in loadsegs)
            {
                var data = seg.GetFileContents();
                Marshal.Copy(data, 0, Z.US(seg.Address), Math.Min((int)seg.Size, (int)seg.FileSize));
            }

            {
                // Compute RW boundaries

                var allocated = _elf.Sections
                                .Where(s => (s.Flags & SectionFlags.Allocatable) != 0);
                var writable = allocated
                               .Where(s => (s.Flags & SectionFlags.Writable) != 0);
                var postSealWritable = writable
                                       .Where(s => !IsSpecialReadonlySection(s));
                var saveable = postSealWritable
                               .Where(s => s != _invisible);
                var executable = allocated
                                 .Where(s => (s.Flags & SectionFlags.Executable) != 0);

                _writeStart         = WaterboxUtils.AlignDown(writable.Min(s => s.LoadAddress));
                _postSealWriteStart = WaterboxUtils.AlignDown(postSealWritable.Min(s => s.LoadAddress));
                _execEnd            = WaterboxUtils.AlignUp(executable.Max(s => s.LoadAddress + s.Size));

                // validate; this may require linkscript cooperation
                // due to the segment limitations, the only thing we'd expect to catch is a custom eventually readonly section
                // in the wrong place (because the linkscript doesn't know "eventually readonly")
                if (_execEnd > _writeStart)
                {
                    throw new InvalidOperationException($"ElfLoader: Executable data to {_execEnd:X16} overlaps writable data from {_writeStart}");
                }
            }

            PrintSections();
            PrintGdbData();
            PrintTopSavableSymbols();
            Protect();
        }
Example #9
0
 public void GithubIssueNo2()
 {
     ELFReader.Load(Utilities.GetBinaryStream("mpuG890.axf"), true);
 }
Example #10
0
        public void ShouldChooseGoodClass32()
        {
            var elf = ELFReader.Load(Utilities.GetBinaryLocation("hello32le"));

            Assert.AreEqual(Class.Bit32, elf.Class);
        }
Example #11
0
        public void ShouldFindProperNumberOfSections64()
        {
            var elf = ELFReader.Load(Utilities.GetBinaryLocation("hello64le"));

            Assert.AreEqual(30, elf.Sections.Count());
        }
Example #12
0
 public void ShouldOpenHelloWorld32()
 {
     ELFReader.Load(Utilities.GetBinaryLocation("hello32le"));
 }
Example #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ElfCoreDump"/> class.
        /// </summary>
        /// <param name="coreDumpPath">The core dump path.</param>
        public ElfCoreDump(string coreDumpPath)
        {
            elf = ELFReader.Load <ulong>(coreDumpPath);
            if (elf.Type != FileType.Core)
            {
                throw new Exception($"Expected core dump, but got: {elf.Type}");
            }
            switch (elf.Machine)
            {
            case Machine.Intel386:
                instance = new Intel386Instance(elf);
                break;

            case Machine.AMD64:
                instance = new AMD64Instance(elf);
                break;

            default:
                throw new Exception($"Unsupported machine type: {elf.Machine}");
            }
            Path = coreDumpPath;

            foreach (var segment in elf.Segments)
            {
                if (segment.Type == SegmentType.Note)
                {
                    DwarfMemoryReader reader = new DwarfMemoryReader(ReadSegment(segment));
                    int noteStructSize       = Marshal.SizeOf <elf_32note>();

                    while (reader.Position + noteStructSize < reader.Data.Length)
                    {
                        // Read note
                        elf_32note note    = reader.ReadStructure <elf_32note>();
                        int        nameEnd = reader.Position + (int)note.NameSize;

                        // Check if note is available to be read
                        if (nameEnd + note.n_descsz > reader.Data.Length)
                        {
                            break;
                        }

                        // Read name and content
                        string name = reader.ReadString();
                        reader.Position = nameEnd;
                        byte[] content = reader.ReadBlock(note.n_descsz);

                        instance.ProcessNote(name, content, note.n_type);
                        if (note.n_type == elf_note_type.File)
                        {
                            DwarfMemoryReader data = new DwarfMemoryReader(content);

                            files = elf_note_file.Parse(data, Is64bit);
                        }
                        else if (note.n_type == elf_note_type.Auxv)
                        {
                            DwarfMemoryReader data = new DwarfMemoryReader(content);
                            uint addressSize       = elf.Class == Class.Bit32 ? 4U : 8U;

                            while (!data.IsEnd)
                            {
                                AuxvEntry entry = new AuxvEntry
                                {
                                    Type  = (AuxvEntryType)data.ReadUlong(addressSize),
                                    Value = data.ReadUlong(addressSize)
                                };

                                if (entry.Type == AuxvEntryType.Null)
                                {
                                    break;
                                }

                                if (entry.Type == AuxvEntryType.Ignore)
                                {
                                    continue;
                                }

                                auxVector.Add(entry);
                            }
                        }
                    }
                }
            }

            DumpFileMemoryReader = new CoreDumpReader(coreDumpPath, elf.Segments.Where(s => s.Type == SegmentType.Load));
        }
 public void ShouldFindProperNumberOfSections64()
 {
     using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello64le"), true);
     Assert.AreEqual(30, elf.Sections.Count());
 }
Example #15
0
 public void ShouldLoadSharedObjectElfWithProgramHeaders()
 {
     ELFReader.Load(Utilities.GetBinaryStream("issue3"), true);
 }
Example #16
0
 public void GithubIssueNo24()
 {
     ELFReader.Load(Utilities.GetBinaryStream("issue24.elf"), true);
 }
Example #17
0
 public void ShouldOpenElfWithStripAll()
 {
     ELFReader.Load(Utilities.GetBinaryStream("stripped-all-binary"), true);
 }
Example #18
0
 public void ShouldFindAllSegmentsH32LE()
 {
     using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true);
     Assert.AreEqual(8, elf.Segments.Count());
 }
Example #19
0
        public void ShouldChooseGoodClass64()
        {
            var elf = ELFReader.Load(Utilities.GetBinary("hello64le"));

            Assert.AreEqual(Class.Bit64, elf.Class);
        }
Example #20
0
 public void ShouldFindAllSegmentsOR32BE()
 {
     using var elf = ELFReader.Load(Utilities.GetBinaryStream("vmlinuxOpenRisc"), true);
     Assert.AreEqual(2, elf.Segments.Count());
 }
Example #21
0
        public void ShouldProperlyParseClass32()
        {
            var elf32 = ELFReader.Load <uint>(Utilities.GetBinary("hello32le"));

            Assert.AreEqual(Class.Bit32, elf32.Class);
        }
Example #22
0
        public void SegmentsCountShouldBeAvailable()
        {
            var elf = ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true);

            Assert.AreEqual(8, elf.Segments.Count);
        }
Example #23
0
 public void ShouldOpenBigEndian()
 {
     ELFReader.Load(Utilities.GetBinary("vmlinuxOpenRisc"));
 }
Example #24
0
 public void ShouldChooseGoodClass32()
 {
     using var elf = ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true);
     Assert.AreEqual(Class.Bit32, elf.Class);
 }
Example #25
0
 public void GithubIssueNo3()
 {
     ELFReader.Load(Utilities.GetBinary("issue3"));
 }
Example #26
0
 public void ShouldOpenHelloWorld32()
 {
     ELFReader.Load(Utilities.GetBinaryStream("hello32le"), true);
 }
Example #27
0
 public void GithubIssueNo24()
 {
     ELFReader.Load(Utilities.GetBinary("issue24.elf"));
 }
Example #28
0
 public void ShouldOpenElfWithNonUniqueSectionNames()
 {
     ELFReader.Load(Utilities.GetBinaryStream("mpuG890.axf"), true);
 }
Example #29
0
        public void ShouldFindAllSegmentsH32LE()
        {
            var elf = ELFReader.Load(Utilities.GetBinaryLocation("hello32le"));

            Assert.AreEqual(8, elf.Segments.Count());
        }
Example #30
0
 public void GithubIssueNo3()
 {
     ELFReader.Load("issue3");
 }