[Autogenerated] Let's create a tool to terminate the
process that we'd like to terminate.
It's very similar to the PS kill tool from the Sysinternals Sweet first.
Let me just change this solution into something more
appropriate like demos just by using rename here.
So now let's add another application to this same solution.
So we have everything here in the same um visuals to the
instance and create another console application.
Let's simply call that kill.
So the purpose of the ______ application is to
terminate the process given its process I.
D.
So we'll add the windows dot h header first and we'll add STD IO to display
stuff with print F Let's accept parameters in the command line.
So these parameters should be the well in fact just a
single parameter should be the process I.
D.
That we'd like to terminate.
So let's check first that we have enough arguments.
If we don't have enough arguments,
then we can just specify that the usage for this application is killed.
With the process idea,
you might want to add an option to search for a process name
but leave that for you as an exercise.
So now that we have the process IDE provided as a parameter, we can now use it.
And the first thing to do is to open a handle to the
process that is powerful enough.
Earlier we use the function create process create process creates a brand new
process based on some image but now it's a different scenario.
We want to terminate an existing process create process is not the function to
use the function to use instead is open process which is the way to open a
handle to a process given two important parameters.
One of them is the access mask you'd like to use.
So what kind of operations would like to do with the process?
And then of course the process I did to identify the process in question.
So the first option here is the access mask and this is where I have to
specify process terminate in order for this to have any potential chance of
succeeding because the terminal process API which we call later guarantees or
requires in fact that you have this access mask without it it would simply
fail with an error of access denied.
The second parameter has to do with handle inheritance which is not
interesting for the purpose of this demonstration.
And then of course we have to get the process the process I.
D.
From the command line by using the simple A.
To I function to convert the ask a stream to the integer which is the process I.
D.
If that fails then of course we have some error on our
hands which means we cannot terminate the process for
whatever reason of course get lost.
L might give us a hint as to why this can't work.
So I'm going to do that if it returns now.
Otherwise we have a proper handle to the process we can go ahead and call the
terminate process API and then we need to provide the handle to the process of
course and we need to force some exit code to to happen because now the process
doesn't get a chance to exit normally.
So we are going to be the ones determining the exit code for the process.
Just for fun.
Let's just use 100.
You can of course get that from the command line as well and if that succeeds,
which it should because we do have a proper handle.
Let's just say success.
Otherwise there is some error which is unlikely to happen
but still uh let's just display error once again and use
exactly the same code as before.
Finally to be a good citizens.
We're going to close the handle to the process.
Not super critical in this simple example because we're about to
get out of the process and so the handle will be closed anyway
but let's just do that uh to get used to doing the right thing
and that's essentially it.
Let's see what happens here.
Let me build that it's built and I want to specify
parameters to terminate some process.
So we have a note that here we can take advantage of
which is my usual sort of Guinea Pig.
So let's go to kill and go to properties select the X- 64 version.
I'm going to run like the debug build here and specify
the parameters to the command line.
Going to task manager oppression pressing control shift,
shift, escape we can look up Notepad here,
we can see the P A DS 18 0 12 So let's just provide
that thing here as a parameter.
So once we do that I'm going to rightly can set this
project as the startup project and run this.
Let's see what happens here.
Once we run this application called kill.
So this point open process hasn't executed just yet,
which is an opportunity for me to open process Explorer here,
look for our kill application here and switch the bottom view to handle
view because now we expect a handle to the process of Notepad to be
available if indeed the succeeds or perhaps not.
So let's see let's press F 10 we can see we get a proper handle,
we can see the handler has the value 64 hex and it's pointing
to exactly are Notepad process and also notice that you have
determinate access mask here, which is exactly what we ask for,
which means it's exactly what we got in this case.
So we have that thing to work with and so all that's left to do now is
to move forward and call the terminate process A P R.
So here we're about to call terminate process,
it returns true on success or false if it fails.
Let's see what happens here and it seems to have succeeded.
In fact you can see that Notepad Well note that is essentially gone.
Now I think it's actually because it's being debugged.
We get a break point here, right when the process exits.
Let's just do go here.
And technically Notepad is in fact gone and we still have
a handle to the process which is fine.
So the data structure in the current in fact is still very much alive but
the process is not running anymore code so you can see there's one handle
that we're holding to the process object and that's exactly this one handle
right here that we have right here.
So at this point there's been nothing else for us to do except continue running.
And then we're going to close the handle which will make the
handle here and disappear from my handle table.
And the process is now completely gone.
And that's it.
We managed to perform this nice feet but let's try something else.
Let's try something like the CsRS s process here with the processor.
D 808.
So let's go to the properties again and change here the
commander and arguments to 8008 and see what we get.
So let's click OK and press F five again.
So we get to the same location.
Try to open a handle to the process with a particular process I.
D.
And here is our kill process.
Let's go here.
The handle should appear here.
If successful.
So in this case you'll notice that handle returns as null which means we failed.
We couldn't get a powerful enough handle uh with the terminate access
to the CSR CSS process with the prostate G 808 and if we go to the
other we can of course look at the output,
we can just go to the watch window, we can see that the area is number five,
this is just a number five here, that in fact is access denied.
And so in this case the CSR sales process is very well
protected and we can't open a powerful handle enough to
kill the process in a forceful way.
So you might think maybe if we run this Visual Studio instance
or the application from an elevated command window or from an
elevated Visual Studio instance,
maybe we'll have more power and indeed we do have more power in that in that
case but still won't be able to to terminate any CSR says instance and that's
because these are says is a protected process,
which we'll discuss in the next module.
So in general we can use this tool here to terminate any process for which we
can get a handle powerful enough which may or may not work.
This is the way to try it.
If I ask for something else, then that's bound to fail for sure.
So if I try to ask for something like process query information,
which is yet another um access mask.
We can ask in order for us to gain more insight into
a process then terminate process.
Even if the handle is successfully obtained tenure process will not work because
the handle is not appropriate for what we're trying to do.
Let's give it a shot anyway, let me select something like perhaps Explorer.
So Explorer here had a bunch of instances here,
let's select the one with the value 2900 seems to be easy number to remember.
Let's try this again.
So I'm going to do F five here to run this again and to try to open the
handle to the process and you can see it succeed to get back a proper
handle to the process which has a value of eight.
We can see that in process Explorer as well.
Here's the value of eight.
It's pointing to the process in question but notice the
access mask is query information,
query limited information which is in fact implied by query information.
Let me move forward now and try to use terminate process.
You can see it fails,
terminate process here fails and the error here
indicates that access denied again.
That's not because the process is not something we can access,
but because we didn't ask for the right permissions,
we asked for process information.
But unfortunately,
tenant process looks for process terminate access mask
and sees the handle doesn't have it.
The function cannot really succeed and we're going to get
the same kind of error of access denied.
The handle in this case is not powerful enough or doesn't
contain the appropriate handle access mask in order for the
terminate process called to succeed.