ObOpenObjectByPointer getting 0xC0000005 for a transaction pointer

Hello all.

I am testing out our software on the latest Windows 10 Redstone build 14332.

I have a registry callback that tries to open the object associated with the transaction passed in as part of the PREG_OPEN_KEY_INFORMATION. I noticed that I started to get a access violation passing this transaction down to the ObOpenObjectByPointer.

One thing I noticed whenever I got a failure was that the pointer that was in the Transaction field was weird because it ended in a 1 (as in not a multiple of 8 or at least 4). I am seeing a value such as 0xfffff80ad6c035c1. When I traced through the ObOpenObjectByPointer assembly, I am getting a crash because the code is expecting to find a value 0x30 bytes before the pointer inside of the object and because it is offset by 1, it doesn’t find the correct value and gets an Access Violation.

So first question is anyone else seeing this?

Second question, what would cause the transaction pointer to be off by 1. All of the rest of the pointers are 100% correct. It is only that one that is bad, and always off by 1. I have checked the value right when my callback is first called. I wanted to eliminate any chance of my code doing something that would change the pointer.

Final point: I only started seeing this with build 14332 of Windows 10. This same code is running just fine on prior versions of Windows 10.

Thanks in advance.

Chip

There is a long-used trick in various places in Windows that exploits the fact that pointers will always be aligned at some level (generally 8 bytes, even on 32 bit systems). For example, ExAllocatePoolWithTag (and friends) always returns 8 byte aligned memory. Thus, there are 3 bits that can be used to store state. The ERESOURCE package does (or did) use this trick and I’ve seen other examples of it over the years. It’s perfect for when you have a tiny bit of state you want to carry around but don’t want to allocate more space.

If you strip the low order bits (x & ~7) does your code work?

Tony
OSR

If you break in the debugger and use !object, !pool and friends on that pointer what does it show.

Also on the -1 pointer. It’s interesting what Tony is saying but I find it weird that you would see this in the callback. You would assume ( and documentation states ) that the passed TM pointer as provided would be “usable” as it is.

Anyway, interesting and I’m curious if this is not only a temporary thing in this build only.


Gabriel Bercea

Windows Kernel Driver Consulting

www.kasardia.com

On Thu, May 5, 2016 at 2:51 AM -0700, “Tony Mason” wrote:

I have a registry callback that tries to open the object associated with the transaction passed in as part of the PREG_OPEN_KEY_INFORMATION. I noticed that I started to get a access violation passing this transaction down to the ObOpenObjectByPointer.

One thing I noticed whenever I got a failure was that the pointer that was in the Transaction field was weird because it ended in a 1 (as in not a multiple of 8 or at least 4). I am seeing a value such as 0xfffff80ad6c035c1. When I traced through the ObOpenObjectByPointer assembly, I am getting a crash because the code is expecting to find a value 0x30 bytes before the pointer inside of the object and because it is offset by 1, it doesn’t find the correct value and gets an Access Violation.

So first question is anyone else seeing this?

Second question, what would cause the transaction pointer to be off by 1. All of the rest of the pointers are 100% correct. It is only that one that is bad, and always off by 1. I have checked the value right when my callback is first called. I wanted to eliminate any chance of my code doing something that would change the pointer.

Final point: I only started seeing this with build 14332 of Windows 10. This same code is running just fine on prior versions of Windows 10.

There is a long-used trick in various places in Windows that exploits the fact that pointers will always be aligned at some level (generally 8 bytes, even on 32 bit systems). For example, ExAllocatePoolWithTag (and friends) always returns 8 byte aligned memory. Thus, there are 3 bits that can be used to store state. The ERESOURCE package does (or did) use this trick and I’ve seen other examples of it over the years. It’s perfect for when you have a tiny bit of state you want to carry around but don’t want to allocate more space.

If you strip the low order bits (x & ~7) does your code work?

Tony
OSR


NTFSD is sponsored by OSR

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at

To unsubscribe, visit the List Server section of OSR Online at

!object of either the pointer or the pointer plus the extra 1 gives the standard "Not a valid object (ObjectType invalid).

!pool of the pointer gives back:
size: 80 previous size: 90 (Allocated) Regi

As to what happens if I strip off the extra 1, everything appears to work correctly. That is what I put into my code, but I wanted to see if it made any sense since I had never seen something in a callback not be correct.