Get reference count of kernel Object

Hi , I need some clarification about use of ObReferenceObject/ObDereferenceObject.

ObReferenceObject increments the reference count of an object. So when we call this API for say EPROCESS, process will remains in memory until ObDereferenceObject called(provided it has done with its activity).Now I have copy of EPROCESS for which i am calling ObReferenceObject after that particular process has died. What would be the consequence? As ObReferenceObject returns VOID, so i don’t get to know what has happened.
Is there a way to figure it out that particular process has died(from EPROCESS ) ? If not, is there a way to get number of times ObReferenceObject has been called on that EPROCESS?

Thanks,
Gyani

A process is a waitable object. It’s signalled when process terminates. You can use KeWaitForSingleObject to check its state.

Whether the process object is still valid should not have any relevance. If you want it to stay valid for later usage, you make sure to call ObReferenceObject. When you don’t need it anymore, you call ObDereferenceObject.

I *think* his question is around the potential race around incrementing the reference on an object and an object going away.

And the answer to THAT is that you can’t reference an object from a context in which you don’t KNOW the object is valid. Otherwise, you risk merely incrementing a random location in non-paged pool.

So… no. You can’t just find an arbitrary PEPROCESS from within and arbitrary process and thread context and without knowing that a reference to that object is being held and call ObReferenceObject on it. That would be… bad.

But, for example, if you have an IRP that originated from a thread that was part of a given process, you know that the Process Object is valid (because the IRP has a reference on the Thread which has a reference on the process). So, there… you’re “good to go”.

Peter
OSR
@OSRDrivers

>Is there a way to figure it out that particular process has died(from EPROCESS )
yes - BOOLEAN NTAPI PsGetProcessExitProcessCalled( PEPROCESS Process) ;

>yes - BOOLEAN NTAPI PsGetProcessExitProcessCalled( PEPROCESS Process) ;

Correct, but bad advice Mr. Brown.

Nothing says that the process didn’t exit immediately after PsGetProcessExitProcessCalled() set the BOOLEAN return, but before the user checked its value (even). So, again… you can’t ref an object “anytime”.

Sort of like MmIsAddressValid… one of my very favorite mis-used functions. The standing joke is that this should have been named MmWASAddressValidWhenYouChecked()…

Peter
OSR
@OSRDrivers

>Nothing says that the process didn’t exit immediately after
yes,agree - if we got FALSE - we cannot be sure that process still running
but after we got TRUE - this already will be not changed. so by using this routine we cannot be shure that process still alive. but can on 100% correct determinate it exit

so not equal Sort of like MmIsAddressValid… - this really full mis-used because address can after call become valid or not valid at any time. but if process already terminated (we got true) - this will be usefully info.
however i never use this function in self practic, only say KeWaitFor*Object and hard imaging scenario where PsGetProcessExitProcessCalled will be usefull.
but formal reply for question - Is there a way to figure it out that particular process has died

xxxxx@live.com wrote:

> Nothing says that the process didn’t exit immediately after
yes,agree - if we got FALSE - we cannot be sure that process still running
but after we got TRUE - this already will be not changed. so by using this routine we cannot be shure that process still alive. but can on 100% correct determinate it exit

Well, yes, but all of that assumes that the PEPROCESS you have is valid
and remains valid. Perhaps I am reading too much, but I think that’s
the direction Peter was trying to go, because that was the direction of
the questioning. If ObReferenceObject is unsafe, then
PsGetProcessExitProcessCalled is unsafe. It consists basically of one C
statement, fetching one member from the EPROCESS. There isn’t any
validation, because there can’t be.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

for call PsGetProcessExitProcessCalled or KeWaitFor*Object we must already have referenced pointer for EPROCESS or do this for current process. than we can call ObReferenceObject and use this referenced pointer in arbitrary thread context later. this already another question.
“Now I have
copy of EPROCESS for which i am calling ObReferenceObject after that particular
process has died.” - this is of course mistake. we must at begin call ObReferenceObject, and after this we can use EPROCESS pointer - for query process died, for get it exit code, or other tasks/ and finaly call ObfDereferenceObject when we not more need pointer

You should take the following steps:

  1. ZwOpenProcess();

2.ObReferenceObjectByHandle();

3.ZwClose();

4.KeWaitXXX();

  1. ObDereferenceObject();

If you do it this way you are going to avoid the potential race condition that is just inevitable if you simply call ObReferenceObject() with a pointer to an object pointer that you don’t own…

Anton Bassov

>ObReferenceObject after that particular process has died.

You will have a valid addrefed EPROCESS describing the already terminated process.

Is there a way to figure it out that particular process has died(from EPROCESS ) ?

Wait on it with zero timeout. If OK - process terminated. If timeout - process is still running.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> 1. ZwOpenProcess();

PsLookupProcessByProcessId is by far easier.


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com

> PsLookupProcessByProcessId is by far easier.

This is certainly true, but the OP seems to be desperate to call ObReferenceXXX() manually. Therefore, I showed him how it can be done without risking a race condition…

Anton Bassov

>Therefore, I showed him how it can be done without risking a race condition…

PsLookupProcessByProcessId

then, when you’re done - ObDereferenceObject


Maxim S. Shatskih
Microsoft MVP on File System And Storage
xxxxx@storagecraft.com
http://www.storagecraft.com