Hello list!
I’ve recently gotten increasingly frustrated at seeing bizarrely huge values for the reference/pointer count values in the OBJECT_HEADER structure when using !object and/or Process Explorer in Windows 8.1. I had scoured MSDN and this list for others having noticed this, but nobody seems to have looked at why this is happening.
I ended up doing some black box testing and documenting my findings on my blog, if anyone else is interested: http://www.alex-ionescu.com/?p=196. I normally post on low-level security details not typically relevant to driver developers, but I figured you might stumble upon this on your debugging adventures…
–
Best regards,
Alex Ionescu
So, dude… Spill the beans and give us a quick summary of what you found.
Peter
OSR
@OSRDrivers
Peter,
Wasn’t sure what the “repost policy” was so I’d love to give a quick summary here!
The gist of it is that the HANDLE_TABLE_ENTRY structure has been re-organized on both x86 and x64 (diagrams in the post, or you can use dt) to include a per-handle-entry reference count, which is more of an “access count”. It starts at its maximum value (0x7FFF on x64, 0x1F on x86) and goes down by one each time a process uses a handle entry. This is useful because you can now actually tell how many times a process used one of its handles, but the side effect is that this number is now used to bias the overall reference count in the OBJECT_HEADER.
This ultimately means that each new handle will add 32767 (or 32 on x86) references to an object, and that each use of a handle will then decrement the reference count by one.
Sadly, this has made the reference count value to quite confusing and nearly useless in tracking down leaks, unless all associated handle entries are also located and analyzed.
–
Best regards,
Alex Ionescu
Great info, Alex. Thanks for sharing.
Strikes me as quite an odd approach, starting at the max value and decrementing. What clever point of this approach am I missing?
Peter
OSR
@OSRDrivers
I don’t actually know the true answer to this – although it may have been motivated by the same reason that EX_FAST_REF’s are also set at their maximum, in the sense that you are ‘given’ all your references at the start, and consume your ‘fast’ references, until you have to replenish (the names of the Exp*Fast/SlowReplenishHandleEntry certainly suggest this, but as I had mentioned in the post, this was all done with black box testing so I had not yet looked at the actual code yet).
The other possibility is that this does make it possible to, in 99% of cases, somewhat infer how many handles are open to an object by merely looking at its pointer count, because it will typically be some close multiple of 32K (at least on 64-bit). While if the RefCnt started at 1, you’d have OBJECT_HEADERs with “8” or “28” references if there were 4 or 14 handles open (1 ref for the handle entry itself, plus 1 ref for the access count of each one). These low numbers would make things even more confusing – at least now with the huge values it’s somewhat clear some bias is applied (and hence this discovery).
But again, I may be grasping at straws here 
–
Best regards,
Alex Ionescu
quote>
The other possibility is that this does make it possible to, in 99% of cases,
somewhat infer how many handles are open to an object by merely looking at its
pointer count, because it will typically be some close multiple of 32K (at least
on 64-bit).
[/quote]
Ah! Good thought, that.
Interesting. Again, nice post Alex. Many thanks.
Peter
OSR
@OSRDrivers