├── nTimestomp
├── icon1.ico
├── resource.h
├── resource1.h
├── nTimestomp.aps
├── nTimestomp.rc
├── nTimestomp.vcxproj.filters
├── nTimestomp.vcxproj.user
├── nTimestomp.vcxproj
└── nTimestomp.c
├── nTimeview
├── icon1.ico
├── nTimeview.rc
├── resource1.h
├── nTimeview.aps
├── nTimeview1.aps
├── nTimeview1.rc
├── resource.h
├── nTimeview.vcxproj.user
├── nTimeview.vcxproj.filters
├── RCa14184
├── nTimeview.c
└── nTimeview.vcxproj
├── nTimeview_v1.0_x64.exe
├── nTimestomp_v1.2_x64.exe
├── NTimetools.sln
└── README.md
/nTimestomp/icon1.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp/icon1.ico
--------------------------------------------------------------------------------
/nTimeview/icon1.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/icon1.ico
--------------------------------------------------------------------------------
/nTimestomp/resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp/resource.h
--------------------------------------------------------------------------------
/nTimestomp/resource1.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp/resource1.h
--------------------------------------------------------------------------------
/nTimeview/nTimeview.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/nTimeview.rc
--------------------------------------------------------------------------------
/nTimeview/resource1.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/resource1.h
--------------------------------------------------------------------------------
/nTimeview_v1.0_x64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview_v1.0_x64.exe
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.aps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp/nTimestomp.aps
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp/nTimestomp.rc
--------------------------------------------------------------------------------
/nTimestomp_v1.2_x64.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimestomp_v1.2_x64.exe
--------------------------------------------------------------------------------
/nTimeview/nTimeview.aps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/nTimeview.aps
--------------------------------------------------------------------------------
/nTimeview/nTimeview1.aps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/nTimeview1.aps
--------------------------------------------------------------------------------
/nTimeview/nTimeview1.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/limbenjamin/nTimetools/HEAD/nTimeview/nTimeview1.rc
--------------------------------------------------------------------------------
/nTimeview/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by nTimeview1.rc
4 |
5 | // Next default values for new objects
6 | //
7 | #ifdef APSTUDIO_INVOKED
8 | #ifndef APSTUDIO_READONLY_SYMBOLS
9 | #define _APS_NEXT_RESOURCE_VALUE 101
10 | #define _APS_NEXT_COMMAND_VALUE 40001
11 | #define _APS_NEXT_CONTROL_VALUE 1001
12 | #define _APS_NEXT_SYMED_VALUE 101
13 | #endif
14 | #endif
15 |
--------------------------------------------------------------------------------
/nTimeview/nTimeview.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | C:\bootTel.dat
5 | WindowsLocalDebugger
6 |
7 |
8 | C:\bootTel.dat
9 | WindowsLocalDebugger
10 |
11 |
12 | C:\bootTel.dat
13 | WindowsLocalDebugger
14 |
15 |
16 | C:\bootTel.dat
17 | WindowsLocalDebugger
18 |
19 |
--------------------------------------------------------------------------------
/nTimeview/nTimeview.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
23 |
24 | Header Files
25 |
26 |
27 | Header Files
28 |
29 |
30 |
31 |
32 | Resource Files
33 |
34 |
35 |
36 |
37 | Resource Files
38 |
39 |
40 |
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
23 |
24 | Header Files
25 |
26 |
27 | Header Files
28 |
29 |
30 |
31 |
32 | Resource Files
33 |
34 |
35 |
36 |
37 | Resource Files
38 |
39 |
40 |
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | C:\test.txt "2014-12-30 09:04:05.1111111" "2014-12-30 09:04:04.2222222" "2014-12-30 09:04:03.3333333" "2014-12-30 09:04:02.4444474"
5 | WindowsLocalDebugger
6 |
7 |
8 | C:\test.txt "2014-12-30 09:04:05.1111111" "2014-12-30 09:04:04.2222222" "2014-12-30 09:04:03.3333333" "2014-12-30 09:04:02.4444474"
9 | WindowsLocalDebugger
10 |
11 |
12 | C:\test.txt "2014-12-30 09:04:05.1111111" "2014-12-30 09:04:04.2222222" "2014-12-30 09:04:03.3333333" "2014-12-30 09:04:02.4444474"
13 | WindowsLocalDebugger
14 |
15 |
16 | C:\test.txt "2014-12-30 09:04:05.1111111" "2014-12-30 09:04:04.2222222" "2014-12-30 09:04:03.3333333" "2014-12-30 09:04:02.4444474"
17 | WindowsLocalDebugger
18 |
19 |
--------------------------------------------------------------------------------
/NTimetools.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nTimeview", "NTimeview\NTimeview.vcxproj", "{220659AE-24BA-4F0C-AD77-8D2D4B5387FE}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nTimestomp", "nTimestomp\nTimestomp.vcxproj", "{BDFD58BC-C440-471D-BD8B-6D55B20326F8}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Debug|x64.ActiveCfg = Debug|x64
19 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Debug|x64.Build.0 = Debug|x64
20 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Debug|x86.ActiveCfg = Debug|Win32
21 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Debug|x86.Build.0 = Debug|Win32
22 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Release|x64.ActiveCfg = Release|x64
23 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Release|x64.Build.0 = Release|x64
24 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Release|x86.ActiveCfg = Release|Win32
25 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}.Release|x86.Build.0 = Release|Win32
26 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Debug|x64.ActiveCfg = Debug|x64
27 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Debug|x64.Build.0 = Debug|x64
28 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Debug|x86.ActiveCfg = Debug|Win32
29 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Debug|x86.Build.0 = Debug|Win32
30 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Release|x64.ActiveCfg = Release|x64
31 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Release|x64.Build.0 = Release|x64
32 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Release|x86.ActiveCfg = Release|Win32
33 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}.Release|x86.Build.0 = Release|Win32
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | EndGlobal
39 |
--------------------------------------------------------------------------------
/nTimeview/RCa14184:
--------------------------------------------------------------------------------
1 | # l i n e 1 " C : \ \ w o r k s p a c e \ \ N T i m e v i e w \ \ N T i m e v i e w \ \ n T i m e v i e w 1 . r c "
2 | # l i n e 1
3 | / / M i c r o s o f t V i s u a l C + + g e n e r a t e d r e s o u r c e s c r i p t .
4 | / /
5 | # i n c l u d e " r e s o u r c e . h "
6 | # l i n e 5
7 | # d e f i n e A P S T U D I O _ R E A D O N L Y _ S Y M B O L S
8 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
9 | / /
10 | / / G e n e r a t e d f r o m t h e T E X T I N C L U D E 2 r e s o u r c e .
11 | / /
12 | # i n c l u d e " w i n r e s . h "
13 | # l i n e 1 2
14 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
15 | # u n d e f A P S T U D I O _ R E A D O N L Y _ S Y M B O L S
16 | # l i n e 1 5
17 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
18 | / / E n g l i s h ( U n i t e d S t a t e s ) r e s o u r c e s
19 | # l i n e 1 8
20 | # i f ! d e f i n e d ( A F X _ R E S O U R C E _ D L L ) | | d e f i n e d ( A F X _ T A R G _ E N U )
21 | L A N G U A G E 9 , 1
22 | # l i n e 2 1
23 | # i f d e f A P S T U D I O _ I N V O K E D
24 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
25 | / /
26 | / / T E X T I N C L U D E
27 | / /
28 | # l i n e 2 7
29 | 1 T E X T I N C L U D E
30 | B E G I N
31 | " r e s o u r c e . h \ 0 "
32 | E N D
33 | # l i n e 3 2
34 | 2 T E X T I N C L U D E
35 | B E G I N
36 | " # i n c l u d e " " w i n r e s . h " " \ r \ n "
37 | " \ 0 "
38 | E N D
39 | # l i n e 3 8
40 | 3 T E X T I N C L U D E
41 | B E G I N
42 | " \ r \ n "
43 | " \ 0 "
44 | E N D
45 | # l i n e 4 4
46 | # e n d i f / / A P S T U D I O _ I N V O K E D
47 | # l i n e 4 6
48 | # e n d i f / / E n g l i s h ( U n i t e d S t a t e s ) r e s o u r c e s
49 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
50 | # l i n e 5 1
51 | # i f n d e f A P S T U D I O _ I N V O K E D
52 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
53 | / /
54 | / / G e n e r a t e d f r o m t h e T E X T I N C L U D E 3 r e s o u r c e .
55 | / /
56 | # l i n e 5 8
57 | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
58 | # e n d i f / / n o t A P S T U D I O _ I N V O K E D
59 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | nTimetools
2 | ======================
3 | nTimetools is a suite of console tools developed to work with timestamps in Windows. NTFS stores timestamps with 100-nanosecond level of precision. However, most live response forensic tools as well as timestomping tools are only able to provide up to 1 second level of precision. nTimetools (n is short for nano) comprises 2 tools that allow both forensic analysts as well as red teamers to modify and verify file timestamps up to 100-nanosecond precision.
4 |
5 | 1. **nTimeview allows forensic analysts to view the MACB timestamps of files on a live system.** It uses the undocumented NtQueryInformationFile API. As such, it works on NTFS/FAT and even mapped drives. It does not require privileged access. This is particularly useful in the case of mapped drives as the current user does not usually have privileged access on a mapped drive in enterprise settings. It is also oftentimes not possible to take the mapped drive offline due to other connected users.
6 |
7 | 
8 |
9 | 2. **nTimestomp allows red teamers to timestomp MACB timestamps of files with 100-nanosecond level precision.** Forensic analysts are usually taught to spot 0s in the millisecond position as evidence that timestomping has occurred. nTimestomp will allow your files to blend in on cursory inspection. It uses the same undocumented NtSetInformationFile API which means privileged access is not neccessary and files on NTFS/FAT and mapped drives can also be timestomped.
10 |
11 | 
12 |
13 | The syntax for nTimestomp is `nTimestomp.exe -F F:\VERSION-FOR508-18-2A.txt -M "1995-05-19 12:34:56.7890123" -A "1995-05-19 12:34:56.7890123" -C "1995-05-19 23:59:59.0000001" -B "1995-05-19 23:59:59.0000001"` The separator for the nanoseconds portion is a dot and not a colon. The date format is `YYYY-MM-DD`. Filename is a required argument, any combination of `-M -A -C -B` is accepted, current timestamp will be retained if that argument is not specified.
14 |
15 | FAT does not keep track of metadata change time, hence the null value. The difference in timestamps is due to the level of precision of FAT timestamps. Also, creation timestamps on mounted drives cannot be modified to due API limitations.
16 |
17 | Downloads
18 | =========
19 |
20 | [nTimeview_v1.0_64bit](https://limbenjamin.com/files/nTimeTools/nTimeview_v1.0_x64.exe) - SHA1() = 7b0506dca02e7a3dd9ba4fcbe4f4ff45008d31c8
21 | [nTimestomp_v1.2_64bit](https://limbenjamin.com/files/nTimeTools/nTimestomp_v1.2_x64.exe) - SHA1() = 1175837865ab8282f1905b66c7417efdd8a56259
22 |
23 |
24 | Q&A
25 | ===
26 |
27 | Are there any similar tools out there?
28 | --------------------------------------
29 | Joakim Schicht (jschicht) has an excellent set of tools out there, MftRcrd and SetMace, that work with timestamps of up to 100-nanosecond precision. These tools work in a different way. The raw device is mounted and the MFT is parsed and read from. The advantage of doing so is that $FILE_NAME timestamps can also be read. This allows a more in-depth check for signs of timestomping. However, the downside of using raw device mounting is that it will only work on NTFS filesystems and it requires privileged access. For SetMace, due to restrictions placed in recent version of Windows on writing to a raw device, it will only work on non system drives.
30 |
31 | License?
32 | --------
33 | The software is distributed "as is". No warranty of any kind is expressed or implied. You use at your own risk. The author will not be liable for data loss, damages, loss of profits or any other kind of loss while using or misusing this software.
34 |
35 | The Licensee is allowed to freely redistribute the software subject to the following conditions.
36 | 1. The Software may be installed and used by the Licensee for any legal purpose.
37 | 2. The Licensee will not charge money or fees for the software product, except to cover distribution costs.
38 | 3. The Licensor retains all copyrights and other proprietary rights in and to the Software.
39 | 4. Use within the scope of this License is free of charge and no royalty or licensing fees shall be paid by the Licensee.
40 |
41 | Bugs or comments?
42 | -----------------
43 | Create an issue on [github](https://github.com/limbenjamin/nTimetools)
44 |
45 | Changelog
46 | ---------
47 | nTimestomp v1.1 (10/02/19) - Modified help example to have only 7 digits for nanosecond field.
48 | nTimestomp v1.2 (14/09/21) - Consistency in order of MACB arguments. Added flags for arguments.
49 |
--------------------------------------------------------------------------------
/nTimeview/nTimeview.c:
--------------------------------------------------------------------------------
1 | // #######################################################################
2 | // ############ HEADER FILES
3 | // #######################################################################
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | typedef LONG NTSTATUS;
11 | char* VERSION_NO = "1.0";
12 |
13 | typedef struct _FILE_BASIC_INFORMATION {
14 | LARGE_INTEGER CreationTime; // Created
15 | LARGE_INTEGER LastAccessTime; // Accessed
16 | LARGE_INTEGER LastWriteTime; // Modifed
17 | LARGE_INTEGER ChangeTime; // Entry Modified
18 | ULONG FileAttributes;
19 | } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
20 |
21 |
22 |
23 | typedef NTSTATUS(WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
24 |
25 | HANDLE RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi);
26 | DWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger);
27 | VOID About();
28 | VOID Usage();
29 |
30 | // #######################################################################
31 | // ############ FUNCTIONS
32 | // #######################################################################
33 |
34 | VOID About() {
35 | printf("nTimeview, Version %s\r\n", VERSION_NO);
36 | printf("Copyright (C) 2019 Benjamin Lim\r\n");
37 | printf("Available for free from https://limbenjamin.com/pages/ntimetools\r\n");
38 | printf("\r\n");
39 | }
40 |
41 | VOID Usage() {
42 | printf("\r\n");
43 | printf("Usage: .\\nTimeview.exe [Filename]\r\n");
44 | printf("\r\n");
45 | }
46 |
47 | /* returns the handle on success or NULL on failure. this function opens a file and returns
48 | the FILE_BASIC_INFORMATION on it. */
49 | HANDLE RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi) {
50 |
51 | HANDLE file = NULL;
52 | HMODULE ntdll = NULL;
53 | pNtQueryInformationFile NtQueryInformationFile = NULL;
54 | IO_STATUS_BLOCK iostatus;
55 |
56 | file = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
57 | if (file == INVALID_HANDLE_VALUE) {
58 | printf("Cannot open file: %S\r\n", filename);
59 | Usage();
60 | exit(1);
61 | }
62 |
63 | /* load ntdll and retrieve function pointer */
64 | ntdll = GetModuleHandle(TEXT("ntdll.dll"));
65 | if (ntdll == NULL) {
66 | printf("Cannot load ntdll\r\n");
67 | CloseHandle(file);
68 | exit(1);
69 | }
70 |
71 | /* retrieve current timestamps including file attributes which we want to preserve */
72 | NtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(ntdll, "NtQueryInformationFile");
73 | if (NtQueryInformationFile == NULL) {
74 | CloseHandle(file);
75 | exit(1);
76 | }
77 |
78 | /* obtain the current file information including attributes */
79 | if (NtQueryInformationFile(file, &iostatus, fbi, sizeof(FILE_BASIC_INFORMATION), 4) < 0) {
80 | CloseHandle(file);
81 | exit(1);
82 | }
83 |
84 | /* clean up */
85 | FreeLibrary(ntdll);
86 |
87 | return file;
88 | }
89 |
90 | /* returns 0 on error, 1 on success. this function converts a LARGE_INTEGER to a SYSTEMTIME structure */
91 | DWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger) {
92 |
93 | FILETIME filetime;
94 | FILETIME localfiletime;
95 | DWORD result = 0;
96 |
97 | filetime.dwLowDateTime = largeinteger.LowPart;
98 | filetime.dwHighDateTime = largeinteger.HighPart;
99 |
100 | if (FileTimeToSystemTime(&filetime, localsystemtime) == 0) {
101 | printf("Invalid filetime\r\n");
102 | exit(1);
103 | }
104 |
105 | return 1;
106 | }
107 |
108 | int main(int argc, char* argv[]) {
109 | HANDLE file = NULL;
110 | struct _FILE_BASIC_INFORMATION fbi = { 0 };
111 | struct _SYSTEMTIME time = { 0 };
112 | wchar_t filename[4096] = { 0 };
113 | char str[256];
114 | CHAR lpVolumeNameBuffer[MAX_PATH + 1] = { 0 };
115 | CHAR lpFileSystemNameBuffer[MAX_PATH + 1] = { 0 };
116 | LARGE_INTEGER lpFileSizeHigh = { 0 };
117 |
118 | About();
119 | MultiByteToWideChar(CP_ACP, 0, argv[1], -1, filename, 4096);
120 | file = RetrieveFileBasicInformation(filename, &fbi);
121 | GetVolumeInformationByHandleW(file, &lpVolumeNameBuffer, ARRAYSIZE(lpVolumeNameBuffer), 0, 0, 0, &lpFileSystemNameBuffer, ARRAYSIZE(lpVolumeNameBuffer));
122 | GetFileSizeEx(file, &lpFileSizeHigh);
123 |
124 | printf("Filesystem type: %S\r\n", lpFileSystemNameBuffer);
125 | printf("Filename: %S\r\n", filename);
126 | printf("File size: %d\r\n", lpFileSizeHigh.QuadPart);
127 | printf("\r\n");
128 |
129 | ConvertLargeIntegerToLocalTime(&time, fbi.LastWriteTime);
130 | if (fbi.LastWriteTime.QuadPart != 0) {
131 | sprintf_s(str, 256, "%lld", fbi.LastWriteTime.QuadPart);
132 | printf("[M] Last Write Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
133 | }else {
134 | printf("[M] Last Write Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
135 | }
136 | memset(&time, 0, sizeof(time));
137 |
138 | ConvertLargeIntegerToLocalTime(&time, fbi.LastAccessTime);
139 | if (fbi.LastAccessTime.QuadPart != 0) {
140 | sprintf_s(str, 256, "%lld", fbi.LastAccessTime.QuadPart);
141 | printf("[A] Last Access Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
142 | } else {
143 | printf("[A] Last Access Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
144 | }
145 | memset(&time, 0, sizeof(time));
146 |
147 | ConvertLargeIntegerToLocalTime(&time, fbi.ChangeTime);
148 | if (fbi.ChangeTime.QuadPart != 0) {
149 | sprintf_s(str, 256, "%lld", fbi.ChangeTime.QuadPart);
150 | printf("[C] Metadata Change Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
151 | } else {
152 | printf("[C] Metadata Change Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
153 | }
154 | memset(&time, 0, sizeof(time));
155 |
156 | ConvertLargeIntegerToLocalTime(&time, fbi.CreationTime);
157 | if (fbi.CreationTime.QuadPart != 0) {
158 | sprintf_s(str, 256, "%lld", fbi.CreationTime.QuadPart);
159 | printf("[B] Creation Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
160 | } else {
161 | printf("[B] Creation Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
162 | }
163 | printf("\r\n");
164 | CloseHandle(file);
165 | }
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | {BDFD58BC-C440-471D-BD8B-6D55B20326F8}
36 | Win32Proj
37 | nTimestomp
38 | 8.1
39 |
40 |
41 |
42 | Application
43 | true
44 | v140
45 | Unicode
46 |
47 |
48 | Application
49 | false
50 | v140
51 | true
52 | Unicode
53 |
54 |
55 | Application
56 | true
57 | v140
58 | Unicode
59 |
60 |
61 | Application
62 | false
63 | v140
64 | true
65 | Unicode
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | true
87 |
88 |
89 | true
90 |
91 |
92 | false
93 |
94 |
95 | false
96 |
97 |
98 |
99 |
100 |
101 | Level3
102 | Disabled
103 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
104 | true
105 | MultiThreaded
106 |
107 |
108 | Console
109 | true
110 |
111 |
112 |
113 |
114 |
115 |
116 | Level3
117 | Disabled
118 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
119 | true
120 | MultiThreaded
121 |
122 |
123 | Console
124 | true
125 |
126 |
127 |
128 |
129 | Level3
130 |
131 |
132 | MaxSpeed
133 | true
134 | true
135 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
136 | true
137 | MultiThreaded
138 |
139 |
140 | Console
141 | true
142 | true
143 | true
144 |
145 |
146 |
147 |
148 | Level3
149 |
150 |
151 | MaxSpeed
152 | true
153 | true
154 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
155 | true
156 | MultiThreaded
157 |
158 |
159 | Console
160 | true
161 | true
162 | true
163 |
164 |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/nTimeview/nTimeview.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | {220659AE-24BA-4F0C-AD77-8D2D4B5387FE}
36 | Win32Proj
37 | nTimeview
38 | 8.1
39 | nTimeview
40 |
41 |
42 |
43 | Application
44 | true
45 | v140
46 | Unicode
47 |
48 |
49 | Application
50 | false
51 | v140
52 | true
53 | Unicode
54 |
55 |
56 | Application
57 | true
58 | v140
59 | Unicode
60 |
61 |
62 | Application
63 | false
64 | v140
65 | true
66 | Unicode
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | true
88 |
89 |
90 | true
91 |
92 |
93 | false
94 |
95 |
96 | false
97 |
98 |
99 |
100 |
101 |
102 | Level3
103 | Disabled
104 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
105 | true
106 | MultiThreaded
107 |
108 |
109 | Console
110 | true
111 |
112 |
113 |
114 |
115 |
116 |
117 | Level3
118 | Disabled
119 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
120 | true
121 | MultiThreaded
122 |
123 |
124 | Console
125 | true
126 |
127 |
128 |
129 |
130 | Level3
131 |
132 |
133 | MaxSpeed
134 | true
135 | true
136 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
137 | true
138 | MultiThreaded
139 |
140 |
141 | Console
142 | true
143 | true
144 | true
145 |
146 |
147 |
148 |
149 | Level3
150 |
151 |
152 | MaxSpeed
153 | true
154 | true
155 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
156 | true
157 | MultiThreaded
158 |
159 |
160 | Console
161 | true
162 | true
163 | true
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/nTimestomp/nTimestomp.c:
--------------------------------------------------------------------------------
1 | // #######################################################################
2 | // ############ HEADER FILES
3 | // #######################################################################
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | typedef LONG NTSTATUS;
10 | char* VERSION_NO = "1.1";
11 | HANDLE file = NULL;
12 |
13 |
14 | typedef struct _IO_STATUS_BLOCK {
15 | union {
16 | NTSTATUS Status;
17 | PVOID Pointer;
18 | };
19 | ULONG_PTR Information;
20 | } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
21 |
22 | typedef enum _FILE_INFORMATION_CLASS {
23 | FileBasicInformation = 4,
24 | FileStandardInformation = 5,
25 | FilePositionInformation = 14,
26 | FileEndOfFileInformation = 20,
27 | } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
28 |
29 | typedef struct _FILE_BASIC_INFORMATION {
30 | LARGE_INTEGER CreationTime; // Created
31 | LARGE_INTEGER LastAccessTime; // Accessed
32 | LARGE_INTEGER LastWriteTime; // Modifed
33 | LARGE_INTEGER ChangeTime; // Entry Modified
34 | ULONG FileAttributes;
35 | } FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
36 |
37 | typedef NTSTATUS(WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
38 | typedef NTSTATUS(WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
39 |
40 | HANDLE LoadFile(char *filename, FILE_BASIC_INFORMATION *fbi);
41 | VOID RetrieveFileBasicInformation(char *filename, FILE_BASIC_INFORMATION *fbi);
42 | DWORD SetFileMACE(HANDLE file, DWORD fileAttributes, char *mtimestamp, char *atimestamp, char *ctimestamp, char *btimestamp);
43 | LARGE_INTEGER ParseDateTimeInput(char *inputstring);
44 | VOID About();
45 | VOID Usage();
46 |
47 | // #######################################################################
48 | // ############ FUNCTIONS
49 | // #######################################################################
50 |
51 | VOID About() {
52 | printf("nTimestomp, Version %s\r\n", VERSION_NO);
53 | printf("Copyright (C) 2019 Benjamin Lim\r\n");
54 | printf("Available for free from https://limbenjamin.com/pages/ntimetools\r\n");
55 | printf("\r\n");
56 | }
57 |
58 | VOID Usage() {
59 | printf("\r\n");
60 | printf("Usage: .\\nTimestomp.exe [Modified Date] [Last Access Date] [Last Write Date] [Creation Date]\r\n");
61 | printf("Date Format: yyyy-mm-dd hh:mm:ss.ddddddd\r\n");
62 | printf("\r\n");
63 | }
64 |
65 | HANDLE LoadFile(char *filename, FILE_BASIC_INFORMATION *fbi) {
66 |
67 | HANDLE file = NULL;
68 | HMODULE ntdll = NULL;
69 |
70 | file = CreateFile(filename, GENERIC_READ | GENERIC_WRITE | FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 0, NULL);
71 | if (file == INVALID_HANDLE_VALUE) {
72 | printf("Cannot open file: %S\r\n", filename);
73 | Usage();
74 | exit(1);
75 | }
76 |
77 | /* load ntdll and retrieve function pointer */
78 | ntdll = GetModuleHandle(TEXT("ntdll.dll"));
79 | if (ntdll == NULL) {
80 | printf("Cannot load ntdll\r\n");
81 | CloseHandle(file);
82 | exit(1);
83 | }
84 | FreeLibrary(ntdll);
85 |
86 | return file;
87 | }
88 |
89 | /* returns the handle on success or NULL on failure. this function opens a file and returns
90 | the FILE_BASIC_INFORMATION on it. */
91 | VOID RetrieveFileBasicInformation(HANDLE file, FILE_BASIC_INFORMATION *fbi) {
92 |
93 | HMODULE ntdll = NULL;
94 | pNtQueryInformationFile NtQueryInformationFile = NULL;
95 | IO_STATUS_BLOCK iostatus;
96 |
97 | /* load ntdll and retrieve function pointer */
98 | ntdll = GetModuleHandle(TEXT("ntdll.dll"));
99 | if (ntdll == NULL) {
100 | printf("Cannot load ntdll\r\n");
101 | CloseHandle(file);
102 | exit(1);
103 | }
104 |
105 | /* retrieve current timestamps including file attributes which we want to preserve */
106 | NtQueryInformationFile = (pNtQueryInformationFile)GetProcAddress(ntdll, "NtQueryInformationFile");
107 | if (NtQueryInformationFile == NULL) {
108 | CloseHandle(file);
109 | exit(1);
110 | }
111 |
112 | /* obtain the current file information including attributes */
113 | if (NtQueryInformationFile(file, &iostatus, fbi, sizeof(FILE_BASIC_INFORMATION), 4) < 0) {
114 | CloseHandle(file);
115 | exit(1);
116 | }
117 |
118 | /* clean up */
119 | FreeLibrary(ntdll);
120 |
121 | }
122 |
123 | DWORD SetFileMACE(HANDLE file, DWORD fileAttributes, char *mtimestamp, char *atimestamp, char *ctimestamp, char *btimestamp) {
124 |
125 | HMODULE ntdll = NULL;
126 | pNtSetInformationFile NtSetInformationFile = NULL;
127 | IO_STATUS_BLOCK iostatus;
128 |
129 | FILE_BASIC_INFORMATION fbi;
130 | fbi.LastWriteTime = ParseDateTimeInput(mtimestamp);
131 | fbi.LastAccessTime = ParseDateTimeInput(atimestamp);
132 | fbi.ChangeTime = ParseDateTimeInput(ctimestamp);
133 | fbi.CreationTime = ParseDateTimeInput(btimestamp);
134 |
135 | fbi.FileAttributes = fileAttributes;
136 |
137 | /* load ntdll and retrieve function pointer */
138 | ntdll = GetModuleHandle(TEXT("ntdll.dll"));
139 | if (ntdll == NULL) {
140 | printf("Cannot load ntdll\r\n");
141 | CloseHandle(file);
142 | exit(1);
143 | }
144 |
145 | NtSetInformationFile = (pNtSetInformationFile)GetProcAddress(ntdll, "NtSetInformationFile");
146 | if (NtSetInformationFile == NULL) {
147 | CloseHandle(file);
148 | exit(1);
149 | }
150 |
151 | if (NtSetInformationFile(file, &iostatus, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation) < 0) {
152 | CloseHandle(file);
153 | exit(1);
154 | }
155 |
156 | /* clean up */
157 | printf("File timestamp successfully set\r\n");
158 | FreeLibrary(ntdll);
159 |
160 | return 0;
161 | }
162 |
163 | LARGE_INTEGER ParseDateTimeInput(char *inputstring) {
164 |
165 | SYSTEMTIME systemtime = { 0 };
166 | LARGE_INTEGER nanoTime = { 0 };
167 | FILETIME filetime;
168 | LARGE_INTEGER dec = { 0 };
169 | LARGE_INTEGER res = { 0 };
170 |
171 | if (sscanf_s(inputstring, "%hu-%hu-%hu %hu:%hu:%hu.%7d", &systemtime.wYear, &systemtime.wMonth, &systemtime.wDay, &systemtime.wHour, &systemtime.wMinute, &systemtime.wSecond, &dec.QuadPart) == 0) {
172 | printf("Wrong Date Format");
173 | CloseHandle(file);
174 | exit(1);
175 | }
176 |
177 | /* sanitize input */
178 |
179 | if (systemtime.wMonth < 1 || systemtime.wMonth > 12) {
180 | printf("Wrong Date Format");
181 | CloseHandle(file);
182 | exit(1);
183 | }
184 | if (systemtime.wDay < 1 || systemtime.wDay > 31) {
185 | printf("Wrong Date Format");
186 | CloseHandle(file);
187 | exit(1);
188 | }
189 | if (systemtime.wYear < 1601 || systemtime.wYear > 30827) {
190 | printf("Wrong Date Format");
191 | CloseHandle(file);
192 | exit(1);
193 | }
194 |
195 | if (systemtime.wMinute < 0 || systemtime.wMinute > 59) {
196 | printf("Wrong Date Format");
197 | CloseHandle(file);
198 | exit(1);
199 | }
200 | if (systemtime.wSecond < 0 || systemtime.wSecond > 59) {
201 | printf("Wrong Date Format");
202 | CloseHandle(file);
203 | exit(1);
204 | }
205 |
206 | systemtime.wMilliseconds = 0;
207 | if (SystemTimeToFileTime(&systemtime, &filetime) == 0) {
208 | printf("Invalid filetime\r\n");
209 | CloseHandle(file);
210 | exit(1);
211 | }
212 |
213 | nanoTime.LowPart = filetime.dwLowDateTime;
214 | nanoTime.HighPart = filetime.dwHighDateTime;
215 |
216 | res.QuadPart = nanoTime.QuadPart + dec.QuadPart;
217 |
218 | return res;
219 | }
220 |
221 | /* returns 0 on error, 1 on success. this function converts a LARGE_INTEGER to a SYSTEMTIME structure */
222 | DWORD ConvertLargeIntegerToLocalTime(SYSTEMTIME *localsystemtime, LARGE_INTEGER largeinteger) {
223 |
224 | FILETIME filetime;
225 | FILETIME localfiletime;
226 | DWORD result = 0;
227 |
228 | filetime.dwLowDateTime = largeinteger.LowPart;
229 | filetime.dwHighDateTime = largeinteger.HighPart;
230 |
231 | if (FileTimeToSystemTime(&filetime, localsystemtime) == 0) {
232 | printf("Invalid filetime\r\n");
233 | exit(1);
234 | }
235 |
236 | return 1;
237 | }
238 |
239 | int main(int argc, char* argv[]) {
240 |
241 | if (argc < 5) {
242 | Usage();
243 | exit(1);
244 | }
245 |
246 | FILE_BASIC_INFORMATION fbi;
247 | struct _SYSTEMTIME time = { 0 };
248 | wchar_t filename[4096] = { 0 };
249 | char str[256];
250 | CHAR lpVolumeNameBuffer[MAX_PATH + 1] = { 0 };
251 | CHAR lpFileSystemNameBuffer[MAX_PATH + 1] = { 0 };
252 | LARGE_INTEGER lpFileSizeHigh = { 0 };
253 |
254 | About();
255 | MultiByteToWideChar(CP_ACP, 0, argv[1], -1, filename, 4096);
256 | file = LoadFile(filename, &fbi);
257 | GetVolumeInformationByHandleW(file, &lpVolumeNameBuffer, ARRAYSIZE(lpVolumeNameBuffer), 0, 0, 0, &lpFileSystemNameBuffer, ARRAYSIZE(lpVolumeNameBuffer));
258 | GetFileSizeEx(file, &lpFileSizeHigh);
259 |
260 | printf("Filesystem type: %S\r\n", lpFileSystemNameBuffer);
261 | printf("Filename: %S\r\n", filename);
262 | printf("File size: %d\r\n", lpFileSizeHigh.QuadPart);
263 | printf("\r\n");
264 |
265 | SetFileMACE(file, fbi.FileAttributes, argv[2], argv[3], argv[4], argv[5]);
266 | RetrieveFileBasicInformation(file, &fbi);
267 |
268 | printf("\r\n");
269 | ConvertLargeIntegerToLocalTime(&time, fbi.LastWriteTime);
270 | if (fbi.LastWriteTime.QuadPart != 0) {
271 | sprintf_s(str, 256, "%lld", fbi.LastWriteTime.QuadPart);
272 | printf("[M] Last Write Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
273 | }
274 | else {
275 | printf("[M] Last Write Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
276 | }
277 | memset(&time, 0, sizeof(time));
278 |
279 | ConvertLargeIntegerToLocalTime(&time, fbi.LastAccessTime);
280 | if (fbi.LastAccessTime.QuadPart != 0) {
281 | sprintf_s(str, 256, "%lld", fbi.LastAccessTime.QuadPart);
282 | printf("[A] Last Access Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
283 | }
284 | else {
285 | printf("[A] Last Access Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
286 | }
287 | memset(&time, 0, sizeof(time));
288 |
289 | ConvertLargeIntegerToLocalTime(&time, fbi.ChangeTime);
290 | if (fbi.ChangeTime.QuadPart != 0) {
291 | sprintf_s(str, 256, "%lld", fbi.ChangeTime.QuadPart);
292 | printf("[C] Metadata Change Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
293 | }
294 | else {
295 | printf("[C] Metadata Change Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\r\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
296 | }
297 | memset(&time, 0, sizeof(time));
298 |
299 | ConvertLargeIntegerToLocalTime(&time, fbi.CreationTime);
300 | if (fbi.CreationTime.QuadPart != 0) {
301 | sprintf_s(str, 256, "%lld", fbi.CreationTime.QuadPart);
302 | printf("[B] Creation Time: %04d-%02d-%02d %02d:%02d:%02d.%7s UTC\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, &str[11]);
303 | }
304 | else {
305 | printf("[B] Creation Time: %04d-%02d-%02d %02d:%02d:%02d.0000000 UTC\n", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
306 | }
307 | printf("\r\n");
308 | CloseHandle(file);
309 | }
--------------------------------------------------------------------------------