2016-07-21 23:02:31 +00:00
|
|
|
#include "RegFilter.h"
|
|
|
|
#include "FsFilter.h"
|
2016-08-30 19:40:25 +00:00
|
|
|
#include "PsMonitor.h"
|
2016-07-21 23:02:31 +00:00
|
|
|
#include "Device.h"
|
|
|
|
#include "DeviceAPI.h"
|
2016-12-12 20:40:35 +00:00
|
|
|
#include "Driver.h"
|
2018-12-02 21:56:39 +00:00
|
|
|
#include "Helper.h"
|
2016-07-21 23:02:31 +00:00
|
|
|
|
2016-10-10 21:37:28 +00:00
|
|
|
BOOLEAN g_deviceInited = FALSE;
|
2016-07-21 23:02:31 +00:00
|
|
|
PDEVICE_OBJECT g_deviceObject = NULL;
|
|
|
|
|
|
|
|
// =========================================================================================
|
|
|
|
|
2017-02-02 22:55:19 +00:00
|
|
|
_Function_class_(DRIVER_DISPATCH)
|
|
|
|
_Dispatch_type_(IRP_MJ_CREATE)
|
2016-08-30 19:40:25 +00:00
|
|
|
NTSTATUS IrpDeviceCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-02-02 22:55:19 +00:00
|
|
|
_Function_class_(DRIVER_DISPATCH)
|
|
|
|
_Dispatch_type_(IRP_MJ_CLOSE)
|
2016-08-30 19:40:25 +00:00
|
|
|
NTSTATUS IrpDeviceClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2017-02-02 22:55:19 +00:00
|
|
|
|
|
|
|
_Function_class_(DRIVER_DISPATCH)
|
|
|
|
_Dispatch_type_(IRP_MJ_CLEANUP)
|
2016-08-30 19:40:25 +00:00
|
|
|
NTSTATUS IrpDeviceCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
|
|
|
|
|
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS AddHiddenObject(PHid_HideObjectPacket Packet, USHORT Size, PULONGLONG ObjId)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
UNICODE_STRING path;
|
|
|
|
USHORT i, count;
|
|
|
|
|
2016-08-31 22:28:18 +00:00
|
|
|
// Check can we access to the packet
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size < sizeof(Hid_HideObjectPacket))
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Check packet data size overflow
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size < Packet->dataSize + sizeof(Hid_HideObjectPacket))
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Unpack string to UNICODE_STRING
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
path.Buffer = (LPWSTR)((PCHAR)Packet + sizeof(Hid_HideObjectPacket));
|
|
|
|
path.MaximumLength = Size - sizeof(Hid_HideObjectPacket);
|
2016-07-21 23:02:31 +00:00
|
|
|
|
2016-08-31 22:28:18 +00:00
|
|
|
// Just checking for zero-end string ends in the middle
|
2016-09-04 17:17:21 +00:00
|
|
|
count = Packet->dataSize / sizeof(WCHAR);
|
2016-07-21 23:02:31 +00:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
if (path.Buffer[i] == L'\0')
|
|
|
|
break;
|
|
|
|
|
|
|
|
path.Length = i * sizeof(WCHAR);
|
|
|
|
|
2016-08-31 22:28:18 +00:00
|
|
|
// Perform the packet
|
2016-07-21 23:02:31 +00:00
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
case RegKeyObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = AddHiddenRegKey(&path, ObjId);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case RegValueObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = AddHiddenRegValue(&path, ObjId);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case FsFileObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = AddHiddenFile(&path, ObjId);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case FsDirObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = AddHiddenDir(&path, ObjId);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS RemoveHiddenObject(PHid_UnhideObjectPacket Packet, USHORT Size)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size != sizeof(Hid_UnhideObjectPacket))
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
case RegKeyObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveHiddenRegKey(Packet->id);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case RegValueObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveHiddenRegValue(Packet->id);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case FsFileObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveHiddenFile(Packet->id);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
case FsDirObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveHiddenDir(Packet->id);
|
2016-07-21 23:02:31 +00:00
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS RemoveAllHiddenObjects(PHid_UnhideAllObjectsPacket Packet, USHORT Size)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size != sizeof(Hid_UnhideAllObjectsPacket))
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
case RegKeyObject:
|
|
|
|
status = RemoveAllHiddenRegKeys();
|
|
|
|
break;
|
|
|
|
case RegValueObject:
|
|
|
|
status = RemoveAllHiddenRegValues();
|
|
|
|
break;
|
|
|
|
case FsFileObject:
|
|
|
|
status = RemoveAllHiddenFiles();
|
|
|
|
break;
|
|
|
|
case FsDirObject:
|
|
|
|
status = RemoveAllHiddenDirs();
|
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS AddPsObject(PHid_AddPsObjectPacket Packet, USHORT Size, PULONGLONG ObjId)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
UNICODE_STRING path;
|
|
|
|
USHORT i, count;
|
|
|
|
|
|
|
|
// Check can we access to the packet
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size < sizeof(Hid_AddPsObjectPacket))
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Check packet data size overflow
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size < Packet->dataSize + sizeof(Hid_AddPsObjectPacket))
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Unpack string to UNICODE_STRING
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
path.Buffer = (LPWSTR)((PCHAR)Packet + sizeof(Hid_AddPsObjectPacket));
|
|
|
|
path.MaximumLength = Size - sizeof(Hid_AddPsObjectPacket);
|
2016-08-31 22:28:18 +00:00
|
|
|
|
|
|
|
// Just checking for zero-end string ends in the middle
|
2016-09-04 17:17:21 +00:00
|
|
|
count = Packet->dataSize / sizeof(WCHAR);
|
2016-08-31 22:28:18 +00:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
if (path.Buffer[i] == L'\0')
|
|
|
|
break;
|
|
|
|
|
|
|
|
path.Length = i * sizeof(WCHAR);
|
|
|
|
|
|
|
|
// Perform the packet
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
case PsExcludedObject:
|
2016-10-18 21:28:55 +00:00
|
|
|
status = AddExcludedImage(&path, Packet->inheritType, (Packet->applyForProcesses ? TRUE : FALSE), ObjId);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
case PsProtectedObject:
|
2016-10-18 21:28:55 +00:00
|
|
|
status = AddProtectedImage(&path, Packet->inheritType, (Packet->applyForProcesses ? TRUE : FALSE), ObjId);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS GetPsObjectInfo(PHid_GetPsObjectInfoPacket Packet, USHORT Size, PHid_GetPsObjectInfoPacket OutPacket, PULONG OutSize)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2016-09-04 17:17:21 +00:00
|
|
|
ULONG inheritType, outSize;
|
|
|
|
BOOLEAN enable;
|
2016-08-31 22:28:18 +00:00
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
outSize = *OutSize;
|
|
|
|
*OutSize = 0;
|
|
|
|
|
|
|
|
if (Size < sizeof(Hid_GetPsObjectInfoPacket))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
if (outSize < sizeof(Hid_GetPsObjectInfoPacket))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
|
|
|
switch (Packet->objType)
|
|
|
|
{
|
|
|
|
case PsExcludedObject:
|
|
|
|
status = GetExcludedProcessState((HANDLE)Packet->procId, &inheritType, &enable);
|
|
|
|
break;
|
|
|
|
case PsProtectedObject:
|
|
|
|
status = GetProtectedProcessState((HANDLE)Packet->procId, &inheritType, &enable);
|
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-09-04 17:17:21 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
Packet->enable = (USHORT)enable;
|
|
|
|
Packet->inheritType = (USHORT)inheritType;
|
|
|
|
|
2016-09-22 20:17:12 +00:00
|
|
|
RtlCopyMemory(OutPacket, Packet, sizeof(Hid_GetPsObjectInfoPacket));
|
2016-09-04 17:17:21 +00:00
|
|
|
*OutSize = sizeof(Hid_GetPsObjectInfoPacket);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS SetPsObjectInfo(PHid_SetPsObjectInfoPacket Packet, USHORT Size)
|
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
if (Size != sizeof(Hid_SetPsObjectInfoPacket))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
|
|
|
switch (Packet->objType)
|
|
|
|
{
|
|
|
|
case PsExcludedObject:
|
|
|
|
status = SetExcludedProcessState((HANDLE)Packet->procId, Packet->inheritType, (Packet->enable ? TRUE : FALSE));
|
|
|
|
break;
|
|
|
|
case PsProtectedObject:
|
|
|
|
status = SetProtectedProcessState((HANDLE)Packet->procId, Packet->inheritType, (Packet->enable ? TRUE : FALSE));
|
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-09-04 17:17:21 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS RemovePsObject(PHid_RemovePsObjectPacket Packet, USHORT Size)
|
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
if (Size != sizeof(Hid_RemovePsObjectPacket))
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
case PsExcludedObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveExcludedImage(Packet->id);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
case PsProtectedObject:
|
2016-09-04 17:17:21 +00:00
|
|
|
status = RemoveProtectedImage(Packet->id);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
NTSTATUS RemoveAllPsObjects(PHid_RemoveAllPsObjectsPacket Packet, USHORT Size)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
if (Size != sizeof(Hid_RemoveAllPsObjectsPacket))
|
2016-08-31 22:28:18 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
// Perform packet
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
switch (Packet->objType)
|
2016-08-31 22:28:18 +00:00
|
|
|
{
|
|
|
|
case PsExcludedObject:
|
|
|
|
status = RemoveAllExcludedImages();
|
|
|
|
break;
|
|
|
|
case PsProtectedObject:
|
|
|
|
status = RemoveAllProtectedImages();
|
|
|
|
break;
|
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unsupported object type: %u", Packet->objType);
|
2016-07-21 23:02:31 +00:00
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-12-12 20:40:35 +00:00
|
|
|
NTSTATUS SetDriverStateObject(PHid_DriverStatus Packet, USHORT Size)
|
|
|
|
{
|
|
|
|
if (Size != sizeof(Hid_DriverStatus))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
EnableDisableDriver(Packet->state ? TRUE : FALSE);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS GetDriverStateObject(PHid_DriverStatus Packet, USHORT Size, PULONG state)
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(Packet);
|
|
|
|
|
|
|
|
if (Size != sizeof(Hid_DriverStatus))
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
|
|
|
|
*state = IsDriverEnabled();
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2017-02-02 22:55:19 +00:00
|
|
|
_Function_class_(DRIVER_DISPATCH)
|
|
|
|
_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
|
2016-08-30 19:40:25 +00:00
|
|
|
NTSTATUS IrpDeviceControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
2016-07-21 23:02:31 +00:00
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION irpStack;
|
|
|
|
Hid_StatusPacket result;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
2016-09-04 17:17:21 +00:00
|
|
|
PVOID inputBuffer, outputBuffer, outputData;
|
|
|
|
ULONG ioctl, inputBufferSize, outputBufferSize, outputBufferMaxSize,
|
|
|
|
outputDataMaxSize, outputDataSize;
|
2016-07-21 23:02:31 +00:00
|
|
|
|
|
|
|
UNREFERENCED_PARAMETER(DeviceObject);
|
2016-09-04 17:17:21 +00:00
|
|
|
|
2016-07-21 23:02:31 +00:00
|
|
|
// Get irp information
|
|
|
|
|
|
|
|
irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
ioctl = irpStack->Parameters.DeviceIoControl.IoControlCode;
|
|
|
|
|
|
|
|
inputBuffer = outputBuffer = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
inputBufferSize = irpStack->Parameters.DeviceIoControl.InputBufferLength;
|
|
|
|
outputBufferMaxSize = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
|
2016-09-04 17:17:21 +00:00
|
|
|
outputBufferSize = 0;
|
|
|
|
outputDataSize = 0;
|
|
|
|
outputDataMaxSize = 0;
|
2016-07-21 23:02:31 +00:00
|
|
|
|
|
|
|
RtlZeroMemory(&result, sizeof(result));
|
|
|
|
|
|
|
|
// Check output buffer size
|
|
|
|
|
|
|
|
if (outputBufferMaxSize < sizeof(result))
|
|
|
|
{
|
|
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto EndProc;
|
|
|
|
}
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
// Prepare additional buffer for output data
|
|
|
|
outputData = (PVOID)((UINT_PTR)outputBuffer + sizeof(result));
|
|
|
|
outputDataMaxSize = outputBufferMaxSize - sizeof(result);
|
|
|
|
|
2016-09-11 11:39:12 +00:00
|
|
|
// Important limitation:
|
2016-09-04 17:17:21 +00:00
|
|
|
// Because both input (inputBuffer) and output data (outputData) are located in the same buffer there is a limitation for the output
|
|
|
|
// buffer usage. When a ioctl handler is executing, it can use the input buffer only until first write to the output buffer, because
|
|
|
|
// when you put data to the output buffer you can overwrite data in input buffer. Therefore if you gonna use both an input and output
|
|
|
|
// data in the same time you should make the copy of input data and work with it.
|
2016-07-21 23:02:31 +00:00
|
|
|
switch (ioctl)
|
|
|
|
{
|
2016-12-12 20:40:35 +00:00
|
|
|
// Driver
|
|
|
|
case HID_IOCTL_SET_DRIVER_STATE:
|
|
|
|
result.status = SetDriverStateObject((PHid_DriverStatus)inputBuffer, (USHORT)inputBufferSize);
|
|
|
|
break;
|
|
|
|
case HID_IOCTL_GET_DRIVER_STATE:
|
|
|
|
result.status = GetDriverStateObject((PHid_DriverStatus)inputBuffer, (USHORT)inputBufferSize, &result.info.state);
|
|
|
|
break;
|
2016-08-31 22:28:18 +00:00
|
|
|
// Reg/Fs
|
2016-07-21 23:02:31 +00:00
|
|
|
case HID_IOCTL_ADD_HIDDEN_OBJECT:
|
|
|
|
result.status = AddHiddenObject((PHid_HideObjectPacket)inputBuffer, (USHORT)inputBufferSize, &result.info.id);
|
|
|
|
break;
|
|
|
|
case HID_IOCTL_REMOVE_HIDDEN_OBJECT:
|
|
|
|
result.status = RemoveHiddenObject((PHid_UnhideObjectPacket)inputBuffer, (USHORT)inputBufferSize);
|
|
|
|
break;
|
|
|
|
case HID_IOCTL_REMOVE_ALL_HIDDEN_OBJECTS:
|
|
|
|
result.status = RemoveAllHiddenObjects((PHid_UnhideAllObjectsPacket)inputBuffer, (USHORT)inputBufferSize);
|
|
|
|
break;
|
2016-08-31 22:28:18 +00:00
|
|
|
// Ps
|
|
|
|
case HID_IOCTL_ADD_OBJECT:
|
|
|
|
result.status = AddPsObject((PHid_AddPsObjectPacket)inputBuffer, (USHORT)inputBufferSize, &result.info.id);
|
|
|
|
break;
|
|
|
|
case HID_IOCTL_GET_OBJECT_STATE:
|
2016-09-04 17:17:21 +00:00
|
|
|
outputDataSize = outputDataMaxSize;
|
|
|
|
result.status = GetPsObjectInfo((PHid_SetPsObjectInfoPacket)inputBuffer, (USHORT)inputBufferSize, outputData, &outputDataSize);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
case HID_IOCTL_SET_OBJECT_STATE:
|
2016-09-04 17:17:21 +00:00
|
|
|
result.status = SetPsObjectInfo((PHid_SetPsObjectInfoPacket)inputBuffer, (USHORT)inputBufferSize);
|
2016-08-31 22:28:18 +00:00
|
|
|
break;
|
|
|
|
case HID_IOCTL_REMOVE_OBJECT:
|
|
|
|
result.status = RemovePsObject((PHid_RemovePsObjectPacket)inputBuffer, (USHORT)inputBufferSize);
|
|
|
|
break;
|
|
|
|
case HID_IOCTL_REMOVE_ALL_OBJECTS:
|
|
|
|
result.status = RemoveAllPsObjects((PHid_RemoveAllPsObjectsPacket)inputBuffer, (USHORT)inputBufferSize);
|
|
|
|
break;
|
2016-09-11 11:39:12 +00:00
|
|
|
// Other
|
2016-07-21 23:02:31 +00:00
|
|
|
default:
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Unknown IOCTL code:%08x", ioctl);
|
2016-07-21 23:02:31 +00:00
|
|
|
status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto EndProc;
|
|
|
|
}
|
|
|
|
|
|
|
|
EndProc:
|
|
|
|
|
2016-09-04 17:17:21 +00:00
|
|
|
// If additional output data has been presented
|
|
|
|
if (NT_SUCCESS(status) && outputDataSize > 0)
|
|
|
|
{
|
|
|
|
if (outputDataSize > outputDataMaxSize)
|
|
|
|
{
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("An internal error, looks like a stack corruption!");
|
2016-09-04 17:17:21 +00:00
|
|
|
outputDataSize = outputDataMaxSize;
|
|
|
|
result.status = (ULONG)STATUS_PARTIAL_COPY;
|
|
|
|
}
|
|
|
|
|
|
|
|
result.dataSize = outputDataSize;
|
|
|
|
}
|
|
|
|
|
2016-07-21 23:02:31 +00:00
|
|
|
// Copy result to output buffer
|
|
|
|
if (NT_SUCCESS(status))
|
|
|
|
{
|
2016-09-22 20:17:12 +00:00
|
|
|
outputBufferSize = sizeof(result) + outputDataSize;
|
2016-07-21 23:02:31 +00:00
|
|
|
RtlCopyMemory(outputBuffer, &result, sizeof(result));
|
|
|
|
}
|
|
|
|
|
|
|
|
Irp->IoStatus.Status = status;
|
|
|
|
Irp->IoStatus.Information = outputBufferSize;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS InitializeDevice(PDRIVER_OBJECT DriverObject)
|
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
|
|
|
|
UNICODE_STRING dosDeviceName = RTL_CONSTANT_STRING(DOS_DEVICES_LINK_NAME);
|
|
|
|
PDEVICE_OBJECT deviceObject = NULL;
|
|
|
|
|
|
|
|
status = IoCreateDevice(DriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
|
|
{
|
2018-12-02 21:56:39 +00:00
|
|
|
LogError("Error, device creation failed with code:%08x", status);
|
2016-07-21 23:02:31 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = IoCreateSymbolicLink(&dosDeviceName, &deviceName);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
|
|
{
|
|
|
|
IoDeleteDevice(deviceObject);
|
2018-12-02 21:56:39 +00:00
|
|
|
LogError("Error, symbolic link creation failed with code:%08x", status);
|
2016-07-21 23:02:31 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2016-08-30 19:40:25 +00:00
|
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpDeviceCreate;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpDeviceClose;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = IrpDeviceCleanup;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpDeviceControlHandler;
|
2016-07-21 23:02:31 +00:00
|
|
|
g_deviceObject = deviceObject;
|
2016-10-10 21:37:28 +00:00
|
|
|
g_deviceInited = TRUE;
|
2016-07-21 23:02:31 +00:00
|
|
|
|
2018-12-02 21:56:39 +00:00
|
|
|
LogTrace("Initialization is completed");
|
2016-07-21 23:02:31 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS DestroyDevice()
|
|
|
|
{
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
UNICODE_STRING dosDeviceName = RTL_CONSTANT_STRING(DOS_DEVICES_LINK_NAME);
|
|
|
|
|
2016-10-10 21:37:28 +00:00
|
|
|
if (!g_deviceInited)
|
|
|
|
return STATUS_NOT_FOUND;
|
|
|
|
|
2016-07-21 23:02:31 +00:00
|
|
|
status = IoDeleteSymbolicLink(&dosDeviceName);
|
|
|
|
if (!NT_SUCCESS(status))
|
2018-12-02 21:56:39 +00:00
|
|
|
LogWarning("Error, symbolic link deletion failed with code:%08x", status);
|
2016-07-21 23:02:31 +00:00
|
|
|
|
|
|
|
IoDeleteDevice(g_deviceObject);
|
|
|
|
|
2016-10-10 21:37:28 +00:00
|
|
|
g_deviceInited = FALSE;
|
|
|
|
|
2018-12-02 21:56:39 +00:00
|
|
|
LogTrace("Deinitialization is completed");
|
2016-07-21 23:02:31 +00:00
|
|
|
return status;
|
|
|
|
}
|