Пример #1
0
 private void WriteElf64Segment(ElfProgramHeader ph, System.IO.BinaryWriter w)
 {
     throw new NotImplementedException();
 }
Пример #2
0
        protected override void Write(System.IO.BinaryWriter w)
        {
            Init();

            // First, build a list of output sections
            List<SectionHeader> osects = new List<SectionHeader>();
            Dictionary<ISection, int> osect_map = new Dictionary<ISection, int>();
            osects.Add(new NullSection());

            StringSection strtab = new StringSection();
            StringSection shstrtab = new StringSection();

            foreach(var sect in sections)
            {
                SectionHeader sh = new SectionHeader();
                sh.sh_name = AllocateString(sect.Name, shstrtab);
                if (sect.HasData)
                    sh.sh_type = 1;
                else
                    sh.sh_type = 8;
                sh.sh_flags = 0;
                if (sect.IsWriteable)
                    sh.sh_flags |= 0x1;
                if (sect.IsAlloc)
                    sh.sh_flags |= 0x2;
                if (sect.IsExecutable)
                    sh.sh_flags |= 0x4;
                sh.sh_addr = sect.LoadAddress;
                sh.sh_size = sect.Length;

                sh.sh_link = 0;
                sh.sh_info = 0;
                sh.sh_addralign = sect.AddrAlign;
                sh.sh_entsize = 0;

                osect_map[sect] = osects.Count;
                osects.Add(sh);                
            }

            strtab.sh_name = AllocateString(".strtab", shstrtab);
            int strtab_idx = osects.Count;
            osects.Add(strtab);

            shstrtab.sh_name = AllocateString(".shstrtab", shstrtab);
            int shstrtab_idx = osects.Count;
            e_shstrndx = shstrtab_idx;
            osects.Add(shstrtab);

            SectionHeader symtab = new SectionHeader();
            symtab.sh_name = AllocateString(".symtab", shstrtab);
            symtab.sh_link = strtab_idx;
            symtab.sh_type = 2;
            int symtab_idx = osects.Count;
            osects.Add(symtab);

            // Build symbol table
            List<ElfSymbol> osyms = new List<ElfSymbol>();
            osyms.Add(new ElfSymbol());
            Dictionary<ISymbol, int> sym_map = new Dictionary<ISymbol, int>();

            // Add local symbols first
            foreach(var sym in symbols)
            {
                if (sym.Type == SymbolType.Local)
                    AddSymbol(sym, strtab, osyms, sym_map, osect_map);
            }
            int last_local = osyms.Count;
            foreach(var sym in symbols)
            {
                if (sym.Type != SymbolType.Local)
                    AddSymbol(sym, strtab, osyms, sym_map, osect_map);
            }
            symtab.sh_info = last_local;

            // Write out file header
            // e_ident
            w.Write((byte)0x7f);
            w.Write((byte)'E');
            w.Write((byte)'L');
            w.Write((byte)'F');
            w.Write((byte)ec);
            w.Write((byte)ed);
            w.Write((byte)1);
            for (int i = 0; i < 9; i++)
                w.Write((byte)0);
            // store fh_start because we will re-write the header later
            int fh_start = (int)w.BaseStream.Position;
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    WriteElf32FileHeader(w);
                    break;
                case ElfClass.ELFCLASS64:
                    WriteElf64FileHeader(w);
                    break;
                default:
                    throw new Exception("Invalid ELF class");
            }

            // Now write out the section data
            foreach(var s in sections)
            {
                // align up to addralign
                var sh = osects[osect_map[s]];
                if (sh.sh_addralign != 0)
                {
                    while ((w.BaseStream.Position % sh.sh_addralign) != 0)
                        w.Write((byte)0);
                }

                sh.sh_offset = w.BaseStream.Position;

                if (s.HasData == false)
                    continue;

                // write out data
                foreach (byte b in s.Data)
                    w.Write(b);
            }

            // Write out string tables
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            strtab.sh_offset = w.BaseStream.Position;
            foreach (byte b in strtab.oput)
                w.Write(b);
            strtab.sh_size = strtab.oput.Count;

            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            shstrtab.sh_offset = w.BaseStream.Position;
            foreach (byte b in shstrtab.oput)
                w.Write(b);
            shstrtab.sh_size = shstrtab.oput.Count;

            // Write out symbol table
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);
            symtab.sh_offset = w.BaseStream.Position;
            foreach (var sym in osyms)
            {
                switch (ec)
                {
                    case ElfClass.ELFCLASS32:
                        WriteElf32Symbol(sym, w);
                        break;
                    case ElfClass.ELFCLASS64:
                        WriteElf64Symbol(sym, w);
                        break;
                }
            }

            // Fill in file type specific details in various structures
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    symtab.sh_entsize = 16;
                    symtab.sh_size = osyms.Count * symtab.sh_entsize;
                    e_shentsize = 40;
                    e_phentsize = 32;
                    break;
                case ElfClass.ELFCLASS64:
                    throw new NotImplementedException();
            }

            // Write out section header table
            while ((w.BaseStream.Position % 16) != 0)
                w.Write((byte)0);

            e_shoff = w.BaseStream.Position;
            foreach(var sect in osects)
            {
                switch(ec)
                {
                    case ElfClass.ELFCLASS32:
                        WriteElf32Section(sect, w);
                        break;
                    case ElfClass.ELFCLASS64:
                        WriteElf64Section(sect, w);
                        break;
                }
            }

            // Write program headers
            e_phnum = 0;
            if (IsExecutable)
            {
                while ((w.BaseStream.Position % 16) != 0)
                    w.Write((byte)0);

                e_phoff = w.BaseStream.Position;
                foreach (var sect in sections)
                {
                    ElfProgramHeader ph = new ElfProgramHeader();
                    ph.p_type = ElfProgramHeader.PT_LOAD;
                    ph.p_offset = (ulong)osects[osect_map[sect]].sh_offset;
                    ph.p_vaddr = sect.LoadAddress;
                    ph.p_paddr = 0;
                    ph.p_filesz = sect.HasData ? (ulong)sect.Data.Count : 0UL;
                    ph.p_memsz = (ulong)sect.Length;
                    ph.p_flags = 0;
                    if (sect.IsExecutable)
                        ph.p_flags |= ElfProgramHeader.PF_X;
                    if (sect.IsWriteable)
                        ph.p_flags |= ElfProgramHeader.PF_W;
                    ph.p_flags |= ElfProgramHeader.PF_R;
                    ph.p_align = (ulong)sect.AddrAlign;

                    if (ph.p_memsz != 0)
                    {
                        switch (ec)
                        {
                            case ElfClass.ELFCLASS32:
                                WriteElf32Segment(ph, w);
                                break;
                            case ElfClass.ELFCLASS64:
                                WriteElf64Segment(ph, w);
                                break;
                        }
                        e_phnum++;
                    }
                }
            }
            if (e_phnum == 0)
                e_phoff = 0;

            // Rewrite file header
            e_shnum = osects.Count;
            if (is_exec)
                e_type = 2;
            else
                e_type = 1;

            if(EntryPoint != null && IsExecutable)
            {
                var s = FindSymbol(EntryPoint);
                if (s != null && s.DefinedIn != null)
                    e_entry = s.Offset + s.DefinedIn.LoadAddress;
                else
                {
                    // default to offset 0x0 in text
                    var sect = FindSection(".text");
                    if(sect == null)
                    {
                        // default to 0x0
                        Console.WriteLine("Entry point " + EntryPoint +
                            " not found, defaulting to 0x0");
                        e_entry = 0;
                    }
                    else
                    {
                        Console.WriteLine("Entry point " + EntryPoint +
                            " not found, defaulting to 0x" +
                            sect.LoadAddress.ToString("X"));
                        e_entry = sect.LoadAddress;
                    }
                }
            }

            int cur_pos = (int)w.BaseStream.Position;
            w.Seek(fh_start, System.IO.SeekOrigin.Begin);
            switch(ec)
            {
                case ElfClass.ELFCLASS32:
                    WriteElf32FileHeader(w);
                    break;
                case ElfClass.ELFCLASS64:
                    WriteElf64FileHeader(w);
                    break;
            }
            w.Seek(cur_pos, System.IO.SeekOrigin.Begin);
        }
Пример #3
0
 private void WriteElf32Segment(ElfProgramHeader ph, System.IO.BinaryWriter w)
 {
     w.Write((uint)ph.p_type);
     w.Write((uint)ph.p_offset);
     w.Write((uint)ph.p_vaddr);
     w.Write((uint)ph.p_paddr);
     w.Write((uint)ph.p_filesz);
     w.Write((uint)ph.p_memsz);
     w.Write((uint)ph.p_flags);
     w.Write((uint)ph.p_align);
 }