We all know that we try to do those things that we are barred from… J A normal human tendency! Or maybe a weird human tendency!
So let's first put down what we want to achieve:
- We want a way to inject some code in a process (of course I am not talking about our own process).
- How do we make it execute?
One line answers:
- We can load a DLL in the process to inject the code.
- We need to create a thread which will execute that piece of code.
Let's enumerate as to what we have that we can make use of:
- CreateRemoteThread API to create a thread in a process.
- LoadLibrary API to load a DLL.
CreateRemoteThread has a parameter which takes the address of the function to be executed when the thread starts. Can we somehow combine points 1 & 2 enumerated above? Yes, we can pass the address of LoadLibrary in CreateRemoteThread. But there is a catch! Don't just write LoadLibrary in the following manner:
CreateRemoteThread( …, LoadLibrary, …);
This is incorrect. You need to get the address of LoadLibrary in kernel32.dll using GetProcAddress and pass that address in CreateRemoteThread.
Next step is to tell LoadLibrary the name of the DLL which needs to be loaded. But remember one thing, you can't use a string allocated in your process in the process where the DLL needs to be loaded. So you need to allocate memory in the target process using VirtualAllocEx. And then copy the path of the DLL in the allocated space using WriteProcessMemory.
Upto this point we have discussed how to inject the code; by using CreateRemoteThread, LoadLibrary, GetProcAddress, VirtualAllocEx and WriteProcessMemory.
But where should we place the code in the DLL so that it gets executed? Afterall if you make some functions in DLL and export them, the target process will not call them anyways. Let's think of the first function that gets called in the DLL when it is loaded. It is DllMain with notification type DLL_PROCESS_ATTACH. You can place the code to be executed in DllMain under the case for DLL_PROCESS_ATTACH.
Simple! Isn't it? But this method faces a problem in Vista. This is because the CreateRemoteThread API does not work across sessions. So all process that run in a different session cannot be targeted using this method.