11#include "TimeDefuser.h"
22
3- #ifndef TD_LEGACY
43BOOLEAN PatchExGetExpirationDate (void * pExGetExpirationDate ) {
54 PMDL mdl = NULL ;
65 unsigned char * map = NULL ;
@@ -35,28 +34,25 @@ BOOLEAN PatchExGetExpirationDate(void* pExGetExpirationDate) {
3534 IoFreeMdl (mdl );
3635 return TRUE;
3736}
38- #endif
39- #define PDRIVER_OBEJCT void* // Unused by TimeDefuser
4037
41- NTSTATUS DriverEntry (void * DriverObject , PUNICODE_STRING RegistryPath ) {
38+ NTSTATUS DriverEntry (PDRIVER_OBEJCT DriverObject , PUNICODE_STRING RegistryPath ) {
4239 LARGE_INTEGER * li = KUSERSystemExpirationDate ; // Address of SystemExpirationDate field at KUSER_SHARED_DATA
4340 unsigned long long TimebombStamp = 0 ; // Expiration date stamp
4441 RTL_PROCESS_MODULES ModuleInfo = { 0 }; // Structure used for getting kernel base address
4542 unsigned long long * KernelBase = NULL ; // Kernel Base address
4643 ULONG KernelSize = 0 ; // Kernel image size
4744 //HANDLE hKey = OpenRegistryKey(RegistryPath);
4845 HANDLE hKey = 0 ;
49- #ifndef TD_LEGACY
5046 unsigned int KernelSize2 = 0 ; // Var used in loops as a max value
5147 PAGESections ps [5 ] = { 0 }; // PE sections that name starts with "PAGE"
5248 unsigned char * PotentialTimestamp = NULL ;// Potential address of ExNtExpirationDate/a
53- #endif
49+ BOOLEAN Legacy = FALSE;
5450
5551 // Unrefence unused variables.
5652 UNREFERENCED_PARAMETER (DriverObject );
5753
5854 // Print version info.
59- TDPrint ("[*] TimeDefuser: version " td_version td_variant " loaded "
55+ TDPrint ("[*] TimeDefuser: version " td_version " loaded "
6056 "| Compiled on " __DATE__ " " __TIME__ " "
6157 "| https://github.com/NevermindExpress/TimeDefuser\n" );
6258
@@ -68,6 +64,16 @@ NTSTATUS DriverEntry(void* DriverObject, PUNICODE_STRING RegistryPath) {
6864 }
6965 TDPrint ("[+] TimeDefuser: SystemExpirationDate is 0x%llx\n" , TimebombStamp );
7066
67+ // Determine if we are running in a legacy system
68+ {
69+ int verMajor = 0 ;
70+ PsGetVersion (& verMajor , 0 , 0 , 0 );
71+ if (verMajor == 5 ) {
72+ TDPrint ("[*] TimeDefuser: Legacy system detected.\n" );
73+ Legacy = TRUE;
74+ }
75+ }
76+
7177 // Get kernel base
7278 ZwQuerySystemInformation (SystemModuleInformation , & ModuleInfo , sizeof (ModuleInfo ), 0 );
7379 if (ModuleInfo .NumberOfModules == 0 ) {
@@ -80,77 +86,75 @@ NTSTATUS DriverEntry(void* DriverObject, PUNICODE_STRING RegistryPath) {
8086
8187 // Check whether addresses are cached
8288 if (hKey ) {
83- //if (CompareKernelVersion(hKey)) {
84- if (0 ) {
85- //// Get cached address offsets for timestamps.
86- ////int Stamp1 = RegReadValue(hKey, L"Stamp1", NULL, 0),
87- //// Stamp2 = RegReadValue(hKey, L"Stamp2", NULL, 0);
88-
89- //// Zero first timestamp
90- ////if (!Stamp1) {
91- //if(1) {
92- // // No cached address, assume nothing is cached.
93- // goto patchBeginning;
94- //}
95- //TDPrint("[*] TimeDefuser: Cached addresses are found on registry.\n");
96- //TDPrint("[+] TimeDefuser: Cached ExpNtExpirationDate address 0x%p is used.\n", (unsigned long long*)((char*)KernelBase + Stamp1));
97- //*(unsigned long long*)((char*)KernelBase+Stamp1) = 0;
98- //#ifdef TD_LEGACY
99- // // On legacy, for some reason, actual timebomb stamp
100- // // is the next qword (on XP 2526). We will zero that too.
101- // *(unsigned long long*)((char*)KernelBase+Stamp1+8) = 0;
102- //#endif
103- //
104- //// Zero second timestamp if available.
105- //if (Stamp2) {
106- // TDPrint("[+] TimeDefuser: Cached ExpNtExpirationData address 0x%p is used.\n", (char*)KernelBase + Stamp2);
107- // #ifdef TD_LEGACY
108- // RtlZeroMemory((char*)KernelBase + Stamp2, 16);
109- // #else
110- // *(unsigned long long*)((char*)KernelBase + Stamp2) = 0;
111- // #endif
112- //}
113-
114- //#ifndef TD_LEGACY
115- //int Function = RegReadValue(hKey, L"Function", NULL, 0);
116- // TDPrint("[+] TimeDefuser: Cached ExGetExpirationDate function address 0x%p is used.\n", (char*)KernelBase + Function);
117- // if (!PatchExGetExpirationDate((char*)KernelBase + Function))
118- // goto patchFail;
119- //#endif
120- // goto patchOK;
89+ if (CompareKernelVersion (hKey )) {
90+ // Get cached address offsets for timestamps.
91+ int Stamp1 = RegReadValue (hKey , L"Stamp1" , NULL , 0 ),
92+ Stamp2 = RegReadValue (hKey , L"Stamp2" , NULL , 0 );
93+
94+ // Zero first timestamp
95+ if (!Stamp1 ) {
96+ // No cached address, assume nothing is cached.
97+ goto patchBeginning ;
98+ }
99+ TDPrint ("[*] TimeDefuser: Cached addresses are found on registry.\n" );
100+ TDPrint ("[+] TimeDefuser: Cached ExpNtExpirationDate address 0x%p is used.\n" , (unsigned long long * )((char * )KernelBase + Stamp1 ));
101+ * (unsigned long long * )((char * )KernelBase + Stamp1 ) = 0 ;
102+ if (Legacy ) {
103+ // On legacy, for some reason, actual timebomb stamp
104+ // is the next qword (on XP 2526). We will zero that too.
105+ * (unsigned long long * )((char * )KernelBase + Stamp1 + 8 ) = 0 ;
106+ }
107+
108+ // Zero second timestamp if available.
109+ if (Stamp2 ) {
110+ TDPrint ("[+] TimeDefuser: Cached ExpNtExpirationData address 0x%p is used.\n" , (char * )KernelBase + Stamp2 );
111+ * (unsigned long long * )((char * )KernelBase + Stamp2 ) = 0 ;
112+ if (Legacy )
113+ * (unsigned long long * )((char * )KernelBase + Stamp2 + 8 ) = 0 ;
114+ }
115+
116+ if (!Legacy ) {
117+ int Function = RegReadValue (hKey , L"Function" , NULL , 0 );
118+ TDPrint ("[+] TimeDefuser: Cached ExGetExpirationDate function address 0x%p is used.\n" , (char * )KernelBase + Function );
119+ if (!PatchExGetExpirationDate ((char * )KernelBase + Function ))
120+ goto patchFail ;
121+ }
122+ goto patchOK ;
121123 }
122124 // Kernel version mismatch.
123125 }
124- // patchBeginning:
126+ patchBeginning :
125127 TDPrint ("[*] TimeDefuser: No or mismatching cached addresses are found on registry.\n" );
126- //SaveKernelVersion(hKey);
127- #ifdef TD_LEGACY
128- // Search for timebomb stamp in memory
129- KernelSize /= sizeof (unsigned __int64 );
130- for (unsigned int i = 0 ; i < KernelSize ; i ++ ) {
131- if (KernelBase [i ] == TimebombStamp ) {
132- TDPrint ("[+] TimeDefuser: ExpNtExpirationDate found at 0x%p\n" , & KernelBase [i ]);
133- KernelBase [i ] = 0 ;
134- // For some reason actual timebomb was the next qword on XP 2526, I'll save this and search for it again.
135- TimebombStamp = KernelBase [i + 1 ]; // Save the lower part of stamp.
136- KernelBase [i + 1 ] = 0 ; // And null where I found it too.
137- RegWriteDword (hKey , L"Stamp1" , (ULONG )((unsigned char * )& KernelBase [i ] - (unsigned char * )KernelBase ));
138- break ;
128+ SaveKernelVersion (hKey );
129+
130+ if (Legacy ) {
131+ // Search for timebomb stamp in memory
132+ KernelSize /= sizeof (unsigned __int64 );
133+ for (unsigned int i = 0 ; i < KernelSize ; i ++ ) {
134+ if (KernelBase [i ] == TimebombStamp ) {
135+ TDPrint ("[+] TimeDefuser: ExpNtExpirationDate found at 0x%p\n" , & KernelBase [i ]);
136+ KernelBase [i ] = 0 ;
137+ // For some reason actual timebomb was the next qword on XP 2526, I'll save this and search for it again.
138+ TimebombStamp = KernelBase [i + 1 ]; // Save the lower part of stamp.
139+ KernelBase [i + 1 ] = 0 ; // And null where I found it too.
140+ RegWriteDword (hKey , L"Stamp1" , (ULONG )((unsigned char * )& KernelBase [i ] - (unsigned char * )KernelBase ));
141+ break ;
142+ }
139143 }
140- }
141144
142- // Search for the second stamp, ExpNtExpirationData (and not Date)
143- for (unsigned int i = 0 ; i < KernelSize ; i ++ ) {
144- if ((int )KernelBase [i ] == (int )TimebombStamp ) {
145- TDPrint ("[+] TimeDefuser: ExpNtExpirationData found at 0x%p\n" , & KernelBase [i ]);
146- RtlZeroMemory (& KernelBase [i ], 16 );
147- RegWriteDword (hKey , L"Stamp2" , (ULONG )((unsigned char * )& KernelBase [i ] - (unsigned char * )KernelBase ));
148- goto patchOK ;
145+ // Search for the second stamp, ExpNtExpirationData (and not Date)
146+ for (unsigned int i = 0 ; i < KernelSize ; i ++ ) {
147+ if ((int )KernelBase [i ] == (int )TimebombStamp ) {
148+ TDPrint ("[+] TimeDefuser: ExpNtExpirationData found at 0x%p\n" , & KernelBase [i ]);
149+ KernelBase [i ] = KernelBase [i + 1 ] = 0 ;
150+ RegWriteDword (hKey , L"Stamp2" , (ULONG )((unsigned char * )& KernelBase [i ] - (unsigned char * )KernelBase ));
151+ goto patchOK ;
152+ }
149153 }
154+ // That's all for legacy implementation, get out.
155+ goto patchOK ;
150156 }
151- // That's all for legacy implementation, get out.
152157
153- #else
154158 // Check for PE Header existance.
155159 if (* (short * )KernelBase != PEheader ) {
156160 TDPrint ("[X] TimeDefuser: PE Header not found!\n" );
@@ -291,8 +295,6 @@ NTSTATUS DriverEntry(void* DriverObject, PUNICODE_STRING RegistryPath) {
291295 // No references found so far so we fail.
292296 TDPrint ("[X] TimeDefuser: could not find ExpTimeRefreshWork!\n" );
293297
294- #endif
295-
296298patchFail :
297299 TDPrint ("[X] TimeDefuser: Patch failed.\n" );
298300 return STATUS_FAILED_DRIVER_ENTRY ;
0 commit comments