public void Load(ElfEndian endian, ElfClass elfclass, Byte[] data) { if (elfclass == ElfClass.EC_32) { p_type = endian.Convert(BitConverter.ToUInt32(data, 0)); p_offset = endian.Convert(BitConverter.ToUInt32(data, 4)); p_vaddr = endian.Convert(BitConverter.ToUInt32(data, 8)); p_paddr = endian.Convert(BitConverter.ToUInt32(data, 0xC)); p_filesz = endian.Convert(BitConverter.ToUInt32(data, 0x10)); p_memsz = endian.Convert(BitConverter.ToUInt32(data, 0x14)); p_flags = endian.Convert(BitConverter.ToUInt32(data, 0x18)); p_align = endian.Convert(BitConverter.ToUInt32(data, 0x1C)); } else { p_type = endian.Convert(BitConverter.ToUInt32(data, 0)); p_flags = endian.Convert(BitConverter.ToUInt32(data, 4)); p_offset = endian.Convert(BitConverter.ToUInt64(data, 8)); p_vaddr = endian.Convert(BitConverter.ToUInt64(data, 0x10)); p_paddr = endian.Convert(BitConverter.ToUInt64(data, 0x18)); p_filesz = endian.Convert(BitConverter.ToUInt64(data, 0x20)); p_memsz = endian.Convert(BitConverter.ToUInt64(data, 0x28)); p_align = endian.Convert(BitConverter.ToUInt64(data, 0x30)); } }
public void Load(ElfEndian endian, ElfClass elfclass, Byte[] data) { if (elfclass == ElfClass.EC_32) { sh_name = endian.Convert(BitConverter.ToUInt32(data, 0)); sh_type = endian.Convert(BitConverter.ToUInt32(data, 4)); sh_flags = endian.Convert(BitConverter.ToUInt32(data, 8)); sh_addr = endian.Convert(BitConverter.ToUInt32(data, 0xC)); sh_offset = endian.Convert(BitConverter.ToUInt32(data, 0x10)); sh_size = endian.Convert(BitConverter.ToUInt32(data, 0x14)); sh_link = endian.Convert(BitConverter.ToUInt32(data, 0x18)); sh_info = endian.Convert(BitConverter.ToUInt32(data, 0x1C)); sh_addralign = endian.Convert(BitConverter.ToUInt32(data, 0x20)); sh_entsize = endian.Convert(BitConverter.ToUInt32(data, 0x24)); } else { sh_name = endian.Convert(BitConverter.ToUInt32(data, 0)); sh_type = endian.Convert(BitConverter.ToUInt32(data, 4)); sh_flags = endian.Convert(BitConverter.ToUInt64(data, 8)); sh_addr = endian.Convert(BitConverter.ToUInt64(data, 0x10)); sh_offset = endian.Convert(BitConverter.ToUInt64(data, 0x18)); sh_size = endian.Convert(BitConverter.ToUInt64(data, 0x20)); sh_link = endian.Convert(BitConverter.ToUInt32(data, 0x28)); sh_info = endian.Convert(BitConverter.ToUInt32(data, 0x2C)); sh_addralign = endian.Convert(BitConverter.ToUInt64(data, 0x30)); sh_entsize = endian.Convert(BitConverter.ToUInt64(data, 0x38)); } }
public void Save(ElfEndian endian, ElfClass elfclass, ref Byte[] data) { if (elfclass == ElfClass.EC_32) { Array.Copy(BitConverter.GetBytes(endian.Convert(p_type)), 0, data, 0, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_offset)), 0, data, 4, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_vaddr)), 0, data, 8, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_paddr)), 0, data, 0xC, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_filesz)), 0, data, 0x10, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_memsz)), 0, data, 0x14, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(p_flags)), 0, data, 0x18, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)p_align)), 0, data, 0x1C, 4); } else { Array.Copy(BitConverter.GetBytes(endian.Convert(p_type)), 0, data, 0, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(p_flags)), 0, data, 4, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(p_offset)), 0, data, 8, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(p_vaddr)), 0, data, 0x10, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(p_paddr)), 0, data, 0x18, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(p_filesz)), 0, data, 0x20, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(p_memsz)), 0, data, 0x28, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(p_align)), 0, data, 0x30, 8); } }
public void Save(ElfEndian endian, ElfClass elfclass, ref Byte[] data) { if (elfclass == ElfClass.EC_32) { Array.Copy(BitConverter.GetBytes(endian.Convert(sh_name)), 0, data, 0, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_type)), 0, data, 4, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_flags)), 0, data, 8, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_addr)), 0, data, 0xC, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_offset)), 0, data, 0x10, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_size)), 0, data, 0x14, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_link)), 0, data, 0x18, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_info)), 0, data, 0x1C, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_addralign)), 0, data, 0x20, 4); Array.Copy(BitConverter.GetBytes(endian.Convert((UInt32)sh_entsize)), 0, data, 0x24, 4); } else { Array.Copy(BitConverter.GetBytes(endian.Convert(sh_name)), 0, data, 0, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_type)), 0, data, 4, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_flags)), 0, data, 8, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_addr)), 0, data, 0x10, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_offset)), 0, data, 0x18, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_size)), 0, data, 0x20, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_link)), 0, data, 0x28, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_info)), 0, data, 0x2C, 4); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_addralign)), 0, data, 0x30, 8); Array.Copy(BitConverter.GetBytes(endian.Convert(sh_entsize)), 0, data, 0x38, 8); } }
public ElfSHDR(ElfClass elfclass) { if (elfclass == ElfClass.EC_32) { DataSize = 0x28; } else { DataSize = 0x40; } }
public ElfPHDR(ElfClass elfclass) { if (elfclass == ElfClass.EC_32) { DataSize = 0x20; } else { DataSize = 0x38; } }
// Write out the hash table void WriteHash(BinaryWriter s, List <ElfSymbol> syms, ElfClass ec) { // Build hash table long hash_table_start = s.BaseStream.Position; List <int>[] ht = BuildHashTable(syms); WriteIntPtr(s, ht.Length, ec); WriteIntPtr(s, syms.Count, ec); // Build arrays to contain the bucket and chains long[] buckets = new long[ht.Length]; long[] chains = new long[syms.Count]; // Iterate through each chain for (int i = 0; i < ht.Length; i++) { List <int> bucket = ht[i]; if (bucket == null) { continue; } for (int j = 0; j < bucket.Count; j++) { int chain = bucket[j]; // First entry is pointed to by bucket if (j == 0) { buckets[i] = chain; } int next_chain = 0; if (j < (bucket.Count - 1)) { next_chain = bucket[j + 1]; } chains[chain] = next_chain; } } // Write out foreach (long b in buckets) { WriteIntPtr(s, b, ec); } foreach (long c in chains) { WriteIntPtr(s, c, ec); } }
void WriteIntPtr(BinaryWriter s, long val, ElfClass ec) { switch (ec) { case ElfClass.ELFCLASS32: case ElfClass.ELFCLASS64: s.Write((int)val); break; default: throw new Exception("Unsupported elf class value: " + ec.ToString()); } }
public static void GetEmbeddedModule(ModuleReader reader) { // Read the elf identifier. byte[] ident; reader.Read(out ident, (int)ElfIdent.EI_NIDENT); // Check the magic number. for (int i = 0; i < ElfMagic.Length; ++i) { if (ident[i] != ElfMagic[i]) { throw new ModuleException("File is not an ELF."); } } // Check the version. if (ident[(int)ElfIdent.EI_VERSION] != (int)ElfVersion.EV_CURRENT) { throw new ModuleException("Invalid elf version."); } // Check the elf class. ElfClass clazz = (ElfClass)ident[(int)ElfIdent.EI_CLASS]; if (clazz == ElfClass.ELFCLASS32) { GetEmbeddedModule32(reader, ident); } else if (clazz == ElfClass.ELFCLASS64) { GetEmbeddedModule64(reader, ident); } else { throw new ModuleException("Unsupported ELF class."); } }
protected override void Read(System.IO.BinaryReader r) { Init(); // Read e_ident byte[] e_ident = r.ReadBytes(16); if ((e_ident[0] != 0x7f) || (e_ident[1] != (byte)'E') || (e_ident[2] != (byte)'L') || (e_ident[3] != (byte)'F')) throw new Exception("Not an ELF file"); ec = (ElfClass)e_ident[4]; ed = (ElfData)e_ident[5]; if ((ec != ElfClass.ELFCLASS32) && (ec != ElfClass.ELFCLASS64)) throw new Exception("Invalid ELF class: " + e_ident[4].ToString()); if (ed != ElfData.ELFDATA2LSB) throw new Exception("Invalid ELF data type: " + e_ident[5].ToString()); if (e_ident[6] != 1) throw new Exception("Invalid ELF version: " + e_ident[6].ToString()); // Read the rest of the file header switch (ec) { case ElfClass.ELFCLASS32: ReadElf32FileHeader(r); break; case ElfClass.ELFCLASS64: ReadElf64FileHeader(r); break; } // Identify the arch, OS and machine type os = "none"; binary_type = BinaryTypes[ec]; architecture = MachineTypes[e_machine]; // First iterate through and identify the offsets of each section List<long> sect_offsets = new List<long>(); for (int i = 0; i < e_shnum; i++) { long sh_start = e_shoff + i * e_shentsize; r.BaseStream.Seek(sh_start, System.IO.SeekOrigin.Begin); switch (ec) { case ElfClass.ELFCLASS32: r.BaseStream.Seek(16, System.IO.SeekOrigin.Current); sect_offsets.Add(r.ReadInt32()); break; case ElfClass.ELFCLASS64: r.BaseStream.Seek(24, System.IO.SeekOrigin.Current); sect_offsets.Add(r.ReadInt64()); break; } } // Now load the section data List<SectionHeader> sect_headers = new List<SectionHeader>(); for (int i = 0; i < e_shnum; i++) { // First load the section header long sh_start = e_shoff + i * e_shentsize; r.BaseStream.Seek(sh_start, System.IO.SeekOrigin.Begin); SectionHeader sh = null; switch (ec) { case ElfClass.ELFCLASS32: sh = ReadElf32SectionHeader(r); break; case ElfClass.ELFCLASS64: sh = ReadElf64SectionHeader(r); break; } sect_headers.Add(sh); // Now get the name string name = "unknown"; if (e_shstrndx != 0) { long name_offset = sect_offsets[e_shstrndx] + sh.sh_name; name = ReadString(r, name_offset); } // Now load the actual section // Decide on the type of section ISection sect = null; switch (sh.sh_type) { case SectionHeader.SHT_NULL: break; case SectionHeader.SHT_PROGBITS: case SectionHeader.SHT_REL: case SectionHeader.SHT_RELA: case SectionHeader.SHT_HASH: case SectionHeader.SHT_DYNAMIC: case SectionHeader.SHT_NOTE: case SectionHeader.SHT_STRTAB: sect = new ContentsSection(this); break; case SectionHeader.SHT_SYMTAB: case SectionHeader.SHT_DYNSYM: sect = new ElfSymbolSection(this); break; case SectionHeader.SHT_NOBITS: sect = new BssSection(this); break; } if (sect != null) { // Interpret the section type sect.IsWriteable = ((sh.sh_flags & SectionHeader.SHF_WRITE) != 0); sect.IsAlloc = ((sh.sh_flags & SectionHeader.SHF_ALLOC) != 0); sect.IsExecutable = ((sh.sh_flags & SectionHeader.SHF_EXECINSTR) != 0); sect.LoadAddress = sh.sh_addr; sect.Name = name; sect.AddrAlign = sh.sh_addralign; // Load the contents if it has any sect.Length = sh.sh_size; if (sect.HasData) { r.BaseStream.Seek(sh.sh_offset, System.IO.SeekOrigin.Begin); for (long l = 0; l < sh.sh_size; l++) sect.Data[(int)l] = r.ReadByte(); } } sections.Add(sect); } // Interpret symbols for (int i = 0; i < e_shnum; i++) { SectionHeader sh = sect_headers[i]; ISection sect = sections[i]; if ((sh.sh_type == SectionHeader.SHT_SYMTAB) && sect.HasData) { int cur_sym = 0; for (long p = 0; p < sect.Length; p += sh.sh_entsize) { ElfSymbol s = null; switch (ec) { case ElfClass.ELFCLASS32: s = ReadElf32Symbol(sect.Data, (int)p); break; case ElfClass.ELFCLASS64: s = ReadElf64Symbol(sect.Data, (int)p); break; } if (s != null) { // Load up the name of the symbol if (sh.sh_link != 0) s.Name = ReadString(sections[sh.sh_link].Data, s.st_name); // Offset s.Offset = s.st_value; // Length s.Size = s.st_size; // Type switch (s.st_bind) { case ElfSymbol.STB_GLOBAL: s.Type = SymbolType.Global; break; case ElfSymbol.STB_LOCAL: s.Type = SymbolType.Local; break; case ElfSymbol.STB_WEAK: s.Type = SymbolType.Weak; break; } switch(s.st_type) { case ElfSymbol.STT_FUNC: s.ObjectType = SymbolObjectType.Function; break; case ElfSymbol.STT_OBJECT: s.ObjectType = SymbolObjectType.Object; break; default: s.ObjectType = SymbolObjectType.Unknown; break; } // DefinedIn if (s.st_shndx == 0) { s.DefinedIn = null; s.Type = SymbolType.Undefined; } else if (s.st_shndx == -15) { // SHN_ABS s.DefinedIn = AbsSection; } else if (s.st_shndx == -14) { // SHN_COMMON s.DefinedIn = CommonSection; } else s.DefinedIn = sections[s.st_shndx]; } if(!symbols.Contains(s)) symbols.Add(s); ((ElfSymbolSection)sect).elf_syms[cur_sym++] = s; } } } // Interpret relocations for (int i = 0; i < e_shnum; i++) { SectionHeader sh = sect_headers[i]; ISection sect = sections[i]; switch (sh.sh_type) { case SectionHeader.SHT_REL: ReadRelocationSection(sh, sect, sections, false); break; case SectionHeader.SHT_RELA: ReadRelocationSection(sh, sect, sections, true); break; } } }