Serial number enumeration failed when we cast Descriptor+Descriptor->SerialNumberOffset - c

I have a kernel driver which is used to find the serial number of storage devices, but there is an issue with the driver.
Descriptor->SerialNumberOffset is 103
but (LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset is NULL
here is my code
NTSTATUS GetDeviceTypeAndUniqueID(IN PDEVICE_OBJECT StorageStackDeviceObject, cwDevices *lDeviceTypeArg, char *pszUidArg)
{
DWORRD lDeviceType=0;
STORAGE_PROPERTY_QUERY Query;
STORAGE_DEVICE_DESCRIPTOR Buffer[4];
NTSTATUS Status = STATUS_SUCCESS;
ULONG uBusType=BusTypeUnknown;
PSTORAGE_DEVICE_DESCRIPTOR Descriptor=NULL;
PIRP NewIrp2=NULL;
PIO_STACK_LOCATION NextIrpStack=NULL;
IO_STATUS_BLOCK IoStatus;
char szSptr[2]={'_','\0'};
Query.PropertyId = StorageDeviceProperty;// first set the query properties
Query.QueryType = PropertyStandardQuery;
lDeviceType=0;
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
{
return STATUS_SUCCESS;
}
if(StorageStackDeviceObject == NULL)
{
return STATUS_SUCCESS;
}
if((StorageStackDeviceObject->DeviceType != FILE_DEVICE_DISK) &&
(StorageStackDeviceObject->DeviceType != FILE_DEVICE_CD_ROM)&&
(StorageStackDeviceObject->DeviceType != FILE_DEVICE_DVD)&&
(StorageStackDeviceObject->DeviceType !=FILE_DEVICE_TAPE) )
{
return STATUS_SUCCESS;
}
KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);// initialize the waitable event
__try
{
NewIrp2=IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject,
(PVOID)&Query,sizeof(STORAGE_PROPERTY_QUERY),
(PVOID)Buffer,sizeof(STORAGE_DEVICE_DESCRIPTOR)*4,
FALSE,&WaitEvent_newIrp,&IoStatus);
if(NewIrp2==NULL)
{
return STATUS_SUCCESS;
}
Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send this irp to the storage device
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL);
Status =IoStatus.Status;
}
}
__finally
{
if(NT_SUCCESS(Status))
{
if (NT_SUCCESS(Status))
{
if(Buffer!=NULL)
{
char szStart[256];
Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer;
uBusType = Descriptor->BusType; //Get the bus type.
if(Descriptor->SerialNumberOffset!=0)//Is Valid SerialNumberOffset, returns 103
{
strcpy(szStart,(char*)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset);
//szStart is null
}
}
NewIrp2 = NULL;
}
}
}
}
please share how to solve this

you mistake in OutputBufferLength - why you decide that sizeof(STORAGE_DEVICE_DESCRIPTOR)*4 is enough ? why not 5* sizeof(STORAGE_DEVICE_DESCRIPTOR) for example ? really what OutputBufferLength must be is unknown - you need call this query in loop and compare your current OutputBufferLength with STORAGE_DEVICE_DESCRIPTOR.Size - if OutputBufferLength < STORAGE_DEVICE_DESCRIPTOR.Size - you must again send IOCTL_STORAGE_QUERY_PROPERTY with OutputBufferLength = STORAGE_DEVICE_DESCRIPTOR.Size. the code can be look like.
STORAGE_PROPERTY_QUERY spq = { StorageDeviceProperty, PropertyStandardQuery };
union {
PVOID buf;
PSTR psz;
PSTORAGE_DEVICE_DESCRIPTOR psdd;
};
ULONG size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 0x100;
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
do
{
status = STATUS_INSUFFICIENT_RESOURCES;
if (buf = ExAllocatePool(PagedPool, size))
{
switch (status = (NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb,
IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), buf, size)))
{
case STATUS_SUCCESS:
case STATUS_BUFFER_OVERFLOW:
if (psdd->Version == sizeof(STORAGE_DEVICE_DESCRIPTOR))
{
if (psdd->Size > size)
{
size = psdd->Size;
status = STATUS_BUFFER_OVERFLOW;
}
else
{
if (psdd->SerialNumberOffset)
{
DbgPrint("SerialNumber = %s\n", psz + psdd->SerialNumberOffset);
}
}
}
else
{
status = STATUS_INVALID_PARAMETER;
}
break;
}
ExFreePool(buf);
}
} while (status == STATUS_BUFFER_OVERFLOW);
in place NtDeviceIoControlFile we of course can use IoBuildDeviceIoControlRequest + IoCallDriver - this nothing change and unrelated to problem

Related

Wait for all tasks to get initialized before starting capturing of data

I am running an application which reads ADC data through DMA at a frequency of 12kHz and transfers the captured data in a queue as soon as I get an interrupt.
Following is the configuration
STM32L496
CMSIS RTOS 2
Following are the problems I am facing:
Higher priority task gets initialized and running before other tasks are initialized.
Getting different errors when queue size is changed
osThreadId_t main_task_id;
osThreadId_t acquisition_task_id;
const osThreadAttr_t main_thread_attr = {
.stack_size = 1024U,
.priority = osPriorityAboveNormal3,
};
const osThreadAttr_t acq_thread_attr = {
.stack_size = 1024U,
.priority = osPriorityAboveNormal2,
};
osMessageQueueId_t main_queue_id = NULL;
osMessageQueueId_t acquisition_queue_id = NULL;
main(void)
{
osKernelInitialize();
main_task_init();
acquisition_task_init();
osKernelStart();
}
void main_task(void *argument)
{
osStatus_t status;
message_t msg;
switch_state swt_state;
swt_state = get_switch_state();
if(swt_state == SWITCH_ON)
{
msg.type = START_ADC_CAPTURE;
status = osMessageQueuePut(main_queue_id, &msg, 0U, 0U);
if (status != osOK)
{
// Handle error
}
}
memset(msg, 0x00, sizeof(msg));
while(1)
{
status = osMessageQueueGet(main_queue_id, &msg, NULL, osWaitForever);
if (status != osOK)
{
// Handle error
}
if (msg.type == START_ADC_CAPTURE)
{
// start capturing ADC data
}
}
}
void main_task_init(void)
{
main_queue_id = osMessageQueueNew(10, sizeof(message_t), NULL);
if (main_queue_id == NULL)
{
// Handle error
}
main_task_id = osThreadNew(main_task, NULL, &main_thread_attr);
if (main_task_id == NULL)
{
// Handle error
}
}
void acquisition_task(void *argument)
{
message_t msg;
osStatus_t status;
while(1)
{
status = osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever);
if (status != osOK)
{
// Handle error
}
}
}
void acquisition_task_init(void)
{
acquisition_queue_id = osMessageQueueNew(10, sizeof(message_t), NULL);
if (acquisition_queue_id == NULL)
{
// Handle error
}
acquisition_task_id = osThreadNew(acquisition_task, NULL, &acq_thread_attr);
if (acquisition_task_id == NULL)
{
// Handle error
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
osStatus_t status;
message_t msg;
memcpy(msg.buff, l_buff, l_buff_size * sizeof(uint16_t));
msg.type = ADC_DATA;
status = osMessageQueuePut(acquisition_queue_id, &msg, 0U, 0U);
if (status != osOK)
{
// Handle error
}
}
When I set acquisition_queue msg_count to 10, osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever); in acquisition_task is never called and queue becomes full resulting in osErrorResource error.
If I set msg_count to 20, osMessageQueueGet(acquisition_queue_id, &msg, NULL, osWaitForever); gets called but it keeps on waiting and immediately get osRtxErrorISRQueueOverflow error.
How to resolve this issue?
I tried adding random delay before starting capture to see what happens, no change is observed.

Correct closing DBus connection

Could you explain how to close DBus connection correctly/ Below is my variant:
int P_dbus_proto_init(DBusConnection **dbus_conn, const char *name, dbus_MessageHandler mh, int num_rules, const char **rules)
{
int rc = 0;
DBusError dbus_err;
dbus_error_init(&dbus_err);
*dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
rc = dbus_bus_request_name(*dbus_conn, name, DBUS_NAME_FLAG_REPLACE_EXISTING, &dbus_err);
if (dbus_error_is_set(&dbus_err) || (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != rc))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
dbus_connection_add_filter(*dbus_conn, mh, NULL, NULL);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Add Filter Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
for(int i = 0; i < num_rules; i++)
{
dbus_bus_add_match(*dbus_conn, rules[i], &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Match Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
}
return 0;
}
static const char* rules[] = {
"interface='acl_management.method'",
};
And how I use it:
DBusConnection *dbus_conn;
if (P_dbus_proto_init(&dbus_conn, "com.bla-bla-bla.acl", P_dbus_proto_job, 1, rules) == 0)
{
while (dbus_connection_read_write_dispatch(dbus_conn, 5000))
{
if(p_ctx->execute.n_nl_exit_app == 0) //My app can be terminated by n_nl_exit_app flag
{
break;
}
}
dbus_connection_close(dbus_conn);// Should I do it or not?
dbus_connection_unref(dbus_conn);// Should I do it or not?
}
From dbus.freedesktop.org docs I cannot understand how to do it correctly. I can terminate my app by turn on 'n_nl_exit_app' flag - should I call dbus_connection_closein this case?

Driver Blue Screen of Death System Service Exception

I'm Trying to test this Sagaan AntiCheat but i got bluescreen i use OSRLoader to load the driver and its load perfectly but when i open the .exe it's give me Blue Screen of Death https://prnt.sc/m9zl6o
the Source code of the FullProject https://github.com/SagaanTheEpic/Sagaan-AntiCheat-V2.0 I cant see where is the error can someone help me analyze this project that im trying to build. i want to recode it to add more features and make it better more.
#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;
}
Im not sure why i got bluescreen of death because of this rand() function.
#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;
}

Obtaining handle to key with NtCreateKey/NtOpenKey

PURPOSE
I'm trying to make a function which will create a given sub key in the HKCU registry hive, or open the sub key if it already exists, then return TRUE.
NOTES
Let RegSidPath represent a fully qualified HKCU registry path with an user SID appended to it such as \\Registry\\User\\S-1-5-20-xxxxxx-xxxxxx-xxxxxxxx-1050
Let KeyToCreate represent a specific registry path such as \\Software\\MyCompany\\MySoftware\\MySubKey
CODE
I have the following function:
BOOL CreateHKCUKey(PWCHAR RegSidPath, PWCHAR KeyToCreate) {
UNICODE_STRING uString;
RtlInitUnicodeString(&uString, RegSidPath);
OBJECT_ATTRIBUTES ObjAttributes;
InitializeObjectAttributes(&ObjAttributes, &uString, OBJ_CASE_INSENSITIVE, 0, 0);
HANDLE BaseKeyHandle = NULL;
NTSTATUS Status = NtOpenKey(&BaseKeyHandle, KEY_CREATE_SUB_KEY, &ObjAttributes);
if (NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) {
UNICODE_STRING KeyString = { 0 };
do {
PWCHAR NextSubKey = StrStrW((KeyString.Length == 0 ? KeyToCreate : KeyString.Buffer) + 1, L"\\");
DWORD CurrentKeyLength = lstrlenW(KeyToCreate) - lstrlenW(NextSubKey);
PWCHAR CurrentSubKey = PWCHAR(GlobalAlloc(GPTR, CurrentKeyLength + sizeof(WCHAR)));
if (CurrentSubKey != ERROR) {
memcpy(CurrentSubKey, KeyToCreate, CurrentKeyLength * sizeof(WCHAR));
CurrentSubKey[CurrentKeyLength] = UNICODE_NULL;
RtlInitUnicodeString(&KeyString, CurrentSubKey);
OBJECT_ATTRIBUTES KeyAttributes;
InitializeObjectAttributes(&KeyAttributes, &KeyString, OBJ_CASE_INSENSITIVE, &BaseKeyHandle, 0);
HANDLE CurrentHiveEntry = NULL;
Status = NtOpenKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes);
if (RtlNtStatusToDosError(Status) == ERROR_BAD_PATHNAME) {
InitializeObjectAttributes(&KeyAttributes, &KeyString, OBJ_CASE_INSENSITIVE, &CurrentHiveEntry, 0);
DWORD DefaultDisposition;
Status = NtCreateKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes, 0, NULL, REG_OPTION_NON_VOLATILE, &DefaultDisposition);
if (NT_SUCCESS(Status)) {
if (StrCmpNW(KeyString.Buffer + uString.Length, KeyString.Buffer, lstrlenW(KeyToCreate) == 0))
return TRUE;
else continue;
} else break;
} else break;
BaseKeyHandle = CurrentHiveEntry;
}
} while (TRUE);
}
NtClose(BaseKeyHandle);
return FALSE;
}
PROBLEM
Whenever the code gets to this part of the function
Status = NtOpenKey(&CurrentHiveEntry, KEY_CREATE_SUB_KEY, &KeyAttributes);
if (RtlNtStatusToDosError(Status) == ERROR_BAD_PATHNAME) {
The return value is always ERROR_BAD_PATHNAME (161) even if the current sub key already exists.
QUESTION
What is the reason, and what am I doing wrong? Is there anything that I've done which is not correct, and how can I fix it?
NTSTATUS CreateKey(PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, PWCHAR RegSidPath, PWCHAR KeyToCreate, PULONG Disposition)
{
UNICODE_STRING ObjectName;
RtlInitUnicodeString(&ObjectName, RegSidPath);
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName ,OBJ_CASE_INSENSITIVE };
NTSTATUS status = ZwOpenKey(&oa.RootDirectory, KEY_CREATE_SUB_KEY, &oa);
if (0 <= status)
{
ObjectName.Buffer = KeyToCreate;
do
{
ACCESS_MASK Access;
if (KeyToCreate = wcschr(++ObjectName.Buffer, '\\'))
{
ObjectName.Length = (USHORT)RtlPointerToOffset(ObjectName.Buffer, KeyToCreate);
Access = KEY_CREATE_SUB_KEY;
}
else
{
ObjectName.Length = (USHORT)wcslen(ObjectName.Buffer) * sizeof(WCHAR);
Access = DesiredAccess;
}
ObjectName.MaximumLength = ObjectName.Length;
status = ZwCreateKey(KeyHandle, Access, &oa, 0, 0, 0, Disposition);
NtClose(oa.RootDirectory);
oa.RootDirectory = *KeyHandle;
} while (0 <= status && (ObjectName.Buffer = KeyToCreate));
}
return status;
}
and use as
HANDLE hKey;
NTSTATUS status = CreateKey(&hKey, KEY_ALL_ACCESS,
L"\\REGISTRY\\USER\\S-***",
L"\\Software\\MyCompany\\MySoftware\\MySubKey", 0);
Unless you are writing a driver, use RegCreateKeyEx() instead. It handles all the logic of creating intermediate keys for you if they don't already exist. 1 function call, no looping needed.
HKEY hKey;
DWORD dwDisposition;
LONG lRet = RegCreateKeyExW(HKEY_USERS, L"S-1-5-20-xxxxxx-xxxxxx-xxxxxxxx-1050\\Software\\MyCompany\\MySoftware\\MySubKey", 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &hKey, &dwDisposition);
if (lRet == 0)
{
...
RegCloseKey(hKey);
}
However, to access the HKEY_CURRENT_USER hive of a specific user, the preferred solution is to use RegOpenCurrentUser() or LoadUserProfile() instead of accessing HKEY_USERS directly:
// impersonate the desired user first, then...
HKEY hRootKey;
LONG lRet = RegOpenCurrentUser(samDesired, &hRootKey);
if (lRet == 0)
{
HKEY hKey;
DWORD dwDisposition;
lRet = RegCreateKeyExW(hRootKey, L"Software\\MyCompany\\MySoftware\\MySubKey", 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &hKey, &dwDisposition);
if (lRet == 0)
{
...
RegCloseKey(hKey);
}
RegCloseKey(hRootKey);
}
// stop impersonating...
// obtain token to desired user first, then...
PROFILEINFO profile = {0};
profile.dwSize = sizeof(profile);
profile.dwFlags = PI_NOUI;
if (LoadUserProfile(hToken, &profile))
{
HKEY hKey;
DWORD dwDisposition;
LONG lRet = RegCreateKeyExW((HKEY)profile.hProfile, L"Software\\MyCompany\\MySoftware\\MySubKey", 0, NULL, REG_OPTION_NON_VOLATILE, samDesired, NULL, &hKey, &dwDisposition);
if (lRet == 0)
{
...
RegCloseKey(hKey);
}
UnloadUserProfile(hToken, profile.hProfile);
}
// release token ...

How to set l2tp preshared key?

I need to create RASENTRY for L2TP with pre-shared key set. So far, I can see that entry has somewhat correct flags, but no key is set, unfortunately.
Here is code:
int common_ras_manager_create_entry(const char* server_address, const char* username, const char* password, MY_VPN_CONNECTION_TYPE connection_type, const char* preshared_key)
{
DWORD EntryInfoSize = 0;
DWORD DeviceInfoSize = 0;
DWORD Ret;
LPRASENTRY lpRasEntry;
LPBYTE lpDeviceInfo;
// Get buffer sizing information for a default phonebook entry
if ((Ret = RasGetEntryProperties(NULL, "", NULL, &EntryInfoSize, lpDeviceInfo, &DeviceInfoSize)) != 0)
{
if (Ret != ERROR_BUFFER_TOO_SMALL)
{
printf("RasGetEntryProperties sizing failed with error %d\n", Ret);
return Ret;
}
}
lpRasEntry = (LPRASENTRY) GlobalAlloc(GPTR, EntryInfoSize);
if (DeviceInfoSize == 0)
lpDeviceInfo = NULL;
else
lpDeviceInfo = (LPBYTE) GlobalAlloc(GPTR, DeviceInfoSize);
// Get default phonebook entry
lpRasEntry->dwSize = sizeof(RASENTRY);
if ((Ret = RasGetEntryProperties(NULL, "", lpRasEntry, &EntryInfoSize, lpDeviceInfo, &DeviceInfoSize)) != 0)
{
printf("RasGetEntryProperties failed with error %d\n", Ret);
return Ret;
}
// Validate new phonebook name "Testentry"
if ((Ret = RasValidateEntryName(NULL, APP_NAME)) != ERROR_SUCCESS)
{
printf("RasValidateEntryName failed with error %d\n", Ret);
if (Ret != ERROR_ALREADY_EXISTS)
return Ret;
}
LPRASDEVINFO ras_devices;
DWORD cb =sizeof(RASDEVINFO);
DWORD cbDevices = 0;
ras_devices = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
if (NULL == ras_devices)
{
printf("HeapAlloc failed.\n");
return ERROR_OUTOFMEMORY;
}
ras_devices->dwSize = sizeof(RASDEVINFO);
if ((Ret = RasEnumDevices(ras_devices, &cb, &cbDevices)) != ERROR_SUCCESS)
{
printf("RasEnumDevices failed with error %d\n", Ret);
switch(Ret)
{
case ERROR_BUFFER_TOO_SMALL:
printf("buffer too small");
HeapFree(GetProcessHeap(), 0, (LPVOID)ras_devices);
ras_devices = (LPRASDEVINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
if (NULL == ras_devices)
{
printf("HeapAlloc failed.\n");
return ERROR_OUTOFMEMORY;
}
ras_devices->dwSize = sizeof(RASDEVINFO);
Ret = RasEnumDevices(ras_devices, &cb, &cbDevices);
if (ERROR_SUCCESS == Ret)
{
//fSuccess = TRUE;
}
else
{
printf("RasEnumDevices failed again: Error = %d\n", Ret);
return Ret;
//goto done;
}
break;
case ERROR_NOT_ENOUGH_MEMORY:
printf("ERROR_NOT_ENOUGH_MEMORY");
return Ret;
break;
case ERROR_INVALID_PARAMETER:
printf("ERROR_INVALID_PARAMETER");
return Ret;
break;
case ERROR_INVALID_USER_BUFFER:
printf("ERROR_INVALID_USER_BUFFER");
return Ret;
break;
}
}
DWORD dwVpnStrategy = 0;
char device_name_mask[5];
strcpy(device_name_mask, "");
gboolean preshared_key_valid = 0;
switch(connection_type)
{
case PPTP:
strcpy(device_name_mask, "PPTP");
dwVpnStrategy = VS_PptpOnly;
break;
case L2TP:
if (preshared_key == 0 || strlen(preshared_key) == 0)
{
printf("CRITICAL: preshared key not set.");
return 1;
}
else
{
preshared_key_valid = TRUE;
}
strcpy(device_name_mask, "L2TP");
dwVpnStrategy = VS_L2tpOnly;
break;
}
int i =0;
for (i = 0; i < cbDevices; i++)
{
RASDEVINFO r = ras_devices[i];
if (strstr(r.szDeviceName, device_name_mask))
{
break;
}
}
//lpRasEntry->dwfOptions |= RASEO_SpecificIpAddr;
//lpRasEntry->szLocalPhoneNumber = RASDT_Vpn;
lpRasEntry->dwfNetProtocols |= RASNP_Ip;
lpRasEntry->dwFramingProtocol = RASFP_Ppp;
lstrcpy(lpRasEntry->szDeviceType, RASDT_Vpn);
lstrcpy(lpRasEntry->szDeviceName, ras_devices[i].szDeviceName);
lstrcpy(lpRasEntry->szLocalPhoneNumber, server_address);
lpRasEntry->dwVpnStrategy = dwVpnStrategy; // VS_PptpOnly; VS_SstpOnly
if (preshared_key_valid)
{
L2TP_CONFIG_DATA* data = GlobalAlloc(GPTR, sizeof(L2TP_CONFIG_DATA));
lpRasEntry->dwfOptions2 |= RASEO2_UsePreSharedKey;
data->dwOffsetKey = 16;
memcpy((PBYTE)data + data->dwOffsetKey, preshared_key, strlen(preshared_key));
data->dwAuthType =L2TP_IPSEC_AUTH_PRESHAREDKEY;
RasSetCustomAuthData(NULL, APP_NAME, data, sizeof(L2TP_CONFIG_DATA));
}
if ((Ret = RasSetEntryProperties(NULL, APP_NAME, lpRasEntry, EntryInfoSize, lpDeviceInfo, DeviceInfoSize)) != 0)
{
printf("RasSetEntryProperties failed with error %d\n", Ret);
return Ret;
}
//if ((Ret = RasSetCredentials(NULL, lpRasEntry.))
}
I cant find where is buffer to fill for pre-shared key.
Following code works fine.
// l2tp
if (preshared_key_valid)
{
RASCREDENTIALS ras_cre_psk = {0};
ras_cre_psk.dwSize = sizeof(ras_cre_psk);
ras_cre_psk.dwMask = 0x00000010; //RASCM_PreSharedKey;
wcscpy(ras_cre_psk.szPassword, preshared_key);
if ((Ret = RasSetCredentials(NULL, APP_NAME, &ras_cre_psk, FALSE)))
{
printf("RasSetCredentials failed with error %d\n", Ret);
return Ret;
}
}

Resources