Exemplo n.º 1
0
 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));
     }
 }
Exemplo n.º 2
0
 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));
     }
 }
Exemplo n.º 3
0
 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);
     }
 }
Exemplo n.º 4
0
 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);
     }
 }
Exemplo n.º 5
0
 public ElfSHDR(ElfClass elfclass)
 {
     if (elfclass == ElfClass.EC_32)
     {
         DataSize = 0x28;
     }
     else
     {
         DataSize = 0x40;
     }
 }
Exemplo n.º 6
0
 public ElfPHDR(ElfClass elfclass)
 {
     if (elfclass == ElfClass.EC_32)
     {
         DataSize = 0x20;
     }
     else
     {
         DataSize = 0x38;
     }
 }
Exemplo n.º 7
0
        // 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);
            }
        }
Exemplo n.º 8
0
        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());
            }
        }
Exemplo n.º 9
0
        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.");
            }
        }
Exemplo n.º 10
0
        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;
                }
            }
        }