6
0
mirror of https://github.com/JKornev/hidden synced 2024-06-27 09:28:04 +00:00
hidden/Hidden/Device.c
2016-09-01 01:28:24 +03:00

383 lines
9.8 KiB
C

#include "RegFilter.h"
#include "FsFilter.h"
#include "PsMonitor.h"
#include "Device.h"
#include "DeviceAPI.h"
PDEVICE_OBJECT g_deviceObject = NULL;
// =========================================================================================
NTSTATUS IrpDeviceCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!!\n");
return STATUS_SUCCESS;
}
NTSTATUS IrpDeviceClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!!\n");
return STATUS_SUCCESS;
}
NTSTATUS IrpDeviceCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DbgPrint("FsFilter1!" __FUNCTION__ ": !!!!!\n");
return STATUS_SUCCESS;
}
NTSTATUS AddHiddenObject(PHid_HideObjectPacket packet, USHORT size, PULONGLONG objId)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING path;
USHORT i, count;
// Check can we access to the packet
if (size < sizeof(Hid_HideObjectPacket))
return STATUS_INVALID_PARAMETER;
// Check packet data size overflow
if (size < packet->size + sizeof(Hid_HideObjectPacket))
return STATUS_INVALID_PARAMETER;
// Unpack string to UNICODE_STRING
path.Buffer = (LPWSTR)((PCHAR)packet + sizeof(Hid_HideObjectPacket));
path.MaximumLength = size - sizeof(Hid_HideObjectPacket);
// Just checking for zero-end string ends in the middle
count = packet->size / sizeof(WCHAR);
for (i = 0; i < count; i++)
if (path.Buffer[i] == L'\0')
break;
path.Length = i * sizeof(WCHAR);
// Perform the packet
switch (packet->objType)
{
case RegKeyObject:
status = AddHiddenRegKey(&path, objId);
break;
case RegValueObject:
status = AddHiddenRegValue(&path, objId);
break;
case FsFileObject:
status = AddHiddenFile(&path, objId);
break;
case FsDirObject:
status = AddHiddenDir(&path, objId);
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS RemoveHiddenObject(PHid_UnhideObjectPacket packet, USHORT size)
{
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(Hid_UnhideObjectPacket))
return STATUS_INVALID_PARAMETER;
// Perform packet
switch (packet->objType)
{
case RegKeyObject:
status = RemoveHiddenRegKey(packet->id);
break;
case RegValueObject:
status = RemoveHiddenRegValue(packet->id);
break;
case FsFileObject:
status = RemoveHiddenFile(packet->id);
break;
case FsDirObject:
status = RemoveHiddenDir(packet->id);
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS RemoveAllHiddenObjects(PHid_UnhideAllObjectsPacket packet, USHORT size)
{
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(Hid_UnhideAllObjectsPacket))
return STATUS_INVALID_PARAMETER;
// Perform packet
switch (packet->objType)
{
case RegKeyObject:
status = RemoveAllHiddenRegKeys();
break;
case RegValueObject:
status = RemoveAllHiddenRegValues();
break;
case FsFileObject:
status = RemoveAllHiddenFiles();
break;
case FsDirObject:
status = RemoveAllHiddenDirs();
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS AddPsObject(PHid_AddPsObjectPacket packet, USHORT size, PULONGLONG objId)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING path;
USHORT i, count;
// Check can we access to the packet
if (size < sizeof(Hid_AddPsObjectPacket))
return STATUS_INVALID_PARAMETER;
// Check packet data size overflow
if (size < packet->size + sizeof(Hid_AddPsObjectPacket))
return STATUS_INVALID_PARAMETER;
// Unpack string to UNICODE_STRING
path.Buffer = (LPWSTR)((PCHAR)packet + sizeof(Hid_AddPsObjectPacket));
path.MaximumLength = size - sizeof(Hid_AddPsObjectPacket);
// Just checking for zero-end string ends in the middle
count = packet->size / sizeof(WCHAR);
for (i = 0; i < count; i++)
if (path.Buffer[i] == L'\0')
break;
path.Length = i * sizeof(WCHAR);
// Perform the packet
switch (packet->objType)
{
case PsExcludedObject:
status = AddExcludedImage(&path, packet->inheritType, objId);
break;
case PsProtectedObject:
status = AddProtectedImage(&path, packet->inheritType, objId);
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS RemovePsObject(PHid_RemovePsObjectPacket packet, USHORT size)
{
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(Hid_RemovePsObjectPacket))
return STATUS_INVALID_PARAMETER;
// Perform packet
switch (packet->objType)
{
case PsExcludedObject:
status = RemoveExcludedImage(packet->id);
break;
case PsProtectedObject:
status = RemoveProtectedImage(packet->id);
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS RemoveAllPsObjects(PHid_RemoveAllPsObjectsPacket packet, USHORT size)
{
NTSTATUS status = STATUS_SUCCESS;
if (size != sizeof(Hid_RemoveAllPsObjectsPacket))
return STATUS_INVALID_PARAMETER;
// Perform packet
switch (packet->objType)
{
case PsExcludedObject:
status = RemoveAllExcludedImages();
break;
case PsProtectedObject:
status = RemoveAllProtectedImages();
break;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": Unsupported object type: %u\n", packet->objType);
return STATUS_INVALID_PARAMETER;
}
return status;
}
NTSTATUS IrpDeviceControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
Hid_StatusPacket result;
NTSTATUS status = STATUS_SUCCESS;
PVOID inputBuffer, outputBuffer;
ULONG ioctl, inputBufferSize, outputBufferSize, outputBufferMaxSize;
UNREFERENCED_PARAMETER(DeviceObject);
// 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;
outputBufferSize = 0;
RtlZeroMemory(&result, sizeof(result));
// Check output buffer size
if (outputBufferMaxSize < sizeof(result))
{
status = STATUS_INVALID_PARAMETER;
goto EndProc;
}
switch (ioctl)
{
// Reg/Fs
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;
// Ps
case HID_IOCTL_ADD_OBJECT:
result.status = AddPsObject((PHid_AddPsObjectPacket)inputBuffer, (USHORT)inputBufferSize, &result.info.id);
break;
case HID_IOCTL_GET_OBJECT_STATE:
result.status = (ULONG)STATUS_NOT_IMPLEMENTED;
break;
case HID_IOCTL_SET_OBJECT_STATE:
result.status = (ULONG)STATUS_NOT_IMPLEMENTED;
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;
default:
DbgPrint("FsFilter1!" __FUNCTION__ ": unknown IOCTL code:%08x\n", ioctl);
status = STATUS_INVALID_PARAMETER;
goto EndProc;
}
EndProc:
// Copy result to output buffer
if (NT_SUCCESS(status))
{
outputBufferSize = sizeof(result);
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))
{
DbgPrint("FsFilter1!" __FUNCTION__ ": device creation failed with code:%08x\n", status);
return status;
}
status = IoCreateSymbolicLink(&dosDeviceName, &deviceName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(deviceObject);
DbgPrint("FsFilter1!" __FUNCTION__ ": symbolic link creation failed with code:%08x\n", status);
return status;
}
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;
g_deviceObject = deviceObject;
return status;
}
NTSTATUS DestroyDevice()
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING dosDeviceName = RTL_CONSTANT_STRING(DOS_DEVICES_LINK_NAME);
status = IoDeleteSymbolicLink(&dosDeviceName);
if (!NT_SUCCESS(status))
DbgPrint("FsFilter1!" __FUNCTION__ ": symbolic link deletion failed with code:%08x\n", status);
IoDeleteDevice(g_deviceObject);
return status;
}