Search code examples
windowspermissionsadministratordll-injection

Prevent administrator from taking ownership of an object


As a premise I want you to know that this has nothing to do with game cheating, as I am only interested in knowing the way that Windows works. I don't even personally play video-games.

EasyAntiCheat, that comes with Fortnite, prevents the game process to be modified and his parameters to be changed.

For example, trying to change the priority (I am not looking for a way to change priority, as a solution has already been posted here, and here in a Wayback Machine capture) results in an access denied error.

Modifying the process' ACL using Process Hacker or Process Explorer also produces the same error, even if the user is an administrator and holds the SeTakeOwnershipPrivilege right.


Since:

  • PatchGuard is enabled, so old-style kernel hooking is not possible even for the EAC driver
  • Kernel exposes APIs that only allow drivers to be notified of system calls happening and not to change the the stock kernel behavior
  • EasyAntiCheat driver file-system mini-filter should not affect processes ACL. In fact, the result is the same even when the filter is unloaded using FLTMC.exe
  • A code injection within the process does not seem to be happening, at least when listing the Load Image events with Process Monitor, even though injection could be achieved by other means (I don't have enough knowledge about this)
  • The process is not Protected or Light Protected

What is the mechanism through which Windows 10 x64 (1803) allows EAC to do what described above? Maybe to find an answer it would be enought to put more attention to the 4th method.

Here you can find a link to a list of the Load Image events that show up from the startup of ProcessHacker.exe to its end in Sysinternals Process Monitor.

P.S.: Excuse me for any grammar error, English is not my main language.


Solution

  • So I almost randomly came around this post on Reddit that I think explains it.

    The key is the ObRegisterCallbacks kernel-mode function that I didn't know about.

    It allows a driver to register for events about processes, threads and (starting with Windows 10) desktop objects.

    I was initally aware of PsSetCreateProcessNotifyRoutine, which not only allows to "passively" monitor processes creation/termination, but provides a driver a way to "actively" cancelling the creation by returning an error on the callback.

    That wasn't however what I was dealing with in my case: there was no process creation going on, just me trying to rise the priority of a process that was not Protected or Light Protected.

    The use of ObRegisterCallbacks goes like this: the protecting driver, from the registered callback, would strip the DesiredAccess of the handle request to what it wants, making the handle creation operation proceed as the process never actually asked to be able to terminate/set process priority, and thus effectively blocking it.

    A good example is provided in this GitHub repo. This link is a permalink to the point in code that accesses the DesiredAccess member of CreateHandleInformation (or DuplicateHandleInformation).