The Windows kernel is a rich environment where countless drivers implement on a normal system, and where tens of thousands of factors containing global state are present. For advanced troubleshooting, IT specialists will typically use tools such as the Windows Debugger (WinDbg), SysInternals Tools, or compose their own. Unfortunately, usage of those tools is getting increasingly hard, and they are themselves limited by their particular access to Windows APIs and exposed features.
A number of today’s challenges include:
- Windows 8 and after service Secure Boot, which averts kernel debugging (including local debugging) and loading of test-signed driver code. This limits troubleshooting tools to those that have a signed kernel-mode driver.
- Even on systems without Secure Boot empowered, allowing local debugging or altering boot choices which facilitate debugging capabilities will often activate BitLocker’s recovery manner.
- Windows 10 Anniversary Update and after consist of considerably stricter driver signature demands, which now apply Microsoft EV Attestation Signing. This restricts the freedom of software programmers as generic”read-write-everything” drivers are frowned upon.
- Windows 10 Spring Update now contains customer-facing options for enabling HyperVisor Code Integrity (HVCI) which further restricts allowable drivers and blacklists multiple 3rd party drivers that had”read-write-everything” capacities because of badly written interfaces and security risks.
- Technologies such as Supervisor Mode Execution Prevention (SMEP), Kernel Control Flow Guard (KCFG) along with HVCI with Second Level Address Translation (SLAT) are making conventional Ring 0 implementation tricks’ obsoleted, therefore a new approach is necessary.
In such an environment, it was obvious that a very simple tool which may be utilized as a crisis band-aid/hotfix and also to quickly troubleshoot kernel/system-level issues which may be apparent by analyzing kernel state may be valuable for your community.
How it Works
R0ak works by redirecting the execution flow of the window manager’s trusted font validation checks when trying to load a new font, by substituting the font table comparator routine with another function which schedules an executive function thing (
WORK_QUEUE_ITEM) saved from the input node. Then, the trusted font table right child (which functions as the origin node) is overwritten using a named pipe’s draft buffer (
NP_DATA_ENTRY) where a custom work item is saved. This item’s underlying worker function and its parameter are exactly what will be implemented by a dedicated at
PASSIVE_LEVELafter a ribbon load is tried along with the comparator routine executes, receiving the name pipe-backed parent node as its input. A real-time Event Tracing for Windows (ETW) follow up occasion is used to obtain an asynchronous notification which the work item has finished executing, which makes it safe to tear down the arrangements, free the kernel-mode buffers, and restore normal operation.
While using the choice
--execute, this purpose and parameter are provided by the user.
--compose a custom-made gadget is used to alter arbitrary 32-bit values anywhere in kernel memory.
--read the right gadget is used to modify the system’s HSTI buffer pointer and size (N.B.: This is damaging behavior regarding any other software that will request the HSTI data. As this can be optional Windows behavior, and this instrument is meant for emergency debugging/experimentation, this loss of data was considered acceptable). Afterward, the HSTI Query API is used to copy back in the program’s user-mode address space, and a hex dump is shown.
Because only built-in, Microsoft-signed, Windows performance is utilized, and all called functions are part of their KCFG bitmap, there’s absolutely no violation of any security checks, and no debugging flags are required, or usage of 3rd party poorly-written drivers.v
Because of the usage of the Windows Symbol Engine, you must have the Windows Software Development Kit (SDK) or Windows Driver Kit (WDK) installed with the Debugging Tools for Windows. The tool will search your setup route automatically and leverage them
SymSrv.dll are present in that directory. As these documents aren’t re-distributable, they cannot be contained with the launch of the tool.
Alternatively, if you get these libraries on your own, you can alter the source-code to utilize them.
Use of symbols requires an Internet connection unless you’ve pre-cached these locally. Additionally, you should set up the variable
_NT_SYMBOL_PATH pointing to a suitable emblem server and cached location.
It’s supposed that an IT Pro or alternative troubleshooter which seemingly has a need to read/write/execute kernel memory (and has knowledge of the right kernel variables to get ) is already more than intimately familiar with the aforementioned setup requirements. Please don’t file issues asking what the SDK is how to set an environment variable.
- Some driver leaked kernel pool? Why not call and
ntoskrnl.exe!ExFreePoolmove into the kernel address that is leaking? What about an object reference? Go call and
ntoskrnl.exe!ObfDereferenceObjectalso have that cleaned up.
- Wish to ditch the kernel DbgPrint log? Why don’t you ditch the internal circular buffer at
- Wondering how big the kernel stacks are on your machine? Consider looking at
- Want to dump the system call table to look for hooks? Go print out
These are only a few examples — all Ring 0 addresses are accepted, either by syntax
module!symbol or directly passing the kernel pointer when understood. The Windows Symbol Engine is used to look up these.
The tool requires certain kernel variables and functions that are only known to exist in contemporary versions of Windows 10 and was just intended to operate on 64-bit systems. These limitations are due to the fact that on older systems (or even x86 systems), these more rigorous security conditions do not exist, and therefore, more traditional approaches may be used alternatively. This is a private tool which I am making available, and that I had no need for those older systems, where I really could use a very simple driver instead. That having been said, this repository accepts pull asks, if anyone is interested in porting it.
Secondly, because of the use cases and my needs, the following restrictions apply:
- Reads — Limited to 4 GB of data at a time
- Writes — Restricted to 32-bits of Information at a time
- Executes — Limited to functions which just take 1 scalar parameter
Obviously, these constraints could be fixed by programmatically picking a different strategy, but they match the needs of a command line tool and my use cases. Again, pull requests are accepted if others want to contribute their own developments.
Note that all implementation (including implementation of the and
--write commands) occurs in the context of a System Worker Thread in.
PASSIVE_LEVEL Thus, user-mode addresses should not be passed in as parameters/arguments.
r0ak v1.0.0 -- Ring 0 Army Knife http://www.github.com/ionescu007/r0ak Copyright (c) 2018 Alex Ionescu [@aionescu] USAGE: r0ak.exe [--executemodule.ext!function> ] [–write module.ext!function> ] [–read module.ext!function> ]