Code Injection is a process of injection code (often malicious) into third party application’s memory. A lot of software is using this technique: from malware to game bots. To show this approach, let’s try to execute third party application’s internal function with our own parameters, hacking simple application. Warning, C and debugger knowledge are required!
Primary skill is, obviously, C lang. Also it’s required to be familiar with WinApi, x86 assembler and application debugging with OllyDBG or any similar Windows debugger.
Why do we need it?
Let me give you a quick example. Let’s say we have a game bot, that automates playing for us. It collects game data, analyses it and based on it’s algorithms, takes decisions who and how to attack. After this bot attacks enemy.
It this case bot’s steps will be:
- Find unique enemy’s ID (
- Decide, what type of attack to use (
- Attack enemy in game, based on calculated
Actually the last step (attack itself) should call function
attackEnemy with calculated params:
The problem is by default game client doesn’t provide any public API to call it’s internal function
attackEnemy — it’s in-game functionality and can be performed only by authorised game client. So the only way to emit in-game function from “external” world is to perform Code Injection.
DLL Injection VS DLL Hijacking VS Code Injection
Though these terms are quite similar, it’s extremely important to understand the difference between them:
- DLL Hijacking — is a process of replacement app’s original DLL’s with our ones. The key idea is to place malicious DLL aside with application. If the app is vulnerable, it will load our DLL instead of it’s own and execute our code. Completely differs from DLL/Code Injection, though sounds practically the same.
- Code Injection — is a process of code injection into memory of vulnerable app for it’s further execution.
- DLL Injection — is a process of loading own DLL into memory of vulnerable app’s process. Often way simpler than Code Injection and commonly used. But in hard cases you still need to use way more complex Code Injection technique. That’s why it’s better to know about both of them.
Writing test app
Our test app will be pretty simple. After pressing Enter key, it just prints data from buffer. Data is hardcoded, stored in memory and does not change anywhere. So every time you hit Enter, app will print “default message” and nothing else.
void PrintMessage(char *buffer);
char *buffer = "default message";
void PrintMessage(char *buffer)
But will it? Let’s try to hack our app and make it print something else without modifying binaries.
Debugging our app
First of all we need to find addresses and functions. As it said before, we’ll use OllyDbg. We’re seeking for
PrintMessage() function. There are plenty of ways to find one particular function in debugger. I’ll describe the simplest one.
- Press Step Over (F8). At this moment debugger starts to iterate over instructions. When it stops on CALL or JMP, go to it (press Enter) and immediately place breakpoint (F2).
- Restart debug (Ctrl + F2) and press Step Over (F8) again. This time debugger will jump over previous CALL/JUMP, but will catch the next one. Place new breakpoint again.
- Repeat these steps until you find
getchar()call. This call is inside
main()function just before
PrintMessage()call. Thats what we need!
In my case I’ve got
0x001613C0 address for
PrintMessage() function call. Obviously, you’ll get the different one. There also can be dome differences in assembler code. The one I’ve got is shown at figure 2.