├── NTimetools.sln ├── README.md ├── nTimestomp ├── icon1.ico ├── nTimestomp.aps ├── nTimestomp.c ├── nTimestomp.rc ├── nTimestomp.vcxproj ├── nTimestomp.vcxproj.filters ├── nTimestomp.vcxproj.user ├── resource.h └── resource1.h ├── nTimestomp_v1.2_x64.exe ├── nTimeview ├── RCa14184 ├── icon1.ico ├── nTimeview.aps ├── nTimeview.c ├── nTimeview.rc ├── nTimeview.vcxproj ├── nTimeview.vcxproj.filters ├── nTimeview.vcxproj.user ├── nTimeview1.aps ├── nTimeview1.rc ├── resource.h └── resource1.h └── nTimeview_v1.0_x64.exe /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 | -------------------------------------------------------------------------------- /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 | ![image](https://limbenjamin.com/media/ntimetools.png) 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 | ![image](https://limbenjamin.com/media/ntimetools2.png) 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 | -------------------------------------------------------------------------------- /nTimestomp/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp/icon1.ico -------------------------------------------------------------------------------- /nTimestomp/nTimestomp.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp/nTimestomp.aps -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /nTimestomp/nTimestomp.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp/nTimestomp.rc -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /nTimestomp/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp/resource.h -------------------------------------------------------------------------------- /nTimestomp/resource1.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp/resource1.h -------------------------------------------------------------------------------- /nTimestomp_v1.2_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimestomp_v1.2_x64.exe -------------------------------------------------------------------------------- /nTimeview/RCa14184: -------------------------------------------------------------------------------- 1 | #line 1"C:\\workspace\\NTimeview\\NTimeview\\nTimeview1.rc" 2 | #line 1 3 | // Microsoft Visual C++ generated resource script. 4 | // 5 | #include "resource.h" 6 | #line 5 7 | #define APSTUDIO_READONLY_SYMBOLS 8 | ///////////////////////////////////////////////////////////////////////////// 9 | // 10 | // Generated from the TEXTINCLUDE 2 resource. 11 | // 12 | #include "winres.h" 13 | #line 12 14 | ///////////////////////////////////////////////////////////////////////////// 15 | #undef APSTUDIO_READONLY_SYMBOLS 16 | #line 15 17 | ///////////////////////////////////////////////////////////////////////////// 18 | // English (United States) resources 19 | #line 18 20 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 21 | LANGUAGE 9, 1 22 | #line 21 23 | #ifdef APSTUDIO_INVOKED 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // TEXTINCLUDE 27 | // 28 | #line 27 29 | 1 TEXTINCLUDE 30 | BEGIN 31 | "resource.h\0" 32 | END 33 | #line 32 34 | 2 TEXTINCLUDE 35 | BEGIN 36 | "#include ""winres.h""\r\n" 37 | "\0" 38 | END 39 | #line 38 40 | 3 TEXTINCLUDE 41 | BEGIN 42 | "\r\n" 43 | "\0" 44 | END 45 | #line 44 46 | #endif // APSTUDIO_INVOKED 47 | #line 46 48 | #endif // English (United States) resources 49 | ///////////////////////////////////////////////////////////////////////////// 50 | #line 51 51 | #ifndef APSTUDIO_INVOKED 52 | ///////////////////////////////////////////////////////////////////////////// 53 | // 54 | // Generated from the TEXTINCLUDE 3 resource. 55 | // 56 | #line 58 57 | ///////////////////////////////////////////////////////////////////////////// 58 | #endif // not APSTUDIO_INVOKED 59 | -------------------------------------------------------------------------------- /nTimeview/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview/icon1.ico -------------------------------------------------------------------------------- /nTimeview/nTimeview.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview/nTimeview.aps -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /nTimeview/nTimeview.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview/nTimeview.rc -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/nTimeview1.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview/nTimeview1.aps -------------------------------------------------------------------------------- /nTimeview/nTimeview1.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/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/resource1.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview/resource1.h -------------------------------------------------------------------------------- /nTimeview_v1.0_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/limbenjamin/nTimetools/cce1415e208f171591c44b3fe869c42e7cc6f9df/nTimeview_v1.0_x64.exe --------------------------------------------------------------------------------