mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Decode ELF version tags from FreeBSD, MINIX, OpenBSD and NetBSD.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
34
libexeinfo/ELF/FreeBSD.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
|
||||
@@ -384,5 +384,12 @@ namespace libexeinfo
|
||||
public uint minor;
|
||||
public uint revision;
|
||||
}
|
||||
|
||||
struct FreeBSDTag
|
||||
{
|
||||
public uint major;
|
||||
public uint minor;
|
||||
public uint revision;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user