当前位置:  开发笔记 > 编程语言 > 正文

如何确定编译可执行文件的平台?

如何解决《如何确定编译可执行文件的平台?》经验,为你挑选了4个好方法。

我需要使用为x86,x64和IA64制作的Windows可执行文件.我想通过检查文件本身以编程方式找出平台.

我的目标语言是PowerShell,但C#示例可以.如果您知道所需的逻辑很好,那么其中任何一个都会失败.



1> Keith Hill..:

如果安装了Visual Studio,则可以使用dumpbin.exe.PowerShell社区扩展中还有Get-PEHeadercmdlet ,可用于测试可执行映像.

Dumpbin会将DLL报告为machine (x86)machine (x64)

Get-PEHeader将DLL报告为PE32PE32+


对于那些懒得阅读本手册的人(比如我):`dumpbin/headers | findstr机器`

2> Andrew Backe..:

(来自另一个Q,自从删除)

机器类型:这是一些快速的代码我基于一些获取链接器时间戳的代码.这是在相同的标题中,它似乎工作 - 当编译-any cpu-时它返回I386,而当使用它作为目标平台编译时返回x64.

探索PE标题(K. Stanton,MSDN)博客文章向我展示了偏移,正如另一个回应所指出的那样.

public enum MachineType {
    Native = 0, I386 = 0x014c, Itanium = 0x0200, x64 = 0x8664
}

public static MachineType GetMachineType(string fileName)
{
    const int PE_POINTER_OFFSET = 60;            
    const int MACHINE_OFFSET = 4;
    byte[] data = new byte[4096];
    using (Stream s = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
        s.Read(data, 0, 4096);
    }
    // dos header is 64 bytes, last element, long (4 bytes) is the address of the PE header
    int PE_HEADER_ADDR = BitConverter.ToInt32(data, PE_POINTER_OFFSET);
    int machineUint = BitConverter.ToUInt16(data, PE_HEADER_ADDR + MACHINE_OFFSET);
    return (MachineType)machineUint;
}



3> gbjbaanb..:

您需要GetBinaryType win32函数.这将返回PE格式可执行文件的相关部分.

通常,您将在BinaryType字段中获得SCS_32BIT_BINARY或SCS_64BIT_BINARY,

另外,您可以检查PE格式本身,以查看可执行文件的编译体系结构.

IMAGE_FILE_HEADER.Machine字段将为IA64二进制文件设置"IMAGE_FILE_MACHINE_IA64",为32位设置IMAGE_FILE_MACHINE_I386,为64位设置IMAGE_FILE_MACHINE_AMD64(即x86_64).

有一篇MSDN杂志的文章可以帮助你开始.

附录:这可能对你有所帮助.您将二进制文件读作文件:检查前两个字节是否为"MZ",然后跳过接下来的58个字节,并将60字节的魔术32位值读入图像(对于PE可执行文件,它等于0x00004550).以下字节是此标头,其前2个字节告诉您二进制设计的机器(0x8664 = x86_64,0x0200 = IA64,0x014c = i386).

(执行摘要:读取文件的字节65和66以获取图像类型)


这看起来有点不准确.EXE文件中偏移量为60的4个字节是PE头从文件开头的偏移量.因此,正确答案是:读取2个字节,检查它们是否等于"MZ",跳转到偏移60,读取4个字节,解释为偏移并跳转到那里,读取4个字节并与"PE\0\0"进行比较(这是0x00004550).接下来的2个字节是如上所述的机器ID.

4> ICR..:
Assembly assembly = Assembly.LoadFile(Path.GetFullPath("ConsoleApplication1.exe"));
Module manifestModule = assembly.ManifestModule;
PortableExecutableKinds peKind;
ImageFileMachine machine;
manifestModule.GetPEKind(out peKind, out machine);

然后目标机器应该在机器中.

这只适用于.NET程序集.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有