Hi all,
I have gone through the documentation and coded my own examples, but it looks like what I just mentioned on the title cannot be done.
I am aware of STATUS_CALLBACK_BYPASS and how to dereference and replace an existing object coming from the Pre-Operation, and other actions that need to be taken for that matter.
However, it looks like STATUS_CALLBACK_BYPASS only works when we need to change the ReturnStatus of the PostOp, like from success to failure and viceversa.
In my example I am receiving a successful Pre-Operation where the granted access is KEY_ALL_ACCESS which I want to reduce to KEY_READ.
The following steps are taken:
- Validate Pre-Op was successful
- Validate access granted contains additional flags, not present in KEY_READ only, such as KEY_ALL_ACCESS .
- Open a new handle to the same target registry key using ZwOpenKey and KEY_READ access.
- Use ObReferenceObjectByHandle to get the object address from the handle opened in step 2.
- Store this object in pPreInfo->ResultObject
- Close handle opened in step 2.
- Dereference pPostInfo->Object to delete original object
- Replace pPostInfo->Object original object with pPreInfo->ResultObject (new object)
- Set pPreInfo->GrantedAccess to KEY_READ
- Set ReturnStatus to success
- Return STATUS_CALLBACK_BYPASS
All the above completes without any errors. However, examining the usermode handle that is returned to the caller, ProcessHacker reports that access granted is KEY_ALL_ACCESS.
I have also verified that the object associated with the usermode handle is the new object we used to replace the original one.
In other words, everything looks fine from the coding point of view, so I am now thinking that changing the granted access is not actually possible and we can only either fail a successful Pre-Op, or make a failed Pre-Op to succeed by taking over the operation and redirecting to another key etcā¦etcā¦, depending on why it failedā¦etcā¦etc⦠You get the point.
Is my final conclusion correct?
Thank you,
kyREcon