Query the Offline Registry with OffReg.dll

Query the Offline Registry with OffReg.dll

Ok.  It's time for some code.  I've been crazy busy lately and haven't had time to post anything really useful on this site yet. So here is a quick tutorial on using the Offline Registry API.  

I'm not sure how many people actually need to do this, but it is quite useful for servicing Windows images or querying data while booted to Windows PE, and while it is similar to querying online registry I didn't see a whole lot out there and thought it could use it's own tutorial.

Overview

First a little about Offreg.dll.  Offreg.dll is distributed as part of the WDK and there are versions that go all the way back to Windows XP so just download the version compatible with the OS you want to tinker with.  Many versions are even backwards compatible.

The process to query the offline registry is pretty simple.

  1. Open the Hive
  2. Open the Key
  3. Query the Value to get Size and Type info you need to handle
  4. Query the value again with the right buffers/type
  5. Close the Key
  6. Close the Hive

Error Handling

Every call using the offline registry library returns a system error code.  Successful calls return ERROR_SUCCESS (0), but if you get something else you can look them up here System Error Codes

Testing

You will need to open the offline registry hive.  This will not work if something else has the registry hive loaded so even if you wanted to load the backup registry hives at C:\Windows\System32\config\regback it wont work.  The active system holds these open.

Your best bet is to mount a wim image for testing your own offline registry code.  Instructions for that can be found here Mount-WindowsImage - Technet

ORHKEY hHive;

// Open the Hive file.
if(OROpenHive(L"C:\\Source\\Temp\\windows\\system32\\config\\SOFTWARE", &hHive) != ERROR_SUCCESS)
{
    //An Error Occurred.  Check the last error value
    //and lookup the system error code.
}

Congratulations we have a handle to the hive.  Next we need to open the key so we can access the value.  This is a little different than a standard registry query. In this example I've opened the SOFTWARE hive/file directly so we are already in HKEY_LOCAL_MACHINE\Software and I just need to open the key Microsoft\\Windows\\CurrentVersion, or whatever other path you want to go to

ORHKEY hKey;

//Open the Key.  Pass the hive handle and the key you want to open
if (OROpenKey(hHive, L"Microsoft\\Windows\\CurrentVersion",  &hKey) != ERROR_SUCCESS)
{
    //An Error Occurred.  Check the last error value
    //and lookup the system error code.	
}

You should have a handle to an open key at this point and we are ready to query the value.  This requires two calls.  One to get the size and type of the value and the other to get the value.  I'm just going to query a string in this example.

//Try to get the size/type of the data/value
DWORD dwType;
DWORD dwSize = 0;
if (ORGetValue(hKey, nullptr, L"ProgramFilesDir", &dwType, nullptr, &dwSize) != ERROR_SUCCESS)
{
    //Handle errors. Yada, yada...
}

//Ok we got the size & type.  Let's get the data now in the next call.
wstring result;
result.resize(dwSize);
if (ORGetValue(hKey, nullptr, L"ProgramFilesDir", &dwType, reinterpret_cast<LPBYTE>(&result[0]), &dwSize) != ERROR_SUCCESS)
{
    //Handle Errors. 			
}

Hopefully we got our data in the result variable and we can just close the key and hive now.

if (ORCloseKey(hKey) != ERROR_SUCCESS)
{
    //Handle Errors
}

if (ORCloseHive(hHive))
{
    //Handle Errors		
}

I hope you found this tutorial helpful.  Happy coding.