如何检查exe是否设置为LARGEADDRESSAWARE

本文关键字:是否 设置 LARGEADDRESSAWARE exe 何检查 检查 | 更新日期: 2023-09-27 18:22:01

我正在开发一个C#程序,该程序将加载文件并获取加载文件的创建日期、修改日期、大小等信息。我需要知道的另一件事是加载的文件(executable.exe)是否与LARGEADDRESSAWARE标志链接。FileInfo类不提供此信息。

有人知道在C#中如何查找给定的executable.exe是否与LARGEADDRESSAWARE标志链接(以处理大于2GB的地址)吗?

如何检查exe是否设置为LARGEADDRESSAWARE

以下是一些检查Large Address Aware标志的代码。您所要做的就是传递一个指向可执行文件开头的流。

IsLargeAware("some.exe");
static bool IsLargeAware(string file)
{
    using (var fs = File.OpenRead(file))
    {
        return IsLargeAware(fs);
    }
}
/// <summary>
/// Checks if the stream is a MZ header and if it is large address aware
/// </summary>
/// <param name="stream">Stream to check, make sure its at the start of the MZ header</param>
/// <exception cref=""></exception>
/// <returns></returns>
static bool IsLargeAware(Stream stream)
{
    const int IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20;
    var br = new BinaryReader(stream);
    if (br.ReadInt16() != 0x5A4D)       //No MZ Header
        return false;
    br.BaseStream.Position = 0x3C;
    var peloc = br.ReadInt32();         //Get the PE header location.
    br.BaseStream.Position = peloc;
    if (br.ReadInt32() != 0x4550)       //No PE header
        return false;
    br.BaseStream.Position += 0x12;
    return (br.ReadInt16() & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE;
}

用于/LARGEADDRESSAWARE的MSDN文档指出:

如果应用程序与/LARGEADDRESSAWARE链接,则DUMPBIN/HEADERS将显示相应的信息。

如果您正在寻找一种用程序实现这一点的方法,您可以从应用程序中调用dumpbin并解析输出。

更新:

这里还有一篇很好的博客文章,更深入地讨论了这个问题。

根据Will的回答,我在x86安装包中使用了以下内容:

    static bool LargeAware(string file) {
        using (var fs = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) {
            bool b = LargeAware(fs);
            fs.Close();
            return b;
        }
    }
    const int IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x20;
    static bool LargeAware(Stream stream) {
        var br = new BinaryReader(stream);
        var bw = new BinaryWriter(stream);
        if (br.ReadInt16() != 0x5A4D)       //No MZ Header
            return false;
        br.BaseStream.Position = 0x3C;
        var peloc = br.ReadInt32();         //Get the PE header location.
        br.BaseStream.Position = peloc;
        if (br.ReadInt32() != 0x4550)       //No PE header
            return false;
        br.BaseStream.Position += 0x12;
        long nFilePos = (int)br.BaseStream.Position;
        Int16 nLgaInt = br.ReadInt16();
        bool bIsLGA = (nLgaInt & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE;
        if (bIsLGA)
            return true;
        nLgaInt |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
        long nFilePos1 = bw.Seek((int)nFilePos, SeekOrigin.Begin);
        bw.Write(nLgaInt);
        bw.Flush();
        long nFilePos2 = br.BaseStream.Seek(nFilePos, SeekOrigin.Begin);
        nLgaInt = br.ReadInt16();
        bIsLGA = (nLgaInt & IMAGE_FILE_LARGE_ADDRESS_AWARE) == IMAGE_FILE_LARGE_ADDRESS_AWARE;
        return bIsLGA;
    }