well, lets start off by saying that there are many many different ways of injecting into a program. The methods covered here are just one of the popular or most used. I will also not be responsible for any damages this could cause, things like injecting into system programs or just making a virus. Note that i do not recommend making programs with ill intents or just being dumb with this. Alright, lets move on to the article
What Is Injection?
My definition of injection is basically a way to run your own codes in someone’s else program. This can be used in many many ways, cheats, viruses, heck even anti viruses and anti cheat. There can be many reasons why someone would like to run their own code in another program. For example, anti cheats does this to monitor and hook onto some APIs. Things like CreateThread to check for any new threads created and checking their start addresses. Other things such as trying to create a virus or a cheat, cheats usually just try to rpm and wpm inside a game and even hook onto direct x to draw their own things like ESP and so on. Viruses can use this to hide themselves or just abuse programs such as the system’s program. Remember that once injected, you will be part of the program. Meaning, calling APIs such as GetCurrentProcessId will return the injected process’s PID. Since you are inside the program and somewhat part of it, you can hook onto some parts or do basically anything you like. This is why Anti Cheats tries so hard to not make it easy to inject into their programs, once inside or injected, game over.
Detection / Defense?
There is no easy way of detecting a injection. Like i mentioned before, there are many ways of injecting into a program and trying to catch them all or detect them will take forever. There will also always be new injection methods being discovered, making detecting it harder. One of the best way is just to make it harder globally, rather then focusing. Notice how i said harder. Personally, defending injections globally ( all processes ) is basically almost close to impossible ( and dumb ). However, protecting curtain programs ( system program, games or even your own programs ) is not too hard. Things like Hooking onto CreateThread and knowing all created processes and they start addresses to check if they are loaded outside the module can be helpful. Other things like only accepting Digitally Signed DLLs would also help ( WinVerifyTrust ), you can do this to only to DLLs injected using the standard methods ( LoadLibrary Native Injection ). Other things like manual map, will just fly over the radar. Other things like using CbRegisterCallback ( Kernel API ) to deny handle access will make it extremely hard to inject. Note that there are ways to injecting without a need of a handle or obtaining a handle. You can also use Packers / Encryptors. Programs like VMProtect or others, which protects the program from standard injections. Using those can also make it quite hard to reverse engineer the program. Runtime Checksum also helps.
- CreateRemoteThread + LoadLibrary
- Process Hollowing
- APC Injection
- Thread Hijacking
Don’t forget that there are many other ways to inject. These are just afew.
Create Remote Thread + LoadLibrary ( Standard )
This is the most standard way of injecting and the most easiest method to detect or defend against. The method is as easy as getting a handle to the program ( Full Access would be great, but Query limited information, VM operation, VM read, VM write can work ), getting the address of LoadLibraryA inside kernel.dll ( GetProcAddress and GetModuleHandle ), allocating space in the process for the DLL’s path ( VirtualAllocEx ), writing the DLL’s path name in the allocated space ( WriteProcessMemory ) and finally calling CreateRemoteThread, making a thread in the process which then calls LoadLibraryA with the perimeter of your DLL path. Easy isn’t it? Well, if you plan to make a stealthy injection, this will not work. People can easily list the modules inside their program and find that there is an extra or new module.
As the name suggests, it basically “hollows” the process and runs your own code instead. The easiest way of doing this is by using the API called CreateProcess ( Suspend Flag: CREATE_SUSPENDED ), why? This makes it easy to suspend the program. You can also try to do it another way, but just make sure it is suspended. After this, you need to unmap some sections and contents and change it to your own. Use ZwUnmapViewOfSection/NtUnmapViewOfSection to do so. After it is unmapped, allocate new memory ( VirtualAllocEx ) and write onto it ( WriteProcessMemory ). Simple enough. However, this definitely makes it much harder to detect then the LoadLibrary method, but this is not that stealthy, packers and such and avoid this by things like Runtime Checksum. Hollowing a program out is also not really that recommended. Other then that, this is a decent way of injecting.
This is somewhat a weird method. So, first of all, APC stands for Asynchronous Procedure Calls. So to understand how this is abuse able, lets see how it works. So, usually, in a program / thread, there are usually a list of APCs which are basically waiting to get ran. This should set off some red flags. Now imagine being able to be in one of those list and being able to run your own code. Well, this is possible. First of all, you need to find a thread which is actually using functions like SleepEx or even SignalObjectAndWait ( There are more functions which allows the program to run or go through some of the APC ). Once you get one thread, you will have to use OpenThread ( Opens an existing thread object ) and queue a APC ( QueueUserAPC ). Usually, i find malware calling LoadLibraryA and passing their DLL path to it. This usually works, but not that stealthy. This is usually done by Rootkits or drivers.
I only see this method being used when the process has a way to check for new threads. Hijacking a thread would just bypass any create thread callbacks. To start off, this isn’t really easy to pull off. Some programs are smart enough to add dummy threads or just hide their main threads. There are also many ways of hijacking a thread, i will share the common one. Find a thread to hijack, allocate some memory in the process ( VirtualAllocEx ), open a thread handle ( OpenThread ), suspend the thread ( SuspendThread ), get thread context ( GetThreadContext ), allocate some memory ( VirtualAlloc ), “inject” your shellcode by writing to the allocated memory ( WriteProcessMemory ) then resume the thread ( ResumeThread ). This is quite simple and effective.
Manual map is basically just making your own loader. Making your own LoadLibraryA, making your own loader makes it so that your DLL would not be able to be detected normally. This makes it extremely hard to get detected if done right.
Hooking onto the import address table is very effective. Imagine being able to execute your code each time they call a curtain API. You can basically hook onto some functions and let your own code be executed whenever that function is called in your target process. Each process has their own IAT. Meaning you will still have to find a way to get a handle and so on.
Well, there are many ways of injecting and detecting it. But in the end, its just a cat and mouse game. Who does what first. Well, hopefully you learn something new, and use this knowledge to do something better! See you around.