Aquí está mi propia implementación de este que tiene varias más cheques en su lugar y siempre devuelve un resultado .
// the enum of known pe file types
public enum FilePEType : ushort
{
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1c0,
IMAGE_FILE_MACHINE_EBC = 0xebc,
IMAGE_FILE_MACHINE_I386 = 0x14c,
IMAGE_FILE_MACHINE_IA64 = 0x200,
IMAGE_FILE_MACHINE_M32R = 0x9041,
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
IMAGE_FILE_MACHINE_R4000 = 0x166,
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
}
// pass the path to the file and check the return
public static FilePEType GetFilePE(string path)
{
FilePEType pe = new FilePEType();
pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN;
if(File.Exists(path))
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] data = new byte[4096];
fs.Read(data, 0, 4096);
ushort result = BitConverter.ToUInt16(data, BitConverter.ToInt32(data, 60) + 4);
try
{
pe = (FilePEType)result;
} catch (Exception)
{
pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN;
}
}
}
return pe;
}
Modo de empleo:
string myfile = @"c:\windows\explorer.exe"; // the file
FilePEType pe = GetFilePE(myfile);
System.Diagnostics.WriteLine(pe.ToString());
Para los valores de enumeración utilizados aquí, que se obtuvieron de pe.go. La razón por la que esto funciona es que para cada distribución binaria de 'go' debe tener el indicador correcto en el ensamblado para permitirle pasar los sistemas operativos '¿puede ejecutar aquí?' comprobar. Como 'ir' es multiplataforma (todas las plataformas), es una buena base para obtener esta información. Probablemente haya otras fuentes para esta información, pero parecen estar anidadas hasta la rodilla en google ca-ca que requieren un cinturón negro de décimo dan en Google-fu para localizar.
Esto funciona bien, si se puede cargar el binario de destino. En mi caso, había una DLL .NET que necesitaba VCRedist y traté de averiguar cuál (x86 o x64), que corresponde a .NET dll. Pero, lógicamente e irónicamente, no puedo cargar este .NET dll sin VCRedist instalado y, por lo tanto, no puedo detectar cuál necesita (con este método). – Nicolas