Undocumented Environment Variables

Although we have less Easter Eggs, there are still a huge number of undocumented behaviors.

Recently I'm writing a CLR profiler using ICorProfilerCallback for fun, the CLR profiler was modeled as an in-proc COM server, and the activition was done through environment variables:

  • SET COR_ENABLE_PROFILING=1
  • SET COR_PROFILER={XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
  • SET COR_PROFILER_PATH="C:\FOO\BAR\MyProfiler.dll"

Immediately I realized there must be a lot more environment variables, and it was a perfect time to use WinDBG: 

 cdb.exe -hd -g -G -xi ld -xe cpr -c "bu KERNELBASE!GetEnvironmentVariableW \"du @rcx; gc\"; g" "%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
 0:000> cdb: Reading initial command 'bu KERNELBASE!GetEnvironmentVariableW "du @rcx; gc"; g'
000007fe`581406f0  "SHIM_DEBUG_LEVEL"
000007fe`58140428  "SHIM_FILE_LOG"
000007fe`581406f0  "SHIM_DEBUG_LEVEL"
SHIMVIEW: ShimInfo(Complete)
(ba0.db8): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
000007fe`5c4eada0 cc              int     3
0:000> g
Microsoft (R) Visual C# Compiler version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

warning CS2008: No source files specified
000000a3`60e9c230  "COMPlus_Version"
000000a3`60e9c230  "COMPlus_InstallRoot"
000000a3`60e9b790  "COMPlus_InstallRoot"
000000a3`60e9c140  "COMPlus_DefaultVersion"
000000a3`60e9bad0  "COMPlus_InstallRoot"
000000a3`60e9b880  "COMPlus_InstallRoot"
000000a3`60e9b8a0  "COMPlus_3gbEatMem"
000000a3`60e9b400  "COMPLUS_CLRLoadLogDir"
000000a3`60e9b1d0  "COMPlus_InstallRoot"
000000a3`60e9b180  "COMPlus_NicPath"
000000a3`60e9b180  "COMPlus_RegistryRoot"
000000a3`60e9b180  "COMPlus_AssemblyPath"
000000a3`60e9b180  "COMPlus_AssemblyPath2"
000000a3`60e9ab80  "COMPLUS_InstallRoot"
000000a3`60e9ab40  "COMPLUS_DefaultVersion"
000000a3`60e9ab40  "COMPLUS_Version"
000000a3`60e9af60  "COMPLUS_ApplicationMigrationRunt"
000000a3`60e9afa0  "imeActivationConfigPath"
000000a3`60e9afb0  "COMPLUS_OnlyUseLatestCLR"
000007fe`51a06580  "APPX_PROCESS"
000000a3`60e9af60  "COMPLUS_BuildFlavor"
000007f6`2e5c16a8  "LIB"
error CS1562: Outputs without source must have the /out option specified

As we can see, the red parts are the environment variables used by Application Compatibility team for debugging a shim.

The blue parts are the environment variables used by COMPLUS, which was the original name for .NET.

Notice that there is no guarantee of completeness using my WinDBG approach, since GetEnvironmentVariableW is not the only way to retrieve environment variables.

I'll leave a homework for the readers - find the environment variables consumed by the Visual Studio IDE (hint: you need to modify the command line to make it work under 32bit).