Decode ELF version tags from FreeBSD, MINIX, OpenBSD and NetBSD.

This commit is contained in:
2018-03-13 20:00:53 +00:00
parent bb6b17800f
commit ac6cf3d1c2
6 changed files with 207 additions and 10 deletions

View File

@@ -190,7 +190,7 @@ namespace libexeinfo
buffer = new byte[sections[i].sh_size];
BaseStream.Read(buffer, 0, buffer.Length);
if(sectionNames[i] == ".interp" || sectionNames[i] == ".dynstr" || sectionNames[i] == ".comment")
if(sectionNames[i] == ".interp" || sectionNames[i] == ".dynstr" || sectionNames[i] == ".comment" || sectionNames[i] == ".strtab")
{
strStart = 0;
len = 0;
@@ -211,7 +211,7 @@ namespace libexeinfo
len++;
}
}
else if(sectionNames[i].StartsWith(".note"))
else if(sectionNames[i].StartsWith(".note") && buffer.Length > 12)
{
uint namesz = BitConverter.ToUInt32(buffer, 0);
uint descsz = BitConverter.ToUInt32(buffer, 4);
@@ -237,10 +237,10 @@ namespace libexeinfo
switch(Header.ei_class)
{
case eiClass.ELFCLASS32:
pos += pos % 4;
pos += pos % 4 != 0 ? 4 - (pos % 4) : 0;
break;
case eiClass.ELFCLASS64:
pos += pos % 8;
pos += pos % 8 != 0 ? 8 - (pos % 8) : 0;
break;
}
@@ -260,7 +260,78 @@ namespace libexeinfo
MajorVersion = (int)gnuAbiTag.major,
MinorVersion = (int)gnuAbiTag.minor
};
else if(!string.IsNullOrEmpty(interpreter))
RequiredOperatingSystem = new OperatingSystem {Name = interpreter};
}
else if(notes.TryGetValue(".note.netbsd.ident", out ElfNote netbsdIdent) && netbsdIdent.name == "NetBSD")
{
uint netbsdVersionConstant = BitConverter.ToUInt32(netbsdIdent.contents, 0);
if(IsBigEndian) netbsdVersionConstant = Swapping.Swap(netbsdVersionConstant);
if(netbsdVersionConstant > 100000000)
{
RequiredOperatingSystem = new OperatingSystem
{
Name = "NetBSD",
MajorVersion = (int)(netbsdVersionConstant / 100000000),
MinorVersion = (int)((netbsdVersionConstant / 1000000) % 100)
};
}
else
{
RequiredOperatingSystem = new OperatingSystem
{
Name = "NetBSD"
};
}
}
else if(notes.TryGetValue(".note.minix.ident", out ElfNote minixIdent) && minixIdent.name == "Minix")
{
uint minixVersionConstant = BitConverter.ToUInt32(minixIdent.contents, 0);
if(IsBigEndian) minixVersionConstant = Swapping.Swap(minixVersionConstant);
if(minixVersionConstant > 100000000)
{
RequiredOperatingSystem = new OperatingSystem
{
Name = "MINIX",
MajorVersion = (int)(minixVersionConstant / 100000000),
MinorVersion = (int)((minixVersionConstant / 1000000) % 100)
};
}
else
{
RequiredOperatingSystem = new OperatingSystem
{
Name = "MINIX"
};
}
}
else if(notes.TryGetValue(".note.openbsd.ident", out ElfNote openbsdIdent) && openbsdIdent.name == "OpenBSD")
{
RequiredOperatingSystem = new OperatingSystem
{
Name = "OpenBSD"
};
}
else if(notes.TryGetValue(".note.tag", out ElfNote freebsdTag) && freebsdTag.name == "FreeBSD")
{
uint freebsdVersionConstant = BitConverter.ToUInt32(freebsdTag.contents, 0);
if(IsBigEndian) freebsdVersionConstant = Swapping.Swap(freebsdVersionConstant);
FreeBSDTag freeBsdVersion = DecodeFreeBSDTag(freebsdVersionConstant);
RequiredOperatingSystem = new OperatingSystem
{
Name = "FreeBSD",
MajorVersion = (int)freeBsdVersion.major,
MinorVersion = (int)freeBsdVersion.minor
};
}
else if(!string.IsNullOrEmpty(interpreter))
RequiredOperatingSystem = new OperatingSystem {Name = interpreter};
if(strings.Count > 0)
{

View File

@@ -944,7 +944,11 @@ namespace libexeinfo
enum GnuAbiSystem : uint
{
Linux = 0
Linux = 0,
Hurd = 1,
Solaris = 2,
kFreeBSD = 3,
kNetBSD = 4
}
}
}

34
libexeinfo/ELF/FreeBSD.cs Normal file
View File

@@ -0,0 +1,34 @@
namespace libexeinfo
{
public partial class ELF
{
static FreeBSDTag DecodeFreeBSDTag(uint desc)
{
FreeBSDTag tag = new FreeBSDTag {major = desc / 100000};
if(desc == 460002)
{
tag.major = 4;
tag.minor = 6;
tag.revision = 2;
}
else if(desc < 460100)
{
tag.minor = desc / 10000 % 10;
if(desc / 1000 % 10 > 0) tag.revision = desc / 1000 % 10;
}
else if(desc < 500000)
{
tag.minor = desc / 10000 % 10 + desc / 1000 % 10;
if(desc / 10 % 10 > 0) tag.revision = desc / 10 % 10;
}
else
{
tag.minor = desc / 1000 % 100;
if(desc / 10 % 10 > 0) tag.revision = desc / 10 % 10;
}
return tag;
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Text;
using System;
using System.Text;
namespace libexeinfo
{
@@ -83,12 +84,91 @@ namespace libexeinfo
sb.AppendFormat("\t\t\tLength: {0} bytes", note.contents.Length).AppendLine();
}
if(notes.TryGetValue(".note.ABI-tag", out ElfNote abiTag))
if(notes.TryGetValue(".note.ABI-tag", out ElfNote abiTag) && abiTag.name == "GNU")
{
GnuAbiTag gnuAbiTag = DecodeGnuAbiTag(abiTag, IsBigEndian);
if(gnuAbiTag != null)
sb.AppendFormat("\tGNU ABI tag: Requires {0} version {1}.{2}.{3}", gnuAbiTag.system,
gnuAbiTag.major, gnuAbiTag.minor, gnuAbiTag.revision).AppendLine();
sb.AppendFormat("\tGNU ABI tag: Requires {0} version {1}.{2}.{3}", gnuAbiTag.system,
gnuAbiTag.major, gnuAbiTag.minor, gnuAbiTag.revision).AppendLine();
}
if(notes.TryGetValue(".note.netbsd.ident", out ElfNote netbsdIdent) && netbsdIdent.name == "NetBSD")
{
uint netbsdVersionConstant = BitConverter.ToUInt32(netbsdIdent.contents, 0);
if(IsBigEndian) netbsdVersionConstant = Swapping.Swap(netbsdVersionConstant);
if(netbsdVersionConstant > 100000000)
{
uint nbsdPatch = (netbsdVersionConstant / 100) % 100;
uint nbsdRel = (netbsdVersionConstant / 10000) % 100;
uint nbsdMinor = (netbsdVersionConstant / 1000000) % 100;
uint nbsdMajor = netbsdVersionConstant / 100000000;
sb.AppendFormat("\tNetBSD version: {0}.{1}", nbsdMajor, nbsdMinor);
if(nbsdRel == 0 && nbsdPatch != 0) sb.AppendFormat(".{0}", nbsdPatch);
else if(nbsdRel != 0)
{
while(nbsdRel > 26)
{
sb.Append("Z");
nbsdRel -= 26;
}
sb.AppendFormat("{0}", (char)('A' + nbsdRel - 1));
}
sb.AppendLine();
}
else
{
sb.AppendFormat("\tNetBSD version constant: {0}", netbsdVersionConstant).AppendLine();
}
}
if(notes.TryGetValue(".note.minix.ident", out ElfNote minixIdent) && minixIdent.name == "Minix")
{
uint minixVersionConstant = BitConverter.ToUInt32(minixIdent.contents, 0);
if(IsBigEndian) minixVersionConstant = Swapping.Swap(minixVersionConstant);
if(minixVersionConstant > 100000000)
{
uint minixPath = (minixVersionConstant / 100) % 100;
uint minixRel = (minixVersionConstant / 10000) % 100;
uint minixMinor = (minixVersionConstant / 1000000) % 100;
uint minixMajor = minixVersionConstant / 100000000;
sb.AppendFormat("\tMINIX version: {0}.{1}", minixMajor, minixMinor);
if(minixRel == 0 && minixPath != 0) sb.AppendFormat(".{0}", minixPath);
else if(minixRel != 0)
{
while(minixRel > 26)
{
sb.Append("Z");
minixRel -= 26;
}
sb.AppendFormat("{0}", (char)('A' + minixRel - 1));
}
sb.AppendLine();
}
else
{
sb.AppendFormat("\tMINIX version constant: {0}", minixVersionConstant).AppendLine();
}
}
if(notes.TryGetValue(".note.tag", out ElfNote freebsdTag) && freebsdTag.name == "FreeBSD")
{
uint freebsdVersionConstant = BitConverter.ToUInt32(freebsdTag.contents, 0);
if(IsBigEndian) freebsdVersionConstant = Swapping.Swap(freebsdVersionConstant);
FreeBSDTag freeBsdVersion = DecodeFreeBSDTag(freebsdVersionConstant);
sb.AppendFormat("\tFreeBSD version: {0}.{1}");
if(freeBsdVersion.revision > 0) sb.AppendFormat("{0}", freeBsdVersion.revision);
sb.AppendLine();
}
if(notes.TryGetValue(".note.gnu.build-id", out ElfNote buildId))

View File

@@ -384,5 +384,12 @@ namespace libexeinfo
public uint minor;
public uint revision;
}
struct FreeBSDTag
{
public uint major;
public uint minor;
public uint revision;
}
}
}

View File

@@ -57,6 +57,7 @@
<Compile Include="ELF\Consts.cs" />
<Compile Include="ELF\ELF.cs" />
<Compile Include="ELF\Enums.cs" />
<Compile Include="ELF\FreeBSD.cs" />
<Compile Include="ELF\GNU.cs" />
<Compile Include="ELF\Info.cs" />
<Compile Include="ELF\Structs.cs" />