Image Header vs. File Timestamps.

Folks may use the term “Module Timestamp” to mean both file timestamp and image header timestamp. Although they’re usually very close, they’re different and won’t be identical. Here’s a compare/contrast:

  File timestamp Image header timestamp
What is it? This is tracked by the file system, and includes several metrics such as when the file was created, when it was last modified, and when it was last accessed. Emitted by the compiler and stored in the image header. Thus, it’s in the contents of the file and separate from the meta-information tracked by the filesystem.
Who normally sets it? The file system. The compiler (which then generally creates a file to persists the results to, thus the file and image timestamps are usually very close)
Underlying storage 64-bit FileTime structure 32-bit time_t structure.
Win32 exposure kernel32!GetFileTime IMAGE_FILE_HEADER, exposed via the ImageHelp library.
Matt Pietrek has an excellent article about cracking the PE file to get information like this. (The PE file format is publicly specced).
.NET exposure In .NET, these are accessible as System.DateTime objects via File.GetCreationTime, File.GetLastAccessTime, File.GetLastWriteTime. I don’t think there are any .Net APIs to get these. (does anybody want them?).  The Pdb2Xml writer in MDbg sample alludes to this a little.
BradA tells how to convert time_t to a System.DateTime.    

The image timestamp is what you see under a debugger. For example, windbg’s ‘lmv’ command displays the timestamp as both the raw 32-bit value and a conversion to something useful:

Image name: notepad.exe
Timestamp: Tue Aug 03 23:05:55 2004 (41107CC3)
CheckSum: 00014F7F

The filetimestamps can be viewed from Explorer. Just right click on the file and bring up properties.  For comparison, the timestamps from the same file via the file system:
  Created: Monday, August 09, 2004, 11:11:33 AM
  Modified: Wednesday, August 04, 2004, 4:00:00 AM
  Accessed: Today, January 18, 2007, 7:22:56 PM

The image timestamp (and other related data) is also what’s captured in a dump file  (see MINIDUMP_MODULE). So when a debugger wants to correlate modules in a minidump to real modules on disk, it can use the timestamp and checksums in the image header. This is similar to how PDB matching works.

While I’m on topic, Raymond has an excellent overview of different time formats

Comments (5)

  1. Jb Evain says:

    Hello Mike,

    You can use Cecil [1] to read the timestamp from an image header of a PE file in the managed world.



  2. Michiel says:

    I believe Mono Cecil provides a .NET interface to the meta data of an assembly and PE file and thus the image data with all its properties. Cecil is a real nice tool to work with assemblies at a very low level. It even had the ability to read and write sequence points and documents from/to PDB files.

  3. I just noticed that my blog had birthday #3 (Sep 30th) . In tradition, some various stats… 384 posts.