|
| 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