• 2007-07-25

    进程保护 - [内核驱动]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://romio64.blogbus.com/logs/7049623.html

    没啥说的。。。挂钩NtOpenProcess

    #include "ntddk.h"

    #define FILE_DEVICE_PROTECTPROC 0x8000
    #define PROTECTPROC_IOCTL_BASE 0x800
    #define CTL_CODE_PROTECTPROC(i) CTL_CODE(FILE_DEVICE_PROTECTPROC, PROTECTPROC_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

    #define IOCTL_PROTECTPROC_PID CTL_CODE_PROTECTPROC(0)

    #define PROTECTPROC_WIN32_DEVICE_NAME_W L"\\\\.\\ProtectAntiy"
    #define PROTECTPROC_DEVICE_NAME_A   "
    \\Device\\ProtectAntiy"
    #define PROTECTPROC_DEVICE_NAME_W   L"
    \\Device\\ProtectAntiy"
    #define PROTECTPROC_DOS_DEVICE_NAME_A  "
    \\DosDevices\\ProtectAntiy"
    #define PROTECTPROC_DOS_DEVICE_NAME_W  L"
    \\DosDevices\\ProtectAntiy"

    #define PROTECTPROC_WIN32_DEVICE_NAME_A "\\\\.\\ProtectAntiy"
    #define PROTECTPROC_WIN32_DEVICE_NAME_W L"\\\\.\\ProtectAntiy"
    #define PROTECTPROC_DEVICE_NAME_A   "
    \\Device\\ProtectAntiy"
    #define PROTECTPROC_DEVICE_NAME_W   L"
    \\Device\\ProtectAntiy"
    #define PROTECTPROC_DOS_DEVICE_NAME_A  "
    \\DosDevices\\ProtectAntiy"
    #define PROTECTPROC_DOS_DEVICE_NAME_W  L"
    \\DosDevices\\ProtectAntiy"

    #ifdef _UNICODE
    #define PROTECTPROC_WIN32_DEVICE_NAME PROTECTPROC_WIN32_DEVICE_NAME_W
    #define PROTECTPROC_DEVICE_NAME  PROTECTPROC_DEVICE_NAME_W
    #define PROTECTPROC_DOS_DEVICE_NAME PROTECTPROC_DOS_DEVICE_NAME_W
    #else
    #define PROTECTPROC_WIN32_DEVICE_NAME PROTECTPROC_WIN32_DEVICE_NAME_A
    #define PROTECTPROC_DEVICE_NAME  PROTECTPROC_DEVICE_NAME_A
    #define PROTECTPROC_DOS_DEVICE_NAME PROTECTPROC_DOS_DEVICE_NAME_A
    #endif

    typedef struct ServiceDescriptorEntry {
         unsigned int   *ServiceTableBase;
         unsigned int   *ServiceCounterTableBase;
         unsigned int   NumberOfServices;
         unsigned char *ParamTableBase;
    } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t ;

    __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable ;

    #define SYSTEMSERVICE(_fun) KeServiceDescriptorTable.ServiceTableBase[*(PLONG) ((PUCHAR)_fun +1)]

    typedef
    NTSTATUS
    (* ZWOPENPROCESS)(
        OUT PHANDLE  ProcessHandle,
        IN ACCESS_MASK  DesiredAccess,
        IN POBJECT_ATTRIBUTES  ObjectAttributes,
        IN PCLIENT_ID  ClientId
        );

    ZWOPENPROCESS OriZwOpenProcess ;

    NTSYSAPI
    NTSTATUS
    NTAPI
    ZwOpenProcess  (
        OUT PHANDLE  ProcessHandle,
        IN ACCESS_MASK  DesiredAccess,
        IN POBJECT_ATTRIBUTES  ObjectAttributes,
        IN PCLIENT_ID  ClientId
        );

    NTSTATUS
    DriverEntry(
     IN PDRIVER_OBJECT  DriverObject,
     IN PUNICODE_STRING  RegistryPath
     );

    NTSTATUS
    ProtectprocDispatch(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP     Irp
     );

    NTSTATUS
    ProtectprocDispatchDeviceControl(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP     Irp
     );

    VOID
    ProtectprocUnload(
     IN PDRIVER_OBJECT  DriverObject
     );

    #ifdef ALLOC_PRAGMA
    #pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, ProtectprocDispatch)
    #pragma alloc_text(PAGE, ProtectprocDispatchDeviceControl)
    #pragma alloc_text(PAGE, ProtectprocUnload)
    #endif // ALLOC_PRAGMA

    ULONG dwPID = 0 ;

    //写保护
    VOID DisableWriteProtect()
    {
     __asm
     {
      push eax
      mov eax,cr0
      and eax,0x0FFFEFFFF
      mov cr0, eax
      pop eax
     }

    }

    VOID EnableWriteProtect()
    {
     __asm
     {
      push eax
      mov eax,cr0
      or eax,NOT 0x0FFFEFFFF
      mov cr0,eax
      pop eax
     }
    }
    NTSTATUS
    MyZwOpenProcess (
        OUT PHANDLE  ProcessHandle,
        IN ACCESS_MASK  DesiredAccess,
        IN POBJECT_ATTRIBUTES  ObjectAttributes,
        IN PCLIENT_ID  ClientId
        )
    {
     NTSTATUS status = STATUS_SUCCESS ;

     //if (dwPID != 0)
     {
      if ((ULONG)ClientId->UniqueProcess == dwPID)
      {
       status = STATUS_ACCESS_DENIED ;
      }
      else
      {
       status = OriZwOpenProcess (ProcessHandle,DesiredAccess,ObjectAttributes,ClientId) ;
      }
     }
     return status ;
    }
    NTSTATUS
    DriverEntry(
     IN PDRIVER_OBJECT  DriverObject,
     IN PUNICODE_STRING  RegistryPath
     )
    {
     NTSTATUS   status = STATUS_SUCCESS;   
        UNICODE_STRING  ntDeviceName;
     UNICODE_STRING  dosDeviceName;
     PDEVICE_OBJECT  deviceObject = NULL;
     BOOLEAN    fSymbolicLink = FALSE;
     ULONG    OldCr0 = 0 ;

        RtlInitUnicodeString(&ntDeviceName, PROTECTPROC_DEVICE_NAME_W);

        status = IoCreateDevice(
      DriverObject,
      0,
      &ntDeviceName,
      FILE_DEVICE_PROTECTPROC,
      0,
      TRUE,
      &deviceObject
      );

        if (!NT_SUCCESS(status))
     {
      goto __failed;
     }

        RtlInitUnicodeString(&dosDeviceName, PROTECTPROC_DOS_DEVICE_NAME_W);

        status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
      goto __failed;
        }

     fSymbolicLink = TRUE;

        DriverObject->MajorFunction[IRP_MJ_CREATE]         = ProtectprocDispatch;
        DriverObject->MajorFunction[IRP_MJ_CLOSE]          = ProtectprocDispatch;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ProtectprocDispatchDeviceControl;
        DriverObject->DriverUnload                         = ProtectprocUnload;
     
     OriZwOpenProcess = (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) ;

     __asm cli
     DisableWriteProtect() ;
     (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = MyZwOpenProcess ;
     EnableWriteProtect();
     __asm sti

        if (NT_SUCCESS(status))
         return status;

    __failed:

     if (fSymbolicLink)
      IoDeleteSymbolicLink(&dosDeviceName);

     if (deviceObject)
      IoDeleteDevice(deviceObject);

     return status;
    }

    NTSTATUS
    ProtectprocDispatch(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP     Irp
     )
    {
     NTSTATUS status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;

        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
    }


    NTSTATUS
    ProtectprocDispatchDeviceControl(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP     Irp
     )
    {
     NTSTATUS   status = STATUS_SUCCESS;
        PIO_STACK_LOCATION irpStack;
        PVOID    ioBuf;
        ULONG    inBufLength, outBufLength;
     ULONG    ioControlCode;

        irpStack = IoGetCurrentIrpStackLocation(Irp);

        Irp->IoStatus.Information = 0;

        ioBuf = Irp->AssociatedIrp.SystemBuffer;
        inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
        outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
        ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

        switch (ioControlCode)
        {
     case IOCTL_PROTECTPROC_PID:
      {
       if (inBufLength >= sizeof (ULONG) && outBufLength >= sizeof (ULONG))
       {
        //从ring3获得要保护进程的PID
        dwPID = *(ULONG *)(ioBuf);
       }
       Irp->IoStatus.Information = sizeof (dwPID) ;
                break;
      }

        default:
            status = STATUS_INVALID_PARAMETER;
            break;
     }

        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return status;
    }

    VOID
    ProtectprocUnload(
     IN PDRIVER_OBJECT  DriverObject
     )
    {
        UNICODE_STRING dosDeviceName;
     
     //恢复原服务入口
     __asm cli
     DisableWriteProtect() ;
     (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = OriZwOpenProcess ;
     EnableWriteProtect();
     __asm sti
        RtlInitUnicodeString(&dosDeviceName, PROTECTPROC_DOS_DEVICE_NAME_W);

        IoDeleteSymbolicLink(&dosDeviceName);

        IoDeleteDevice(DriverObject->DeviceObject);

    }


    收藏到:Del.icio.us




    评论

  • if ((ULONG)ClientId->UniqueProcess == dwPID)



    嘿嘿。。