• hook NtTerminateProcess进行应用的保护


    这段时间在学习驱动,然后看到hook ssdt的代码,找了一个写的清晰的学习了一下:http://www.netfairy.net/?post=218

     

    这里是hook NtOpenProcess,但是想自己练手所以hook NtTerminateProcess,经过多次蓝屏后,然后这里记录一下

     

    • 遇到的问题

    由于所学的例子是通过应用程序获取pid来控制保护的进程,但是ZwTerminateProcess不能通过参数获得PID,那如何获取PID呢?

    • 解决方案

    通过ZwQueryInformationProcess获得ProcessInformation再获得PID

    • 环境

    开发配置:vs2015  x86  debug

    测试环境:xp sp3

    驱动代码

      1 #include <ntddk.h>
      2 
      3 #define NT_DEVICE_NAME L"\Device\ProtectProcess"
      4 #define DOS_DEVICE_NAME L"\DosDevices\ProtectProcess"
      5 
      6 #define IOCTL_PROTECT_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
      7 
      8 
      9 #pragma pack(1)        //SSDT表的结构
     10 typedef struct ServiceDescriptorEntry
     11 {
     12   unsigned int *ServiceTableBase;
     13   unsigned int *ServiceCounterTableBase; //Used only in checked build
     14   unsigned int NumberOfServices;
     15   unsigned char *ParamTableBase;
     16 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
     17 #pragma pack()
     18 
     19 __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;        //变量名是不能变的,因为是从外部导入
     20 
     21                                            //这个用于查询某个函数的地址的宏定义
     22 #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
     23 
     24 NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(
     25   IN HANDLE ProcessHandle,
     26   IN PROCESSINFOCLASS ProcessInformationClass,
     27   OUT PVOID ProcessInformation,
     28   IN ULONG ProcessInformationLength,
     29   OUT PULONG ReturnLength);
     30 
     31 NTSYSAPI NTSTATUS NTAPI ZwTerminateProcess(
     32   IN HANDLE ProcessHandle OPTIONAL,
     33   IN NTSTATUS ExitStatus);
     34 
     35 
     36 typedef NTSTATUS (*ZWTERMINATEPROCESS)(
     37   IN HANDLE ProcessHandle OPTIONAL,
     38   IN NTSTATUS ExitStatus);
     39 
     40 ZWTERMINATEPROCESS OldZwTerminateProcess;
     41 long pid = -1;
     42 
     43 NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
     44 {
     45   NTSTATUS nStatus = STATUS_SUCCESS;
     46   ULONG IoControlCode = 0;
     47   PIO_STACK_LOCATION IrpStack = NULL;
     48 
     49   long* inBuf = NULL;
     50   char* outBuf = NULL;
     51   ULONG inSize = 0;
     52   ULONG outSize = 0;
     53   PCHAR buffer = NULL;
     54   PMDL mdl = NULL;
     55 
     56   Irp->IoStatus.Status = STATUS_SUCCESS;
     57   Irp->IoStatus.Information = 0;
     58 
     59   IrpStack = IoGetCurrentIrpStackLocation(Irp);    //利用函数获得当前请求任务的参数
     60   switch (IrpStack->MajorFunction)
     61   {
     62   case IRP_MJ_CREATE:
     63     DbgPrint("IRP_MJ_CREATE被调用
    ");
     64     break;
     65   case IRP_MJ_CLOSE:
     66     DbgPrint("IRP_MJ_CLOSE被调用
    ");
     67     break;
     68   case IRP_MJ_DEVICE_CONTROL:
     69     DbgPrint("IRP_MJ_DEVICE_CONTROL被调用
    ");
     70     IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
     71     switch (IoControlCode)
     72     {
     73     case IOCTL_PROTECT_CONTROL:
     74       inSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
     75       outSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
     76 
     77       inBuf = (long*)Irp->AssociatedIrp.SystemBuffer;
     78       pid = *inBuf;
     79       DbgPrint("==================================");
     80       DbgPrint("IOCTL_PROTECT_CONTROL被调用,通讯成功
    ");
     81       DbgPrint("输入缓冲区大小:%d
    ", inSize);
     82       DbgPrint("输出缓冲区大小:%d
    ", outSize);
     83       DbgPrint("输入缓冲区内容:%ld
    ", inBuf);
     84       DbgPrint("当前保护进程ID:%ld
    ", pid);
     85       DbgPrint("==================================");
     86       break;
     87     default:
     88       break;
     89     }
     90     break;
     91   default:
     92     DbgPrint("未知请求包被调用
    ");
     93     break;
     94   }
     95 
     96   nStatus = Irp->IoStatus.Status;
     97 
     98   IoCompleteRequest(Irp, IO_NO_INCREMENT);
     99 
    100   return nStatus;
    101 }
    102 
    103 NTSTATUS NewZwTerminateProcess(
    104   IN HANDLE ProcessHandle OPTIONAL,
    105   IN NTSTATUS ExitStatus)
    106 {
    107   NTSTATUS nStatus = STATUS_SUCCESS;
    108   
    109   ULONG Ret;
    110   PROCESS_BASIC_INFORMATION pbi;
    111 
    112   //pBuffer = ExAllocatePool(PagedPool, sizeof(PROCESS_BASIC_INFORMATION));
    113   ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, (PVOID)&pbi, sizeof(PROCESS_BASIC_INFORMATION), &Ret);
    114 
    115 
    116   if (pbi.UniqueProcessId == pid)
    117   {
    118     DbgPrint("保护进程不被关闭:%d
    ", pid);
    119     return STATUS_ACCESS_DENIED;
    120   }
    121 
    122   nStatus = OldZwTerminateProcess(ProcessHandle, ExitStatus);
    123   return STATUS_SUCCESS;
    124 }
    125 
    126 VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
    127 {
    128   UNICODE_STRING DeviceLinkString;
    129   PDEVICE_OBJECT DeviceObjectTemp1 = NULL;
    130   PDEVICE_OBJECT DeviceObjectTemp2 = NULL;
    131 
    132   DbgPrint("Driver Unload
    ");
    133 
    134   RtlInitUnicodeString(&DeviceLinkString, DOS_DEVICE_NAME);
    135   IoDeleteSymbolicLink(&DeviceLinkString);
    136   if (pDriverObject)
    137   {
    138     DeviceObjectTemp1 = pDriverObject->DeviceObject;
    139     while (DeviceObjectTemp1)
    140     {
    141       DeviceObjectTemp2 = DeviceObjectTemp1;
    142       DeviceObjectTemp1 = DeviceObjectTemp1->NextDevice;
    143       IoDeleteDevice(DeviceObjectTemp2);
    144     }
    145   }
    146 
    147   DbgPrint("设备已经卸载
    ");
    148   DbgPrint("修复SSDT表
    ");
    149   (ZWTERMINATEPROCESS)(SYSTEMSERVICE(ZwTerminateProcess)) = OldZwTerminateProcess;
    150   DbgPrint("驱动卸载完毕
    ");
    151 }
    152 
    153 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
    154 {
    155   NTSTATUS ntStatus = STATUS_SUCCESS;
    156   UNICODE_STRING ntDeviceName;
    157   UNICODE_STRING DeviceLinkString;
    158   PDEVICE_OBJECT deviceObject = NULL;
    159 
    160   RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
    161 
    162   ntStatus = IoCreateDevice(
    163     pDriverObject,
    164     0,
    165     &ntDeviceName,
    166     FILE_DEVICE_UNKNOWN,
    167     0,
    168     FALSE,
    169     &deviceObject);
    170 
    171   if (!NT_SUCCESS(ntStatus))
    172   {
    173     DbgPrint("无法创建驱动设备");
    174     return ntStatus;
    175   }
    176 
    177   RtlInitUnicodeString(&DeviceLinkString, DOS_DEVICE_NAME);
    178   ntStatus = IoCreateSymbolicLink(&DeviceLinkString, &ntDeviceName);
    179 
    180   if (!NT_SUCCESS(ntStatus))
    181   {
    182     return ntStatus;
    183   }
    184 
    185   pDriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchDeviceControl;
    186   pDriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchDeviceControl;
    187   pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
    188   pDriverObject->DriverUnload = DriverUnload;
    189 
    190   DbgPrint("驱动程序已经启动
    ");
    191   DbgPrint("修改SSDT表。。。
    ");
    192 
    193   //修改ZwTerminateProcess函数地址
    194   //将原来ssdt中所要hook的函数地址换成我们自己的函数地址
    195   OldZwTerminateProcess = (ZWTERMINATEPROCESS)(SYSTEMSERVICE(ZwTerminateProcess));
    196   SYSTEMSERVICE(ZwTerminateProcess) = (unsigned int)NewZwTerminateProcess;
    197 
    198   DbgPrint("驱动程序加载完毕
    ");
    199 
    200   return STATUS_SUCCESS;
    201 }

    控制程序与上面所给链接的代码相同

  • 相关阅读:
    Linux修改密码后不能SSH远程登录了
    scala spark2.0 sparksql 连接mysql8.0 操作多表 使用 dataframe 及RDD进行数据处理
    spark2.0 连接mysql8.0数据库操作表数据
    spark2.0以上 RDD 转 dataframe 及数据处理 ERROR Executor:91
    Oracle 存储过程、存储函数
    mysql8.0 存储过程 、存储函数
    Ubuntu 12.04 使用root用户登录桌面
    python与conda 包管理工具 Miniconda 的安装 及 conda安装 python 3.6.5 from conda.cli import main ModuleNotFoundError
    mysql 月统计计算
    mysql数据库整体迁移:
  • 原文地址:https://www.cnblogs.com/QKSword/p/9960140.html
Copyright © 2020-2023  润新知