πŸ’‘ SagaanTheEpic's Millin (Kernel )

Posts 1–4 of 4 Β· Page 1 of 1
πŸ’‘ SagaanTheEpic's Millin (Kernel )
SagaanTheEpic's Millin

Important:
First of all, credits goes to Zer0Mem0ry. He basically supplied the basic RPM and WPM which i had no time to do. The other people such as Daax and afew others who helped me quite abit. This source is basically to help people learning Kernel and just teaching people on how to make an external using a Driver.

My Goals:
My goals isnt to release a complete cheat ( if this gets enough support, i will ) but to make a cheat which VAC will find it difficult to detect. Things like using ObRegisterCallback and other things to isolate and making the cheat untouchable from a ring 3 Anti Cheat (VAC). A side note is that, i will try my best to hide the cheat and my main goal is to teach people on how to make a external cheat using a driver instead.

Extra:
Well, to start off. this isnt for people who dont know C++, you will need to know the basic and thats it. I will try my best to spoon feed the code and how to do everything, but i will not be covering the basic. If this is your first time starting on Kernel please visit google and search and research to understand what i am doing properly.

Download And Use ( For people who are looking to hack )

How To Use:

1) You will need to be in "Testmode", which is extremely easy, just opening CMD using admin and typing bcdedit /set TESTSIGNING ON ( only tested in Windows 7, use google for windows 10
and no, VAC doesnt check for test mode, not complaining )

2) After that, just load the Driver.

3) Open CS:GO

4) Go into a game

5) Open the Cheat

Features:
Bunnyhop
No Flash
Triggerbot (Left ALT)
Driver hiding ( Hides the driver from ring 3 programs, if you know what you are doing, use https://github.com/JKornev/hidden )


Download And Compile ( For people looking at the source )

Important:
Well, this section of the post is for people who are wanting to learn how the cheat works, this was my main goal, to teach people how to use drivers. This will require basic C++ and basic knowledge of Drivers. Other then that, enjoy!

Setup:
well, the most important thing you need is Windows Driver Kit. This basically allows you to program drivers. The other things you need is obvly microsoft visual studio and a Driver loader. Things like "NoVirusThanks Driver Loader" would be fine. This is important as Drivers isnt a normal program.It cant just be opened just by double clicking ( without extensions or external programs ).

How The Cheat Works:

Basic
Well, so there are two programs. One is a agent ( Usermode ) the other is a main guy ( Kernel Mode ). What basically happens is that the agent, basically sends requests towards the Driver which would take actions and send back some information. So when you Write, you are basically sending a request towards the Driver which then will call some functions such as MmCopyVirtualMemory and will return what that function has returned. Thats the basic of how the cheat would work.

Communications:
How the "agent" would communicate with the Driver would be just by using a function called DeviceIoControl. To use that function, you will need a HANDLE for the Driver by basically using a simple function called CreateFileA. After getting the Handle, you will need a "Code". This code will define what request you are making. If you were to lets say write, then you can make a code such as 0x712 or anything you like and define it like this.

Code:
#define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, /* Your Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
After this, you are all set in using DeviceIoControl.

How Does The Driver Get The Client Module:
The Driver uses PsSetLoadImageNotifyRoutine, this is basically a callback which will notify the Driver of any LoadedModules, Process ID Of it and the full directory of the module. My cheat Driver would be searching for "\\csgo\\bin\\client.dll" and if it finds it, it will take the Process ID of the program which has this and the Address. This address would then be returned to the usermode program ( the agent ).

Other Things You Can Add To Secure The Cheat:
Using things like ObRegisterCallback would be extremely helpful. I will provide a simple Driver which would strip Handles permissions from any programs trying to access the cheat.

This will be another Driver, i did not want to combine it as it cause some problems to some. You can run this separately along side the cheat agent and driver.

Driver.c
Code:
#include <ntdef.h>
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include <wdf.h>

DRIVER_INITIALIZE DriverEntry;
#pragma alloc_text(INIT, DriverEntry)
#define PROCESS_QUERY_LIMITED_INFORMATION      0x1000



typedef struct _OB_REG_CONTEXT {
	USHORT Version;
	UNICODE_STRING Altitude;
	USHORT ulIndex;
	OB_OPERATION_REGISTRATION *OperationRegistration;
} REG_CONTEXT, *PREG_CONTEXT;

UNICODE_STRING SACDriverName, SACSymbolName;
PVOID ObHandle = NULL;

//ULONG ProtectedProcess1 = 516; // The Usermode Anti Cheat PID
ULONG ProtectedProcess = 0; // Your game's PID
ULONG Lsass = 0;
ULONG Csrss1 = 0;
ULONG Csrss2 = 0;
ULONG ProtectedThreadID = 0;
// This function will be called when a handle is about to be created
OB_PREOP_CALLBACK_STATUS PreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
	UNREFERENCED_PARAMETER(RegistrationContext);

	if (ProtectedProcess == 0)
		return OB_PREOP_SUCCESS;

	if (Lsass == 0)
		return OB_PREOP_SUCCESS;

	if (Csrss1 == 0)
		return OB_PREOP_SUCCESS;

	if (Csrss2 == 0)
		return OB_PREOP_SUCCESS;

	PEPROCESS LsassProcess;
	PEPROCESS Csrss1Process;
	PEPROCESS Csrss2Process;
	PEPROCESS ProtectedProcessProcess;

	PEPROCESS OpenedProcess = (PEPROCESS)OperationInformation->Object,
		CurrentProcess = PsGetCurrentProcess();

	PsLookupProcessByProcessId(ProtectedProcess, &ProtectedProcessProcess); // Getting the PEPROCESS using the PID 
	PsLookupProcessByProcessId(Lsass, &LsassProcess); // Getting the PEPROCESS using the PID 
	PsLookupProcessByProcessId(Csrss1, &Csrss1Process); // Getting the PEPROCESS using the PID 
	PsLookupProcessByProcessId(Csrss2, &Csrss2Process); // Getting the PEPROCESS using the PID 


	if (OpenedProcess == Csrss1Process) // Making sure to not strip csrss's Handle, will cause BSOD
		return OB_PREOP_SUCCESS;

	if (OpenedProcess == Csrss2Process) // Making sure to not strip csrss's Handle, will cause BSOD
		return OB_PREOP_SUCCESS;

	if (OpenedProcess == CurrentProcess) // make sure the driver isnt getting stripped ( even though we have a second check )
		return OB_PREOP_SUCCESS;

	if (OpenedProcess == ProtectedProcess) // Making sure that the game can open a process handle to itself
		return OB_PREOP_SUCCESS;

	if (OperationInformation->KernelHandle) // allow drivers to get a handle
		return OB_PREOP_SUCCESS;


	// PsGetProcessId((PEPROCESS)OperationInformation->Object) equals to the created handle's PID, so if the created Handle equals to the protected process's PID, strip
	if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == ProtectedProcess)
	{

		if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle 
		{
			OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION);
		}
		else
		{
			OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION);
		}

		return OB_PREOP_SUCCESS;
	}
}

// This happens after everything. 
VOID PostCallBack(PVOID RegistrationContext, POB_POST_OPERATION_INFORMATION OperationInformation)
{
	UNREFERENCED_PARAMETER(RegistrationContext);
	UNREFERENCED_PARAMETER(OperationInformation);
}

// Unregistering the callback.
VOID UnRegister()
{
	ObUnRegisterCallbacks(ObHandle); // unregistering the callback
	ObHandle = NULL;
}

// Terminating a process of your choice using the PID, usefull if the cheat is also using a driver to strip it's handles and therefore you can forcefully close it using the driver
NTSTATUS TerminatingProcess(ULONG targetPid)
{
	NTSTATUS NtRet = STATUS_SUCCESS;
	PEPROCESS PeProc = { 0 };
	NtRet = PsLookupProcessByProcessId(targetPid, &PeProc);
	if (NtRet != STATUS_SUCCESS)
	{
		return NtRet;
	}
	HANDLE ProcessHandle;
	NtRet = ObOpenObjectByPointer(PeProc, NULL, NULL, 25, *PsProcessType, KernelMode, &ProcessHandle);
	if (NtRet != STATUS_SUCCESS)
	{
		return NtRet;
	}
	ZwTerminateProcess(ProcessHandle, 0);
	ZwClose(ProcessHandle);
	return NtRet;
}

NTSTATUS DriverDispatchRoutine(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
	PVOID buffer;
	NTSTATUS NtStatus = STATUS_SUCCESS;
	PIO_STACK_LOCATION pIo;
	pIo = IoGetCurrentIrpStackLocation(pIrp);
	pIrp->IoStatus.Information = 0;
	switch (pIo->MajorFunction)
	{
	case IRP_MJ_CREATE:
		NtStatus = STATUS_SUCCESS;
		break;
	case IRP_MJ_READ:
		NtStatus = STATUS_SUCCESS;
		break;
	case IRP_MJ_WRITE:
		break;
	case IRP_MJ_CLOSE:
		NtStatus = STATUS_SUCCESS;
		break;
	default:
		NtStatus = STATUS_INVALID_DEVICE_REQUEST;
		break;
	}
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return NtStatus;
}

// This will be called, if the driver is unloaded or just returns something
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{

	UnRegister();

	IoDeleteSymbolicLink(&SACSymbolName);
	IoDeleteDevice(pDriverObject->DeviceObject);

	//DbgPrint("Unload called!");
}

void RemoveTheLinks(PLIST_ENTRY Current)
{

	PLIST_ENTRY Previous, Next;

	Previous = (Current->Blink);
	Next = (Current->Flink);

	// Loop over self (connect previous with next)
	Previous->Flink = Next;
	Next->Blink = Previous;

	// Re-write the current LIST_ENTRY to point to itself (avoiding BSOD)
	Current->Blink = (PLIST_ENTRY)&Current->Flink;
	Current->Flink = (PLIST_ENTRY)&Current->Flink;

	return;

}

ULONG LookForProcessOffsets()
{


	ULONG pid_ofs = 0; // The offset we're looking for
	int idx = 0;                // Index 
	ULONG pids[3];				// List of PIDs for our 3 processes
	PEPROCESS eprocs[3];		// Process list, will contain 3 processes

								//Select 3 process PIDs and get their EPROCESS Pointer
	for (int i = 16; idx<3; i += 4)
	{
		if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)i, &eprocs[idx])))
		{
			pids[idx] = i;
			idx++;
		}
	}


	/*
	Go through the EPROCESS structure and look for the PID
	we can start at 0x20 because UniqueProcessId should
	not be in the first 0x20 bytes,
	also we should stop after 0x300 bytes with no success
	*/

	for (int i = 0x20; i<0x300; i += 4)
	{
		if ((*(ULONG *)((UCHAR *)eprocs[0] + i) == pids[0])
			&& (*(ULONG *)((UCHAR *)eprocs[1] + i) == pids[1])
			&& (*(ULONG *)((UCHAR *)eprocs[2] + i) == pids[2]))
		{
			pid_ofs = i;
			break;
		}
	}

	ObDereferenceObject(eprocs[0]);
	ObDereferenceObject(eprocs[1]);
	ObDereferenceObject(eprocs[2]);


	return pid_ofs;
}

// hides any process from the task bar and everything. only works for about 10 - 30 mins before patch guard is triggered and BSOD happens
PCHAR GhostProcess(UINT32 pid)
{


	LPSTR result = ExAllocatePool(NonPagedPool, sizeof(ULONG) + 20);;


	// Get PID offset nt!_EPROCESS.UniqueProcessId
	ULONG PID_OFFSET = LookForProcessOffsets();

	// Check if offset discovery was successful 
	if (PID_OFFSET == 0) {
		return (PCHAR)"Could not find PID offset!";
	}

	// Get LIST_ENTRY offset nt!_EPROCESS.ActiveProcessLinks
	ULONG LIST_OFFSET = PID_OFFSET;


	// Check Architecture using pointer size
	INT_PTR ptr;

	// Ptr size 8 if compiled for a 64-bit machine, 4 if compiled for 32-bit machine
	LIST_OFFSET += sizeof(ptr);

	// Get current process
	PEPROCESS CurrentEPROCESS = PsGetCurrentProcess();

	// Initialize other variables
	PLIST_ENTRY CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
	PUINT32 CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);

	// Check self 
	if (*(UINT32 *)CurrentPID == pid) {
		RemoveTheLinks(CurrentList);
		return (PCHAR)result;
	}

	// Record the starting position
	PEPROCESS StartProcess = CurrentEPROCESS;

	// Move to next item
	CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
	CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
	CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);

	// Loop until we find the right process to remove
	// Or until we circle back
	while ((ULONG_PTR)StartProcess != (ULONG_PTR)CurrentEPROCESS)
	{

		// Check item
		if (*(UINT32 *)CurrentPID == pid) {
			RemoveTheLinks(CurrentList);
			return (PCHAR)result;
		}

		// Move to next item
		CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
		CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
		CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
	}

	return (PCHAR)result;
}

PDEVICE_OBJECT g_MyDevice; // Global pointer to our device object



NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;

	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

// Request to read from usermode
#define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to write virtual user memory (memory of a program) from kernel space
#define IO_UNLOADDRIVER_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0702 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)


// datatype for read request
typedef struct _KERNEL_READ_REQUEST
{
	ULONG CSGO;

	ULONG LSASS;
	ULONG CSRSS;
	ULONG CSRSS2;
	ULONG ProtectedThread;
	ULONG TerminatePrograms;

} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;

// database for unload details
typedef struct _KERNEL_UNLOADDRIVER
{
	ULONG UnloadDriver;

} KERNEL_UNLOADDRIVER, *PKERNEL_UNLOADDRIVER;

ULONG TerminateProcess = 0;
BOOLEAN  UnloadDriver = FALSE;
NTSTATUS IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	NTSTATUS Status;
	ULONG BytesIO = 0;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	// Code received from user space
	ULONG ControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
	if (ControlCode == IO_UNLOADDRIVER_REQUEST)
	{
		PKERNEL_UNLOADDRIVER ReadInput = (PKERNEL_UNLOADDRIVER)Irp->AssociatedIrp.SystemBuffer;

		if (ReadInput->UnloadDriver)
		{
			UnloadDriver = TRUE;
		}
	}
	if (ControlCode == IO_READ_REQUEST)
	{
		// Get the input buffer & format it to our struct
		PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;

		if (ReadInput->ProtectedThread != 0)
		{
			ProtectedThreadID = ReadInput->ProtectedThread;
		}
		if (ReadInput->CSGO != 0)
		{
			ProtectedProcess = ReadInput->CSGO;
		}

		if (ReadInput->LSASS != 0)
		{
			Lsass = ReadInput->LSASS;
		}

		if (ReadInput->CSRSS != 0)
		{
			Csrss1 = ReadInput->CSRSS;
		}

		if (ReadInput->CSRSS2 != 0)
		{
			Csrss2 = ReadInput->CSRSS2;
		}

		if (ReadInput->TerminatePrograms != 0)
		{
			TerminateProcess = ReadInput->TerminatePrograms;
		}

		Status = STATUS_SUCCESS;
		BytesIO = sizeof(KERNEL_READ_REQUEST);
	}
	else
	{
		// if the code is unknown
		Status = STATUS_INVALID_PARAMETER;
		BytesIO = 0;
	}

	// Complete the request
	Irp->IoStatus.Status = Status;
	Irp->IoStatus.Information = BytesIO;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return Status;
}
NTSTATUS CallBackHandle = STATUS_SUCCESS;
// Enabling the callback,
VOID EnableCallBack()
{
	
	OB_OPERATION_REGISTRATION OBOperationRegistration;
	OB_CALLBACK_REGISTRATION OBOCallbackRegistration;
	REG_CONTEXT regContext;
	UNICODE_STRING usAltitude;
	memset(&OBOperationRegistration, 0, sizeof(OB_OPERATION_REGISTRATION));
	memset(&OBOCallbackRegistration, 0, sizeof(OB_CALLBACK_REGISTRATION));
	memset(&regContext, 0, sizeof(REG_CONTEXT));
	regContext.ulIndex = 1;
	regContext.Version = 120;
	RtlInitUnicodeString(&usAltitude, L"1000");

	if ((USHORT)ObGetFilterVersion() == OB_FLT_REGISTRATION_VERSION)
	{
		OBOperationRegistration.ObjectType = PsProcessType; // Use To Strip Handle Permissions For Threads PsThreadType
		OBOperationRegistration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
		OBOperationRegistration.PostOperation = PostCallBack; // Giving the function which happens after creating
		OBOperationRegistration.PreOperation = PreCallback; // Giving the function which happens before creating

															// Setting the altitude of the driver
		OBOCallbackRegistration.Altitude = usAltitude;
		OBOCallbackRegistration.OperationRegistration = &OBOperationRegistration;
		OBOCallbackRegistration.RegistrationContext = &regContext;
		OBOCallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
		OBOCallbackRegistration.OperationRegistrationCount = (USHORT)1;

		CallBackHandle = ObRegisterCallbacks(&OBOCallbackRegistration, &ObHandle); // Register The CallBack

		
	}


	if (TerminateProcess != 0)
	{
		TerminatingProcess(TerminateProcess);
		TerminateProcess = 0;
	}
}

VOID MyLoadImageNotifyRoutine(
IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessID,
IN PIMAGE_INFO iMAGEiNFO)
{
	DbgPrintEx("Loaded Modules. ProcessID = %d, ThreadID = %d, Full ImageInfo = %d \n",
		ProcessID, iMAGEiNFO, iMAGEiNFO);
}

VOID CreateThreadNotifyRoutine(
	IN HANDLE ProcessId,
	IN HANDLE ThreadId,
	IN BOOLEAN Create
)
{
	if (Create)
	{
		DbgPrintEx("Create Thread. ProcessID = %d, ThreadID = %d \n",
			ProcessId, ThreadId);
	}
	else
	{
		DbgPrintEx("Delete Thread. ProcessID = %d, ThreadID = %d \n",
			ProcessId, ThreadId);

	}
}


typedef struct _LDR_DATA_TABLE_ENTRY
{
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderLinks;
	LIST_ENTRY InInitializationOrderLinks;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	WORD LoadCount;
	WORD TlsIndex;
	union
	{
		LIST_ENTRY HashLinks;
		struct
		{
			PVOID SectionPointer;
			ULONG CheckSum;
		};
	};
	union
	{
		ULONG TimeDateStamp;
		PVOID LoadedImports;
	};
	struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
	PVOID PatchInformation;
	LIST_ENTRY ForwarderLinks;
	LIST_ENTRY ServiceTagLinks;
	LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

PDEVICE_OBJECT DeviceObject;

// Driver's Main function. This will be called and looped through till returned, or unloaded.
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pUniStr)
{
	DbgPrint("Loaded");
	PLDR_DATA_TABLE_ENTRY CurDriverEntry = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
	PLDR_DATA_TABLE_ENTRY NextDriverEntry = (PLDR_DATA_TABLE_ENTRY)CurDriverEntry->InLoadOrderLinks.Flink;
	PLDR_DATA_TABLE_ENTRY PrevDriverEntry = (PLDR_DATA_TABLE_ENTRY)CurDriverEntry->InLoadOrderLinks.Blink;

	PrevDriverEntry->InLoadOrderLinks.Flink = CurDriverEntry->InLoadOrderLinks.Flink;
	NextDriverEntry->InLoadOrderLinks.Blink = CurDriverEntry->InLoadOrderLinks.Blink;

	CurDriverEntry->InLoadOrderLinks.Flink = (PLIST_ENTRY)CurDriverEntry;
	CurDriverEntry->InLoadOrderLinks.Blink = (PLIST_ENTRY)CurDriverEntry;

	NTSTATUS NtRet = STATUS_SUCCESS;
	PDEVICE_OBJECT pDeviceObj;
	RtlInitUnicodeString(&SACDriverName, L"\\Device\\HandleDriver"); // Giving the driver a name
	RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\HandleDriver"); // Giving the driver a symbol
	UNICODE_STRING deviceNameUnicodeString, deviceSymLinkUnicodeString;
	NTSTATUS NtRet2 = IoCreateDevice(pDriverObject, 0, &SACDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
	if (NtRet2 == STATUS_SUCCESS)
	{
		ULONG i;
		for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
		{
			pDriverObject->MajorFunction[i] = DriverDispatchRoutine;
		}


		IoCreateSymbolicLink(&SACSymbolName, &SACDriverName);

		pDriverObject->MajorFunction[IRP_MJ_CREATE] = Create;
		pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Close;
		pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;

		pDeviceObj->Flags |= DO_DIRECT_IO;
		pDeviceObj->Flags &= (~DO_DEVICE_INITIALIZING);
	}
	else
	{
		return STATUS_UNSUCCESSFUL;
	}

	pDriverObject->DriverUnload = DriverUnload; // Telling the driver, this is the unload function
	EnableCallBack();

	NTSTATUS ThreadChecking;
	ThreadChecking = PsSetCreateThreadNotifyRoutine(*CreateThreadNotifyRoutine);
	NTSTATUS LoadChecking;
	LoadChecking = PsSetLoadImageNotifyRoutine(*MyLoadImageNotifyRoutine);


	return NtRet;
}

Usermode.cpp
Code:
#include <iostream>
#include <map>
#include <vector>
#include "KeInterface.h"
#pragma comment(lib,"ntdll.lib")
#include <TlHelp32.h>
#include <algorithm>
#pragma comment(lib,"ntdll.lib")

// datatype for read request
typedef struct _KERNEL_READ_REQUEST
{
	ULONG CSGO;

	ULONG LSASS;
	ULONG CSRSS;
	ULONG CSRSS2;
	ULONG UsermodeProgram;
	ULONG TerminatePrograms;

} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;

// database for unload details
typedef struct _KERNEL_UNLOADDRIVER
{
	ULONG UnloadDriver;

} KERNEL_UNLOADDRIVER, *PKERNEL_UNLOADDRIVER;

// Request to write to kernel mode
#define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to write virtual user memory (memory of a program) from kernel space
#define IO_UNLOADDRIVER_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0702 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

HANDLE hDriver;
bool SendProcessIDs(ULONG CSGO, ULONG LSASS, ULONG CSRSS, ULONG CSRSS2, ULONG USERMODEANTICHEAT, ULONG TerminatePrograms)
{
	if (hDriver == INVALID_HANDLE_VALUE)
		return false;

	DWORD Return, Bytes;
	KERNEL_READ_REQUEST ReadRequest;

	ReadRequest.CSGO = CSGO;
	ReadRequest.LSASS = LSASS;
	ReadRequest.CSRSS = CSRSS;
	ReadRequest.CSRSS2 = CSRSS2;
	ReadRequest.UsermodeProgram = USERMODEANTICHEAT;
	ReadRequest.TerminatePrograms = TerminatePrograms;

	// send code to our driver with the arguments
	if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest,
		sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), &Bytes, NULL))
	{
		return true;
	}
	else
	{
		return false;
	}
}

// These structures are copied from Process Hacker source code (ntldr.h)

typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
	HANDLE Section;
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES
{
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

vector<DWORD> GetPIDs(wstring targetProcessName)
{
	vector<DWORD> pids;
	if (targetProcessName == L"")
		return pids;
	HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32W entry;
	entry.dwSize = sizeof entry;
	if (!Process32FirstW(snap, &entry))
		return pids;
	do {
		if (wstring(entry.szExeFile) == targetProcessName) {
			pids.emplace_back(entry.th32ProcessID);
		}
	} while (Process32NextW(snap, &entry));
	return pids;
}




int main(int argc, char *argv[])
{
	SetDebugPrivA();


	HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
	ProtectProcess(hProc);
	SetPriorityClass(hProc, ABOVE_NORMAL_PRIORITY_CLASS);
	CloseHandle(hProc);

	HANDLE hDevice;
	DWORD dwReturn;
	DWORD ProcessId, write;

	hDriver = CreateFileA("\\\\.\\HandleDriver", GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

	DWORD csrss1 = NULL;
	DWORD csrss2 = NULL;
	wstring we1 = L"";
	wstring lsassNoStr1 = we1 +L'c' + L's' + L'r' + L's' + L's' + L'.' + L'e' + L'x' + L'e';
	vector<DWORD> pidsLsass1 = GetPIDs(lsassNoStr1);
	if (pidsLsass1.empty())
		cout << "Not Found" << endl;
	sort(pidsLsass1.begin(), pidsLsass1.end()); // In case there is several lsass.exe running (?) take the first one (based on PID)
	csrss1 = pidsLsass1[0];
	csrss2 = pidsLsass1[1];
	if (!csrss1)
		cout << "Not Found" << endl;
	if (!csrss2)
		cout << "Not Found" << endl;

	DWORD pivotPID = NULL;
	wstring we = L"";
	wstring lsassNoStr = we + L'l' + L's' + L'a' + L's' + L's' + L'.' + L'e' + L'x' + L'e';
	vector<DWORD> pidsLsass = GetPIDs(lsassNoStr);
	if (pidsLsass.empty())
		cout << "Not Found" << endl;
	sort(pidsLsass.begin(), pidsLsass.end()); // In case there is several lsass.exe running (?) take the first one (based on PID)
	pivotPID = pidsLsass[0];
	if (!pivotPID)
		cout << "Not Found" << endl;


	if (SendProcessIDs(FindProcessId("YOUR CHEAT NAME"), pivotPID, csrss1, csrss2, (ULONG)GetCurrentProcessId(), 0)) // 396 & = Csrss's PIDs
	{
		cout << "Sent Data" << endl;
	}
	else
	{
		cout << "False" << endl;
	}

	
	CloseHandle(hDriver);
        return 0;
}

How Use This Driver?
Well, this is as easy as the cheat itself. Just replace the "YOUR NAME NAME" with your cheat process's name ( example: csgo.exe ). After that, you will need to load this driver first then load the cheat driver, after that, you can run the cheat and then this. Its quite a mouthful, but just use this logic, the usermode programs are like a client and the drivers are the server, you will need the server to be running first before you can use your client to access it.

To Dos:
If you like to improve this to a somewhat perfect cheat, combine https://github.com/JKornev/hidden, my handle stripping driver and the cheat itself. This will cause the Driver to be somewhat unstable sometimes but other then that, it should be fine.

Source:

Kernel Mode (Driver):

Driver.c
Code:
#include "ntos.h"
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include <wdf.h>
#include <ntdef.h>

// Request to read virtual user memory (memory of a program) from kernel space
#define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to write virtual user memory (memory of a program) from kernel space
#define IO_WRITE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0702 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to retrieve the process id of csgo process, from kernel space
#define IO_GET_ID_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0703 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to retrieve the base address of client.dll in csgo.exe from kernel space
#define IO_GET_MODULE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0704 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)


PDEVICE_OBJECT pDeviceObject; // our driver object
UNICODE_STRING dev, dos; // Driver registry paths

ULONG csgoId, ClientAddress;

// datatype for read request
typedef struct _KERNEL_READ_REQUEST
{
	ULONG ProcessId;

	ULONG Address;
	ULONG Response;
	ULONG Size;

} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;

typedef struct _KERNEL_WRITE_REQUEST
{
	ULONG ProcessId;

	ULONG Address;
	ULONG Value;
	ULONG Size;

} KERNEL_WRITE_REQUEST, *PKERNEL_WRITE_REQUEST;

NTSTATUS UnloadDriver(PDRIVER_OBJECT pDriverObject);
NTSTATUS CreateCall(PDEVICE_OBJECT DeviceObject, PIRP irp);
NTSTATUS CloseCall(PDEVICE_OBJECT DeviceObject, PIRP irp);

NTSTATUS KeReadVirtualMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
	PSIZE_T Bytes;
	if (NT_SUCCESS(MmCopyVirtualMemory(Process, SourceAddress, PsGetCurrentProcess(),
		TargetAddress, Size, KernelMode, &Bytes)))
		return STATUS_SUCCESS;
	else
		return STATUS_ACCESS_DENIED;
}

NTSTATUS KeWriteVirtualMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size)
{
	PSIZE_T Bytes;
	if (NT_SUCCESS(MmCopyVirtualMemory(PsGetCurrentProcess(), SourceAddress, Process,
		TargetAddress, Size, KernelMode, &Bytes)))
		return STATUS_SUCCESS;
	else
		return STATUS_ACCESS_DENIED;
}

// set a callback for every PE image loaded to user memory
// then find the client.dll & csgo.exe using the callback
PLOAD_IMAGE_NOTIFY_ROUTINE ImageLoadCallback(PUNICODE_STRING FullImageName,
	HANDLE ProcessId, PIMAGE_INFO ImageInfo)
{
	// Compare our string to input
	if (wcsstr(FullImageName->Buffer, L"\\csgo\\bin\\client.dll")) {
		// if it matches
		DbgPrintEx(0, 0, "Loaded Name: %ls \n", FullImageName->Buffer);
		DbgPrintEx(0, 0, "Loaded To Process: %d \n", ProcessId);

		ClientAddress = ImageInfo->ImageBase;
		csgoId = ProcessId;
	}
}


// IOCTL Call Handler function

NTSTATUS IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	NTSTATUS Status;
	ULONG BytesIO = 0;

	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

	// Code received from user space
	ULONG ControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
	if (ControlCode == IO_READ_REQUEST)
	{
		// Get the input buffer & format it to our struct
		PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
		PKERNEL_READ_REQUEST ReadOutput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;

		PEPROCESS Process;
		// Get our process
		if (NT_SUCCESS(PsLookupProcessByProcessId(ReadInput->ProcessId, &Process)))
			KeReadVirtualMemory(Process, ReadInput->Address,
				&ReadInput->Response, ReadInput->Size);

		//DbgPrintEx(0, 0, "Read Params:  %lu, %#010x \n", ReadInput->ProcessId, ReadInput->Address);
		//DbgPrintEx(0, 0, "Value: %lu \n", ReadOutput->Response);

		Status = STATUS_SUCCESS;
		BytesIO = sizeof(KERNEL_READ_REQUEST);
	}
	else if (ControlCode == IO_WRITE_REQUEST)
	{
		// Get the input buffer & format it to our struct
		PKERNEL_WRITE_REQUEST WriteInput = (PKERNEL_WRITE_REQUEST)Irp->AssociatedIrp.SystemBuffer;

		PEPROCESS Process;
		// Get our process
		if (NT_SUCCESS(PsLookupProcessByProcessId(WriteInput->ProcessId, &Process)))
			KeWriteVirtualMemory(Process, &WriteInput->Value,
				WriteInput->Address, WriteInput->Size);

		//DbgPrintEx(0, 0, "Write Params:  %lu, %#010x \n", WriteInput->Value, WriteInput->Address);

		Status = STATUS_SUCCESS;
		BytesIO = sizeof(KERNEL_WRITE_REQUEST);
	}
	else if (ControlCode == IO_GET_ID_REQUEST)
	{
		PULONG OutPut = (PULONG)Irp->AssociatedIrp.SystemBuffer;
		*OutPut = csgoId;

		DbgPrintEx(0, 0, "id get %#010x", csgoId);
		Status = STATUS_SUCCESS;
		BytesIO = sizeof(*OutPut);
	}
	else if (ControlCode == IO_GET_MODULE_REQUEST)
	{
		PULONG OutPut = (PULONG)Irp->AssociatedIrp.SystemBuffer;
		*OutPut = ClientAddress;

		DbgPrintEx(0, 0, "Module get %#010x", ClientAddress);
		Status = STATUS_SUCCESS;
		BytesIO = sizeof(*OutPut);
	}
	else
	{
		 // if the code is unknown
		Status = STATUS_INVALID_PARAMETER;
		BytesIO = 0;
	}

	// Complete the request
	Irp->IoStatus.Status = Status;
	Irp->IoStatus.Information = BytesIO;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
	return Status;
}

typedef struct _LDR_DATA_TABLE_ENTRY
{
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderLinks;
	LIST_ENTRY InInitializationOrderLinks;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	WORD LoadCount;
	WORD TlsIndex;
	union
	{
		LIST_ENTRY HashLinks;
		struct
		{
			PVOID SectionPointer;
			ULONG CheckSum;
		};
	};
	union
	{
		ULONG TimeDateStamp;
		PVOID LoadedImports;
	};
	struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
	PVOID PatchInformation;
	LIST_ENTRY ForwarderLinks;
	LIST_ENTRY ServiceTagLinks;
	LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

PDEVICE_OBJECT DeviceObject;


// Driver Entrypoint
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,
	PUNICODE_STRING pRegistryPath)
{
	DbgPrintEx(0, 0, "123123123Driver Loaded\n");

	PsSetLoadImageNotifyRoutine(ImageLoadCallback);

	PLDR_DATA_TABLE_ENTRY CurDriverEntry = (PLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
	PLDR_DATA_TABLE_ENTRY NextDriverEntry = (PLDR_DATA_TABLE_ENTRY)CurDriverEntry->InLoadOrderLinks.Flink;
	PLDR_DATA_TABLE_ENTRY PrevDriverEntry = (PLDR_DATA_TABLE_ENTRY)CurDriverEntry->InLoadOrderLinks.Blink;

	PrevDriverEntry->InLoadOrderLinks.Flink = CurDriverEntry->InLoadOrderLinks.Flink;
	NextDriverEntry->InLoadOrderLinks.Blink = CurDriverEntry->InLoadOrderLinks.Blink;

	CurDriverEntry->InLoadOrderLinks.Flink = (PLIST_ENTRY)CurDriverEntry;
	CurDriverEntry->InLoadOrderLinks.Blink = (PLIST_ENTRY)CurDriverEntry;

	RtlInitUnicodeString(&dev, L"\\Device\\kernelhop");
	RtlInitUnicodeString(&dos, L"\\DosDevices\\kernelhop");

	IoCreateDevice(pDriverObject, 0, &dev, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
	IoCreateSymbolicLink(&dos, &dev);

	pDriverObject->MajorFunction[IRP_MJ_CREATE] = CreateCall;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = CloseCall;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;
	pDriverObject->DriverUnload = UnloadDriver;

	pDeviceObject->Flags |= DO_DIRECT_IO;
	pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}



NTSTATUS UnloadDriver(PDRIVER_OBJECT pDriverObject)
{
	DbgPrintEx(0, 0, "Unload routine called.\n");
	PsRemoveLoadImageNotifyRoutine(ImageLoadCallback);
	IoDeleteSymbolicLink(&dos);
	IoDeleteDevice(pDriverObject->DeviceObject);
}

NTSTATUS CreateCall(PDEVICE_OBJECT DeviceObject, PIRP irp)
{
	irp->IoStatus.Status = STATUS_SUCCESS;
	irp->IoStatus.Information = 0;

	IoCompleteRequest(irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS CloseCall(PDEVICE_OBJECT DeviceObject, PIRP irp)
{
	irp->IoStatus.Status = STATUS_SUCCESS;
	irp->IoStatus.Information = 0;

	IoCompleteRequest(irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
Usermode (Agent):

Main.cpp
Code:
#include <iostream>
#include <map>
#include <vector>
#include "Header.h"
#pragma comment(lib,"ntdll.lib")
#include <TlHelp32.h>
#include <algorithm>

typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
	HANDLE Section;
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES
{
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

using namespace std;

void Shoot()
{
	mouse_event(MOUSEEVENTF_LEFTDOWN, NULL, NULL, NULL, NULL);
	Sleep(10);
	mouse_event(MOUSEEVENTF_LEFTUP, NULL, NULL, NULL, NULL);
}

int main()
{

	KeInterface Driver("\\\\.\\kernelhop");


	SetConsoleTitle(L"TEST");
	// Get address of client.dll & pid of csgo from our driver
	DWORD ProcessId = Driver.GetTargetPid();
	DWORD ClientAddress = Driver.GetClientModule();

	// Get address of localplayer
	DWORD LocalPlayer = Driver.ReadVirtualMemory<DWORD>(ProcessId, ClientAddress + LOCAL_PLAYER, sizeof(ULONG));

	// address of inground
	DWORD InGround = Driver.ReadVirtualMemory<DWORD>(ProcessId,
		LocalPlayer + FFLAGS, sizeof(ULONG));

	
	while (true)
	{
		
		int crossId = Driver.ReadVirtualMemory<int>(ProcessId, LocalPlayer + CrosshairID, sizeof(int));
		int LocalTeam = Driver.ReadVirtualMemory<int>(ProcessId, LocalPlayer + teamNum, sizeof(int));
		if (crossId > 0 && crossId < 64 && (GetAsyncKeyState(VK_MENU) & 0x8000))
		{
			if (LocalTeam != Driver.ReadVirtualMemory<int>(ProcessId, LocalPlayer + teamNum * crossId, sizeof(int)))
			{
				Shoot();
			}
		}

		// No Flash
		Driver.WriteVirtualMemory(ProcessId, LocalPlayer + FlashMaxAlpha, 0.f, 8);

		// Bunny Hop
		Driver.WriteVirtualMemory(ProcessId, ClientAddress + FORCE_JUMP, 0x5, 8);
		DWORD InGround = Driver.ReadVirtualMemory<DWORD>(ProcessId, LocalPlayer + FFLAGS, sizeof(ULONG));
		if ((GetAsyncKeyState(VK_SPACE) & 0x8000) && (InGround & 1 == 1))
		{
			// Jump
			Driver.WriteVirtualMemory(ProcessId, ClientAddress + FORCE_JUMP, 0x5, 8);
			Sleep(50);
			// Restore
			Driver.WriteVirtualMemory(ProcessId, ClientAddress + FORCE_JUMP, 0x4, 8);
			
		}
		Sleep(10);
	}
    return 0;
}
Header.h
Code:
#include <Windows.h>

/* IOCTL Codes needed for our driver */

// Request to read virtual user memory (memory of a program) from kernel space
#define IO_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to write virtual user memory (memory of a program) from kernel space
#define IO_WRITE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0702 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to retrieve the process id of csgo process, from kernel space
#define IO_GET_ID_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0703 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Request to retrieve the base address of client.dll in csgo.exe from kernel space
#define IO_GET_MODULE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0704 /* Our Custom Code */, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

// Offset to force jump action
#define FORCE_JUMP 0x4F1AAF4
#define  m_iGlowIndex 0xA310
#define LOCAL_PLAYER 0xAA6614
#define m_bDormant 0xE9
#define FFLAGS 0x00000100
#define CrosshairID 0xB2A4
#define FlashMaxAlpha 0xA2F4
#define teamNum 0xF0

#define dwGlowObjectManager 0x4FA08E8

#define m_iTeamNum 0xF0

#define dwEntityList 0x4A8387C

typedef struct _KERNEL_READ_REQUEST
{
	ULONG ProcessId;

	ULONG Address;
	ULONG Response;
	ULONG Size;

} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;

typedef struct _KERNEL_WRITE_REQUEST
{
	ULONG ProcessId;

	ULONG Address;
	ULONG Value;
	ULONG Size;

} KERNEL_WRITE_REQUEST, *PKERNEL_WRITE_REQUEST;



// interface for our driver
class KeInterface
{
public:
	HANDLE hDriver; // Handle to driver

					// Initializer
	KeInterface::KeInterface(LPCSTR RegistryPath)
	{
		hDriver = CreateFileA(RegistryPath, GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
	}

	template <typename type>
	type ReadVirtualMemory(ULONG ProcessId, ULONG ReadAddress,
		SIZE_T Size)
	{
		if (hDriver == INVALID_HANDLE_VALUE)
			return (type)false;

		DWORD Return, Bytes;
		KERNEL_READ_REQUEST ReadRequest;

		ReadRequest.ProcessId = ProcessId;
		ReadRequest.Address = ReadAddress;
		ReadRequest.Size = Size;

		// send code to our driver with the arguments
		if (DeviceIoControl(hDriver, IO_READ_REQUEST, &ReadRequest,
			sizeof(ReadRequest), &ReadRequest, sizeof(ReadRequest), &Bytes, 0))
			return (type)ReadRequest.Response;
		else
			return (type)false;
	}

	bool WriteVirtualMemory(ULONG ProcessId, ULONG WriteAddress,
		ULONG WriteValue, SIZE_T WriteSize)
	{
		if (hDriver == INVALID_HANDLE_VALUE)
			return false;
		DWORD Bytes;

		KERNEL_WRITE_REQUEST  WriteRequest;
		WriteRequest.ProcessId = ProcessId;
		WriteRequest.Address = WriteAddress;
		WriteRequest.Value = WriteValue;
		WriteRequest.Size = WriteSize;

		if (DeviceIoControl(hDriver, IO_WRITE_REQUEST, &WriteRequest, sizeof(WriteRequest),
			0, 0, &Bytes, NULL))
			return true;
		else
			return false;
	}

	DWORD GetTargetPid()
	{
		if (hDriver == INVALID_HANDLE_VALUE)
			return false;

		ULONG Id;
		DWORD Bytes;

		if (DeviceIoControl(hDriver, IO_GET_ID_REQUEST, &Id, sizeof(Id),
			&Id, sizeof(Id), &Bytes, NULL))
			return Id;
		else
			return false;
	}

	DWORD GetClientModule()
	{
		if (hDriver == INVALID_HANDLE_VALUE)
			return false;

		ULONG Address;
		DWORD Bytes;

		if (DeviceIoControl(hDriver, IO_GET_MODULE_REQUEST, &Address, sizeof(Address),
			&Address, sizeof(Address), &Bytes, NULL))
			return Address;
		else
			return false;
	}

};
Comment my mistakes and i will make a change!
Moved to proper section
Quote Originally Posted by Ally View Post
Moved to proper section
thanks //2short
1- can i use PsSetLoadImageNotifyRoutine callback to get any ProcessId?
2- can i change (\\csgo\\bin\\client.dll) to (\\game\\bin\\game.exe), just to catch the ProcessID only without any modules like client.dll etc?.
Posts 1–4 of 4 Β· Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us