【问题标题】:how to check if exe is set as LARGEADDRESSAWARE如何检查 exe 是否设置为 LARGEADDRESSAWARE
【发布时间】:2012-02-21 16:36:40
【问题描述】:

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

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

【问题讨论】:

  • 请不要在标题前加上“C#”之类的前缀。这就是标签的用途。另外,仅供参考,FileInfo 不是 C# 的一部分。它是 .NET 的一部分。
  • 存储在IMAGE_FILE_HEADER.Characteristics, IMAGE_FILE_LARGE_ADDRESS_AWARE位:msdn.microsoft.com/en-us/library/windows/desktop/…

标签: c# memory virtual-address-space address-space


【解决方案1】:

这里是一些检查大地址感知标志的代码。您所要做的就是传递一个指向可执行文件开头的流。

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;
}

【讨论】:

    【解决方案2】:

    /LARGEADDRESSAWAREMSDN documentation 声明:

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

    如果您正在寻找一种以编程方式执行此操作的方法,您可以从您的应用程序中调用 dumpbin 并解析输出。

    更新:

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

    【讨论】:

    • This answer 有更多关于使用 dumpbin 检查大地址感知的详细信息。
    【解决方案3】:

    根据上面 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;
        }
    

    【讨论】:

      猜你喜欢
      • 2011-04-08
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2015-10-27
      • 2018-05-24
      • 1970-01-01
      • 2013-08-24
      • 2013-10-01
      相关资源
      最近更新 更多