mirror of
https://github.com/jsecurity101/JonMon
synced 2026-06-08 15:08:08 +00:00
225 lines
6.6 KiB
C++
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);
|
|
} |