In this this post, i will share with you a tiny tool that i wrote to discover all occurrences of TimeDateStamps in a PE executable. The tool simply traverses the PE header and specifically the following structures/fields:
1) The "TimeDateStamp" field of the "_IMAGE_FILE_HEADER" structure.
This is the most notorious field that is always a target for both malware authors and forensic guys.
N.B. Certain versions of Delphi linkers always emit a fixed TimeDateStamp of 0x2A425E19, Sat Jun 20 01:22:17 1992. In this case you should not rely on this field and continue looking in other fields.
2) The "TimeDateStamp" field of the "_IMAGE_EXPORT_DIRECTORY" structure.
It is usually the same as or very close to the "TimeDateStamp" field of the the "_IMAGE_FILE_HEADER" structure".
N.B. Not all linkers fill this field, but Microsoft Visual Studio linkers do fill it for both DLL's and EXE's.
3) The "TimeDateStamp" field of the "_IMAGE_IMPORT_DESCRIPTOR" structure.
Unlike what the name implies, this field is a bit useless if you are trying to determine when the executable was built. It is -1 if the executable/dll is bound (see #8) and zero if not. So, it is not implemented in my tool.
4) The "TimeDateStamp" field of the "_IMAGE_RESOURCE_DIRECTORY" structure.
Usually Microsoft Visual Studio linkers don't set it (I have tested with linker versions of 6.0, 8.0, 9.0, and 10.0).
Borland C and Delphi set this field for the main _IMAGE_RESOURCE_DIRECTORY and its subdirectories.
Sometimes spoofers forget to forge this field for subdirectories.
5) The "TimeDateStamp" of the "_IMAGE_DEBUG_DIRECTORY" structures.
Microsoft Visual Studio linkers emitting debug info. in the final PE always set this field. Spoofers may forge the field in the first "_IMAGE_DEBUG_DIRECTORY" structure and forget the following ones.
N.B. Debug info as pointed to by Debug Data Directory is an array of "_IMAGE_DEBUG_DIRECTORY" structures, each representing debug info of different type e.g. COFF, CodeView, etc.
6) If "_IMAGE_DEBUG_DIRECTORY" has the "Type" field set to 0x2 (IMAGE_DEBUG_TYPE_CODEVIEW), then by following the "PointerToRawData" field we can find another occurrence of TimeDateStamp ( only if the PDB format is PDB 2.0 i.e when "Signature" field is set to "NB10" )
7) The "TimeDateStamp" field of the "_IMAGE_LOAD_CONFIG_DIRECTORY" structure.
I have not seen it being used before. However, it is implemented in the tool.
8) The "TimeDateStamp" field of the "_IMAGE_BOUND_IMPORT_DESCRIPTOR" structures.
It is the TimeDateStamp of the DLL that the executable is bound to. We can't use this field to know when the executable was build, but we can use it to determine on which Windows version/Service pack the file was built/bound. It is not implemented in the tool.
The tool has a very simple command line. See below.
You download the tool from here. For any bugs or suggestions, please don't hesitate to leave me a comment or contant me @waleedassar.
GitHub Project here.
1) The "TimeDateStamp" field of the "_IMAGE_FILE_HEADER" structure.
This is the most notorious field that is always a target for both malware authors and forensic guys.
N.B. Certain versions of Delphi linkers always emit a fixed TimeDateStamp of 0x2A425E19, Sat Jun 20 01:22:17 1992. In this case you should not rely on this field and continue looking in other fields.
2) The "TimeDateStamp" field of the "_IMAGE_EXPORT_DIRECTORY" structure.
It is usually the same as or very close to the "TimeDateStamp" field of the the "_IMAGE_FILE_HEADER" structure".
N.B. Not all linkers fill this field, but Microsoft Visual Studio linkers do fill it for both DLL's and EXE's.
3) The "TimeDateStamp" field of the "_IMAGE_IMPORT_DESCRIPTOR" structure.
Unlike what the name implies, this field is a bit useless if you are trying to determine when the executable was built. It is -1 if the executable/dll is bound (see #8) and zero if not. So, it is not implemented in my tool.
4) The "TimeDateStamp" field of the "_IMAGE_RESOURCE_DIRECTORY" structure.
Usually Microsoft Visual Studio linkers don't set it (I have tested with linker versions of 6.0, 8.0, 9.0, and 10.0).
Borland C and Delphi set this field for the main _IMAGE_RESOURCE_DIRECTORY and its subdirectories.
Sometimes spoofers forget to forge this field for subdirectories.
5) The "TimeDateStamp" of the "_IMAGE_DEBUG_DIRECTORY" structures.
Microsoft Visual Studio linkers emitting debug info. in the final PE always set this field. Spoofers may forge the field in the first "_IMAGE_DEBUG_DIRECTORY" structure and forget the following ones.
N.B. Debug info as pointed to by Debug Data Directory is an array of "_IMAGE_DEBUG_DIRECTORY" structures, each representing debug info of different type e.g. COFF, CodeView, etc.
6) If "_IMAGE_DEBUG_DIRECTORY" has the "Type" field set to 0x2 (IMAGE_DEBUG_TYPE_CODEVIEW), then by following the "PointerToRawData" field we can find another occurrence of TimeDateStamp ( only if the PDB format is PDB 2.0 i.e when "Signature" field is set to "NB10" )
7) The "TimeDateStamp" field of the "_IMAGE_LOAD_CONFIG_DIRECTORY" structure.
I have not seen it being used before. However, it is implemented in the tool.
8) The "TimeDateStamp" field of the "_IMAGE_BOUND_IMPORT_DESCRIPTOR" structures.
It is the TimeDateStamp of the DLL that the executable is bound to. We can't use this field to know when the executable was build, but we can use it to determine on which Windows version/Service pack the file was built/bound. It is not implemented in the tool.
The tool has a very simple command line. See below.
You download the tool from here. For any bugs or suggestions, please don't hesitate to leave me a comment or contant me @waleedassar.
GitHub Project here.