public void WrongVersion() { elfData[TestData.versionIndex] = ElfHeader.CurrentElfVersion - 1; var dataReader = new BinaryReader(new MemoryStream(elfData)); Assert.IsFalse(ElfHeader.TryRead(dataReader, out ElfHeader h)); }
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 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)); } }
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); }
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)); }
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); }
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; }
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)); }
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];