[Autogenerated] Let's now create a new C++ project
to perform the actual injection.
I'm going to use a console application and call
that injector seems fitting here.
I'm going to remove all the boilerplate that I don't care about provided
here and use the normal includes for Windows and S T D I O.
So what what do you want to do here?
Want to accept a process I.
D.
In the command line and a DLL path and then do the injection to whatever
process we get here to the DLL provided on the command line.
So we need three parameters here.
Right.
Actually two parameters but the third one is the excusable name so if we have
not enough parameters to go around we can use a simple usage here indicating
that we need to provide injector with the process I.
D.
And the DLL path.
That's what we need.
Okay, what would be our first step?
The first step is to open the handle to the Tiger process.
If we can actually inject anything to it to begin with and for
that we're going to use the normal open process API the key here
is to ask for the correct access mask.
Now because we want to be able to write some data into the process and
through space that would be the path for the target.
DLL must have the process VM right permission here,
the access mask that we need but that's not enough.
We also need to allocate memory in the target process and for that we'll
need process VM operation and even that is not enough because we plan to
inject a thread into the target process,
that would be the one loading the DLL,
which means that we also need the process create thread access mask.
That should be good enough.
If we can get those kinds of access to a process of our choosing,
then there's a chance for the rest of these operations to work.
So we just need the process A D here,
which we're going to grab as the first parameter from the command line,
which means what we get from our V one here.
If that fails for whatever reason of course we have an error on our hands.
Just going to use a simple error function here to report
that so failed or error in opening process,
I'm going to call this function error.
Let me write that word quickly.
So what I want to provide here is the text to display
some text and then use some error code,
which I'm going to just default to whatever get last
error has to say the last error.
Return from the last API I'm just going to display here using simple print f
providing the string and then the error in parenthesis.
So have some text here and whatever error is and return one here
that will make it easier to get out of the process.
So if that works as we expect we need to call the create a remote
threat function but before we do that we have to prepare the path
to the DLL in the target process.
So for that we have to allocate some memory in the target process.
And this is where the virtual I'll e X function comes in.
This is an extension extended version of the normal virtual
I'll API that has an additional parameter,
which is the target process for allocation.
So this is where age process comes in as the first parameter,
then I don't care what the address is going to be.
I need to have a size which is going to hold the path to the DLL.
So because everything is going to be rounded up to the next page,
a single page will be just good enough.
That's for kilobytes and then I'm going to reserve and commit that because
I need the memory that I can readily use immediately.
So reserve and commit and of course we'll be able to read and
write otherwise that wouldn't make any difference.
So if this fails,
for whatever reason it shouldn't really because as
we get the correct access mask,
the only way this could fail is if the system is really really,
really low on memory but just in case let's do the
right thing and called error here, say failed to allocate memory,
that's going to be good enough.
The next thing to do is to write the path to the DLL to the target process to
the buffer here and notice that this buffer is in fact in the other process
address space has no meaning in my address space,
which means that to write to this buffer I have to
use use the right process memory, API There's no other way to do that.
Here's again where I need the h process that has the process VM Right.
Access mask.
The base address to write is buffer.
That's the buffer in that other process address space and then
we have the buffer from our process to copy.
That's going to be whatever is in our V two that would be the path to the DLL
and the size is supposed to be the string length of that DLL.
So you can do DLL path really So string length of RGB two and
we have to add one for the null terminator.
Not strictly necessary because the page in its entirety is filled with zero.
This is part of the contract we get with men commit but still just to make
it a bit clearer and then the last parameter indicates how many bytes were
actually written and I don't care about those.
So now it's fine to say I don't care if this fails for whatever reason.
Again we can call our simple error function and say that we failed to
write to process once we have that we're almost ready to perform our
final trick which is creating a threat.
So I'm going to use the create remote threat function.
This is an extended version of the normal create read function we've
seen in the previous course in this series and again,
there's just one extra parameter there which is the handle to the
process where we'd like that threat to be created.
The problem with this call is that the address of the threat
has to be the address in the target process.
Not in our process.
So somehow we have to prepare the code in the other process to execute.
Now, fortunately the way we inject DLL into the other processes.
Using a simple trick.
And the trick is that a threat function accepts a
pointer to void and returns some number.
And the load library API also expects a pointer and returns some numbers.
So essentially from a binary perspective they're almost identical.
So what we want to do here,
we want to to tell the other threat that remote threat.
Please run the load library function then the parameter is
going to be provided by us pointing to that buffer where we
allocated that path to the DLL.
So how can we get that function?
The function is load library How do you know what load
library is in the other process?
And the answer is it's in the same address as it is in our process
because it's mapped to the same virtual address and there are a
couple of reasons for that and one of them will discuss in the
next clip related to address,
space law organization but even without SLR because we're talking
about the function from kernel 32 doe dealer.
It's going to be in the same address in every process.
That is a windows process.
So in order to get that we need to call the function get address And get
model handled here to get the handle to the Kernel 32.
Dll,
which is where load library is and then select the function
would like to get its address dynamically,
which is load library to be more precise.
It's not really load library because the library is not really a function.
It's actually a macro that expands to the A or W variant in
this case I need to select something I'm going to select a for
simplicity and that's because we have written and asked the
stream to the target process.
If you would have wanted to do something more perhaps correct in some sense.
For example you might want to use paths with much which might contain
unicode characters that are beyond what we can represent.
Would have to use load library W and for that we
have to make a few more changes,
such as changing the string here to be a unicode string but that's not enough.
We also have have to change main here to W main.
So the Lincoln and the sea ranch and pick up on that and
and send to us in the main function.
Unicode strings rather than just ask strings and now of
course eight y will not work either.
We have to work with W two I to actually convert unicode.
Utf 16 string to integer.
And then of course the str len here doesn't make sense.
Again now we have to use wcs land plus one but that's not enough
because this size is always in bite so we have to multiply by size of
white character which is just two bites.
That would make it correct.
So since I've done that already,
let's just keep using load library W here while we're at it.
And still the compiler is not very happy because the actual type
of get crocodiles is some generic pointer.
We have to make that lp thread start routine or something which is the
official type that thread function has for binary perspective is the same but
from the compiler perspective they're not the same.
And then the second key here is to provide a buffer value here,
that's the buffer in the other process where we've copied the
path to the DLS hopefully And that's about it.
Just 04 flags and we don't care about the Fred I.
D.
and just for fun again,
if we fail for whatever reason we can specify that we have an error here,
failed to create a thread and last we can wait for the threat to
complete the threat is supposed to load the library load the Dll
and then once we dismiss the message box,
the thread will die out but the dealer remains and that was exactly the point.
But for fun we can wait on the thread or not.
Doesn't really matter here.
And once we're done, we can close handles all that.
That's of course just being nice cases will just end our application here.
We shouldn't really care too much, but let's just do that for fun.
In this case we're also leaving the memory allocated in
the target process for the delay path.
That's for kilobyte.
Probably not too bad.
But it's possible to call the virtual free function to release even that
because now that the threat is done with its work,
that path is no longer actually needed.
So this is it.
Let's see if that works in the next clip.