[Autogenerated] Let's look at a couple of things we can do with the returned
handle from create process in the case of a successful call.
So one thing we can do is wait until the process terminates.
For whatever reason, we can do that using the weight for single object function.
So wait for single object is a generic function allows us to
wait until the kernel object becomes signal,
where the meaning of signal depends on the type of object.
In the case of a process,
it means the process has terminated for whatever reason.
So it puts the common thread into a wait state until the process terminates for
the amount of time I can specify in the second parameter.
And for now I'm going to start with a simple example of Infinite.
Infinite is a constant.
That indicates that I would like to wait for as long as it takes.
So when I get to the next line that means not bad has definitely
terminated and it doesn't indicate why it has terminated.
Maybe it was a normal termination, maybe it was abnormal regardless.
I know this has been done, this happened for sure.
And one other thing you can get from that is the exit code of the process,
which means what's their value returned from the main function of that process.
We can do that using a function called get exit code process.
I'm going to provide the handle again.
And because the hand is an old powerful handle,
I can do anything I want with the process given this handle,
I can definitely get the exit code from the process and that's return using
some the word 32-bit value so I can add that here With code.
And let me just display whatever code has returned from.
Get exit code process.
So let's try this out.
We're going to build the project and then just press control F5
perhaps to run this without a debugger I'm going to press control the
five and we should be seeing a Notepad coming up so I'm not going to
run with the debugger at this point.
You can see Notepad has is coming up and notice my create process.
Process is in kind of a waiting state.
It's waiting for some thing, although it's not obvious what that something is.
So let's see if we can find out a bit more information in Process Explorer.
So first thing is to configure the symbol,
something that they haven't done properly earlier.
So let me just do that properly by moving to the uh,
the D B G engine here that we get from the Windows
debugging tools for Windows package that we get from the
debugging tools for Windows package.
So here's X 64 this is where we're going to get D B G help and the
symbols already set up by the environment variable.
Let's look at, create process at this point,
create process,
let's double-click that we can see that we have the first thread here,
which is the one we're using right now for the waiting.
There are some other threads in the process but we
don't care about those at this point.
Let me just double click here or press the stop button to
look at the call stack for this thread.
We expect the call stack to contain some kind of weight function.
You can see here that indeed we have the main
function calling wait for single object.
That's the call we we made here.
It's a function called wait for single object E x which is an extended
version that has been called by wait for single object.
And obviously we're waiting here in a system called by N T DLL.
We don't see the kernel stack here.
And that's because I've launched or explore with normal user rights.
Let me re launch that with admin privileges.
And this is what I recommend you do.
So going back to create process here, double clicking again.
We should now be able to see the coal stacking current space as well,
which we do.
So you can see here this is the bottom of the stack,
that's our main function and then we have wait for single object here.
Auntie, wait for single object,
that's the system call in anti DLL and then we go over to the
colonel notice the anti os kernel module here.
So we have the actual system called implemented here using the function.
Anti wait for single object.
That's again the same function but this is the real
implementation as we discussed in the previous course and
eventually there's a call here to okay,
wait for single object which is the function that is documenting the Windows
driver kit for waiting on a kernel object given its pointer.
And this point we can see that this is in fact waiting here and swap
context is really where the thread is waiting and doing nothing at
this point and doesn't use up any CPU time.
So now to make things kind of move a bit forward,
what we need to do is to kill this note that instance in whatever way,
such as simply closing its window, which will also terminate the process.
You can see note but has terminated its printed immediately
and the exit code happens to be zero,
which is the normal exit code and probably the most
common for processes exiting and normally,
so that's fine.
So let's change it a little bit and see what we get
instead of waiting infinitely.
Let's just change that to a finite number like 10 seconds.
The number here is in milliseconds.
So let's use 10,000 milliseconds.
And so in this case the wait might be over for one Two reasons.
Either the note that process has terminated and the
object became signaled before.
10 seconds have elapsed or the other options that 10 seconds
have elapsed and note that was still running.
And so in that case the return value is going to be wait time out,
let me grab that one and compare that to whatever we get from,
wait for single object so if we have a time out it means
that Notepad is still executing code.
Let me just write something to that effect.
Notepad is still running,
that's something I can say for sure at least at that
point in time maybe a millisecond later,
Notepad will be closed but at that point it's no longer my concern so to speak,
so let's see what that looks like when we run this.
I'm going to press control at five again to build and run this immediately.
You can see Notepad coming up and again we're in a wait state
here and if I wait those 10 seconds without closing Notepad
you'll notice that we get the output.
Notepad is still running which is exactly what we expect.
Let's close these aerial Notepad let's try this again.
But this time let's make sure we kill Notepad before 10 seconds have elapsed.
So here's another rand.
I'm going to kill Notepad now and we get immediately notified of the fact
that nobody has terminated with exit code of zero again because it just
ended normally and there are other APIs we can use,
there is in fact a very big list of APIs we can use that all have the first
parameter as the handle to the process in question where we can find more
details about the process or do stuff with the process of course once it dies
in the sense that doesn't run anymore, code there's not a lot we can do,
we can grab the exit code which is definitely something that could be useful.
You can also call a function called get processed times that
returns the creation and exit time of the process and its
user time and current time usage.
So there's something might want to try out and see what that looks like.
You might also be wondering what would happen if I called get exit code
process in the case where not but is still running,
what would happen in this case you might imagine that this function would
probably fail because the process is still running however,
it actually doesn't fail and return a particular value which has
the value still active so you're going to get back still active
which has happens to have a value 259.
If I press F 12 here we can see that it has another macro defining it,
which is normally used by kernel code called status
spending which is the same thing.
You can see the value here is 103 hex which is indeed 259 so it is possible
to call get exit code process but it perhaps doesn't make much sense to do
that while we're trying to do something like this.
Now obviously once we close the handle to the process,
that's it, we can't access that process anymore.
Using that handle,
the handle is now a garbage handle and any API we call on it will will likely
fail because now that handle entry is going to be empty,
not pointing to anything anymore,
so we need to be careful not to close handles prematurely
before we actually done what we set out to do.