public void WrongVersion()
        {
            elfData[TestData.versionIndex] = ElfHeader.CurrentElfVersion - 1;
            var dataReader = new BinaryReader(new MemoryStream(elfData));

            Assert.IsFalse(ElfHeader.TryRead(dataReader, out ElfHeader h));
        }
Exemple #2
0
        public Elf(Stream input)
        {
            var reader = new BinaryReader(input);

            _header = ElfHeader.Read(reader);

            if (_header.e_type != 1)
                throw new InvalidDataException("Only relocatable objects are supported");
            if (_header.e_machine != 0x14)
                throw new InvalidDataException("Only PowerPC is supported");

            input.Seek(_header.e_shoff, SeekOrigin.Begin);
            for (int i = 0; i < _header.e_shnum; i++)
            {
                _sections.Add(ElfSection.Read(reader));
            }

            if (_header.e_shstrndx > 0 && _header.e_shstrndx < _sections.Count)
            {
                var table = _sections[_header.e_shstrndx].data;

                for (int i = 0; i < _sections.Count; i++)
                {
                    _sections[i].name = Util.ExtractNullTerminatedString(table, (int)_sections[i].sh_name);
                }
            }
        }
Exemple #3
0
        public Elf(byte[] data)
        {
            var er = new EndianBinaryReader(new MemoryStream(data), Endianness.LittleEndian);

            Header = new ElfHeader(er);

            er.BaseStream.Position = Header.ProgramHeaderTableOffset;
            ProgramHeaderTable     = new ProgramHeaderTableEntry[Header.ProgramHeaderTableEntryCount];
            for (int i = 0; i < Header.ProgramHeaderTableEntryCount; i++)
            {
                ProgramHeaderTable[i] = new ProgramHeaderTableEntry(er);
            }

            er.BaseStream.Position = Header.SectionHeaderTableOffset;
            SectionHeaderTable     = new SectionHeaderTableEntry[Header.SectionHeaderTableEntryCount];
            for (int i = 0; i < Header.SectionHeaderTableEntryCount; i++)
            {
                SectionHeaderTable[i] = new SectionHeaderTableEntry(er);
            }

            er.Close();

            var namestab = new ElfStrtab(SectionHeaderTable[Header.SectionNamesIndex], null);

            Sections = new ElfSection[SectionHeaderTable.Length];
            for (int i = 0; i < SectionHeaderTable.Length; i++)
            {
                Sections[i] = ElfSection.CreateInstance(SectionHeaderTable[i],
                                                        namestab.GetString(SectionHeaderTable[i].NameOffset));
            }
        }
Exemple #4
0
        static string ReadString(ElfHeader ehdr, uint strtabndx, uint strndx)
        {
            long old_pos = ehdr.r.BaseStream.Position;

            Section str_sect = ehdr.all_sects[(int)strtabndx];

            ehdr.r.BaseStream.Seek((long)str_sect.sh_offset + (long)strndx, SeekOrigin.Begin);

            byte        cur_byte;
            List <char> str = new List <char>();

            do
            {
                cur_byte = ehdr.r.ReadByte();

                if (cur_byte != 0)
                {
                    str.Add((char)cur_byte);
                }
            } while (cur_byte != 0);
            string ret = new string(str.ToArray());

            ehdr.r.BaseStream.Seek(old_pos, SeekOrigin.Begin);
            return(ret);
        }
Exemple #5
0
        public Elf(Stream input)
        {
            var reader = new BinaryReader(input);

            _header = ElfHeader.Read(reader);

            if (_header.e_type != 1)
            {
                throw new InvalidDataException("Only relocatable objects are supported");
            }
            if (_header.e_machine != 0x14)
            {
                throw new InvalidDataException("Only PowerPC is supported");
            }


            input.Seek(_header.e_shoff, SeekOrigin.Begin);
            for (int i = 0; i < _header.e_shnum; i++)
            {
                _sections.Add(ElfSection.Read(reader));
            }

            if (_header.e_shstrndx > 0 && _header.e_shstrndx < _sections.Count)
            {
                var table = _sections[_header.e_shstrndx].data;

                for (int i = 0; i < _sections.Count; i++)
                {
                    _sections[i].name = Util.ExtractNullTerminatedString(table, (int)_sections[i].sh_name);
                }
            }
        }
        public void WrongEndianness()
        {
            elfData[TestData.endiannessIndex] = (byte)ElfHeader.Endianness.Big;
            var dataReader = new BinaryReader(new MemoryStream(elfData));

            Assert.IsFalse(ElfHeader.TryRead(dataReader, out ElfHeader h));
        }
        public void WrongMagicNumber()
        {
            elfData[0] = 0;
            var dataReader = new BinaryReader(new MemoryStream(elfData));

            Assert.IsFalse(ElfHeader.TryRead(dataReader, out ElfHeader h));
        }
        public void ShortStream()
        {
            var shortData   = elfData.Take(ElfHeader.Size - 1).ToArray();
            var emptyReader = new BinaryReader(new MemoryStream(shortData));

            Assert.IsFalse(ElfHeader.TryRead(emptyReader, out ElfHeader h));
        }
Exemple #9
0
            public static ElfHeader Read(BinaryReader reader)
            {
                var h = new ElfHeader();

                h.ei_mag = reader.ReadBigUInt32();
                if (h.ei_mag != 0x7F454C46) // "\x7F" "ELF"
                {
                    throw new InvalidDataException("Incorrect ELF header");
                }

                h.ei_class = reader.ReadByte();
                if (h.ei_class != 1)
                {
                    throw new InvalidDataException("Only 32-bit ELF files are supported");
                }

                h.ei_data = reader.ReadByte();
                if (h.ei_data != 2)
                {
                    throw new InvalidDataException("Only big-endian ELF files are supported");
                }

                h.ei_version = reader.ReadByte();
                if (h.ei_version != 1)
                {
                    throw new InvalidDataException("Only ELF version 1 is supported [a]");
                }

                h.ei_osabi      = reader.ReadByte();
                h.ei_abiversion = reader.ReadByte();
                reader.BaseStream.Seek(7, SeekOrigin.Current);

                h.e_type    = reader.ReadBigUInt16();
                h.e_machine = reader.ReadBigUInt16();
                h.e_version = reader.ReadBigUInt32();
                if (h.e_version != 1)
                {
                    throw new InvalidDataException("Only ELF version 1 is supported [b]");
                }

                h.e_entry     = reader.ReadBigUInt32();
                h.e_phoff     = reader.ReadBigUInt32();
                h.e_shoff     = reader.ReadBigUInt32();
                h.e_flags     = reader.ReadBigUInt32();
                h.e_ehsize    = reader.ReadBigUInt16();
                h.e_phentsize = reader.ReadBigUInt16();
                h.e_phnum     = reader.ReadBigUInt16();
                h.e_shentsize = reader.ReadBigUInt16();
                h.e_shnum     = reader.ReadBigUInt16();
                h.e_shstrndx  = reader.ReadBigUInt16();

                return(h);
            }
        private ArchiveEntryType GetArchiveEntryType(byte[] fileHeader)
        {
            if (ElfFile.IsElfFile(fileHeader))
            {
                ElfHeader elfHeader = ElfFile.ReadHeader(fileHeader);

                if (elfHeader.@class == ElfClass.Elf32)
                {
                    return(ArchiveEntryType.Executable32);
                }
                else
                {
                    return(ArchiveEntryType.Executable64);
                }
            }

            return(ArchiveEntryType.None);
        }
Exemple #11
0
            public static ElfHeader Read(BinaryReader reader)
            {
                var h = new ElfHeader();

                h.ei_mag = reader.ReadBigUInt32();
                if (h.ei_mag != 0x7F454C46) // "\x7F" "ELF"
                    throw new InvalidDataException("Incorrect ELF header");

                h.ei_class = reader.ReadByte();
                if (h.ei_class != 1)
                    throw new InvalidDataException("Only 32-bit ELF files are supported");

                h.ei_data = reader.ReadByte();
                if (h.ei_data != 2)
                    throw new InvalidDataException("Only big-endian ELF files are supported");

                h.ei_version = reader.ReadByte();
                if (h.ei_version != 1)
                    throw new InvalidDataException("Only ELF version 1 is supported [a]");

                h.ei_osabi = reader.ReadByte();
                h.ei_abiversion = reader.ReadByte();
                reader.BaseStream.Seek(7, SeekOrigin.Current);

                h.e_type = reader.ReadBigUInt16();
                h.e_machine = reader.ReadBigUInt16();
                h.e_version = reader.ReadBigUInt32();
                if (h.e_version != 1)
                    throw new InvalidDataException("Only ELF version 1 is supported [b]");

                h.e_entry = reader.ReadBigUInt32();
                h.e_phoff = reader.ReadBigUInt32();
                h.e_shoff = reader.ReadBigUInt32();
                h.e_flags = reader.ReadBigUInt32();
                h.e_ehsize = reader.ReadBigUInt16();
                h.e_phentsize = reader.ReadBigUInt16();
                h.e_phnum = reader.ReadBigUInt16();
                h.e_shentsize = reader.ReadBigUInt16();
                h.e_shnum = reader.ReadBigUInt16();
                h.e_shstrndx = reader.ReadBigUInt16();

                return h;
            }
Exemple #12
0
        public ElfHeader Read(string filename, libtysila.Assembler.FileLoader floader)
        {
            fname = filename;
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);

            r = new BinaryReader(fs);

            ehdr       = new ElfHeader();
            ehdr.r     = r;
            ehdr.fname = filename;

            // Check its an ELF file
            ehdr.e_ident1 = r.ReadUInt32();
            if (ehdr.e_ident1 != 0x464c457f)
            {
                throw new Exception("Not an ELF file");
            }

            ehdr.ei_class = r.ReadByte();
            if (ehdr.ei_class != 0x2)
            {
                throw new Exception("Not an ELF64 file");
            }
            ehdr.ei_data = r.ReadByte();
            if (ehdr.ei_data != 0x1)
            {
                throw new Exception("Not an ELF64 LSB file");
            }
            ehdr.ei_version    = r.ReadByte();
            ehdr.ei_osabi      = r.ReadByte();
            ehdr.ei_abiversion = r.ReadByte();

            r.BaseStream.Seek(16, SeekOrigin.Begin);
            ehdr.e_type        = r.ReadUInt16();
            ehdr.e_machinetype = r.ReadUInt16();
            ehdr.e_version     = r.ReadUInt32();
            ehdr.e_entry       = r.ReadUInt64();
            ehdr.e_phoff       = r.ReadUInt64();
            ehdr.e_shoff       = r.ReadUInt64();
            ehdr.e_flags       = r.ReadUInt32();
            ehdr.e_ehsize      = r.ReadUInt16();
            ehdr.e_phentsize   = r.ReadUInt16();
            ehdr.e_phnum       = r.ReadUInt16();
            ehdr.e_shentsize   = r.ReadUInt16();
            ehdr.e_shnum       = r.ReadUInt16();
            ehdr.e_shstrndx    = r.ReadUInt16();

            bool is_exec = (ehdr.e_type == 0x2);

            if (!is_exec)
            {
                throw new Exception("Not an ELF64 executable");
            }

            // Now load the sections
            r.BaseStream.Seek((long)ehdr.e_shoff, SeekOrigin.Begin);
            for (int i = 0; i < (int)ehdr.e_shnum; i++)
            {
                r.BaseStream.Seek((long)ehdr.e_shoff + (long)i * (long)ehdr.e_shentsize, SeekOrigin.Begin);

                Section s = new Section();
                s.ehdr         = ehdr;
                s.sh_name      = r.ReadUInt32();
                s.sh_type      = r.ReadUInt32();
                s.sh_flags     = r.ReadUInt64();
                s.sh_addr      = r.ReadUInt64();
                s.sh_offset    = r.ReadUInt64();
                s.sh_size      = r.ReadUInt64();
                s.sh_link      = r.ReadUInt32();
                s.sh_info      = r.ReadUInt32();
                s.sh_addralign = r.ReadUInt64();
                s.sh_entsize   = r.ReadUInt64();
                ehdr.all_sects.Add(s);

                // Decide on the type of the section
                if ((s.sh_type == 1) && ((s.sh_flags & 2) != 0))
                {
                    // Loadable program section
                    ehdr.load_sects.Add(s);
                }
                else if (s.sh_type == 2)
                {
                    // Symbol table
                    ehdr.sym_sects.Add(s);
                }
                else if ((s.sh_type == 4) || (s.sh_type == 9))
                {
                    // Relocation table
                    ehdr.rel_sects.Add(s);
                }
            }

            // Find the comment section
            foreach (Section s in ehdr.all_sects)
            {
                if (s.Name == ".comment")
                {
                    ehdr.r.BaseStream.Seek((long)s.sh_offset, SeekOrigin.Begin);
                    string   comment      = Encoding.UTF8.GetString(ehdr.r.ReadBytes((int)s.sh_size));
                    string[] comments     = comment.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    bool     found_tysila = false;
                    foreach (string c in comments)
                    {
                        if (c.StartsWith("tysila"))
                        {
                            found_tysila = true;
                        }
                        else if (c.StartsWith("endtysila"))
                        {
                            found_tysila = false;
                        }
                        else if (found_tysila)
                        {
                            try
                            {
                                string[] val_args = c.Split(new string[] { ": " }, StringSplitOptions.None);
                                ehdr.comments.Add(val_args[0], val_args[1]);
                            }
                            catch (Exception) { }
                        }
                    }
                }
            }

            SymbolTable stab = new SymbolTable();

            // Now load the symbols
            foreach (Section sym_sect in ehdr.sym_sects)
            {
                for (ulong sym_off = 0; sym_off < sym_sect.sh_size; sym_off += sym_sect.sh_entsize)
                {
                    ehdr.r.BaseStream.Seek((long)sym_sect.sh_offset + (long)sym_off, SeekOrigin.Begin);

                    uint   st_name  = ehdr.r.ReadUInt32();
                    byte   st_info  = ehdr.r.ReadByte();
                    byte   st_other = ehdr.r.ReadByte();
                    ushort st_shndx = ehdr.r.ReadUInt16();
                    ulong  st_value = ehdr.r.ReadUInt64();
                    ulong  st_size  = ehdr.r.ReadUInt64();

                    byte st_type = (byte)(st_info & 0xf);
                    byte st_bind = (byte)((st_info >> 4) & 0xf);

                    if ((st_type == 1) || (st_type == 2))
                    {
                        // STT_OBJECT or STT_FUNC
                        string name = ReadString(ehdr, sym_sect.sh_link, st_name);

                        if (is_exec)
                        {
                            // For executables st_value is the load address of the symbol - we therfore need to find
                            //  its offset from its st_shndx link
                            ulong vaddr = st_value;
                            ulong size  = st_size;

                            Section sect   = ehdr.all_sects[(int)st_shndx];
                            ulong   offset = st_value - sect.sh_addr + sect.sh_offset;
                            stab.Add(name, vaddr, offset, size, ehdr);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }

            // Try and create an assembler
            if (!ehdr.comments.ContainsKey("arch"))
            {
                throw new Exception("Architecture not specified in ELF file");
            }
            try
            {
                stab.ass = libtysila.Assembler.CreateAssembler(libtysila.Assembler.ParseArchitectureString(ehdr.comments["arch"]), floader, null, null);
            }
            catch (Exception e)
            {
                throw new Exception("Unable to create assembler: " + ehdr.comments["arch"] + Environment.NewLine + "Error: " + e.ToString(), e);
            }
            stab.lm   = new LayoutManager(stab.ass, stab);
            ehdr.stab = stab;

            return(ehdr);
        }
        public void EmptyStream()
        {
            var emptyReader = new BinaryReader(new MemoryStream());

            Assert.IsFalse(ElfHeader.TryRead(emptyReader, out ElfHeader h));
        }
Exemple #14
0
 static Section[] ReadSectionHdrs(FileStream stream, ElfHeader elfHdr)
 {
     using (var reader = new BinaryReader(stream, Encoding.ASCII, true))
     {
         var noname_sections = new (uint name_index, uint addr, uint offset, uint size)[elfHdr.SectionHdrEntryNum];