如何识别内置的Windows二进制文件是32位还是64位? [关闭]

问题描述 投票:1回答:1

我使用go build为不同的os和不同的arch构建一些二进制文件。

在linux上,我可以使用类似下面的东西来知道64或32的二进制文件:

# file try
try: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
# file newtry
newtry: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped

如何在Windows上获取此信息?

file-format portable-executable
1个回答
0
投票

file工具通过查看某些“魔法”模式的预定义位置来工作;这些位置在magic file中描述。

使用简单的Go程序可以很容易地复制这种行为;微软网站有一个good description of the WinPE file format

以下程序正是如此,有一些限制:

  • 它假定该文件是WinPE文件。
  • 它简单的字节搜索COFF文件头的位置;找到合适的字节偏移量会更好: 在位置0x3c处,存根具有到PE签名的文件偏移量。此信息使Windows能够正确执行图像文件,即使它具有MS-DOS存根。在链接期间,此文件偏移位于0x3c处。签名(仅图像) 在MS-DOS存根之后,在偏移量0x3c处指定的文件偏移量处,是一个4字节的签名,它将文件标识为PE格式的图像文件。该签名是“PE \ 0 \ 0”(字母“P”和“E”后跟两个空字节)。

实现这一点留给读者练习;-)

package main

import (
    "bytes"
    "fmt"
    "log"
    "os"
)

func main() {
    fp, err := os.Open(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }
    defer fp.Close()


    data := make([]byte, 8192)
    _, err = fp.Read(data)
    if err != nil {
        log.Fatal(err)
    }

    h := bytes.Index(data, []byte("PE\x00\x00"))
    if h == -1 {
        log.Fatal("could not find COFF header")
    }

    // First two bytes is machine type.
    mach := fmt.Sprintf("0x%x%x", data[h+5:h+6], data[h+4:h+5])
    if err != nil {
        log.Fatal(err)
    }

    desc, ok := machineTypes[mach]
    if !ok {
        log.Fatalf("unknown machine type %s", mach)
    }

    fmt.Printf("%s %s\n", mach, desc)
}

var machineTypes = map[string]string{
    "0x0000": "The contents of this field are assumed to be applicable to any machine type",
    "0x01d3": "Matsushita AM33",
    "0x8664": "x64",
    "0x01c0": "ARM little endian",
    "0xaa64": "ARM64 little endian",
    "0x01c4": "ARM Thumb-2 little endian",
    "0x0ebc": "EFI byte code",
    "0x014c": "Intel 386 or later processors and compatible processors",
    "0x0200": "Intel Itanium processor family",
    "0x9041": "Mitsubishi M32R little endian",
    "0x0266": "MIPS16",
    "0x0366": "MIPS with FPU",
    "0x0466": "MIPS16 with FPU",
    "0x01f0": "Power PC little endian",
    "0x01f1": "Power PC with floating point support",
    "0x0166": "MIPS little endian",
    "0x5032": "RISC-V 32-bit address space",
    "0x5064": "RISC-V 64-bit address space",
    "0x5128": "RISC-V 128-bit address space",
    "0x01a2": "Hitachi SH3",
    "0x01a3": "Hitachi SH3 DSP",
    "0x01a6": "Hitachi SH4",
    "0x01a8": "Hitachi SH5",
    "0x01c2": "Thumb",
    "0x0169": "MIPS little-endian WCE v2 ",
}
© www.soinside.com 2019 - 2024. All rights reserved.