Sunday, May 14, 2017

Configuring blue light reduction settings with PowerShell

Windows 10 1703 introduces the "night light" feature, also known as blue light reduction. Its settings are stored in the Registry, but it's a binary blob under CloudStore, rather difficult to manipulate. One user was interested in automating the setting in some way. They already found this GitHub script that sets some values, but it only supports a handful of predefined configurations. So I took a look.

Wild speculation brought me to the SettingsHandlers_Display.dll file, which I suspect is responsible for the relevant part of the Settings app. I got a hold of a 32-bit version so IDA could disassemble it, but it appears to be written in C++ and so is a huge mess to reverse engineer. There seems to be COM involved as well, and though IDA mentions some class names and even some structs' members' names, I couldn't figure out where the saving/loading took place. Looking for struct definitions to get some ideas on the blob's layout, I acquired the PDB file for the DLL, but couldn't accomplish anything with it.

So I was back to plain old pattern recognition. One run of bytes changed every time I edited the blue light settings, no matter what control I altered, and I deduced that to be a FILETIME indicating the store entry's last-modified time. Flipping some switches caused the blob to grow in size, which was puzzling, but most changes just replaced one or two bytes - at least those were easy to track down. It was in that way that I figured out where the color temperature slider's state was kept. The actual numeric value that it changed, though, did not make sense. Changing the Registry value in certain slight ways inexplicably jammed the slider against one end of the other. It didn't help that I didn't know what value the bytes were serializing from the slider.

Use of the Inspect tool revealed the numeric value of the slider. Like f.lux, it remembers color temperature in Kelvin. Some seriously bizarre binary math goes on in the serialization. Nevertheless, I figured out the formula. And though I don't quite have a handle on why the blob expands and contracts, my script works consistently. Interestingly, some of the UI elements in the Settings app immediately update when the script is run.

The script itself is in my Super User answer.

No comments:

Post a Comment