Code Injection
Code injection is a technique where you can insert code into a process and then reroute its execution to traverse through your injected custom code segment.
Working from a debugger eg. OllyDbg, we can search for “code caves”, ie. sequences of nop (or "DB 00" in Olly) instructions that are large enough to "fit" our custom code.
Alternatively we can also allocate more memory in the target process to store the code. This is what we will do in this case.
One of the best ways to inject code is via dlls, because they are meant to be loaded by multiple processes at runtime.
Compulsory ingredients:
- injector process -
DLLInjector
project - the process that will "inject" the code, - the process to inject -
ProcessToInject
project - the process that will "receive" the code, - the dll to inject -
dllToInject
project - The "code".
Now the injector will grab the dll and inject it into the process to call custom code.
The discovery of memory addresses of certain API functions, such as LoadLibrary
and VirtualAlloc
is crucial. Those will be discovered in shared (or dynamic) libraries, such as Kernel32.dll or ntddl.dll which are used by almost all windows processes; certainly the user processes that we will be targeting here. These functions will be used to inject the dll into the target process' address space and call its entry point DllMain
.
Steps that DLLInjector has to perform:
- Get the process id of your target process of choice. Supply its pid manually, or use GetProcessId , or use
GetWindowThreadProcessId
- Access the process with appropriate permissions and get its handle.
OpenProcess
- Allocate sufficient memory inside the process to store the code.
VirtualAllocEx
- Write the dll into that memory.
WriteProcessMemory
- Create a remote thread, which I call
hLoaderThread
in the code, to execute the dll's code.CreateRemoteThread
- first gets the address of "LoadLibraryA" (do NOT be tempted to write the Unicode variant here
LoadLibraryW
! - it won't work!) function to use for placing the dll.GetProcAddress
- it instructs the newly created thread to execute:
LoadLibraryW("dllToInject.dll")
and when it does the dll's main function, which contains our "custom code", will be automatically called upon injection.
- first gets the address of "LoadLibraryA" (do NOT be tempted to write the Unicode variant here
- Wait until the thread is done.
WaitForSingleObject
- Free the additional memory we allocated in the host process. VirtualFreeEx
Visual Demonstration:
For more information about windows libraries & dlls see here.
Github
Github repository link.