Quantcast
Channel: ASP.NET Core
Viewing all articles
Browse latest Browse all 9386

PE format difference: .NET vs .NET Core

$
0
0

Strictly speaking, it is not an ASP.NET question, but I could not find any other forum... Sorry...

The idea of the code below is to extract build timestamp from PE-compatible EXE or DLL. The code works perfectly for .NET binaries (for >6 years by now, btw) and reports rubbish for .NET Core ones. For a freshly built .NET (not Core) assembly it (correctly) reports "Mon Oct  9 13:30:14 2017", for a freshly built .NET Core  v.2 assembly it reports "Tue Mar 29 05:14:00 2061" (?).

It means that .NET Core assemblies do not follow PE file format _exactly_. In .NET Core case the timestamp field of IMAGE_FILE_HEADER does not contain "The low 32 bits of the number of seconds since 00:00 January 1, 1970 (a C run-time time_t value), that indicates when the file was created" (quote from pecoff.docx) as it should.

Why? Can it be fixed?

    // per "Microsoft PE and COFF Specification" pecoff_v8.docx at (as of 06/18/11)
    // http://msdn.microsoft.com/en-us/windows/hardware/gg463125
    // or, as of Oct 9th, 2017, pecoff.docx available at
    // https://www.microsoft.com/en-us/download/confirmation.aspx?id=19509
    const long c_offsetOfOffsetOfPE = 0x3c;     // per section 2 of pecoff_v8.docx
    const Int32 c_PE00 = 0x00004550;			// = 50 45 00 00 = PE\0\0

    /// <summary>
    /// Extracts build time from a PE executable (EXE or DLL) per "Microsoft PE and COFF Specification" pecoff_v8.docx
    /// </summary>
    static DateTime GetExeOrDll_EST_TimeStampDT()
    {
        DateTime timeStamp = new DateTime();
        try
        {
            // This works OK for .NET but produces invalid timestamp for .NET Core assemblies(why ?)
            string path = MyAssembly.Location;
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (BinaryReader br = new BinaryReader(fs))
                {
                    fs.Position = c_offsetOfOffsetOfPE;
                    byte OffsetOfPE = br.ReadByte();            //  = 0x80
                    fs.Position = OffsetOfPE;
                    Int32 PE00 = br.ReadInt32();                // = 0x00004550 [ = 50 45 00 00 = PE\0\0 ]
                    if (PE00 != c_PE00) { return timeStamp; }   // invalid file format, return "best guess" (last write time)
                    fs.Position = OffsetOfPE + 8;
                    UInt32 timeStampLower32Bits = br.ReadUInt32();    // .ReadInt32();                        // = 0x4dfcd934
                    if (timeStampLower32Bits == 0 || timeStampLower32Bits == 0xFFFFFFFF) { return timeStamp; }   // invalid date/time stamp, return "best guess" (last write time)
                    timeStamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);    // 00:00 January 1, 1970 (a C run-time time_t value)
                    timeStamp = timeStamp.AddSeconds(timeStampLower32Bits);
                    TimeZoneInfo easternStdTime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
                    timeStamp = TimeZoneInfo.ConvertTimeFromUtc(timeStamp, easternStdTime);
                }
            }
        }
        catch (Exception ex)
        {
            string qqq = ex.Message;
        }
        return timeStamp;
    }


Viewing all articles
Browse latest Browse all 9386

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>