Skip to content

Commit 221fbe2

Browse files
Restore mysteriously disappeared research whitepaper
Then they ask me why I curse at t*rvalds every day for creating this garbage named 'git'...
1 parent bcbb0af commit 221fbe2

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

TimeDefuser-Research.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# TimeDefuser: Security Research into Windows Timebombs for Expiration Date Enforcement
2+
3+
**Author:** Oğuzhan Karacan (@NevermindExpress)
4+
**Type:** Independent Security Research
5+
**Date:** May 4, 2025 (Initial release), January 20, 2026 (Whitepaper)
6+
**Repository:** https://github.com/NevermindExpress/TimeDefuser
7+
**Revision:** 1
8+
9+
*This document analyzes Windows kernel expiration enforcement mechanisms and presents a proof-of-concept implementation for educational and research purposes only.*
10+
11+
## 1. Prologue
12+
Every prerelease and evaluation build of Microsoft Windows since Windows 2000 included a *timebomb* mechanism designed
13+
to prevent users from being able to keep using the prerelease builds after expiration date. This mechanism is often tightly integrated
14+
with Windows Product Activation (WPA) which will cause system to become *deactivated*, leading to effects such as blocking user logon or
15+
restricting system features (e.g., personalization); but it standalone bringins the system down with a `0x98 END_OF_NT_EVALUATION_PERIOD`
16+
bugcheck (a.k.a. a *blue screen*) approximately two hours after system boot.
17+
18+
This research examines how this mechanism operates internally and demonstrates how it can be exploited for arbitrary kernel-level behavior.
19+
A proof-of-concept (PoC) implementation is provided that disables expiration enforcement entirely.
20+
21+
For legal reasons, this document avoids vague descriptions and direct references to leaked Windows NT source codes.
22+
23+
## 2. Expiration Date Storage and Enforcement
24+
The location of the expiration date has evolved over time: initially residing in the registry, then getting moved into WPA licensing data and product policies.
25+
In all cases, it is ultimately loaded into specific locations in kernel memory which are used by the timebomb enforcement logic and therefore constitute the primary
26+
targets of this research.
27+
28+
The expiration date is located inside three fields in kernel memory, first two are undocumented kernel globals named `ExpNtExpirationDate` and
29+
`ExpNtExpiratonData`, and third field is the `SystemExpiratonDate` field of `KUSER_SHARED_DATA` structure, which is used by user mode
30+
applications (including `winver.exe` itself). Additionally, a boolean flag named `ExpNextExpirationIsFatal` is set during the first enforcement cycle.
31+
32+
These fields are initialized during system boot by the `ExInitializeTimeRefresh` routine, which retrieves expiration date using version-specific mechanisms.
33+
On Windows XP and earlier, this function also spawns a background task called `ExpWatchExpirationDataWork` that prevents modification of the registry values of
34+
expiration date. Beginning with Windows Vista, this protection is implemented through different mechanisms, discussed later in this document.
35+
36+
The core timebomb enforcement code resides inside the internal kernel routine `ExpTimeRefreshWork` that runs each hour. In addition to synchronizing system
37+
and hardware clocks, this function checks if expiration date has passed, and initiates enforcement actions with specific behavior varying by Windows version.
38+
39+
On Windows XP and earlier, it simply compares current system time against the expiration date stored in kernel memory. If `ExpNextExpirationIsFatal` is false,
40+
it displays an error message to user by `NtRaiseHardError` indicating that the build has expired and sets `ExpNextExpirationIsFatal`. On subsequent execution, it
41+
halts the system with aforementioned bugcheck.
42+
43+
Beginning with Windows Vista, the mechanism becomes more sophisticated. Instead of relying solely on data stored in kernel memory, it introduces the `ExGetExpirationDate`
44+
function to retrieve the expiration date dynamically. This function is invoked both during boot by `ExInitializeTimeRefresh` and periodically by `ExpTimeRefreshWork` during each
45+
enforcement cycle. Its return value is then used to repopulate the expiration date fields in kernel memory, effectively reasserting expiration state on every execution of the
46+
timebomb logic and invalidating the method of zero-ing those fields for bypassing timebomb logic on Windows XP and before.
47+
48+
## 3. Finding and Patching The Timebomb Logic in Kernel Memory.
49+
In the previous section, we established that on Windows Vista and later, expiration date fields in kernel memory are repopulated during each enforcement cycle. The first two fields
50+
(`ExpNtExpirationDate` and `ExpNtExpirationData`) are internal kernel global variables whose addresses vary between kernel builds. This does not apply to the third field,
51+
`SystemExpirationDate`, which corresponds to offset `0x2C8` within the `KUSER_SHARED_DATA` structure.
52+
53+
`KUSER_SHARED_DATA` is a well defined but undocumented structure in Windows NT which is used for fast access to various system-wide values from user mode with an
54+
increasing size and contents with each Windows NT version. Due to its purpose, this structure is always mapped at a fixed virtual address depending on architecture
55+
(i.e., `0xffdf0000` on x86) regardless of the Windows NT build.
56+
57+
Because timebomb enforcement is implemented in two routines (`ExInitializeTimeRefresh` and `ExpTimeRefreshWork`), there are as much amount of immediate absolute address references
58+
to `+0x2c8` offset of `KUSER_SHARED_DATA` that does not exist in anywhere else in kernel memory. By searching for this absolute address reference within kernel memory, the locations
59+
where `SystemExpirationDate` is repopulated can be identified (with the first occurrence typically belonging to `ExpTimeRefreshWork`). By iterating backward from this reference,
60+
the relative call target of `ExGetExpirationDate` can be resolved.
61+
62+
At this point, several patching strategies are possible
63+
1. Resolving the relative address and patching `ExGetExpirationDate` function
64+
2. Patching the caller instruction to call an arbitrary function
65+
3. Modifying other portions of the timebomb enforcement routines themselves.
66+
67+
On Windows XP and earlier, the approach slightly changes due to lack of an `ExGetExpirationDate` function and repopulation of fields including the `SystemExpirationDate` in each cycle.
68+
For those systems, retrieving `SystemExpirationDate` and searching for that same value within kernel memory will yield other two fields of expiration date. By then searching for references
69+
to their addresses, `ExpTimeRefreshWork` can be found.
70+
71+
## 4. Limitations
72+
73+
### PatchGuard (Kernel Patch Protection)
74+
64-bit versions of Windows kernel includes a Kernel Patch Protection mechanism called "PatchGuard" which may detect modifications to timebomb enforcement routines depending on the version, limiting
75+
the applicability of this technique. 32-bit versions does not include this mechanism.
76+
77+
### Stack Safety Checks
78+
Windows NT kernel checks for any improperities happening in stack. This includes stack corruptions, shifts caused by imbalances, and direct attacks performed against stack. If the kernel detects any
79+
such improperities, it will bring the system down. Calling convention semantics and stack discipline must be retained to not trigger these protections.
80+
81+
### Security Cookies and Control Flow Guard
82+
Modern Windows kernels employ stack cookies, Control Flow Guard (CFG), and related mitigations to detect stack smashing and invalid control transfers. This especially causes extra difficulty when patching
83+
`ExGetExpirationDate` as modification of function prologues will trigger those protections and cause system to halt. This is more prevalent in 32-bit x86 systems.
84+
85+
## 5. Advantages Over Simply Having A Kernel Driver
86+
While any desired operation could also be performed using a kernel driver, this approach offers several advantages:
87+
88+
1. **Non-persistence:** Instead of keeping a continuously running kernel driver, the kernel can be patched and execution can terminate immediately, leaving no persistent artifacts behind.
89+
2. **Consistency and Versatility:** Time synchronization and expiration enforcement routines are relatively stable and easier to target compared to many other kernel subsystems.
90+
3. **Independence from Driver Loading Mechanisms:** This approach can be applied using a future arbitrary kernel memory read/write vulnerability, without requiring driver loading, signature bypasses, or test-signing configurations.
91+
92+
## 6. Proof-of-Concept Implementation
93+
This research is also bundled with a practical Proof-of-Concept (PoC) implementation of the techniques described. It can be retrieved from the same repository this paper published at
94+
(https://github.com/NevermindExpress/TimeDefuser). The PoC serves as a practical demonstration that simply removes expiration date enforcement entirely.
95+
96+
## 7. Threat Model and Abuse Potential
97+
While this research focuses on expiration enforcement mechanisms, the techniques described are broadly applicable to kernel patching and runtime modification of enforcement logic.
98+
In a threat context, these routines can be modified to do any arbitrary and potentially malicious activities with a frequency of once per hour.
99+
## 8. Responsible Use and Ethical Considerations
100+
This research is conducted and presented for educational, defensive, and academic purposes. The techniques described are intended to improve understanding of kernel enforcement mechanisms,
101+
tamper resistance, and system integrity, and to contribute to the broader field of operating system security research.
102+
103+
The proof-of-concept implementation is provided solely as a demonstration of feasibility and is not intended for unauthorized use, circumvention of licensing agreements, violation of
104+
software terms of service, or as a weapon for system compromising. Users of this research are responsible for ensuring compliance with all applicable laws, licensing agreements, and ethical standards.
105+
106+
The author does not condone or support the misuse of these techniques for piracy, evasion of security controls, or unauthorized system modification. Any experimentation should be conducted
107+
in controlled environments, such as virtual machines or test systems, and with appropriate authorization.
108+
109+
## 9. Conclusion
110+
This research examined the internal mechanisms used by Windows to enforce expiration dates on prerelease and evaluation builds, focusing on their evolution, implementation, and enforcement at the kernel level.
111+
By analyzing the storage, propagation, and periodic refresh of expiration state, this work demonstrated how these mechanisms can be reliably located and modified in memory.
112+
113+
The accompanying proof-of-concept implementation illustrates the feasibility of these techniques across multiple Windows versions and architectures, while also highlighting real-world constraints
114+
imposed by modern kernel mitigations such as PatchGuard, control flow integrity, and stack protection mechanisms.
115+
116+
Beyond expiration enforcement, the techniques described in this paper underscore broader implications for kernel security, particularly in the context of integrity enforcement, runtime patching,
117+
and tamper resistance. This work contributes to a deeper understanding of how kernel-level enforcement mechanisms operate and how they may be strengthened against unauthorized modification.

0 commit comments

Comments
 (0)