Uninformed: Informative Information for the Uninformed

Vol 8» 2007.Sep


Multiple Concurrent PatchGuard Check Contexts

In previous PatchGuard releases, there existed a single PatchGuard check context that would periodically be used to verify the integrity of protected regions. Some bypass techniques relied on the fact that there existed only one PatchGuard context by virtue of disabling any invasive kernel patching that would be required to ``catch PatchGuard in the act'' after locating PatchGuard. PatchGuard 3 improves upon this by creating at least one PatchGuard context if PatchGuard is enabled, with a probability of a second context being initialized at system boot time2.1. Both PatchGuard check contexts, which include all of the data used by PatchGuard to check system integrity (including the self-decrypting check routine in non-paged pool memory), operate completely independently if two contexts happen to be used for a particular system boot.

There are several advantages to randomly creating more than one check context. First of all, because the second context is not always created, an element of uncertainty is (theoretically) introduced into the testing and development process for PatchGuard bypass techniques, as it is possible that at first glance, an individual that is researching PatchGuard 3 might not notice that there is a chance to create more than one context. This may result in lost time during the debugging process, as some bypass techniques are affected by the number of active contexts. For example, the original bypass technique described by the author for PatchGuard 2 [1] effectively turned itself off after the first positive indication that PatchGuard was caught (although in this particular instance, the PatchGuard-catching hooks could have allowed to remain in place afterwards).

A better example of bypass techniques that might be affected by this sort of scheme are those that rely on searching system pool memory for a sign of PatchGuard. For example, a theoretical bypass scheme that operates by pro-actively locating the PatchGuard context in non-paged pool and disabling it somehow (perhaps by rewriting the self-decrypting code stub to expand into a no-operation function) might run afoul of this approach randomly during testing if it were not designed to re-try a pool memory scan after a positive hit on PatchGuard. It also eliminates the degree of confidence that such memory scan approaches provide, as previously, if one had a way to locate the PatchGuard context in non-paged pool memory, one would either know for certain that PatchGuard had in fact been disabled by getting a single hit (which could be taken as an indication that it would now be safe to perform actions blockedg by PatchGuard). With multiple check contexts having a probability to run, it is no longer possible for a bypass technique to have logic along the lines of ``if a PatchGuard context has been located and disabled, then it is safe to continue'', because there may exist a non-constant number of contexts in the wild.