Uninformed: Informative Information for the Uninformed

Vol 8» 2007.Sep

Timer List Obfuscation

PatchGuard 2 and PatchGuard 3 employ an obfuscation scheme that is used to obfuscate timer and DPC object pointers in the timer list. This obfuscation scheme hinges around two special kernel variables, KiWaitAlways and KiWaitNever that represent two random obfuscation keys that are calculated at boot time. These obfuscation keys are used to encode various pointers (such as links to DPC objects in a KTIMER object residing in the kernel timer list) that are intended to be protected from outside interference. For example, the following algorithm is used to decode the KDPC link in a KTIMER object when a timer DPC is going to be executed at expiration:

ULONGLONG Deobfuscated;
PKDPC     RealDpc;

Deobfuscated = Timer->Dpc ^ KiWaitNever;
Deobfuscated = _rotl64(Deobfuscated, (UCHAR)KiWaitNever);
Deobfuscated = Deobfuscated ^ Timer;
Deobfuscated = _byteswap_uint64(Deobfuscated);
Deobfuscated = Deobfuscated ^ KiWaitAlways;

RealDpc      = (PKDPC)Deobfuscated;

By virtue of being non-exported kernel variables, the original intention of such a scheme was to make it difficult for third party drivers to easily interfere with the timer list or certain other protected pointers. However, the algorithm itself is fairly easy to understand once one locates code that references it (such as most any timer-related code in the kernel), which simply leaves detecting the values of KiWaitAlways and KiWaitNever at runtime as the only remaining protection for the timer list to DPC object obfuscation.

Ironically, the kernel debugger extension !kdexts.timer implements the decoding algorithm (in kdexts!KiDecodePointer) so that a valid timer list can be presented to the user if the timer display command is invoked. Because the kernel debugger has access to PDB symbols for the kernel, it can trivially locate KiWaitAlways and KiWaitNever.