Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > Coding Releases > Coding Snippets
You last visited: Today at 22:14

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[C/C++] Injection - the other way

Discussion on [C/C++] Injection - the other way within the Coding Snippets forum part of the Coding Releases category.

Reply
 
Old   #1
 
XxharCs's Avatar
 
elite*gold: 34
Join Date: Apr 2011
Posts: 1,475
Received Thanks: 1,228
[C/C++] Injection - the other way

Hello!

Today i will share with you an injection technique which could be really powerfull. The injection technique is called: PE Injection.

It allows you to inject code directly in other processes.
It works by allocating the executable memory in the target process, relocate the image of the injector process, and then write the relocated image into the target process. Finally the created remote thread will execute your code.

Lets summarize:
The injector write his own image into another process, and a remote thread is created to execute the injected code.
=================================

I commented as much as i could (with a comment or an output), cause I'm using NT functions and most of them aren't documented


main.h
Code:
#ifndef __MAIN_H__
#define __MAIN_H__

#define NT_SUCCESS(x) ((x) >= 0)

/* The CLIENT_ID structure contains identifiers of a process and a thread */
typedef struct _CLIENT_ID
{
    PVOID UniqueProcess;
    PVOID UniqueThread;
} CLIENT_ID,*PCLIENT_ID;

/* The UNICODE_STRING structure is used to pass Unicode strings */
typedef struct _UNICODE_STRING
{
	USHORT Length;
	USHORT MaximumLength;
	PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

/* MSDN-Quote:
   The OBJECT_ATTRIBUTES structure specifies attributes that can be applied to objects or object handles by routines 
   that create objects and/or return handles to objects.
   Use the InitializeObjectAttributes macro to initialize the members of the OBJECT_ATTRIBUTES structure. 
   Note that InitializeObjectAttributes initializes the SecurityQualityOfService member to NULL. If you must specify a non-NULL value, 
   set the SecurityQualityOfService member after initialization */
typedef struct _OBJECT_ATTRIBUTES 
{
	ULONG           Length;
	HANDLE          RootDirectory;
	PUNICODE_STRING ObjectName;
	ULONG           Attributes;
	PVOID           SecurityDescriptor;
	PVOID           SecurityQualityOfService;
}  OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

#define InitializeObjectAttributes(p, n, a, r, s) \
{ \
	(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
	(p)->RootDirectory = r; \
	(p)->Attributes = a; \
	(p)->ObjectName = n; \
	(p)->SecurityDescriptor = s; \
	(p)->SecurityQualityOfService = NULL; \
}

typedef NTSTATUS (NTAPI *_RtlCreateUserThread)(HANDLE ProcessHandle, PSECURITY_DESCRIPTOR SecurityDescriptor, BOOLEAN CreateSuspended, ULONG StackZeroBits, PULONG StackReserved, PULONG StackCommit, PVOID StartAddress, PVOID StartParameter, PHANDLE ThreadHandle, PCLIENT_ID ClientID);
typedef PIMAGE_NT_HEADERS (NTAPI *_RtlImageNtHeader)(PVOID ModuleAddress);
typedef NTSTATUS (NTAPI *_RtlAdjustPrivilege)(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled);
typedef NTSTATUS (NTAPI *_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientID);
typedef NTSTATUS (NTAPI *_NtWriteVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten);
typedef NTSTATUS (NTAPI *_NtClose)(HANDLE ObjectHandle);
typedef NTSTATUS (NTAPI *_NtWaitForSingleObject)(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout);

/* Returns the process id of the specified process name */
DWORD GetProcID(std::string ProcName);
/* Function we gonna inject in a process */
DWORD WINAPI FuncThread(LPVOID unused);
/* Check if the specified process is running/existing */
BOOL ProcessExists(std::string process);
/* Returns the address of the specified library */
PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName);
///----------------------------------------------------------------------///

#endif
main.cpp
Code:
#include <Windows.h>
#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <conio.h>
#include <tlhelp32.h>
#include "main.h"

//---------------------------------------------------------------------------------------------------------------------------------------------------//

int main(int argc, char **argv)
{
	PIMAGE_NT_HEADERS pINH;
	PIMAGE_DATA_DIRECTORY pIDD;
	PIMAGE_BASE_RELOCATION pIBR;

	HMODULE hModule;
	HANDLE hProcess, hThread;
	PVOID image, mem;
	DWORD i, count, nSizeOfImage;
	DWORD_PTR delta, OldDelta;
	LPWORD list;
	PDWORD_PTR p;
	BOOLEAN enabled;
	NTSTATUS status;

	OBJECT_ATTRIBUTES objAttr;
	CLIENT_ID cID;

	DWORD dwPid = 0;

	SetConsoleTitleA("PE Injection by XxharCs");

	if(argc != 2)
	{
		std::cout << "Usage: PEInjection.exe [process_name]\n";
		_getch();
		return 1;
	}

	// Loading needed libraries
	_RtlCreateUserThread RtlCreateUserThread = (_RtlCreateUserThread)GetLibraryProcAddress("ntdll.dll", "RtlCreateUserThread");
	_RtlImageNtHeader RtlImageNtHeader = (_RtlImageNtHeader)GetLibraryProcAddress("ntdll.dll", "RtlImageNtHeader");
	_RtlAdjustPrivilege RtlAdjustPrivilege = (_RtlAdjustPrivilege)GetLibraryProcAddress("ntdll.dll", "RtlAdjustPrivilege");
	_NtOpenProcess NtOpenProcess = (_NtOpenProcess)GetLibraryProcAddress("ntdll.dll", "NtOpenProcess");
	_NtWriteVirtualMemory NtWriteVirtualMemory = (_NtWriteVirtualMemory)GetLibraryProcAddress("ntdll.dll", "NtWriteVirtualMemory");
	_NtClose NtClose = (_NtClose)GetLibraryProcAddress("ntdll.dll", "NtClose");
	_NtWaitForSingleObject NtWaitForSingleObject = (_NtWaitForSingleObject)GetLibraryProcAddress("ntdll.dll", "NtWaitForSingleObject");


	std::cout << "Waiting for the process...\n\n";
	while (!ProcessExists(argv[1])){ }
	dwPid = GetProcID(argv[1]);


	RtlAdjustPrivilege(20, TRUE, FALSE, &enabled);

	hModule = GetModuleHandle(NULL);
	pINH = RtlImageNtHeader(hModule);
	nSizeOfImage = pINH->OptionalHeader.SizeOfImage;

	InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);

	cID.UniqueProcess = (PVOID)dwPid;
	cID.UniqueThread = 0;

	std::cout << "Opening target process handle...\n";
	// Opening target process handle
	if(!NT_SUCCESS(status = NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &objAttr, &cID)))
	{
		std::cout << "Error: Unable to open target process handle. NtOpenProcess failed with status: " << status << "\n";

		_getch();
		return 1;
	}

	std::cout << "Successfully opened target process handle!\n";


	std::cout << "Allocating memory in the target process...\n";
	// Allocating memory in the target process
	mem = VirtualAllocEx(hProcess, NULL, nSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

	if(mem == NULL)
	{
		std::cout << "Error: Unable to allocate memory in the target process. " << GetLastError() << "\n";
		NtClose(hProcess);

		_getch();
		return 1;
	}

	std::cout << "Memory allocated. Address: 0x" << mem <<"\n";

	// Image relocation - start
	image = VirtualAlloc(NULL, nSizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

	memcpy(image, hModule, nSizeOfImage);

	pIDD = &pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
	pIBR = (PIMAGE_BASE_RELOCATION)((LPBYTE)image + pIDD->VirtualAddress);

	delta = (DWORD_PTR)((LPBYTE)mem - pINH->OptionalHeader.ImageBase);
	OldDelta = (DWORD_PTR)((LPBYTE)hModule - pINH->OptionalHeader.ImageBase);

	while(pIBR->VirtualAddress !=0)
	{
		if(pIBR->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))
		{
			count = (pIBR->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
			list = (LPWORD)((LPBYTE)pIBR + sizeof(IMAGE_BASE_RELOCATION));

			for(i=0; i<count; i++)
			{
				if(list[i] > 0)
				{
					p = (PDWORD_PTR)((LPBYTE)image + (pIBR->VirtualAddress + (0x0fff & (list[i]))));

					*p -= OldDelta;
					*p += delta;
				}
			}
		}

		pIBR = (PIMAGE_BASE_RELOCATION)((LPBYTE)pIBR + pIBR->SizeOfBlock);
	}
	// Image relocation - end

	std::cout << "Writing executable image into target process...\n";
	// Writing executable image into target process
	if(!NT_SUCCESS(status = NtWriteVirtualMemory(hProcess, mem, image, nSizeOfImage, NULL)))
	{
		std::cout << "Error: Unable to write executable image into target process. NtWriteVirtualMemory failed with status: " << status << "\n";
		VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
		NtClose(hProcess);
		VirtualFree(mem, 0, MEM_RELEASE);

		_getch();
		return 1;
	}

	std::cout << "Executable image successfully written to target process!\n";

	std::cout << "Creating remote thread in target process...\n";
	// Creating remote thread in target process
	if(!NT_SUCCESS(status = RtlCreateUserThread(hProcess, NULL, FALSE, 0, 0, 0,(PVOID)((LPBYTE)mem + (DWORD_PTR)(LPBYTE)FuncThread - (LPBYTE)hModule), NULL, &hThread, NULL)))
	{
		std::cout << "Error: Unable to create remote thread in target process. RtlCreateUserThread failed with status: " << status << "\n";
		VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
		NtClose(hProcess);
		VirtualFree(image, 0, MEM_RELEASE);

		_getch();
		return 1;
	}

	std::cout << "Thread successfully created! Waiting for the thread to terminate...\n";
	NtWaitForSingleObject(hThread, FALSE, NULL);

	std::cout << "Thread terminated!\n";
	NtClose(hThread);

	std::cout << "Freeing allocated memory...\n";
	VirtualFreeEx(hProcess, mem, 0, MEM_RELEASE);
	NtClose(hProcess);
	VirtualFree(image, 0, MEM_RELEASE);

	std::cout << "Allocated memory is free!\n";
	
	_getch();
	return 0;
}

DWORD WINAPI FuncThread(LPVOID unused)
{
	MessageBoxA(NULL, "Wuhu, i'm inside the other process!!!!!", "1337 h4xX0r", MB_OK);
	
	Sleep(10);

	ExitThread(0);
	return 0;
}

DWORD GetProcID(std::string ProcName)
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pe32.dwSize = sizeof(PROCESSENTRY32);
	do{
		if(strcmp(pe32.szExeFile,ProcName.c_str()) == 0)
		{
            DWORD ProcId = pe32.th32ProcessID;
            CloseHandle(hProcessSnap);
            return ProcId;
		}
	} 
	while(Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
    return 0;
}

BOOL ProcessExists(std::string process)
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    pe32.dwSize = sizeof(PROCESSENTRY32);
	do{
		if(strcmp(pe32.szExeFile,process.c_str()) == 0)
		{
            CloseHandle(hProcessSnap);
            return true;
		}
	} 
	while(Process32Next(hProcessSnap, &pe32));

    CloseHandle(hProcessSnap);
    return false;
}

PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
{
	return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
}
Have Fun!
XxharCs is offline  
Thanks
13 Users
Reply


Similar Threads Similar Threads
.dll Injection?
10/09/2013 - Metin2 Private Server - 6 Replies
Is there a public method to block the .dll injection in the game client executable?
Injection How To
03/05/2011 - General Gaming Discussion - 17 Replies
1.) Wo kriege ich Injection her? -> http://injection.sourceforge.net/ 2.) Knallt euch dann alles in ein Verzeichnis, besorgt euch dann einne der supporteten Clients (steht in der ilpatch.cfg) 3.) Decrypted diesen Client mit UORice -> http://stud4.tuwien.ac.at/~e9425109/UO_RICE.htm
SQL injection
12/25/2009 - Silkroad Online - 19 Replies
can someone please tell me how, or give me a site that can teach me how to perform SQL injection? it will be greatly appericated.
DLL Injection
06/12/2007 - Planetside - 2 Replies
???



All times are GMT +1. The time now is 22:14.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.