Using environment variables in registry strings.

As part of my job, I receive zip files which I want to do some processing on. I wrote a powershell script to do this processing for me and it’s been really useful. However, even having to fire up Powershell and type in the commands to execute it has become a complete chore (I’m a very lazy person!).

So I decided to add a context-menu item to Windows Explorer for .zip files which would run the script for me.

My initial script looked like this, but had a couple of flaws:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.zip\shell\PS Import]
@="Do Powershell Import"

[HKEY_CLASSES_ROOT\.zip\shell\PS Import\command]
@="%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe \"& '%User_Profile%\\Documents\\my_script.ps1' '%1'\""

The first issue I came across was that I was adding the registry keys to HKEY_CLASSES_ROOT\.zip. This turned out to be incorrect. The correct location was HKEY_CLASSES_ROOT\CompressedFolder.

The second issue is that the default value for a registry key is a REG_SZ (a registry string). This would have been fine, except that I was using environment variables (%SystemRoot% and %UserProfile%) in my path. It turns out that these don’t get expanded at runtime.

Instead, I would need to make the default value for the key of type REG_EXPAND_SZ, which is a registry string which will expand variables.

So my new script looks like this:


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CompressedFolder\shell\PS Import]
@="Do Powershell Import"

[HKEY_CLASSES_ROOT\CompressedFolder\shell\PS Import\command]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,\
25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,57,00,69,\
00,6e,00,64,00,6f,00,77,00,73,00,50,00,6f,00,77,00,65,00,72,00,53,00,68,00,\
65,00,6c,00,6c,00,5c,00,76,00,31,00,2e,00,30,00,5c,00,70,00,6f,00,77,00,65,\
00,72,00,73,00,68,00,65,00,6c,00,6c,00,2e,00,65,00,78,00,65,00,20,00,22,00,\
26,00,20,00,27,00,25,00,55,00,73,00,65,00,72,00,5f,00,50,00,72,00,6f,00,66,\
00,69,00,6c,00,65,00,25,00,5c,00,44,00,6f,00,63,00,75,00,6d,00,65,00,6e,00,\
74,00,73,00,5c,00,6d,00,79,00,5f,00,73,00,63,00,72,00,69,00,70,00,74,00,2e,\
00,70,00,73,00,31,00,27,00,20,00,27,00,25,00,31,00,27,00,22,00,00,00

Obviously, this is not directly maintainable. The only way I can maintain it is to edit the string in the registry, then export the shell key to a new reg file.

The final issue I found was when I was writing this post at home. Here, I have WinRar installed, so I also needed to add the same keys to HKEY_CLASSES_ROOT\WINRAR.ZIP\shell, and I added it into HKEY_CLASSES_ROOT\.zip\shell for good luck. If anyone can explain a little bit about how Windows goes about looking up the context menu in the registry for a given extension, I’d really appreciate it!

One thought on “Using environment variables in registry strings.

  1. [b]Use an Expandable String[/b]

    DWORD = dword: Expandable String = hex(2): Multi String = hex(7):

    A DWORD is a 32-bit unsigned integer (range: 0 through 4294967295 decimal) In the registry, a DWORD always begins with 0x. In the registry, DWORDS always have 8 digits that follow 0x. This can be in decimal or hexadecimal format, 1000 can be written as: 0x00001000 or 0x000003e8

    DWORDS can only make use of the digits 0-9. Strings, any kind, always use ASCII, in ACSII 1000 can only be written as 31,30,30,30 For the String data type, ASCII works in the background without you even knowing. It has to because the computer only understand 1s and 0s. For Expandable String and Multi String data types, these save your entries as a series of ASCII codes in a hexadecimal format, separated by a commas and hex zeroes. So, an Expandable String of 1000 would be: hex(2):31,00,30,00,30,00,30,00

    So let’s convert %PROGRAMFILES% into an expandable string. First, download this: https://hotfile.com/dl/244097278/55aa086/ASCII_2_HEX_Conversion_Tool.7z.html

    Now open that in any modern browser. Put %PROGRAMFILES% into the ASCII box, and select encode it. It will give you %25%50%52%4F%47%52%41%4D%46%49%4C%45%53%25 Copy paste that into a text editor, move the first % to the end. Select the replace command, find all “%” and replace with “,00,”. Remove the comma at the very end. You should get: 25,00,50,00,52,00,4F,00,47,00,52,00,41,00,4D,00,46,00,49,00,4C,00,45,00,53,00,25,00 And finally, hex(2):25,00,50,00,52,00,4F,00,47,00,52,00,41,00,4D,00,46,00,49,00,4C,00,45,00,53,00,25,00

    Done.

    Have you ever tried to convert a curious hex registry entry into ASCII and failed miserably. This lesson contains all the knowledge required to reverse engineer any hex coded registry entry that is not encrypted. Have Fun!

Leave a reply to darkreverser Cancel reply