15

I am developing a C# program that will load files and get information such as loaded file created date, modification date, size etc. Another thing that I need to know is whether the loaded file (executable.exe) is linked with the LARGEADDRESSAWARE flag. The FileInfo class doesn't provide this information.

Does anyone know how in C# can I find out whether a given executable.exe is linked with the LARGEADDRESSAWARE flag (to handle addresses larger than 2 GB)?

Frank
  • 2,738
  • 19
  • 30
harrygg
  • 664
  • 1
  • 7
  • 12
  • 2
    Please don't prefix your titles with "C#" and such. That's what tags are for. Also, FYI, `FileInfo` isn't part of C#. It's part of .NET. – John Saunders Jan 29 '12 at 15:53
  • 2
    It is stored in IMAGE_FILE_HEADER.Characteristics, IMAGE_FILE_LARGE_ADDRESS_AWARE bit: http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313%28v=vs.85%29.aspx – Hans Passant Jan 29 '12 at 18:18

3 Answers3

25

Here is some code that checks for the Large Address Aware flag. All you have to do is pass a stream that is pointed to the start of an executable.

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;
}
Will
  • 10,013
  • 9
  • 45
  • 77
15

The MSDN documentation for /LARGEADDRESSAWARE states:

If an application was linked with /LARGEADDRESSAWARE, DUMPBIN /HEADERS will display information to that effect.

If you're looking for a way to do this programatically, you could invoke dumpbin from your application and parse the output.

Update:

There is also a good blog post here that discusses the issue in more depth.

M.Babcock
  • 18,753
  • 6
  • 54
  • 84
  • [This answer](https://stackoverflow.com/a/6777574/25507) has more details on using dumpbin to check large address aware. – Josh Kelley Dec 21 '17 at 14:49
1

From Will's answer above I'm using the following in my x86 setup package:

    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;
    }
Michael Fitzpatrick
  • 682
  • 3
  • 8
  • 18