Files
jsecurity101-JonMon/JonMon/driver.cpp
T
2023-09-26 09:03:04 -05:00

225 lines
6.6 KiB
C++

#include "driver.h"
#include "callbacks.h"
#include "process.h"
extern "C"
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
EventRegisterJonMon();
g_RegPath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED,
RegistryPath->Length, DRIVER_TAG);
if (g_RegPath.Buffer == NULL) {
DbgPrint("Failed allocation\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
g_RegPath.Length = g_RegPath.MaximumLength = RegistryPath->Length;
memcpy(g_RegPath.Buffer, RegistryPath->Buffer, g_RegPath.Length);
DbgPrint("JonMon Driver Entry Called 0x%p\n", DriverObject);
DbgPrint("Registry Path %wZ\n", g_RegPath);
DriverObject->DriverUnload = JonMonUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = JonMonCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = JonMonCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JonMonDeviceControl;
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"\\Device\\JonMon");
PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(DriverObject, 0, &name, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
if (!NT_SUCCESS(status)) {
DbgPrint("Error creating device: 0x%X\n", status);
ExFreePool(g_RegPath.Buffer);
return status;
}
DriverObject->DeviceObject = DeviceObject;
DeviceObject->Flags |= DO_DIRECT_IO;
UNICODE_STRING symlink;
RtlInitUnicodeString(&symlink, L"\\??\\JonMon");
status = IoCreateSymbolicLink(&symlink, &name);
if (!NT_SUCCESS(status)) {
DbgPrint("Error creating device: 0x%X\n", status);
ExFreePool(g_RegPath.Buffer);
IoDeleteDevice(DeviceObject);
return status;
}
status = RegisterCallbacks(DriverObject, DeviceObject);
if (!NT_SUCCESS(status)) {
DbgPrint("Error registering callbacks: 0x%X\n", status);
ExFreePool(g_RegPath.Buffer);
return status;
}
ExFreePool(g_RegPath.Buffer);
return status;
}
NTSTATUS JonMonDeviceControl(
_In_ PDEVICE_OBJECT,
_In_ PIRP Irp
) {
auto irpSp = IoGetCurrentIrpStackLocation(Irp);
auto status = STATUS_INVALID_DEVICE_REQUEST;
auto& dic = irpSp->Parameters.DeviceIoControl;
auto len = 0;
switch (dic.IoControlCode) {
case IOCTL_CHANGE_PROTECTION_LEVEL_PROCESS:
ChangePPL();
}
return CompleteRequest(Irp, status, len);
}
VOID AlterPPL(
_In_ ULONG PID,
_In_ ULONG value
) {
PEPROCESS pProcess = NULL;
PPROCESS_SIGNATURE_PROTECTION pSignatureProtect = NULL;
ULONG pid = PID;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)pid, &pProcess);
if (NT_SUCCESS(status)) {
DbgPrint("Changing PPL value for target PROCESS ID: %d\n", PID);
pSignatureProtect = (PPROCESS_SIGNATURE_PROTECTION)(((ULONG_PTR)pProcess) + 0x878);
if (value == 1) {
pSignatureProtect->SignatureLevel = 0x11;
pSignatureProtect->SectionSignatureLevel = 0x11;
pSignatureProtect->Protection = { 1,0,3 };
}
if (value == 0)
{
pSignatureProtect->SignatureLevel = 0x0;
pSignatureProtect->SectionSignatureLevel = 0x0;
pSignatureProtect->Protection = { 0,0,0 };
}
DbgPrint("Process ID %d 's protection level has changed\n", PID);
ObDereferenceObject(pProcess);
}
}
VOID ChangePPL()
{
UNICODE_STRING functionName;
RtlInitUnicodeString(&functionName, L"ZwQuerySystemInformation");
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&functionName);
NTSTATUS status;
ULONG bufferSize = 0;
UNICODE_STRING processName, processPath;
RtlInitUnicodeString(&processName, L"JonMon-Service.exe");
RtlInitUnicodeString(&processPath, L"\\Windows\\JonMon-Service.exe");
status = ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &bufferSize);
if (status != STATUS_INFO_LENGTH_MISMATCH) {
return;
}
if (bufferSize) {
PVOID info = ExAllocatePool2(POOL_FLAG_PAGED, bufferSize, DRIVER_TAG);
if (info) {
status = ZwQuerySystemInformation(SystemProcessInformation, info, bufferSize, &bufferSize);
if (NT_SUCCESS(status)) {
PSYSTEM_PROCESSES processInfo = (PSYSTEM_PROCESSES)info;
UNICODE_STRING imagePath;
imagePath.MaximumLength = 1024;
imagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, 1024, DRIVER_TAG);
if (imagePath.Buffer == NULL) {
DbgPrint("Failed allocation\n");
return;
}
int count = 0;
do {
do {
if (RtlEqualUnicodeString(&processName, &processInfo->ProcessName, TRUE)) {
status = GetProcessImageName((HANDLE)processInfo->ProcessId, &imagePath);
if (wcsstr(imagePath.Buffer, processPath.Buffer) != NULL) {
g_ServicePID = (ULONG)processInfo->ProcessId;
AlterPPL(g_ServicePID, 1);
count++;
DbgPrint("Found JonMon-Service.exe\n");
}
}
processInfo = (PSYSTEM_PROCESSES)((unsigned char*)processInfo + processInfo->NextEntryDelta);
} while (processInfo->NextEntryDelta);
} while (count != 1);
ExFreePoolWithTag(imagePath.Buffer, DRIVER_TAG);
}
ExFreePoolWithTag(info, DRIVER_TAG);
}
}
}
//
//Function unloads the driver
//
VOID JonMonUnload(
_In_ PDRIVER_OBJECT DriverObject
) {
PAGED_CODE();
EventUnregisterJonMon();
AlterPPL(g_ServicePID, 0);
CmUnRegisterCallback(Cookie);
ObUnRegisterCallbacks(ProcessRegistrationHandle);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PostProcessHandleCallback Unloaded\n"));
PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, TRUE);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutineEx Unloaded\n"));
PsRemoveLoadImageNotifyRoutine(LoadImageRoutine);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetLoadImageNotifyRoutine Unloaded\n"));
PsRemoveCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateThreadNotifyRoutine Unloaded\n"));
PsSetCreateProcessNotifyRoutine(TerminateProcessNotifyRoutine, TRUE);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutine Unloaded\n"));
//sleep for 5 seconds to allow worker threads to finish
LARGE_INTEGER interval;
interval.QuadPart = -(3 * 10000000);
KeDelayExecutionThread(KernelMode, FALSE, &interval);
UNICODE_STRING symlink;
RtlInitUnicodeString(&symlink, L"\\??\\JonMon");
IoDeleteSymbolicLink(&symlink);
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("JonMon Driver Unloaded\n");
}
//Function completes the driver requests
NTSTATUS CompleteRequest(
PIRP Irp,
NTSTATUS status,
ULONG_PTR info
) {
PAGED_CODE();
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
//Function handles the create and close requests. Function just points to CompleteRequest.
NTSTATUS JonMonCreateClose(
_In_ PDEVICE_OBJECT,
_In_ PIRP Irp
) {
PAGED_CODE();
return CompleteRequest(Irp);
}