Notes

How Clarity reads CPU temperature without WinRing0

Why Aikonic has its own kernel driver, what it's allowed to touch, and the copy of WinRing0 our own installs kept loading until 1.1.8.

27 October 2026

Clarity 1.0 went out on 18 August without a kernel driver of its own. On any machine where Windows blocks WinRing0 (the explainer has the background), CPU temperature just read "no signal". A week later we shipped 1.1.5 with a driver we'd written ourselves, and on Intel machines the number came back.

What we tried first

Nobody wants to write a kernel driver, so we tried everything that doesn't need one.

Intel's Power Gadget library reads package temperature, but only on machines where someone has installed Power Gadget first. Windows' own thermal zones need nothing installed. The catch is that on most consumer boards they're measuring somewhere around the chipset. On that route we only accepted a zone with the CPU in its name, so a board without one got nothing, which is still better than a chipset reading with "CPU" written next to it. WMI reads the same zones and wants administrator rights on top.

Running the readings from a Windows service as SYSTEM didn't help either. Windows refuses a blocked driver no matter which account asks for it.

We did look at borrowing another tool's driver. But the ones that could read the temperature register are on the same blocklist as WinRing0, and for the same reason: they'll read or write pretty much anything a program asks them to.

Why we wrote our own

What we wanted was a driver whose whole job was written down before Microsoft signed it. Ours checks every request against a list compiled into it: the processor registers it may read, and the ports on the motherboard's sensor chip. If it isn't on the list, it's refused. Nothing can be loaded into it afterwards either, so the only way to change what it does is to change the source, and a changed driver goes back to Microsoft before anyone gets it.

That costs us a round with Microsoft every time we change it. The quickest came back the same day. The slowest took five days.

Getting it signed

On current Windows a new kernel driver has to carry Microsoft's signature, and Microsoft will only sign for a company that holds an Extended Validation code-signing certificate. So before any of the code mattered, there was paperwork: registering Hancock Technologies in Switzerland, getting a D-U-N-S number, and then the certificate itself, issued on 15 June. It lives on a hardware key. If that key isn't plugged in and the PIN typed, nothing of ours gets signed.

We went the attestation route. You submit the driver with your own signature on it, Microsoft reviews it, and they add theirs. It's the quicker of Microsoft's two routes and, yes, the lighter review. The other one, WHQL, puts the driver through Microsoft's hardware test kit and takes weeks longer.

The first version only read temperature. It went in on 21 August, sat at "Processing" and never came out of it, so we resubmitted the same day and that one went through. The version that shipped in 1.1.5 on 25 August also reads the sensor chip, and that took three more rounds in the four days in between.

What the driver can touch

On Intel it reads the processor's temperature sensors, its temperature limit, and the energy counters that package power is worked out from. On AMD it has read die temperature and package power since 1.1.10. From 1.1.34 it also reads each core's clock and voltage on both. On the motherboard it reads the sensor chip, so fan speeds, board temperatures and voltages. To read that chip you first have to tell it which register you want, and that's technically a write, so the driver lets those selections through.

The driver in 1.1.34 can also change one thing, and that's fan speed. It's there for Control's fan control, which isn't on sale yet. On Clarity, Aikonic never asks it to. And if Aikonic's sensor service stops while it's driving a fan, the driver hands that fan straight back to the motherboard.

There are things it can't do in any build. Nothing in its source writes a processor register, and it can't map physical memory. The only PCI access it has is the one fixed path AMD's temperature read needs.

Windows only lets administrators and the SYSTEM account open it, so a normal program can't talk to it at all. Could a program running as administrator use it to change a fan's speed? From 1.1.34, yes. The driver keeps the fan above a minimum, and the board takes it back when that program closes. We accepted that, because an administrator can already load a driver of their own.

When it refuses a read, Clarity shows that value as unavailable and tells you why. If a reading came from a fallback sensor instead, a board zone say, it gets a ~ and the reason next to it.

The WinRing0 we kept loading

On 27 August we were wiping a laptop for an unrelated test and found WinRing0 on it. Registered as a kernel service, and running. Aikonic 1.1.7 had put it there.

The sensor library we build on, LibreHardwareMonitor, carries WinRing0 inside it and installs it when it starts up. We'd pointed every one of the library's reads at our own driver, but never removed the bit that installs WinRing0. Every build up to 1.1.7 did it wherever Windows allowed, and on our test machines, with memory integrity off, Windows did. It also stayed behind after an uninstall.

Nobody noticed, because nothing looked wrong. On Intel our driver was doing all the reading, so the values were identical either way. On AMD the old drivers were still supplying die temperature, which just looked like everything working. And our checks only looked at the installer, where WinRing0 doesn't exist until the library unpacks it at run time.

Taking it out had its own trap. The library only goes looking for the motherboard's sensor chip if WinRing0 has loaded, so the first build without it lost every fan, board temperature and voltage on our AMD test machine: 66 sensors down to 42, and no error anywhere. Once we changed that check as well, the next run matched the WinRing0 run sensor for sensor.

1.1.8 went out the same day. The library actually carries two third-party drivers, WinRing0 and a smaller one called inpoutx64, and both are deleted from our copy of it, so they can't ship by accident. Our build checks fail if WinRing0 ever comes back. On first run, 1.1.8 removes the WinRing0 service and file that an earlier version left behind.

It still took two goes. On Gigabyte boards and AMD Ryzen systems, versions up to 1.1.6 had installed inpoutx64 and set it to start with Windows, and nothing ever removed it, so it kept loading on every boot with nothing using it. 1.1.12 removes it, once, as long as it's the copy that library installed and nothing else on the machine is using it.

1.1.8 also brought in a bug we didn't fix for a month. The service asked our driver for every core's temperature without saying which core, so the driver read core 0 every time. 1.1.12 fixed it on 25 September.

Losing WinRing0 cost us some readings for a while, too. AMD machines fell back to Windows' thermal zone, marked low confidence, until 1.1.10 started reading them through our driver. Per-core clocks had come through WinRing0 as well, and our driver couldn't read them, so from 1.1.10 each core's clock reads "no reading" until the driver in 1.1.34 adds them back. They show up once that driver is running, which is straight after the update, or after a restart if Windows won't let go of the old one.

What still shows as unavailable

A fan header with nothing plugged in, or a fan with no speed wire, won't report a speed. Some chips, like the ITE IT8792E on several Gigabyte boards, power a header without measuring it at all.

Virtual machines don't pass the processor's sensors through, so in a VM there's no CPU temperature to show.

Up to 1.1.12, one board chip showed complete nonsense. On an MSI MAG B850 TOMAHAWK WIFI, with a Nuvoton NCT6687D, every fan read 65,535 rpm, which is what a chip that isn't answering looks like. From 1.1.34 our driver reads that chip, and its NCT6683D and NCT6686D siblings on most current MSI boards, so the board's temperatures, voltages and fan speeds are real readings. Fan control on those boards stays off for now. A reading Aikonic can't confirm on that chip is still left out, with its reason.

Some boards still have a sensor chip Aikonic doesn't read yet. The Fans and Sensors pages name the chip and say so.

If another monitoring program is holding the sensor chip at the moment Aikonic reads it, 1.1.34 tells you the chip was busy. The reading comes back on the following read, usually a second later.

The hardware report (Settings, Data & exports) lists what your board exposes, and that's how support for new boards gets added. If yours is missing, send it to [email protected]. The help pages explain the messages Clarity shows.

Checking it yourself

The driver is AikonicMsrDriver.sys, in C:\Program Files\Aikonic\aikonic-sensor-service\drivers. Open its Properties, go to the Digital Signatures tab, and you'll see two signatures: Hancock Technologies, and Microsoft Windows Hardware Compatibility Publisher. That second one is Microsoft's attestation.

To see which kernel drivers Aikonic has registered, run this in PowerShell:

Get-CimInstance Win32_SystemDriver | Where-Object PathName -match 'Aikonic' | Select-Object Name, State

You should get one line back, AikonicMsrDriver. If there's also a name starting with R0, that's WinRing0 left behind by a build before 1.1.8, and starting any current version will remove it. Uninstalling removes the driver too, from 1.1.34 on.

The driver's threat model goes a lot further than this page, into detail we'd rather keep off the website. If you're a security reviewer or press, ask for it at [email protected].