diff --git a/exeinfogui/MainForm.xeto b/exeinfogui/MainForm.xeto
index 103306a..29b710f 100644
--- a/exeinfogui/MainForm.xeto
+++ b/exeinfogui/MainForm.xeto
@@ -20,9 +20,17 @@
+
+
+
+
+
+
+
+
-
+
diff --git a/exeinfogui/MainForm.xeto.cs b/exeinfogui/MainForm.xeto.cs
index 35ea6c6..3c38800 100644
--- a/exeinfogui/MainForm.xeto.cs
+++ b/exeinfogui/MainForm.xeto.cs
@@ -26,6 +26,7 @@
using System;
using System.IO;
+using System.Linq;
using Eto.Forms;
using Eto.Serialization.Xaml;
using libexeinfo;
@@ -37,6 +38,7 @@ namespace exeinfogui
TextBox txtFile;
TextArea txtInformation;
TextBox txtType;
+ ComboBox cmbArch;
public MainForm()
{
@@ -70,19 +72,29 @@ namespace exeinfogui
{
txtType.Text = neExe.Type;
txtInformation.Text = neExe.Information;
+ foreach(Architecture arch in neExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
}
else if(lxExe.Recognized)
{
txtType.Text = lxExe.Type;
txtInformation.Text = lxExe.Information;
+ foreach(Architecture arch in lxExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
}
else if(peExe.Recognized)
{
txtType.Text = peExe.Type;
txtInformation.Text = peExe.Information;
+ foreach(Architecture arch in peExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
}
else
+ {
txtType.Text = mzExe.Type;
+ foreach(Architecture arch in mzExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
+ }
txtInformation.Text += mzExe.Information;
}
@@ -90,14 +102,20 @@ namespace exeinfogui
{
txtType.Text = stExe.Type;
txtInformation.Text = stExe.Information;
+ foreach(Architecture arch in stExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
}
else if(coffExe.Recognized)
{
txtType.Text = coffExe.Type;
txtInformation.Text = coffExe.Information;
+ foreach(Architecture arch in coffExe.Architectures)
+ cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(t => t.arch == arch).longName);
}
else
txtType.Text = "Format not recognized";
+
+ cmbArch.SelectedIndex = 0;
exeFs.Close();
}
diff --git a/exeinfogui/exeinfogui.csproj b/exeinfogui/exeinfogui.csproj
index e18e3f2..c76d8f9 100644
--- a/exeinfogui/exeinfogui.csproj
+++ b/exeinfogui/exeinfogui.csproj
@@ -10,6 +10,7 @@
+
diff --git a/libexeinfo/AtariST/AtariST.cs b/libexeinfo/AtariST/AtariST.cs
index 9ead046..e858190 100644
--- a/libexeinfo/AtariST/AtariST.cs
+++ b/libexeinfo/AtariST/AtariST.cs
@@ -67,11 +67,12 @@ namespace libexeinfo
///
/// Header for this executable
///
- public AtariHeader Header { get; private set; }
- public Stream BaseStream { get; }
- public bool IsBigEndian => true;
- public bool Recognized { get; private set; }
- public string Type { get; private set; }
+ public AtariHeader Header { get; private set; }
+ public Stream BaseStream { get; }
+ public bool IsBigEndian => true;
+ public bool Recognized { get; private set; }
+ public string Type { get; private set; }
+ public Architecture[] Architectures => new[] {Architecture.M68K};
void Initialize()
{
diff --git a/libexeinfo/COFF/COFF.cs b/libexeinfo/COFF/COFF.cs
index 1379bba..b256ec7 100644
--- a/libexeinfo/COFF/COFF.cs
+++ b/libexeinfo/COFF/COFF.cs
@@ -68,11 +68,12 @@ namespace libexeinfo
///
/// Header for this executable
///
- public COFFHeader Header { get; private set; }
- public Stream BaseStream { get; }
- public bool IsBigEndian { get; private set; }
- public bool Recognized { get; private set; }
- public string Type { get; private set; }
+ public COFFHeader Header { get; private set; }
+ public Stream BaseStream { get; }
+ public bool IsBigEndian { get; private set; }
+ public bool Recognized { get; private set; }
+ public string Type { get; private set; }
+ public Architecture[] Architectures => new[] {MachineTypeToArchitecture(Header.machine)};
void Initialize()
{
diff --git a/libexeinfo/COFF/MachineTypes.cs b/libexeinfo/COFF/MachineTypes.cs
index 0113eff..e8b749c 100644
--- a/libexeinfo/COFF/MachineTypes.cs
+++ b/libexeinfo/COFF/MachineTypes.cs
@@ -72,5 +72,47 @@ namespace libexeinfo
return $"Unknown machine type with code {(ushort)machine}";
}
}
+
+ internal static Architecture MachineTypeToArchitecture(MachineTypes machine)
+ {
+ switch(machine)
+ {
+ case MachineTypes.IMAGE_FILE_MACHINE_ALPHA:
+ case MachineTypes.IMAGE_FILE_MACHINE_ALPHA64: return Architecture.Alpha;
+ case MachineTypes.IMAGE_FILE_MACHINE_AM33: return Architecture.Am33;
+ case MachineTypes.IMAGE_FILE_MACHINE_AMD64: return Architecture.Amd64;
+ case MachineTypes.IMAGE_FILE_MACHINE_ARM: return Architecture.Arm;
+ case MachineTypes.IMAGE_FILE_MACHINE_ARM64: return Architecture.Aarch64;
+ case MachineTypes.IMAGE_FILE_MACHINE_ARMNT: return Architecture.Thumb2;
+ case MachineTypes.IMAGE_FILE_MACHINE_EBC: return Architecture.EfiByteCode;
+ case MachineTypes.IMAGE_FILE_MACHINE_I386:
+ case MachineTypes.IMAGE_FILE_MACHINE_I386_AIX: return Architecture.I386;
+ case MachineTypes.IMAGE_FILE_MACHINE_IA64: return Architecture.IA64;
+ case MachineTypes.IMAGE_FILE_MACHINE_M32R: return Architecture.M32R;
+ case MachineTypes.IMAGE_FILE_MACHINE_M68K:
+ case MachineTypes.IMAGE_FILE_MACHINE_M68K_OTHER: return Architecture.M68K;
+ case MachineTypes.IMAGE_FILE_MACHINE_MIPS16:
+ case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU16: return Architecture.Mips16;
+ case MachineTypes.IMAGE_FILE_MACHINE_POWERPC:
+ case MachineTypes.IMAGE_FILE_MACHINE_POWERPCFP: return Architecture.PowerPc;
+ case MachineTypes.IMAGE_FILE_MACHINE_MIPSFPU:
+ case MachineTypes.IMAGE_FILE_MACHINE_MIPSEB:
+ case MachineTypes.IMAGE_FILE_MACHINE_WCEMIPSV2:
+ case MachineTypes.IMAGE_FILE_MACHINE_R3000: return Architecture.Mips;
+ case MachineTypes.IMAGE_FILE_MACHINE_R4000:
+ case MachineTypes.IMAGE_FILE_MACHINE_R10000: return Architecture.Mips3;
+ case MachineTypes.IMAGE_FILE_MACHINE_RISCV32:
+ case MachineTypes.IMAGE_FILE_MACHINE_RISCV64:
+ case MachineTypes.IMAGE_FILE_MACHINE_RISCV128: return Architecture.RiscV;
+ case MachineTypes.IMAGE_FILE_MACHINE_SH3:
+ case MachineTypes.IMAGE_FILE_MACHINE_SH3DSP: return Architecture.Sh3;
+ case MachineTypes.IMAGE_FILE_MACHINE_SH4: return Architecture.Sh4;
+ case MachineTypes.IMAGE_FILE_MACHINE_SH5: return Architecture.Sh5;
+ case MachineTypes.IMAGE_FILE_MACHINE_THUMB: return Architecture.Thumb;
+ case MachineTypes.IMAGE_FILE_MACHINE_CLIPPER: return Architecture.Clipper;
+ case MachineTypes.IMAGE_FILE_MACHINE_WE32000: return Architecture.We32000;
+ default: return Architecture.Unknown;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/libexeinfo/Enums.cs b/libexeinfo/Enums.cs
new file mode 100644
index 0000000..37bad55
--- /dev/null
+++ b/libexeinfo/Enums.cs
@@ -0,0 +1,76 @@
+namespace libexeinfo
+{
+ public enum Architecture
+ {
+ Unknown,
+ Aarch64,
+ Alpha,
+ Am33,
+ Amd64,
+ Arm,
+ Clipper,
+ EfiByteCode,
+ I86,
+ I286,
+ I386,
+ I860,
+ IA64,
+ M32R,
+ M68K,
+ Mips,
+ Mips3,
+ Mips16,
+ Power,
+ PowerPc,
+ PowerPc64,
+ RiscV,
+ Sh2,
+ Sh3,
+ Sh4,
+ Sh5,
+ Sparc,
+ Sparc64,
+ Thumb,
+ Thumb2,
+ We32000
+ }
+
+ public static class Enums
+ {
+ public static readonly (Architecture arch, string shortName, string longName)[] ArchitectureName =
+ {
+ (Architecture.Unknown, "unknown", "Unknown"),
+ (Architecture.Aarch64, "aarch64", "ARM64"),
+ (Architecture.Alpha, "axp", "Alpha"),
+ (Architecture.Am33, "am33", "AM33"),
+ (Architecture.Amd64, "amd64", "AMD64"),
+ (Architecture.Arm, "arm", "ARM"),
+ (Architecture.Clipper, "clipper", "Clipper"),
+ (Architecture.EfiByteCode, "ebc", "EFI Byte Code"),
+ (Architecture.I86, "i86", "Intel x86 (16-bit)"),
+ (Architecture.I286, "i286", "Intel x86 (16-bit protected mode)"),
+ (Architecture.I386, "ia32", "Intel IA-32"),
+ (Architecture.I86, "i860", "Intel i860"),
+ (Architecture.IA64, "ia64", "Intel IA-64"),
+ (Architecture.M32R, "m32r", "Mitsubishi M32R"),
+ (Architecture.M68K, "m68k", "Motorola 68000"),
+ (Architecture.Mips, "mips", "MIPS"),
+ (Architecture.Mips3, "mips3", "MIPS III"),
+ (Architecture.Mips16, "mips16", "MIPS16"),
+ (Architecture.Power, "power", "POWER"),
+ (Architecture.PowerPc, "ppc", "PowerPC"),
+ (Architecture.PowerPc64, "ppc64", "PowerPC (64-bit)"),
+ (Architecture.RiscV, "riscv", "RISC-V"),
+ (Architecture.Sh2, "sh2", "Hitachi SH2"),
+ (Architecture.Sh3, "sh3", "Hitachi SH3"),
+ (Architecture.Sh4, "sh4", "Hitachi SH4"),
+ (Architecture.Sh5, "sh5", "Hitachi SH5"),
+ (Architecture.Sparc, "sparc", "SPARC"),
+ (Architecture.Sparc64, "sparc64", "SPARC (64-bit)"),
+ (Architecture.Thumb, "thumb", "ARM Thumb"),
+ (Architecture.Thumb2, "thumb2", "ARM Thumb-2"),
+ (Architecture.We32000, "we32000", "WE32000")
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/libexeinfo/IExecutable.cs b/libexeinfo/IExecutable.cs
index 7ccbc97..baa67c2 100644
--- a/libexeinfo/IExecutable.cs
+++ b/libexeinfo/IExecutable.cs
@@ -24,5 +24,9 @@ namespace libexeinfo
/// General description of executable contents
///
string Information { get; }
+ ///
+ /// Architectures that the executable can run on
+ ///
+ Architecture[] Architectures { get; }
}
}
\ No newline at end of file
diff --git a/libexeinfo/LX/Enums.cs b/libexeinfo/LX/Enums.cs
index b094210..1d827bf 100644
--- a/libexeinfo/LX/Enums.cs
+++ b/libexeinfo/LX/Enums.cs
@@ -111,5 +111,22 @@ namespace libexeinfo
DOS = 3,
Win32 = 4
}
+
+ static Architecture CpuToArchitecture(TargetCpu cpu)
+ {
+ switch(cpu)
+ {
+ case TargetCpu.i286: return Architecture.I286;
+ case TargetCpu.i386:
+ case TargetCpu.i486:
+ case TargetCpu.Pentium: return Architecture.I386;
+ case TargetCpu.i860:
+ case TargetCpu.N11: return Architecture.I860;
+ case TargetCpu.MIPS1:
+ case TargetCpu.MIPS2: return Architecture.Mips;
+ case TargetCpu.MIPS3: return Architecture.Mips3;
+ default: return Architecture.Unknown;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/libexeinfo/LX/LX.cs b/libexeinfo/LX/LX.cs
index 3cb4d41..4bd08a1 100644
--- a/libexeinfo/LX/LX.cs
+++ b/libexeinfo/LX/LX.cs
@@ -79,6 +79,7 @@ namespace libexeinfo
public bool IsBigEndian => false;
public bool Recognized { get; private set; }
public string Type { get; private set; }
+ public Architecture[] Architectures => new[] {CpuToArchitecture(header.cpu_type)};
void Initialize()
{
diff --git a/libexeinfo/MZ/MZ.cs b/libexeinfo/MZ/MZ.cs
index 1eebdca..52adffb 100644
--- a/libexeinfo/MZ/MZ.cs
+++ b/libexeinfo/MZ/MZ.cs
@@ -80,6 +80,7 @@ namespace libexeinfo
///
public bool Recognized { get; private set; }
public string Type { get; private set; }
+ public Architecture[] Architectures => new[] {Architecture.I86};
void Initialize()
{
diff --git a/libexeinfo/NE/NE.cs b/libexeinfo/NE/NE.cs
index e90450b..7225cd2 100644
--- a/libexeinfo/NE/NE.cs
+++ b/libexeinfo/NE/NE.cs
@@ -77,6 +77,15 @@ namespace libexeinfo
public bool IsBigEndian => false;
public bool Recognized { get; private set; }
public string Type { get; private set; }
+ public Architecture[] Architectures =>
+ new[]
+ {
+ Header.target_os == TargetOS.Win32 || Header.program_flags.HasFlag(ProgramFlags.i386)
+ ? Architecture.I386
+ : Header.target_os == TargetOS.OS2 || Header.program_flags.HasFlag(ProgramFlags.i286)
+ ? Architecture.I286
+ : Architecture.I86
+ };
void Initialize()
{
diff --git a/libexeinfo/PE/PE.cs b/libexeinfo/PE/PE.cs
index 6482aa4..5014293 100644
--- a/libexeinfo/PE/PE.cs
+++ b/libexeinfo/PE/PE.cs
@@ -76,6 +76,7 @@ namespace libexeinfo
public bool IsBigEndian => false;
public bool Recognized { get; private set; }
public string Type { get; private set; }
+ public Architecture[] Architectures => new[] {COFF.MachineTypeToArchitecture(Header.coff.machine)};
void Initialize()
{
diff --git a/libexeinfo/libexeinfo.csproj b/libexeinfo/libexeinfo.csproj
index c839a84..ebc4154 100644
--- a/libexeinfo/libexeinfo.csproj
+++ b/libexeinfo/libexeinfo.csproj
@@ -41,8 +41,12 @@
+
+ ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll
+
+
diff --git a/libexeinfo/packages.config b/libexeinfo/packages.config
index 7600cbc..f94f455 100644
--- a/libexeinfo/packages.config
+++ b/libexeinfo/packages.config
@@ -1,4 +1,5 @@
+
\ No newline at end of file