locked
ETW - Registry monitoring RRS feed

  • Question

  • I'm writing an application that uses Event Tracing for Windows (ETW) to monitor the system for file and registry changes.  I've already got the file monitoring working perfectly, but as I'm looking at the registry events I'm questioning the usefulness of the ETW registry monitoring.  Here are just some of the shortcomings I'm running into:

    1.  There is an event for closing a registry handle, yet none of my ETL files have this close event.  Does this event ever get logged?

    2.  The KeyName in the event sometimes is a full registry path, but sometimes is a partial registry path.  This makes tracking changes very difficult.  Is there a trick to linking the events?  I know the 'KeyHandle' can be used to link events, but the value in 'KeyHandle' appears to be getting reused by the system over and over.  Without the close event how is one to know when a handle was closed and reused by the system?

    I'm seeing the same results on XP, Vista, and Win7 both x86 and x64.  Am I missing something when it comes to registry events?  They seem a lot more complicated and less useful than the file events.

    Thanks for any help or advice.

     

    Thursday, August 12, 2010 5:25 PM

Answers

  • Here's a general explanation of how to resolve key names on Vista and above.  Below that is a discussion of your scenario and of registry events on XP.

    To find an event's full key name, you need to use both the given KeyHandle and KeyName.  (N.B.: what ETW calls a KeyHandle is actually known as a Key Control Block (KCB) by the rest of the Windows world -- don't confuse this with the handle that, say, RegOpenKeyEx() returns.  Understanding KCBs will clarify what the KCBCreate, KCBDelete, and KCBRundownEnd events actually mean, if you're interested.) 

    1. If KeyHandle = 0, then FullKeyName = KeyName.  We're done.
    2. Otherwise, let RelativeKeyName be the event's KeyName
    3. Watch for the next KCBDelete or KCBRundownEnd event with the same KeyHandle.  Let BaseKeyName be the KCB* event's KeyName
    4. Now, FullKeyName = BaseKeyName + \ + RelativeKeyName

    This trace should demonstrate the range of possibilities:

    Registry, Open, pid=0x0A30, ..., KeyHandle=0x0, KeyName="\Registry\User", ...
    Registry, Create, pid=0x0A30, ..., KeyHandle=0x8C15EB48, KeyName="MyKey", ...
    Registry, QueryValue, pid=0x0A30, ..., KeyHandle=0x93D8FDC8, KeyName="", ...
    Registry, KCBDelete, pid=0x0044, ..., KeyHandle=0x93D8FDC8, KeyName="\Registry\Machine\Software\Classes\.csv", ...
    Registry, KCBRundownEnd, pid=0x0044, ..., KeyHandle=0x8C15EB48, KeyName="\Registry\Machine\Security", ...
     
    The Open event has KeyHandle = 0x0.  So, the full key name is just the KeyName: "\Registry\User".

    The Create event has (relative) KeyName "MyKey", and by matching it's KeyHandle (0x8C15EB48) to the KCBRundownEnd event, we see that its base key name is "\Registry\Machine\Security".  The full key name is the concatenation of the two: "\Registry\Machine\Security\MyKey".

    The QueryValue event has no KeyName.  By matching it's KeyHandle (0x93D8FDC8) to the KCBDelete event, we see that its base key name is "\Registry\Machine\Software\Classes\.csv".  The full key name is just the base name: "\Registry\Machine\Software\Classes\.csv".

     ----------------------------------

    Now, to explain your trace on Windows 7.  The events should be interpreted as:

    • KCBCreate - the OS just created a global mapping from KeyHandle 0x93D8FDC8 -> KeyName "\REGISTRY\USER\S-1-5...\TmpCreate".  This mapping is valid across all processes until the corresponding KCBDelete event.  KCBCreate happens any time you access a key that doesn't already have a KeyHandle associated with it.  For example, opening a key that no other process has opened, or creating a new key.
    • Create - a key has been created (e.g. using RegCreateKeyEx()).  The KeyHandle 0x8C15EB48 in this event is the parent key's KeyHandle.  That means, somewhere else in the events there is a KCBCreate, KCBDelete, or KCBRundownEnd event that maps KeyHandle 0x8C15EB48 -> KeyName "\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261".  To get the name of this key, you need to find the parent key's name, and append the relative KeyName ("TmpCreate")
    • KCBDelete - the OS just destroyed the global mapping from KeyHandle 0x93D8FDC8 -> KeyName "\REGISTRY\USER\S-1-5...\TmpCreate".  This happens (eventually, and non-deterministically) after the last handle to a registry key is closed.

    I have not used ETW on Windows XP, and registry events are different on Vista+, so I can't say for sure what's going on.  However, I suspect that the Rundown event on XP is similar to the KCBCreate and KCBRundown* events on Vista+.  That is, Rundown events map KeyHandles to KeyNames.  So, if you keep track of these mappings, you should be able to resolve the registry key names as above.  For example, in your XP trace, there should be a Rundown event with KeyHandle=0xE1A379B8 and KeyName="\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261".

    • Edited by Newton A Wednesday, August 18, 2010 12:05 AM fixed code formatting
    • Marked as answer by Freezer75 Thursday, August 19, 2010 5:56 PM
    Wednesday, August 18, 2010 12:03 AM

All replies

  • 1. I've never seen the close event either (on Win7, Server 2008, and Server 2008 R2).  But I don't know for a fact that it doesn't exist.

    2. To correlate names with registry events, see this MSDN forum post: Obtain the full key path of the registry event.  Note that it is not possible to correlate names during a real-time trace.

    For a further explanation of using ETW registry events, see: Core Instrumentation Events in Windows 7, Part 2.

    Saturday, August 14, 2010 12:55 AM
  • Thanks for the reply.  I am beginning to understand how to process registry events.  I think the main thing causing me confusion is inconsistencies between OS versions.  For example, I wrote a test program that creates a new registry key, then closes the new handle.  That's all it does.  If I monitor a run of this program on Windows 7 I get the following (I've removed all the "noise" events not relevant).

     

    Registry, KCBCreate, 0x0A30, 129264621862831860,   0,   0,    0,  0,  0, 0x93D8FDC8, "\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261\TmpCreate",0,0
    Registry,  Create, 0x0A30, 129264621862832656,   0,   0,  345720640,  0,  0, 0x8C15EB48, "TmpCreate",0,0
    Registry, KCBDelete, 0x0044, 129264621872754219,  470,   0,    0,  0,  0, 0x93D8FDC8, "\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261\TmpCreate",0,0
    

    The "KCBCreate" event makes sense, the key was indeed created.  The "Create" event is all but useless to me.  The key handle (0x8C15EB48) does not correlate to any event that allows me to determine the full registry path.  The final "KCBDelete" event is a mystery to me.  The registry key was not deleted, so why am I getting a KCBDelete event?  It's as if Windows7 uses the KCBDelete event in place of a rundown or even a close event.

    Running this same program on Windows XP I get the following:

     

    Registry, RunDown, 0x01D0, 129264630553824480,   0,   0, 0x00000000, 0xE184B0A8,    0,  0, "\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261\TmpCreate",0,0
    Registry,  Create, 0x01D0, 129264630553824480,   0,   0, 0x00000000, 0xE1A379B8,    0,  0, "TmpCreate",0,0
    
    As you can see I don't get the same number nor types of events as I do with Windows 7.  As before the "Create" event there's no way I can see to correlate it to a full registry key.  And my understanding is "Rundown" events are for handles previously opened, but this handle was opened during execution.

     

     

     

    Monday, August 16, 2010 8:16 PM
  • Here's a general explanation of how to resolve key names on Vista and above.  Below that is a discussion of your scenario and of registry events on XP.

    To find an event's full key name, you need to use both the given KeyHandle and KeyName.  (N.B.: what ETW calls a KeyHandle is actually known as a Key Control Block (KCB) by the rest of the Windows world -- don't confuse this with the handle that, say, RegOpenKeyEx() returns.  Understanding KCBs will clarify what the KCBCreate, KCBDelete, and KCBRundownEnd events actually mean, if you're interested.) 

    1. If KeyHandle = 0, then FullKeyName = KeyName.  We're done.
    2. Otherwise, let RelativeKeyName be the event's KeyName
    3. Watch for the next KCBDelete or KCBRundownEnd event with the same KeyHandle.  Let BaseKeyName be the KCB* event's KeyName
    4. Now, FullKeyName = BaseKeyName + \ + RelativeKeyName

    This trace should demonstrate the range of possibilities:

    Registry, Open, pid=0x0A30, ..., KeyHandle=0x0, KeyName="\Registry\User", ...
    Registry, Create, pid=0x0A30, ..., KeyHandle=0x8C15EB48, KeyName="MyKey", ...
    Registry, QueryValue, pid=0x0A30, ..., KeyHandle=0x93D8FDC8, KeyName="", ...
    Registry, KCBDelete, pid=0x0044, ..., KeyHandle=0x93D8FDC8, KeyName="\Registry\Machine\Software\Classes\.csv", ...
    Registry, KCBRundownEnd, pid=0x0044, ..., KeyHandle=0x8C15EB48, KeyName="\Registry\Machine\Security", ...
     
    The Open event has KeyHandle = 0x0.  So, the full key name is just the KeyName: "\Registry\User".

    The Create event has (relative) KeyName "MyKey", and by matching it's KeyHandle (0x8C15EB48) to the KCBRundownEnd event, we see that its base key name is "\Registry\Machine\Security".  The full key name is the concatenation of the two: "\Registry\Machine\Security\MyKey".

    The QueryValue event has no KeyName.  By matching it's KeyHandle (0x93D8FDC8) to the KCBDelete event, we see that its base key name is "\Registry\Machine\Software\Classes\.csv".  The full key name is just the base name: "\Registry\Machine\Software\Classes\.csv".

     ----------------------------------

    Now, to explain your trace on Windows 7.  The events should be interpreted as:

    • KCBCreate - the OS just created a global mapping from KeyHandle 0x93D8FDC8 -> KeyName "\REGISTRY\USER\S-1-5...\TmpCreate".  This mapping is valid across all processes until the corresponding KCBDelete event.  KCBCreate happens any time you access a key that doesn't already have a KeyHandle associated with it.  For example, opening a key that no other process has opened, or creating a new key.
    • Create - a key has been created (e.g. using RegCreateKeyEx()).  The KeyHandle 0x8C15EB48 in this event is the parent key's KeyHandle.  That means, somewhere else in the events there is a KCBCreate, KCBDelete, or KCBRundownEnd event that maps KeyHandle 0x8C15EB48 -> KeyName "\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261".  To get the name of this key, you need to find the parent key's name, and append the relative KeyName ("TmpCreate")
    • KCBDelete - the OS just destroyed the global mapping from KeyHandle 0x93D8FDC8 -> KeyName "\REGISTRY\USER\S-1-5...\TmpCreate".  This happens (eventually, and non-deterministically) after the last handle to a registry key is closed.

    I have not used ETW on Windows XP, and registry events are different on Vista+, so I can't say for sure what's going on.  However, I suspect that the Rundown event on XP is similar to the KCBCreate and KCBRundown* events on Vista+.  That is, Rundown events map KeyHandles to KeyNames.  So, if you keep track of these mappings, you should be able to resolve the registry key names as above.  For example, in your XP trace, there should be a Rundown event with KeyHandle=0xE1A379B8 and KeyName="\REGISTRY\USER\S-1-5-21-1993962763-583907252-1417001333-4261".

    • Edited by Newton A Wednesday, August 18, 2010 12:05 AM fixed code formatting
    • Marked as answer by Freezer75 Thursday, August 19, 2010 5:56 PM
    Wednesday, August 18, 2010 12:03 AM
  • Wow, thanks for that excellent explanation.  I think I understand now how to process registry events.  I just wish the MSDN documentation explained all this.

     

    Wednesday, August 18, 2010 2:29 PM
  • Glad to help.  I spent a while pulling this together from the various scattered sources, so I'm happy I can pass it on.

    Also, if your question has been fully answered, please accept the answer so others can find it.

    Wednesday, August 18, 2010 10:38 PM
  • Hello Freezer75 I am working on a similar application in which i need to capture events for Files and Registry Keys. I am new to ETW so i havn't got anything yet to work as required :). I have been browing about the problem and havn't found anything yet. while googeling, i saw link of your post and as you have mentioned that you have captured events for ETW for file and registry change. Can you please provide me some sort of helpful material or refer to any article to initiate my application...how I can get the proper events for Registry and Files changes ? Thanks in advanced Izhar
    Monday, November 8, 2010 3:46 PM