Archives For Gamehacking

Articles, news, links, tips, snippets, releases and gamehacking tutorials.

C++ Basic DLL Injection Tutorial

March 12, 2008 by Asbra — Leave a comment

This is a repost from my old gamehacking blog ilsken.net

First we open a handle to the target process

*proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);

Get the memory address of LoadLibrary, Windows API function that loads DLL files from disk

void* loadlib = GetProcAddress(GetModuleHandle(kernel32), loadlibrary);

Allocate memory in the process where we will store the string with path to our DLL file

void* alloc = VirtualAllocEx(*proc, 0, strlen(dll), MEM_COMMIT, 4);

Write the string that holds DLL file path to target process memory

BOOL wrote = WriteProcessMemory(*proc, alloc, dll, strlen(dll), NULL);

Create a thread in the remote (target) process, with start address of LoadLibrary, so it executes LoadLibrary function and give it the memory address of our DLL path string, so it loads it

HANDLE thread = CreateRemoteThread(*proc, 0, 0, (LPTHREAD_START_ROUTINE)loadlib, alloc, 0, 0);

Wait for the thread to finish

WaitForSingleObject(thread, 10000);

Finally, do some cleaning up

CloseHandle(thread);
VirtualFreeEx(*proc, alloc, 0, MEM_RELEASE);
void enable_debug_priv()
{
	HANDLE hToken;
	LUID luid;
	TOKEN_PRIVILEGES tkp;

	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

	LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);

	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Luid = luid;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	AdjustTokenPrivileges(hToken, false, &tkp, sizeof(tkp), NULL, NULL);

	CloseHandle(hToken); 
}

DWORD get_process_id(char* imagename)
{
	PROCESSENTRY32 entry;
	entry.dwSize = sizeof(PROCESSENTRY32);

	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

	if(Process32First(snapshot, &entry))
		while(Process32Next(snapshot, &entry))
			if(strcmp(entry.szExeFile, imagename) == 0)
				return entry.th32ProcessID;

	CloseHandle(snapshot);

	return 0;
}

DWORD get_module_handle(DWORD proc_id, char* module)
{
	char dll[64] = {0};
	MODULEENTRY32 entry;
	entry.dwSize = sizeof(MODULEENTRY32);

	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, proc_id);
	if(snapshot == INVALID_HANDLE_VALUE)
		return 0;

	if(Module32First(snapshot, &entry))
	{
		do
		{
			if(entry.th32ProcessID == proc_id)
			{
				memset(dll, 0, 64);

				for(int i = 0; i < strlen(entry.szModule); i++) {
					dll[i] = tolower(entry.szModule[i]);
				}

				if(strcmp(dll, module) == 0)
					return (DWORD)entry.modBaseAddr;
			}
		}
		while(Module32Next(snapshot, &entry));
	}

	CloseHandle(snapshot);

	return 0;
}

int inject(DWORD proc_id, char* dll, HANDLE* proc)
{
	*proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
	if(*proc == NULL)
		return 1;
	
	void* loadlib = GetProcAddress(GetModuleHandle(kernel32), loadlibrary);

	void* alloc = VirtualAllocEx(*proc, 0, strlen(dll), MEM_COMMIT, 4);
	if(!alloc)
		return 2;

	BOOL wrote = WriteProcessMemory(*proc, alloc, dll, strlen(dll), NULL);
	if(!wrote)
		return 3;

	HANDLE thread = CreateRemoteThread(*proc, 0, 0, (LPTHREAD_START_ROUTINE)loadlib, alloc, 0, 0);
	if(!thread)
		return 4;

	WaitForSingleObject(thread, 10000);

	CloseHandle(thread);

	VirtualFreeEx(*proc, alloc, 0, MEM_RELEASE);
	
	return 0;
}