What writes to the Syscache hive?

This is a reply to the Sunday Funday 12/30/18 challenge.

The following results represent an attempt to understand what Windows components write to the Syscache hive in a Windows Server 2008 R2 SP1 installation (64-bit; with updates installed as of January 3, 2019).

First of all, the Syscache hive is an application hive. It means that this hive has no visible mount point, a program that is going to access such a hive should load it and use a handle to a root key returned (actually, this hive is loaded once and later attempts to load it just return a handle to a root key, unless the hive is unloaded). (There is no way to describe a path to a key found in an application hive using typical conventions like “HKEY_LOCAL_MACHINE\<mount point>”. A mount point, which can’t be enumerated, is random.)

However, tools like Process Monitor are capable of catching registry events for application hives. In order to get registry events for application hives only, we should use the following path filter: a registry path should begin with “\REGISTRY\A\” (this is a special key holding mount points of application hives).

In my test, the monitoring tool was running with this filter set for multiple hours. During this period, a standalone GUI application was launched several times from different locations (and then closed), a text editor was installed using an EXE installer, and a file archiver was installed using an MSI package.

At the end of the test, the following tasks were manually launched using Task Scheduler: “AitAgent”, “Microsoft Compatibility Appraiser”, and “ProgramDataUpdater” (all of them completed successfully).

Then, the monitoring tool was stopped and captured events were examined (and those that don’t belong to the Syscache hive were removed). The following stack traces related to the Syscache hive were observed:

syscache-stack.png
Stack traces shown by Process Monitor

As you can see, all read and write events were initiated by the “svchost.exe” process. And these events come from two services: aelupsvc and upnp. And all stacks (starting from corresponding libraries) are identical!

After the manual examination, it was found that the “upnp.dll” library doesn’t contain corresponding calls at the appropriate locations. In fact, corresponding addresses are valid for the “aelupsvc.dll” library. So, this is a bug in Process Monitor.

Thus, the only source of these registry events is the “aelupsvc.dll” library (“Application Experience Service“).

The stack traces shown above can be resolved using debug symbols to the following call chains:

AelTppWorkCallback -> AelpProcessCacheExeMessage -> AelpUpdateFileAndProgramId -> SciRetrieveFileHandleInformation -> (external library) NtQueryInformationFile

AelTppWorkCallback -> AelpProcessCacheExeMessage -> AelpUpdateFileAndProgramId -> SciUpdateFileHandleInformation -> (external library) NtSetInformationFile

The following value is given as the FileInformationClass argument for the NtQueryInformationFile() and NtSetInformationFile() functions: 52 (in Windows 7 and Windows Server 2008 R2, this means FileAttributeCacheInformation; in the current documentation, this value means FileUnusedInformation and it seems to be deprecated).


Next, I want to know what else can (potentially) read from or write to the Syscache hive (even if such events can’t be caught in a simple test).

The following YARA rule was written to find executables with possible calls to the NtQueryInformationFile() and NtSetInformationFile() functions and with data related to such calls:

rule syscache_usage
{
	strings:
		$native_api_func_1 = "NtSetInformationFile"
		$native_api_func_2 = "NtQueryInformationFile"
		$file_id_str_1 = "AeFileID" nocase
		$file_id_str_2 = "AeFileID" wide nocase
		$program_id_str_1 = "AeProgramID" nocase
		$program_id_str_2 = "AeProgramID" wide nocase
		$empty_sha1_str_1 = "da39a3ee5e6b4b0d3255bfef95601890afd80709" nocase
		$empty_sha1_str_2 = "da39a3ee5e6b4b0d3255bfef95601890afd80709" wide nocase
		$empty_md5_str_1 = "d41d8cd98f00b204e9800998ecf8427e" nocase
		$empty_md5_str_2 = "d41d8cd98f00b204e9800998ecf8427e" wide nocase
	condition:
		($native_api_func_1 or $native_api_func_2) and ($file_id_str_1 or $file_id_str_2 or $program_id_str_1 or $program_id_str_2 or $empty_sha1_str_1 or $empty_sha1_str_2 or $empty_md5_str_1 or $empty_md5_str_2)
}

This rule was used to scan the Windows directory and each result was manually filtered and examined in order to remove duplicate libraries and false positives.

Here is a full list of matching files (including duplicate libraries and false positives; each path is relative to the Windows directory):

./SoftwareDistribution/Download/07fa06a192ebf3c5cf05eb35183f9a5d/amd64_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_7ee84be235cf872f/wer.dll
./SoftwareDistribution/Download/07fa06a192ebf3c5cf05eb35183f9a5d/x86_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_22c9b05e7d7215f9/wer.dll
./System32/aelupsvc.dll
./System32/aepic.dll
./System32/aeinv.dll
./System32/appraiser.dll
./System32/CompatTel/diagtrack.dll
./System32/devinv.dll
./System32/diagtrack.dll
./System32/generaltel.dll
./System32/wer.dll
./System32/winsrv.dll
./SysWOW64/wer.dll
./winsxs/amd64_microsoft-windows-a..ence-infrastructure_31bf3856ad364e35_6.1.7601.17514_none_3337092d63596104/aelupsvc.dll
./winsxs/amd64_microsoft-windows-a..de-compat-telemetry_31bf3856ad364e35_6.1.7601.24233_none_e644f1172924348a/generaltel.dll
./winsxs/amd64_microsoft-windows-a..ence-infrastructure_31bf3856ad364e35_6.1.7601.19050_none_33079147637daceb/aelupsvc.dll
./winsxs/amd64_microsoft-windows-a..ence-infrastructure_31bf3856ad364e35_6.1.7601.23255_none_3396316a7c96c88f/aelupsvc.dll
./winsxs/amd64_microsoft-windows-a..rience-program-data_31bf3856ad364e35_6.1.7601.24233_none_d001085cb2d72af2/aepic.dll
./winsxs/amd64_microsoft-windows-a..rience-program-data_31bf3856ad364e35_6.1.7601.24233_none_d001085cb2d72af2/aeinv.dll
./winsxs/amd64_microsoft-windows-a..xperience-inventory_31bf3856ad364e35_6.1.7601.24233_none_e8e2461cfea5b65f/devinv.dll
./winsxs/amd64_microsoft-windows-a..xperience-inventory_31bf3856ad364e35_6.1.7601.24233_none_e8e2461cfea5b65f/diagtrack.dll
./winsxs/amd64_microsoft-windows-a..xperience-inventory_31bf3856ad364e35_6.1.7601.24233_none_e8e2461cfea5b65f/appraiser.dll
./winsxs/amd64_microsoft-windows-a..rience-program-data_31bf3856ad364e35_6.1.7601.17514_none_cf8e57a399a81456/aeinv.dll
./winsxs/amd64_microsoft-windows-a..rience-program-data_31bf3856ad364e35_6.1.7601.17514_none_cf8e57a399a81456/aepic.dll
./winsxs/amd64_microsoft-windows-a..rience-program-data_31bf3856ad364e35_6.1.7601.17514_none_cf8e57a399a81456/aepdu.dll
./winsxs/amd64_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7600.16385_none_7c6ba3bd1f954290/wer.dll
./winsxs/amd64_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_7ee84be235cf872f/wer.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.18869_none_fde7d5f71db043ad/diagtrack.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.18939_none_fe0847a11d97ed01/diagtrack.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.23072_none_fe5f78f236dc8149/diagtrack.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.23142_none_fe7fea9c36c42a9d/diagtrack.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.23548_none_fe85f3f036beb743/diagtrack.dll
./winsxs/amd64_microsoft-windows-u..ed-telemetry-client_31bf3856ad364e35_6.1.7601.24236_none_fe8ea6ce36b88ad0/diagtrack.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.17514_none_14a49c11b2f4bfec/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.17965_none_146f9457b31c5994/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18015_none_14a57c15b2f40121/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18229_none_149eb11db2f87cbc/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18869_none_14737cd1b318db6a/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18923_none_1498bcabb2fdd0c3/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18933_none_148decbfb305ecb4/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.18939_none_1493ee7bb30084be/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.19135_none_148fc75bb3044fcb/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.22125_none_152448f4cc19bcdc/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23915_none_152f1148cc11a3c4/winsrv.dll
./winsxs/Backup/amd64_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_7ee84be235cf872f_wer.dll_c8c67db6
./winsxs/Backup/x86_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_22c9b05e7d7215f9_wer.dll_c8c67db6
./winsxs/Backup/amd64_microsoft-windows-a..ence-infrastructure_31bf3856ad364e35_6.1.7601.19050_none_33079147637daceb_aelupsvc.dll_f420497b
./winsxs/x86_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.17514_none_227e1c01642654f4/wer.dll
./winsxs/x86_microsoft-windows-errorreportingcore_31bf3856ad364e35_6.1.7601.23877_none_22c9b05e7d7215f9/wer.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.24308_none_153cbfe6cc06fe8f/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.22177_none_14f039eccc407b3f/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.22653_none_1501e21acc33cfc4/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23072_none_14eb1fcccc451906/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23126_none_15253276cc18efd4/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23136_none_151a628acc210bc5/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23142_none_150b9176cc2cc25a/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23338_none_151c66eacc1f38c1/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23391_none_14d4855ccc562f06/winsrv.dll
./winsxs/amd64_microsoft-windows-winsrv_31bf3856ad364e35_6.1.7601.23539_none_151d6b00cc1e4c66/winsrv.dll

And here is a list with duplicate libraries removed:

aeinv.dll
aelupsvc.dll
aepdu.dll
aepic.dll
appraiser.dll
devinv.dll
diagtrack.dll
generaltel.dll
wer.dll
winsrv.dll

The “aelupsvc.dll” library was seen before, so it was removed from an examination.

The following files were identified as false positives (no calls to the functions mentioned above with the appropriate FileInformationClass argument): “aeinv.dll”, “aepic.dll”, “appraiser.dll”, “devinv.dll”, “diagtrack.dll”, and “generaltel.dll”.

And the final results are…

The following libraries can read data from the Syscache hive:

  • wer.dll (“Windows Error Reporting DLL“),
  • winsrv.dll (“Multi-User Windows Server DLL“).

The following library can read data from and write data to the Syscache hive:

  • aepdu.dll (“Program Compatibility Data Updater“).

(But don’t forget about the “aelupsvc.dll” library described above!)

And this is all for today! Please, don’t consider these results as exhaustive.

One thought on “What writes to the Syscache hive?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s