예제 #1
0
        public void Read(ParsedDocument doc, ElfSectionHeader section, byte[] data)
        {
            var header = doc.document.header;

            symbols.Clear();
            using (var ms = new System.IO.MemoryStream(data))
            {
                int sylsize = header.Head_Is64Bit ? 24 : 16;
                for (var i = 0; i < data.Length; i += sylsize)
                {
                    Symbol symbol = new Symbol();
                    if (header.Head_Is64Bit)//64位和32位格式,顺序不太一样
                    {
                        symbol.st_name  = ms.ReadUInt32(header);
                        symbol.st_info  = ms.ReadByte1();
                        symbol.st_other = ms.ReadByte1();
                        symbol.st_shndx = ms.ReadUInt16(header);
                        symbol.st_value = ms.ReadUIntPtr(header);
                        symbol.st_size  = ms.ReadUIntPtr(header);
                    }
                    else
                    {
                        symbol.st_name  = ms.ReadUInt32(header);
                        symbol.st_value = ms.ReadUIntPtr(header);
                        symbol.st_size  = ms.ReadUIntPtr(header);
                        symbol.st_info  = ms.ReadByte1();
                        symbol.st_other = ms.ReadByte1();
                        symbol.st_shndx = ms.ReadUInt16(header);
                    }
                    if (doc.Parsed_StringTables.ContainsKey((int)section.Link))
                    {
                        var stable = doc.Parsed_StringTables[(int)section.Link];
                        stable.TryGetValue((int)symbol.st_name, out symbol.Name);
                    }
                    symbol.SymbolBinding = (SymbolBinding)(symbol.st_info >> 4);
                    symbol.SymbolType    = (SymbolType)(symbol.st_info & 0x0F);
                    if (Enum.IsDefined(typeof(SpecialSectionIndex), symbol.st_shndx))
                    {
                        symbol.SpecialSectionIndex = (SpecialSectionIndex)symbol.st_shndx;
                    }
                    else
                    {
                        symbol.SpecialSectionIndex = null;
                    }


                    symbols.Add(symbol);
                }
            }
        }
예제 #2
0
        public void Read(ParsedDocument doc, ElfSectionHeader section, byte[] data)
        {
            var header = doc.document.header;

            Relocations.Clear();
            using (var ms = new System.IO.MemoryStream(data))
            {
                int sylsize = header.Head_Is64Bit ? 8 : 4;
                if (haveAppend)
                {
                    sylsize = sylsize * 3;
                }
                else
                {
                    sylsize = sylsize * 2;
                }
                for (var i = 0; i < data.Length; i += sylsize)
                {
                    Relocation reloc = new Relocation();
                    reloc.r_offset = ms.ReadUIntPtr(header);
                    reloc.r_info   = ms.ReadUIntPtr(header);
                    if (this.haveAppend)
                    {
                        reloc.r_append = ms.ReadUIntPtr(header);
                    }
                    if (header.Head_Is64Bit)
                    {
                        reloc.symAddr   = (uint)(reloc.r_info >> 32);
                        reloc.relocType = (uint)(reloc.r_info);
                    }
                    else
                    {
                        reloc.symAddr   = (uint)(reloc.r_info >> 8);
                        reloc.relocType = (byte)(reloc.r_info);
                    }
                    Relocations.Add(reloc);
                }
            }
        }
예제 #3
0
        internal override unsafe bool GetFileVersion(string dll, out int major, out int minor, out int revision, out int patch)
        {
            using FileStream stream = File.OpenRead(dll);
            StreamAddressSpace streamAddressSpace = new StreamAddressSpace(stream);
            Reader             streamReader       = new Reader(streamAddressSpace);
            ElfFile            file   = new ElfFile(streamReader);
            IElfHeader         header = file.Header;

            ElfSectionHeader headerStringHeader = new ElfSectionHeader(streamReader, header.Is64Bit, header.SectionHeaderOffset + header.SectionHeaderStringIndex * header.SectionHeaderEntrySize);
            long             headerStringOffset = (long)headerStringHeader.FileOffset;

            long dataOffset = 0;
            long dataSize   = 0;

            for (int i = 0; i < header.SectionHeaderCount; i++)
            {
                if (i == header.SectionHeaderStringIndex)
                {
                    continue;
                }

                ElfSectionHeader sectionHeader = new ElfSectionHeader(streamReader, header.Is64Bit, header.SectionHeaderOffset + i * header.SectionHeaderEntrySize);
                if (sectionHeader.Type == ElfSectionHeaderType.ProgBits)
                {
                    string sectionName = streamReader.ReadNullTerminatedAscii(headerStringOffset + sectionHeader.NameIndex * sizeof(byte));
                    if (sectionName == ".data")
                    {
                        dataOffset = (long)sectionHeader.FileOffset;
                        dataSize   = (long)sectionHeader.FileSize;
                        break;
                    }
                }
            }

            DebugOnly.Assert(dataOffset != 0);
            DebugOnly.Assert(dataSize != 0);

            Span <byte> buffer     = stackalloc byte[s_versionLength];
            long        address    = dataOffset;
            long        endAddress = address + dataSize;

            while (address < endAddress)
            {
                int read = streamAddressSpace.Read(address, buffer);
                if (read < s_versionLength)
                {
                    break;
                }

                if (!buffer.SequenceEqual(s_versionString))
                {
                    address++;
                    continue;
                }

                address += s_versionLength;

                // TODO:  This should be cleaned up to not read byte by byte in the future.  Leaving it here
                // until we decide whether to rewrite the Linux coredumpreader or not.
                StringBuilder builder = new StringBuilder();
                while (address < endAddress)
                {
                    Span <byte> bytes = stackalloc byte[1];
                    read = streamAddressSpace.Read(address, bytes);
                    if (read < bytes.Length)
                    {
                        break;
                    }

                    if (bytes[0] == '\0')
                    {
                        break;
                    }

                    if (bytes[0] == ' ')
                    {
                        try
                        {
                            Version v = Version.Parse(builder.ToString());
                            major    = v.Major;
                            minor    = v.Minor;
                            revision = v.Build;
                            patch    = v.Revision;
                            return(true);
                        }
                        catch (FormatException)
                        {
                            break;
                        }
                    }

                    Span <char> chars = stackalloc char[1];
                    fixed(byte *bytesPtr = &MemoryMarshal.GetReference(bytes))
                    fixed(char *charsPtr = &MemoryMarshal.GetReference(chars))
                    {
                        _ = Encoding.ASCII.GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length);
                    }

                    _ = builder.Append(chars[0]);
                    address++;
                }

                break;
            }

            major = minor = revision = patch = 0;
            return(false);
        }