Исключение службы «Синий экран водителя системы безопасности» - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь протестировать этот Sagaan AntiCheat, но я получил bluescreen. Я использую OSRLoader для идеальной загрузки драйвера и его загрузки, но когда я открываю .exe, он дает мне Blue Screen of Death https://prnt.sc/m9zl6o Исходный кодиз FullProject https://github.com/SagaanTheEpic/Sagaan-AntiCheat-V2.0 Я не вижу, где ошибка, может кто-то помочь мне проанализировать этот проект, который я пытаюсь построить.я хочу перекодировать его, чтобы добавить больше функций и сделать его еще лучше.

#include <ntdef.h>
#include <ntifs.h>
#include <ntddk.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
#include <stdio.h>
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include <wdf.h>
#include <ntdef.h>

#include "BlackBone\VadRoutines.h"
#include "BlackBone\Routines.h"
#include "DriverIO.h"
#include "Formula.h"

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

PVOID ObHandle = NULL;

ULONG ProtectedProcess = 0;
ULONG UsermodeAntiCheat = 0;
ULONG ProtectionThreads[7];


VOID CreateThreadNotifyRoutine(
	IN HANDLE ProcessId,
	IN HANDLE ThreadId,
	IN BOOLEAN Create
);

// 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 TerminateProcess(ULONG targetPid)
{
	if (targetPid == ProtectedProcess)
	{
		ProtectedProcess = 0;
	}
	if (targetPid == UsermodeAntiCheat)
	{
		UsermodeAntiCheat = 0;
	}

	NTSTATUS NtRet = ((NTSTATUS)0x00000000L);
	PEPROCESS PeProc = { 0 };
	NtRet = PsLookupProcessByProcessId(targetPid, &PeProc);
	if (NtRet != ((NTSTATUS)0x00000000L))
	{
		return NtRet;
	}
	HANDLE ProcessHandle;
	NtRet = ObOpenObjectByPointer(PeProc, NULL, NULL, 25, *PsProcessType, KernelMode, &ProcessHandle);
	if (NtRet != ((NTSTATUS)0x00000000L))
	{
		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)
{
	DbgPrintEx(0, 0, "UNLOADED \n");
	UNICODE_STRING SACSymbolName;
	RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
	if (ObHandle)
	{
		ObUnRegisterCallbacks(ObHandle);
		ObHandle = NULL;
	}
	PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
	IoDeleteSymbolicLink(&SACSymbolName);
	IoDeleteDevice(pDriverObject->DeviceObject);
}


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;
}

extern   NTSTATUS PsLookupProcessByProcessId(
	HANDLE ProcessId,
	PEPROCESS *Process
);




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

OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
	UNREFERENCED_PARAMETER(RegistrationContext);

	if (OperationInformation->KernelHandle)
		return OB_PREOP_SUCCESS;

	if ((ULONG)PsGetCurrentProcessId() == UsermodeAntiCheat)
	{
		return OB_PREOP_SUCCESS;
	}
	if ((ULONG)PsGetCurrentProcessId() == ProtectedProcess)
	{
		return OB_PREOP_SUCCESS;
	}

	if (PsGetThreadProcessId(OperationInformation->Object) == UsermodeAntiCheat)
	{

		if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
			OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
		else
			OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);


	}
	else if (PsGetThreadProcessId(OperationInformation->Object) == ProtectedProcess)
	{

		if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
			OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
		else
			OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);


	}

	return OB_PREOP_SUCCESS;
}

OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
	UNREFERENCED_PARAMETER(RegistrationContext);
	if (UsermodeAntiCheat == 0)
		return OB_PREOP_SUCCESS;

	if (ProtectedProcess == 0)
		return OB_PREOP_SUCCESS;

	PEPROCESS ProtectedProcessPEPROCESS;
	PEPROCESS ProtectedUserModeACPEPROCESS;

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

	ULONG ulProcessId = PsGetProcessId(OpenedProcess);

	PsLookupProcessByProcessId(ProtectedProcess, &ProtectedProcessPEPROCESS);
	PsLookupProcessByProcessId(ProtectedProcess, &ProtectedUserModeACPEPROCESS);

	if (OperationInformation->KernelHandle)
		return OB_PREOP_SUCCESS;

	if (ProtectedProcess != 0)
	{
		if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == ProtectedProcess)
		{

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

	if (UsermodeAntiCheat != 0)
	{
		if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == UsermodeAntiCheat)
		{

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

VOID CreateThreadNotifyRoutine(
	IN HANDLE ProcessId,
	IN HANDLE ThreadId,
	IN BOOLEAN Create
)
{
	if (!Create)
	{
		if (UsermodeAntiCheat == ProcessId)
		{
			for (int x = 0; x > 8; x++)
			{
				if ((ULONG)ThreadId == ProtectionThreads[x])
				{

					TerminateProcess(ProtectedProcess);
					TerminateProcess(UsermodeAntiCheat);
				}
			}

		}

		if (ProtectedProcess == ProcessId)
		{

		}

	}
}


VOID EnableCallBack()
{
	NTSTATUS NtHandleCallback = STATUS_UNSUCCESSFUL;
	NTSTATUS NtThreadCallback = STATUS_UNSUCCESSFUL;

	OB_OPERATION_REGISTRATION OBOperationRegistration[2];
	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

		OBOperationRegistration[1].ObjectType = PsProcessType;
		OBOperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
		OBOperationRegistration[1].PreOperation = ProcessPreCallback;
		OBOperationRegistration[1].PostOperation = NULL;


		OBOperationRegistration[0].ObjectType = PsThreadType;
		OBOperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
		OBOperationRegistration[0].PreOperation = ThreadPreCallback;
		OBOperationRegistration[0].PostOperation = NULL;

		OBOCallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
		OBOCallbackRegistration.OperationRegistrationCount = 2;
		OBOCallbackRegistration.RegistrationContext = NULL;
		OBOCallbackRegistration.OperationRegistration = &OBOperationRegistration;

		NtHandleCallback = ObRegisterCallbacks(&OBOCallbackRegistration, &ObHandle); // Register The CallBack
		PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);

		if (!NT_SUCCESS(NtHandleCallback))
		{
			if (ObHandle)
			{
				ObUnRegisterCallbacks(ObHandle);
				ObHandle = NULL;
			}
			DbgPrintEx(0, 0, "Error: ObRegisterCallbacks Has Failed\n");
		}
		else
		{

		}
	}
}

static ULONG KsecRandomSeed = 0x62b409a1;

NTSTATUS
NTAPI
KsecGenRandom(
	PVOID Buffer,
	SIZE_T Length)
{
	LARGE_INTEGER TickCount;
	ULONG i, RandomValue;
	PULONG P;

	/* Try to generate a more random seed */
	KeQueryTickCount(&TickCount);
	KsecRandomSeed ^= _rotl(TickCount.LowPart, (KsecRandomSeed % 23));

	P = Buffer;
	for (i = 0; i < Length / sizeof(ULONG); i++)
	{
		P[i] = RtlRandomEx(&KsecRandomSeed);
	}

	Length &= (sizeof(ULONG) - 1);
	if (Length > 0)
	{
		RandomValue = RtlRandomEx(&KsecRandomSeed);
		RtlCopyMemory(&P[i], &RandomValue, Length);
	}

	return STATUS_SUCCESS;
}

ULONG FOR1 = 100, FOR2 = 200, FOR3 = 300, FOR4 = 400, FOR5 = 500;
ULONG Encryption_Forward1 = 1, Encryption_Forward2 = 1, Encryption_Forward3 = 1, Encryption_Forward4 = 1, Encryption_Forward5 = 1;

BOOL Request_1 = FALSE;

BOOLEAN ProtectedGameRecieved = FALSE;
BOOLEAN UsermodeAntiCheatRecieved = 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_SEND_CURRENTPROCESS && UsermodeAntiCheat < 1)
	{
		PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
		UsermodeAntiCheat = ReadInput->UsermodeProgram;

		Status = STATUS_SUCCESS;
		BytesIO = sizeof(KERNEL_READ_REQUEST);
	}


	if ((ULONG)UsermodeAntiCheat == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
	{

		if (ControlCode == IO_SEND_PROCESSID && ProtectedGameRecieved == FALSE)
		{

			PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
			ProtectedProcess = ReadInput->GameProcess;

			if (ProtectedProcess > 0)
			{
				ProtectedGameRecieved = TRUE;
			}

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_READ_REQUEST);

		}

		else if (ControlCode == IO_PROTECTIONT_THREADS)
		{
			PKERNEL_THREAD_REQUEST ReadInput = (PKERNEL_THREAD_REQUEST)Irp->AssociatedIrp.SystemBuffer;
			ProtectionThreads[0] = ReadInput->ThreadID;
			ProtectionThreads[1] = ReadInput->ThreadID2;
			ProtectionThreads[2] = ReadInput->ThreadID3;
			ProtectionThreads[3] = ReadInput->ThreadID4;
			ProtectionThreads[4] = ReadInput->ThreadID5;
			ProtectionThreads[5] = ReadInput->ThreadID6;
			ProtectionThreads[6] = ReadInput->ThreadID7;
			ProtectionThreads[7] = ReadInput->ThreadID8;

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_THREAD_REQUEST);
		}
		else if (ControlCode == IO_TerminateProcess)
		{
			PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;

			TerminateProcess(ReadInput->UsermodeProgram);

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_READ_REQUEST);

		}
		else if (ControlCode == HEARTBEATMAINSTART_FORWARD)
		{


			PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;


			Encryption_Forward1 = ReadInput->Encrypt1;
			Encryption_Forward2 = ReadInput->Encrypt2;
			Encryption_Forward3 = ReadInput->Encrypt3;
			Encryption_Forward4 = ReadInput->Encrypt4;
			Encryption_Forward5 = ReadInput->Encrypt5;



			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);


		}
		else if (ControlCode == HEARTBEATMAINSTART_RETURN)
		{


			PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;


			ReadInput->Encrypt1 = Formula1(Encryption_Forward1);
			ReadInput->Encrypt2 = Formula2(Encryption_Forward2);
			ReadInput->Encrypt3 = Formula3(Encryption_Forward3);
			ReadInput->Encrypt4 = Formula4(Encryption_Forward4);
			ReadInput->Encrypt5 = Formula5(Encryption_Forward5);

			//DbgPrintEx(0, 0, "HEARTBEATMAINSTART_RETURN Called: Formula1(Encryption_Forward1) %d", Formula1(Encryption_Forward1));

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);


		}
		else if (ControlCode == HEARTBEATCREATEPROCESS_RETURN)
		{
			PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
			KsecGenRandom(FOR1, sizeof(FOR1));
			KsecGenRandom(FOR2, sizeof(FOR2));
			KsecGenRandom(FOR3, sizeof(FOR3));
			KsecGenRandom(FOR4, sizeof(FOR4));
			KsecGenRandom(FOR5, sizeof(FOR5));


			ReadInput->Encrypt1 = FOR1;
			ReadInput->Encrypt2 = FOR2;
			ReadInput->Encrypt3 = FOR3;
			ReadInput->Encrypt4 = FOR4;
			ReadInput->Encrypt5 = FOR5;

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);


		}
		else if (ControlCode == IO_VADPROTECTION)
		{
			PHIDE_VAD ReadInput = (PHIDE_VAD)Irp->AssociatedIrp.SystemBuffer;
			if (ReadInput->pid == ProtectedProcess || ReadInput == UsermodeAntiCheat)
			{
				// Enable it if you like. I dont need it so eh
				//BBHideVAD(ReadInput);
			}

			Status = STATUS_SUCCESS;
			BytesIO = sizeof(HIDE_VAD);
		}
		else if (ControlCode == HEARTBEATCREATEPROCESS_FORWARD)
		{
			PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;

			if (ReadInput->Encrypt1 == Formula1(FOR1))
			{
				if (ReadInput->Encrypt2 == Formula2(FOR2))
				{
					if (ReadInput->Encrypt3 == Formula3(FOR3))
					{
						if (ReadInput->Encrypt4 == Formula4(FOR4))
						{
							if (ReadInput->Encrypt5 == Formula5(FOR5))
							{
								//DbgPrintEx(0, 0, "Process Id ( IOCONTROL )%s\n", (ULONG)PsGetProcessId(IoGetCurrentProcess()));
								Status = STATUS_SUCCESS;
								// GOOD
							}
							else
							{
								if (ProtectedProcess)
								{
									TerminateProcess(ProtectedProcess);
								}
								TerminateProcess(UsermodeAntiCheat);
								Status = STATUS_INVALID_PARAMETER;
								//BAD
								// ERROR
								// TERMINATE GAME OR PROTECTION 
								// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
								DbgPrintEx(0, 0, "Error: ReadInput->Encrypt5 == Formula5(FOR5) Encrypt: %s Formula: %s \n", ReadInput->Encrypt5, Formula5(FOR5));
							}
						}
						else
						{
							if (ProtectedProcess)
							{

								TerminateProcess(ProtectedProcess);
							}
							TerminateProcess(UsermodeAntiCheat);
							Status = STATUS_INVALID_PARAMETER;


							//BAD
							// ERROR
							// TERMINATE GAME OR PROTECTION 
							// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
							DbgPrintEx(0, 0, "Error: ReadInput->Encrypt4 == Formula4(FOR4) Encrypt: %s Formula: %s \n", ReadInput->Encrypt4, Formula4(FOR4));
						}
					}
					else
					{
						if (ProtectedProcess)
						{
							TerminateProcess(ProtectedProcess);
						}
						TerminateProcess(UsermodeAntiCheat);
						Status = STATUS_INVALID_PARAMETER;
						//BAD
						// ERROR
						// TERMINATE GAME OR PROTECTION 
						// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
						DbgPrintEx(0, 0, "Error: ReadInput->Encrypt3 == Formula3(FOR3) Encrypt: %s Formula: %s \n", ReadInput->Encrypt3, Formula3(FOR3));
					}
				}
				else
				{
					if (ProtectedProcess)
					{
						TerminateProcess(ProtectedProcess);
					}
					TerminateProcess(UsermodeAntiCheat);
					Status = STATUS_INVALID_PARAMETER;
					//BAD
					// ERROR
					// TERMINATE GAME OR PROTECTION 
					// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
					DbgPrintEx(0, 0, "Error: ReadInput->Encrypt2 == Formula2(FOR2) Encrypt: %s Formula: %s \n", ReadInput->Encrypt2, Formula2(FOR2));
				}
			}
			else
			{
				if (ProtectedProcess)
				{
					TerminateProcess(ProtectedProcess);
				}
				TerminateProcess(UsermodeAntiCheat);
				Status = STATUS_INVALID_PARAMETER;
				//BAD
				// ERROR
				// TERMINATE GAME OR PROTECTION 
				// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
				DbgPrintEx(0, 0, "Error: ReadInput->Encrypt1 == Formula1(FOR1) Encrypt: %s Formula: %s \n", ReadInput->Encrypt1, Formula1(FOR1));
			}

			BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);

		}

	}
	else if ((ULONG)ProtectedProcess == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
	{
		if (ControlCode == IO_RETURNANTICHEATUSERMODE_PROCESSID_GMAE)
		{
			PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
			ReadInput->UsermodeProgram = UsermodeAntiCheat;


			Status = STATUS_SUCCESS;
			BytesIO = sizeof(KERNEL_READ_REQUEST);

		}
	}

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

	return Status;
}

// Driver's Main function. This will be called and looped through till returned, or unloaded.
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pUniStr)
{
	DbgPrintEx(0, 0, "LOADED \n");
	UNICODE_STRING SACDriverName, SACSymbolName;
	NTSTATUS NtRet = STATUS_SUCCESS;
	PDEVICE_OBJECT pDeviceObj;
	RtlInitUnicodeString(&SACDriverName, L"\\Device\\SACDriver"); // Giving the driver a name
	RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
	UNICODE_STRING deviceNameUnicodeString, deviceSymLinkUnicodeString;
	NTSTATUS NtRet2 = IoCreateDevice(pDriverObject, 0, &SACDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);

	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);

	pDriverObject->DriverUnload = DriverUnload;

	EnableCallBack();

	return NtRet;

}

1 Ответ

0 голосов
/ 21 января 2019

Я не уверен, почему я получил синий экран смерти из-за этой функции rand ().

#include "DLLInjectorDector.h"
#include "AbortFailureDetects.h"
#include "DriverLoader\\driver.h"
#include "DriverIO.h"
#include "openssl\\md5.h"
#include "DriverIORequests.h"
#include "Formulas.h"
#include "Anti Debug.h"
#include "DLLInjectionDetector\Utils.h"
#include "Utlis.h"
#include "NamePipe.h"
#include "DigitalSignatureChecker.h"

#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <sys/types.h>  
#include <signal.h> 
#include <vector>

// Link with the Wintrust.lib file.
#pragma comment (lib, "wintrust")


// Varibles
HANDLE hDriver; // Driver
ULONG NamePipe1, NamePipe2, NamePipe3, NamePipe4, NamePipe5;
ULONG FOR1, FOR2, FOR3, FOR4, FOR5;
ULONG CHECK1, CHECK2, CHECK3, CHECK4, CHECK5;
ULONG CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5;
int GameProcessID = 0;

// Functions
bool CheckTestMode();
int randNum(int min, int max);

DWORD TidHeartBeat = 0;
DWORD TidGameValidChech = 0;
DWORD TidAntiDebug = 0;
DWORD tidDriverScanner = 0;
DWORD TidCommonCheatScanner = 0;
DWORD TidOverlayScanner = 0;
DWORD TidAntiKill = 0;
DWORD TidMainThread = 0;

BOOL HeartBeatThreadAntiKill = FALSE;
HANDLE hHeartBeatThread = NULL;
DWORD WINAPI HeartBeatThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		srand(time(0));
		FOR1 = randNum(2, 63);
		FOR2 = randNum(3, 34);
		FOR3 = randNum(8, 45);
		FOR4 = randNum(5, 67);
		FOR5 = randNum(2, 12);

		if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
		{
			KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();


			if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
			{
				if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
				{
					if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
					{
						if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
						{
							if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
							{
								KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();

								CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt1);
								CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt2);
								CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt3);
								CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt4);
								CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt5);
								if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
								{
									if ( CUtils::IsSuspendedThread(TidMainThread))
									{
										ErrorHandler::ErrorMessage("63452 ( Thread Mismatched )", 6);
									}

									HeartBeatThreadAntiKill = TRUE;
									Sleep(400);
								}
								else
								{
									ErrorHandler::ErrorMessage("601 ( HeartBeat System Failed )", 5);
									Sleep(3000);
									exit(1);
								}

							}
							else
							{
								ErrorHandler::ErrorMessage("602 ( HeartBeat System Failed )", 5);
								Sleep(3000);
								exit(1);
							}
						}
						else
						{
							ErrorHandler::ErrorMessage("603 ( HeartBeat System Failed )", 5);
							Sleep(3000);
							exit(1);
						}
					}
					else
					{
						ErrorHandler::ErrorMessage("604 ( HeartBeat System Failed )", 5);
						Sleep(3000);
						exit(1);
					}
				}
				else
				{
					ErrorHandler::ErrorMessage("605 ( HeartBeat System Failed )", 5);
					Sleep(3000);
					exit(1);
				}
			}
			else
			{
				ErrorHandler::ErrorMessage("606 ( HeartBeat System Failed )", 5);
				Sleep(3000);
				exit(1);
			}
		}
		else
		{
			ErrorHandler::ErrorMessage("607 ( HeartBeat System Failed )", 5);
			Sleep(3000);
			exit(1);
		}
	}
	return 0;
}


BOOL GameCheckerAntiKill = FALSE;
HANDLE hGameChecker = NULL;
DWORD WINAPI GameValidCheckThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		if (GameProcessID == 0)
		{
			Sleep(200);
		}
		else
		{
			if (!ErrorHandler::isProcessRunning(GameProcessID))
			{
				ErrorHandler::ErrorMessage("901 ( Game Stopped Running )", 3);
			}
		}

		if (CUtils::IsSuspendedThread(TidAntiDebug)
			|| CUtils::IsSuspendedThread(TidAntiKill))
		{
			ErrorHandler::ErrorMessage("32156 ( Thread Mismatched )", 6);
		}

		GameCheckerAntiKill = TRUE;
	}
}


BOOL AntiDebugAntiKill = FALSE;
HANDLE hAntiDebug = NULL;
DWORD WINAPI AntiDebugThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		if (AntiDebug::CheckRemoteDebuggerPresentAPI())
		{
			ErrorHandler::ErrorMessage("701", 6);
		}
		Sleep(200);
		if (AntiDebug::IsDebuggerPresentAPI())
		{
			ErrorHandler::ErrorMessage("702", 6);
		}
		Sleep(200);
		if (AntiDebug::HardwareBreakpoints())
		{
			ErrorHandler::ErrorMessage("703", 6);
		}
		Sleep(200);
		if (AntiDebug::MemoryBreakpoints_PageGuard())
		{
			ErrorHandler::ErrorMessage("704", 6);
		}
		Sleep(200);
		if (AntiDebug::UnhandledExcepFilterTest())
		{
			ErrorHandler::ErrorMessage("706", 6);
		}
		Sleep(200);
		if (AntiDebug::SharedUserData_KernelDebugger())
		{
			ErrorHandler::ErrorMessage("707", 6);
		}
		Sleep(200);

		if (CUtils::IsSuspendedThread(TidAntiDebug)
			|| CUtils::IsSuspendedThread(TidAntiKill))
		{
			ErrorHandler::ErrorMessage("34524 ( Thread Mismatched )", 6);
		}

		AntiDebugAntiKill = TRUE;
	}
}


BOOL DriversScanAntiKill = FALSE;
HANDLE hDriversScan = NULL;
DWORD WINAPI DriversScanThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		LPVOID drivers[1024];
		DWORD cbNeeded;
		int cDrivers, i;

		if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
		{
			/*
			TCHAR szDriver[1024];

			cDrivers = cbNeeded / sizeof(drivers[0]);

			for (i = 0; i < cDrivers; i++)
			{
				if (GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0])))
				{
					TCHAR szName[MAX_PATH] = { 0 };

					GetDeviceDriverFileName(drivers[i], szName, MAX_PATH);
					//_tprintf(TEXT("%d: %s\n"), i + 1, szName);
					Sleep(10);
				}
			}*/
			Sleep(100);
		}
		else
		{
			ErrorHandler::ErrorMessage("9753 ( Please Restart Your PC )", 5);
		}

		if (CUtils::IsSuspendedThread(TidAntiDebug)
			|| CUtils::IsSuspendedThread(TidAntiKill))
		{
			ErrorHandler::ErrorMessage("565435 ( Thread Mismatched )", 6);
		}
		DriversScanAntiKill = TRUE;
	}
}


BOOL CommonCheatsScannerAntiKill = FALSE;
HANDLE hCommonCheatsScanner = NULL;
DWORD WINAPI CommonCheatsScannerThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		const char DebuggingDrivers[9][20] = {
			"\\\\.\\EXTREM", "\\\\.\\ICEEXT",
			"\\\\.\\NDBGMSG.VXD", "\\\\.\\RING0",
			"\\\\.\\SIWVID", "\\\\.\\SYSER",
			"\\\\.\\TRW", "\\\\.\\SYSERBOOT",
			"\0"
		};


		for (int i = 0; DebuggingDrivers[i][0] != '\0'; i++) {
			HANDLE h = CreateFileA(DebuggingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
			if (h != INVALID_HANDLE_VALUE)
			{
				CloseHandle(h);
				ErrorHandler::ErrorMessage("2001 ( Debugging Drivers Found )", 6);
			}
			CloseHandle(h);
			Sleep(200);
		}

		const char CheatingDrivers[5][20] = {
			"\\\\.\\kernelhop", "\\\\.\\BlackBone",
			"\\\\.\\VBoxDrv", "\\\\.\\Htsysm72FB",
			"\0"
		};


		for (int i = 0; CheatingDrivers[i][0] != '\0'; i++) {
			HANDLE hCheats = CreateFileA(CheatingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
			if (hCheats != INVALID_HANDLE_VALUE)
			{
				CloseHandle(hCheats);
				ErrorHandler::ErrorMessage("3001 ( Cheating Drivers Found )", 2);
			}
			CloseHandle(hCheats);
			Sleep(200);
		}

		if (CUtils::IsSuspendedThread(TidAntiDebug)
			|| CUtils::IsSuspendedThread(TidAntiKill))
		{
			ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
		}

		CommonCheatsScannerAntiKill = TRUE;
		Sleep(200);
	}
}


BOOL OverlayScannerAntiKill = FALSE;
HANDLE hOverlayScanner = NULL;
DWORD WINAPI OverlayScannerThread()
{
	// https://www.unknowncheats.me/forum/anti-cheat-bypass/263403-window-hijacking-dont-overlay-betray.html
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		OverlayFinderParams params;
		params.style = WS_VISIBLE;
		params.styleEx = WS_EX_LAYERED | WS_EX_TRANSPARENT;
		params.percentMainScreen = 90.0f;
		params.satisfyAllCriteria = true;
		std::vector<HWND> hwnds = Utlis::OverlayFinder(params);

		for (int i(0); i < hwnds.size(); ++i) {
			DWORD ProcessIDForOverlay = 0;
			DWORD tid = GetWindowThreadProcessId(hwnds[i], &ProcessIDForOverlay);
			if (ErrorHandler::isProcessRunning(ProcessIDForOverlay))
			{
				DriverRequest::TerminatePrcoess(ProcessIDForOverlay);
				Sleep(200);
			}
			Sleep(200);
		}

		OverlayScannerAntiKill = TRUE;
		Sleep(200);
	}

}


BOOL AntiKillBool = FALSE;
HANDLE hAntiKill = NULL;
DWORD WINAPI AntiKillThread()
{
	AntiDebug::HideThread(GetCurrentThread());
	while (1)
	{
		if (CUtils::IsSuspendedThread(TidHeartBeat)
			|| CUtils::IsSuspendedThread(tidDriverScanner)
			|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
			|| CUtils::IsSuspendedThread(TidOverlayScanner)
			|| CUtils::IsSuspendedThread(TidGameValidChech)
			|| CUtils::IsSuspendedThread(TidMainThread)
			|| CUtils::IsSuspendedThread(TidAntiDebug))
		{
			ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
		}
		else
		{
			Sleep(200);
		}
	}

}


bool IsSystemCodeIntegrityEnabled()
{
	//https://stackoverflow.com/questions/40084077/can-i-have-any-way-to-detect-the-driver-signing-policy-status/50944791
	typedef NTSTATUS(__stdcall* td_NtQuerySystemInformation)(
		ULONG           SystemInformationClass,
		PVOID           SystemInformation,
		ULONG           SystemInformationLength,
		PULONG          ReturnLength
		);

	struct SYSTEM_CODEINTEGRITY_INFORMATION {
		ULONG Length;
		ULONG CodeIntegrityOptions;
	};

	static td_NtQuerySystemInformation NtQuerySystemInformation = (td_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");

	SYSTEM_CODEINTEGRITY_INFORMATION Integrity = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION), 0 };
	NTSTATUS status = NtQuerySystemInformation(103, &Integrity, sizeof(Integrity), NULL);

	return (status && (Integrity.CodeIntegrityOptions & 1));
}

void OnExit()
{
	if (GameProcessID != 0)
	{
		if (ErrorHandler::isProcessRunning(GameProcessID))
		{
			DriverRequest::TerminatePrcoess(GameProcessID);
		}
	}
	ErrorHandler::UnloadDriver();

}


int main()
{
	using namespace std;
	//FreeConsole();
	InitializeDLLCheck();
	InitializeThreadCheck();
	TidMainThread = GetCurrentThreadId();

	if (IsSystemCodeIntegrityEnabled())
	{
		ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
	}

	if (Utlis::IsRunAsAdministrator)
	{
		HANDLE CheckHandle = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

		if (CheckHandle != INVALID_HANDLE_VALUE)
		{
			ErrorHandler::UnloadDriver();
			CloseHandle(CheckHandle);
		}

		ErrorHandler::LoadDriver();
		Sleep(100);
		hDriver = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);


		//printf("File Size: %d \n", WhiteListedDLLs::GetFileSize("SAC-V2-DLL.dll"));

		if (hDriver)
		{
			if (DriverRequest::SendCurrentProcessID())
			{
				hAntiDebug = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiDebugThread, NULL, 0, &TidAntiDebug);

				srand(time(0));
				FOR1 = randNum(1, 35);
				FOR2 = randNum(1, 23);
				FOR3 = randNum(1, 23);
				FOR4 = randNum(1, 23);
				FOR5 = randNum(1, 34);
				if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
				{
					KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();

					ULONG TEST1 = HeartbeatFormula::Formula1(FOR1);
					ULONG TEST2 = RETURNED_HEARTBEAT.Encrypt1;

					if (RETURNED_HEARTBEAT.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
					{
						if (RETURNED_HEARTBEAT.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
						{
							if (RETURNED_HEARTBEAT.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
							{
								if (RETURNED_HEARTBEAT.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
								{
									if (RETURNED_HEARTBEAT.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
									{

										KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();

										CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1);
										CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2);
										CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3);
										CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4);
										CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5);

										if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
										{
											hHeartBeatThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HeartBeatThread, NULL, 0, &TidHeartBeat);
											hDriversScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DriversScanThread, NULL, 0, &tidDriverScanner);
											hCommonCheatsScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommonCheatsScannerThread, NULL, 0, &TidCommonCheatScanner);
											hOverlayScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OverlayScannerThread, NULL, 0, &TidOverlayScanner);


											STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
											PROCESS_INFORMATION ProcessInfo;
											if (CreateProcess("D:\\SteamLibrary\\steamapps\\common\\Kingdom New Lands\\Kingdom.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
											{
												BlockInput(TRUE);
												Utlis::Injection(L"SAC-V2-DLL.dll", ProcessInfo.dwProcessId);
												GameProcessID = ProcessInfo.dwProcessId;
												if (DriverRequest::SendProcessIDs(GameProcessID))
												{
													CloseHandle(ProcessInfo.hProcess);
													CloseHandle(ProcessInfo.hThread);
													

													BlockInput(FALSE);

													hGameChecker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GameValidCheckThread, NULL, 0, &TidGameValidChech);
													hAntiKill = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiKillThread, NULL, 0, &TidAntiKill);

													KERNEL_THREAD_REQUEST Threads;

													Threads.ThreadID = TidAntiDebug;
													Threads.ThreadID2 = TidHeartBeat;
													Threads.ThreadID3 = tidDriverScanner;
													Threads.ThreadID4 = TidCommonCheatScanner;
													Threads.ThreadID5 = TidOverlayScanner;
													Threads.ThreadID6 = TidGameValidChech;
													Threads.ThreadID7 = TidAntiKill;
													Threads.ThreadID8 = TidMainThread;

													if (DriverRequest::SendProtectedThreadID(Threads))
													{
														while (1)
														{
															atexit(OnExit);
															Sleep(4000);
															if (CUtils::IsSuspendedThread(TidHeartBeat)
																|| CUtils::IsSuspendedThread(tidDriverScanner)
																|| CUtils::IsSuspendedThread(TidGameValidChech)
																|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
																|| CUtils::IsSuspendedThread(TidOverlayScanner)
																|| CUtils::IsSuspendedThread(TidAntiDebug)
																|| CUtils::IsSuspendedThread(TidAntiKill))
															{
																ErrorHandler::ErrorMessage("32947 ( Thread Mismatched )", 6);
															}

															if (IsSystemCodeIntegrityEnabled())
															{
																ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
															}

															if (OverlayScannerAntiKill && CommonCheatsScannerAntiKill && DriversScanAntiKill && AntiDebugAntiKill && HeartBeatThreadAntiKill)
															{
																OverlayScannerAntiKill = FALSE;
																CommonCheatsScannerAntiKill = FALSE;
																DriversScanAntiKill = FALSE;
																AntiDebugAntiKill = FALSE;
																HeartBeatThreadAntiKill = FALSE;
															}
															else
															{
																ErrorHandler::ErrorMessage("9452 ( Thread Mismatched )", 5);
															}

														}
													}
													else
													{
														BlockInput(FALSE);
														ErrorHandler::ErrorMessage("43524 ( Thread Mismatched )", 5);
													}
												}
												else
												{
													ErrorHandler::ErrorMessage("202 ( Driver Not Found )", 1);
												}
											}
											else
											{
												ErrorHandler::ErrorMessage("945 ( Failed To Start Game )", 1);
											}

										}
										else
										{
											ErrorHandler::ErrorMessage("207 ( Driver Not Found )", 1);

										}

									}
									else
									{
										ErrorHandler::ErrorMessage("206 ( Driver Not Found )", 1);
									}
								}
								else
								{
									ErrorHandler::ErrorMessage("205 ( Driver Not Found )", 1);
								}
							}
							else
							{
								ErrorHandler::ErrorMessage("204 ( Driver Not Found )", 1);
							}
						}
						else
						{
							ErrorHandler::ErrorMessage("203 ( Driver Not Found )", 1);
						}
					}
					else
					{
						ErrorHandler::ErrorMessage("249 ( Driver Not Found )", 1);
					}

				}
				else
				{
					ErrorHandler::ErrorMessage("201 ( Driver Not Found )", 1);
				}
			}
			else
			{
				ErrorHandler::ErrorMessage("301 ( Driver Not Found )", 1);
			}

		}
		else
		{
			ErrorHandler::ErrorMessage("67 ( Driver Not Found )", 1);
		}

	}
	else
	{
		ErrorHandler::ErrorMessage("1001 ( Run As Admin )", 1);
	}

	return 0;
}


int randNum(int min, int max)
{
	return rand() % max + min;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...