diff --git a/libexeinfo/ELF/ELF.cs b/libexeinfo/ELF/ELF.cs index b2c1f09..9935123 100644 --- a/libexeinfo/ELF/ELF.cs +++ b/libexeinfo/ELF/ELF.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; +using System.Threading; namespace libexeinfo { @@ -14,6 +15,7 @@ namespace libexeinfo string interpreter; string[] sectionNames; Elf64_Shdr[] sections; + Dictionary notes; /// /// Initializes a new instance of the class. @@ -138,10 +140,11 @@ namespace libexeinfo Segment[] segments = new Segment[sections.Length]; int len = 0; + int pos; for(int i = 0; i < sections.Length; i++) { - int pos = (int)sections[i].sh_name; + pos = (int)sections[i].sh_name; len = 0; for(int p = pos; p < buffer.Length; p++) @@ -178,33 +181,70 @@ namespace libexeinfo len++; } + + notes = new Dictionary(); // Sections that contain an array of null-terminated strings by definition for(int i = 0; i < sections.Length; i++) { - if(sectionNames[i] != ".interp" && sectionNames[i] != ".dynstr" && - sectionNames[i] != ".comment") continue; - BaseStream.Position = (long)sections[i].sh_offset; buffer = new byte[sections[i].sh_size]; BaseStream.Read(buffer, 0, buffer.Length); - strStart = 0; - len = 0; - for(int p = 0; p < buffer.Length; p++) + if(sectionNames[i] == ".interp" || sectionNames[i] == ".dynstr" || sectionNames[i] == ".comment") { - if(buffer[p] == 0x00) + strStart = 0; + len = 0; + for(int p = 0; p < buffer.Length; p++) { - if(len == 0) continue; + if(buffer[p] == 0x00) + { + if(len == 0) continue; - strings.Add(Encoding.ASCII.GetString(buffer, strStart, len)); - if(sectionNames[i] == ".interp") interpreter = Encoding.ASCII.GetString(buffer, strStart, len); - strStart = p + 1; - len = 0; - continue; + strings.Add(Encoding.ASCII.GetString(buffer, strStart, len)); + if(sectionNames[i] == ".interp") + interpreter = Encoding.ASCII.GetString(buffer, strStart, len); + strStart = p + 1; + len = 0; + continue; + } + + len++; } + } + else if(sectionNames[i].StartsWith(".note")) + { + uint namesz = BitConverter.ToUInt32(buffer, 0); + uint descsz = BitConverter.ToUInt32(buffer, 4); + uint notetype = BitConverter.ToUInt32(buffer, 8); + pos = 12; - len++; + if(IsBigEndian) + { + namesz= Swapping.Swap(namesz); + descsz = Swapping.Swap(descsz); + notetype = Swapping.Swap(notetype); + } + + ElfNote note = new ElfNote + { + name = Encoding.ASCII.GetString(buffer, pos, (int)(namesz - 1)), + type = notetype, + contents = new byte[descsz] + }; + + pos += (int)namesz; + + switch(Header.ei_class) { + case eiClass.ELFCLASS32: pos += pos % 4; + break; + case eiClass.ELFCLASS64: pos += pos % 8; + break; + } + + Array.Copy(buffer, pos, note.contents, 0, descsz); + + notes.Add(sectionNames[i], note); } } diff --git a/libexeinfo/ELF/Info.cs b/libexeinfo/ELF/Info.cs index 42972f6..1e7b5d3 100644 --- a/libexeinfo/ELF/Info.cs +++ b/libexeinfo/ELF/Info.cs @@ -74,6 +74,13 @@ namespace libexeinfo sb.AppendFormat("\t\tSection is aligned to {0} bytes", sections[i].sh_addralign).AppendLine(); if(sections[i].sh_entsize > 0) sb.AppendFormat("\t\tIndex to name: {0}", sections[i].sh_entsize).AppendLine(); + + if(!notes.TryGetValue(sectionNames[i], out ElfNote note)) continue; + + sb.AppendLine("\t\tNote contents:"); + sb.AppendFormat("\t\t\tName: {0}", note.name).AppendLine(); + sb.AppendFormat("\t\t\tType: {0}", note.type).AppendLine(); + sb.AppendFormat("\t\t\tLength: {0} bytes", note.contents.Length).AppendLine(); } return sb.ToString(); diff --git a/libexeinfo/ELF/Structs.cs b/libexeinfo/ELF/Structs.cs index a899506..7c4d8d1 100644 --- a/libexeinfo/ELF/Structs.cs +++ b/libexeinfo/ELF/Structs.cs @@ -369,5 +369,12 @@ namespace libexeinfo /// public ulong ch_addralign; } + + struct ElfNote + { + public string name; + public uint type; + public byte[] contents; + } } } \ No newline at end of file