Example #1
0
 public ElfSymbolTable(Reader reader, bool is64Bit, long address, ElfStringTable stringTable)
 {
     _reader      = reader;
     _address     = address;
     _is64Bit     = is64Bit;
     _symSize     = is64Bit ? 24 : 16;
     _stringTable = stringTable;
 }
Example #2
0
        public void TestCount()
        {
            var     stream  = new FileStream("Binaries/base32", FileMode.Open, FileAccess.Read);
            var     reader  = new EndianBinaryReader(stream, EndianBitConverter.NativeEndianness);
            ElfFile elfFile = ElfFile.ReadElfFile(reader);

            Assert.IsAssignableFrom <ElfStringTable>(elfFile.Sections[6]);

            ElfStringTable symbolTable = elfFile.Sections[6] as ElfStringTable;

            Assert.Equal(71, symbolTable.Count);
        }
Example #3
0
        public void SimpleCodeSectionAndSymbolSection()
        {
            var elf = new ElfObjectFile();

            var codeStream = new MemoryStream();

            codeStream.Write(Encoding.UTF8.GetBytes("This is a text"));
            codeStream.Position = 0;

            var codeSection = new ElfCustomSection(codeStream).ConfigureAs(ElfSectionSpecialType.Text);

            elf.AddSection(codeSection);

            var stringSection = new ElfStringTable();

            elf.AddSection(stringSection);

            var symbolSection = new ElfSymbolTable()
            {
                Link = stringSection,

                Entries =
                {
                    new ElfSymbol()
                    {
                        Name       = "local_symbol",
                        Bind       = ElfSymbolBind.Local,
                        Section    = codeSection,
                        Size       = 16,
                        Type       = ElfSymbolType.Function,
                        Visibility = ElfSymbolVisibility.Protected,
                        Value      = 0x7896
                    },
                    new ElfSymbol()
                    {
                        Name    = "GlobalSymbol",
                        Bind    = ElfSymbolBind.Global,
                        Section = codeSection,
                        Size    = 4,
                        Type    = ElfSymbolType.Function,
                        Value   = 0x12345
                    }
                }
            };

            elf.AddSection(symbolSection);
            elf.AddSection(new ElfSectionHeaderStringTable());

            AssertReadElf(elf, "test2.elf");
        }
Example #4
0
        public void TestIndex()
        {
            var     stream  = new FileStream("Binaries/base32", FileMode.Open, FileAccess.Read);
            var     reader  = new EndianBinaryReader(stream, EndianBitConverter.NativeEndianness);
            ElfFile elfFile = ElfFile.ReadElfFile(reader);

            Assert.IsAssignableFrom <ElfStringTable>(elfFile.Sections[6]);

            ElfStringTable symbolTable = elfFile.Sections[6] as ElfStringTable;

            Assert.Equal(0x001U, symbolTable[0].Index);
            Assert.Equal(0x00bU, symbolTable[1].Index);
            Assert.Equal(0x012U, symbolTable[2].Index);
            Assert.Equal(0x01fU, symbolTable[3].Index);
            Assert.Equal(0x029U, symbolTable[4].Index);
            Assert.Equal(0x078U, symbolTable[13].Index);
            Assert.Equal(0x086U, symbolTable[15].Index);
            Assert.Equal(0x099U, symbolTable[18].Index);
            Assert.Equal(0x0e4U, symbolTable[22].Index);
            Assert.Equal(0x150U, symbolTable[34].Index);
            Assert.Equal(0x25eU, symbolTable[59].Index);
            Assert.Equal(0x29aU, symbolTable[64].Index);
            Assert.Equal(0x2b3U, symbolTable[66].Index);
        }
Example #5
0
        public void TestValue()
        {
            var     stream  = new FileStream("Binaries/base32", FileMode.Open, FileAccess.Read);
            var     reader  = new EndianBinaryReader(stream, EndianBitConverter.NativeEndianness);
            ElfFile elfFile = ElfFile.ReadElfFile(reader);

            Assert.IsAssignableFrom <ElfStringTable>(elfFile.Sections[6]);

            ElfStringTable symbolTable = elfFile.Sections[6] as ElfStringTable;

            Assert.Equal("libc.so.6", symbolTable[0].Value);
            Assert.Equal("fflush", symbolTable[1].Value);
            Assert.Equal("__printf_chk", symbolTable[2].Value);
            Assert.Equal("setlocale", symbolTable[3].Value);
            Assert.Equal("mbrtowc", symbolTable[4].Value);
            Assert.Equal("realloc", symbolTable[13].Value);
            Assert.Equal("stdin", symbolTable[15].Value);
            Assert.Equal("program_invocation_name", symbolTable[18].Value);
            Assert.Equal("calloc", symbolTable[22].Value);
            Assert.Equal("malloc", symbolTable[34].Value);
            Assert.Equal("fputs_unlocked", symbolTable[59].Value);
            Assert.Equal("__gmon_start__", symbolTable[64].Value);
            Assert.Equal("GLIBC_2.3.4", symbolTable[66].Value);
        }
Example #6
0
        public static string GetStringByKey(this ElfStringTable table, string key)
        {
            var value = table.Single(x => x.Value.StartsWith(key));

            return(value.Value.Replace($"{key}::", ""));
        }
Example #7
0
        public void CreateDwarf()
        {
            // Create ELF object
            var elf = new ElfObjectFile(ElfArch.X86_64);

            var codeSection = new ElfBinarySection(new MemoryStream(new byte[0x64])).ConfigureAs(ElfSectionSpecialType.Text);

            elf.AddSection(codeSection);
            var stringSection = new ElfStringTable();

            elf.AddSection(stringSection);
            elf.AddSection(new ElfSymbolTable()
            {
                Link = stringSection
            });
            elf.AddSection(new ElfSectionHeaderStringTable());

            var elfDiagnostics = new DiagnosticBag();

            elf.UpdateLayout(elfDiagnostics);
            Assert.False(elfDiagnostics.HasErrors);

            // Create DWARF Object
            var dwarfFile = new DwarfFile();

            // Create .debug_line information
            var fileName = new DwarfFileName()
            {
                Name      = "check1.cpp",
                Directory = Environment.CurrentDirectory,
            };
            var fileName2 = new DwarfFileName()
            {
                Name      = "check2.cpp",
                Directory = Environment.CurrentDirectory,
            };

            // First line table
            for (int i = 0; i < 2; i++)
            {
                var lineTable = new DwarfLineProgramTable();
                dwarfFile.LineSection.AddLineProgramTable(lineTable);

                lineTable.AddressSize = DwarfAddressSize.Bit64;
                lineTable.FileNames.Add(fileName);
                lineTable.FileNames.Add(fileName2);
                lineTable.AddLineSequence(new DwarfLineSequence()
                {
                    new DwarfLine()
                    {
                        File    = fileName,
                        Address = 0,
                        Column  = 1,
                        Line    = 1,
                    },
                    new DwarfLine()
                    {
                        File    = fileName,
                        Address = 1,
                        Column  = 1,
                        Line    = 2,
                    }
                }
                                          );
                // NOTE: doesn't seem to be generated by regular GCC
                // (it seems that only one line sequence is usually used)
                lineTable.AddLineSequence(new DwarfLineSequence()
                {
                    new DwarfLine()
                    {
                        File    = fileName2,
                        Address = 0,
                        Column  = 1,
                        Line    = 1,
                    },
                }
                                          );
            }

            // Create .debug_info
            var rootDIE = new DwarfDIECompileUnit()
            {
                Name     = fileName.Name,
                LowPC    = 0,                     // 0 relative to base virtual address
                HighPC   = (int)codeSection.Size, // default is offset/length after LowPC
                CompDir  = fileName.Directory,
                StmtList = dwarfFile.LineSection.LineTables[0],
            };
            var subProgram = new DwarfDIESubprogram()
            {
                Name = "MyFunction",
            };

            rootDIE.AddChild(subProgram);

            var cu = new DwarfCompilationUnit()
            {
                AddressSize = DwarfAddressSize.Bit64,
                Root        = rootDIE
            };

            dwarfFile.InfoSection.AddUnit(cu);

            // AddressRange table
            dwarfFile.AddressRangeTable.AddressSize = DwarfAddressSize.Bit64;
            dwarfFile.AddressRangeTable.Unit        = cu;
            dwarfFile.AddressRangeTable.Ranges.Add(new DwarfAddressRange(0, 0, codeSection.Size));

            // Transfer DWARF To ELF
            var dwarfElfContext = new DwarfElfContext(elf);

            dwarfFile.WriteToElf(dwarfElfContext);

            var outputFileName = "create_dwarf.o";

            using (var output = new FileStream(outputFileName, FileMode.Create))
            {
                elf.Write(output);
            }

            elf.Print(Console.Out);
            Console.WriteLine();
            dwarfFile.AbbreviationTable.Print(Console.Out);
            Console.WriteLine();
            dwarfFile.AddressRangeTable.Print(Console.Out);
            Console.WriteLine();
            dwarfFile.InfoSection.Print(Console.Out);

            Console.WriteLine("ReadBack --debug-dump=rawline");
            var readelf = LinuxUtil.ReadElf(outputFileName, "--debug-dump=rawline").TrimEnd();

            Console.WriteLine(readelf);
        }