Hook SSDT NtOpenProcess的完整代码

以下是通过Hook SSDT NtOpenProcess保护进程的完整代码,对喜欢HOOK的初学者帮助很大

驱动代码Protect.C:
  1. #include "ntddk.h"
  2. #define NT_DEVICE_NAME      L"\\Device\\ProtectProcess"
  3. #define DOS_DEVICE_NAME     L"\\DosDevices\\ProtectProcess"
  4. #define IOCTL_PROTECT_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
  5. NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT  DeviceObject,IN PIRP  Irp);
  6. VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
  7. #pragma pack(1)        //SSDT表的结构
  8. typedef struct ServiceDescriptorEntry {
  9.         unsigned int *ServiceTableBase;
  10.         unsigned int *ServiceCounterTableBase; //Used only in checked build
  11.         unsigned int NumberOfServices;
  12.         unsigned char *ParamTableBase;
  13. } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
  14. #pragma pack()
  15. __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;        //变量名是不能变的,因为是从外部导入
  16. //这个是查询某个函数的地址的一个宏
  17. #define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]

  18. NTSYSAPI NTSTATUS NTAPI ZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
  19. typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);

  20. ZWOPENPROCESS OldZwOpenProcess;
  21. long pid = -1;

  22. NTSTATUS NewZwOpenProcess(OUT PHANDLE ProcessHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL)
  23. {
  24.         //用来替换的新函数
  25.         NTSTATUS nStatus = STATUS_SUCCESS;
  26.         if((long)ClientId->UniqueProcess == pid)
  27.         {
  28.                 DbgPrint("保护进程 PID:%ld\n",pid);
  29.                 return STATUS_ACCESS_DENIED;
  30.         }

  31.         //剩下的交给我们的原函数
  32.         nStatus = OldZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
  33.         return STATUS_SUCCESS;
  34. }

  35. VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
  36. {
  37.         //卸载时会调用
  38.         UNICODE_STRING DeviceLinkString;
  39.         PDEVICE_OBJECT DeviceObjectTemp1=NULL;
  40.         PDEVICE_OBJECT DeviceObjectTemp2=NULL;

  41.         DbgPrint("驱动程序卸载...\n");

  42.         RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
  43.         IoDeleteSymbolicLink(&DeviceLinkString);
  44.         if(DriverObject)
  45.         {
  46.                 DeviceObjectTemp1=DriverObject->DeviceObject;
  47.                 while(DeviceObjectTemp1)
  48.                 {
  49.                         DeviceObjectTemp2=DeviceObjectTemp1;
  50.                         DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;
  51.                         IoDeleteDevice(DeviceObjectTemp2);
  52.                 }
  53.         }  
  54.         DbgPrint("设备已经卸载\n");

  55.         DbgPrint("修复SSDT表\n");
  56.         (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = OldZwOpenProcess;

  57.         DbgPrint("驱动卸载完毕.\n");
  58. }

  59. NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT  DeviceObject,IN PIRP  Irp)
  60. {
  61.         //IRP_MJ_DEVICE_CONTROL的响应函数
  62.         NTSTATUS nStatus = STATUS_SUCCESS;
  63.         ULONG IoControlCode = 0;
  64.         PIO_STACK_LOCATION IrpStack = NULL;

  65.         long* inBuf = NULL;
  66.         char* outBuf = NULL;
  67.         ULONG inSize = 0;
  68.         ULONG outSize = 0;
  69.         PCHAR buffer = NULL;
  70.         PMDL mdl = NULL;

  71.         Irp->IoStatus.Status = STATUS_SUCCESS;
  72.         Irp->IoStatus.Information = 0;

  73.         IrpStack = IoGetCurrentIrpStackLocation(Irp);

  74.         switch(IrpStack->MajorFunction)
  75.         {
  76.         case IRP_MJ_CREATE:
  77.                 DbgPrint("IRP_MJ_CREATE 被调用\n");
  78.                 break;
  79.         case IRP_MJ_CLOSE:
  80.                 DbgPrint("IRP_MJ_CLOSE 被调用\n");
  81.                 break;
  82.         case IRP_MJ_DEVICE_CONTROL:
  83.                 DbgPrint("IRP_MJ_DEVICE_CONTROL 被调用\n");
  84.                 IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
  85.                 switch(IoControlCode)
  86.                 {
  87.                 case IOCTL_PROTECT_CONTROL:
  88.                         inSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
  89.                         outSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;                        
  90.                         inBuf = (long*)Irp->AssociatedIrp.SystemBuffer;
  91.                 
  92.                         pid = *inBuf;
  93.                         DbgPrint("===========================\n");
  94.                         DbgPrint("IOCTL_PROTECT_CONTROL 被调用,通讯成功!\n");
  95.                         DbgPrint("输入缓冲区大小: %d\n",inSize);
  96.                         DbgPrint("输出缓冲区大小: %d\n",outSize);
  97.                         DbgPrint("输入缓冲区内容: %ld\n",*inBuf);
  98.                         DbgPrint("当前保护进程ID: %ld\n",pid);
  99.                         DbgPrint("===========================\n");        
  100.                         
  101.                         strcpy(Irp->UserBuffer,"OK!\n");
  102.                         break;
  103.                 default:
  104.                         break;
  105.                 }
  106.                 break;
  107.         default:
  108.                 DbgPrint("未知请求包被调用\n");
  109.                 break;
  110.         }

  111.         nStatus = Irp->IoStatus.Status;

  112.         IoCompleteRequest(Irp,IO_NO_INCREMENT);

  113.         return nStatus;
  114. }

  115. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING theRegistryPath)
  116. {
  117.         //驱动入口函数
  118.         NTSTATUS        ntStatus = STATUS_SUCCESS;
  119.         UNICODE_STRING  ntDeviceName;
  120.         UNICODE_STRING  DeviceLinkString;
  121.         PDEVICE_OBJECT  deviceObject = NULL;

  122.         DbgPrint("驱动程序加载...\n");

  123.         RtlInitUnicodeString( &ntDeviceName, NT_DEVICE_NAME );

  124.         ntStatus = IoCreateDevice(
  125.                 DriverObject,
  126.                 0,
  127.                 &ntDeviceName,
  128.                 FILE_DEVICE_UNKNOWN,
  129.                 0,
  130.                 FALSE,
  131.                 &deviceObject );

  132.         if ( !NT_SUCCESS( ntStatus ) )
  133.         {
  134.                 DbgPrint("无法创建驱动设备");
  135.                 return ntStatus;
  136.         }

  137.         RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);
  138.         ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&ntDeviceName);

  139.         if(!NT_SUCCESS(ntStatus))
  140.         {
  141.                 return ntStatus;
  142.         }

  143.         DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchDeviceControl;
  144.         DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchDeviceControl;
  145.         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
  146.         DriverObject->DriverUnload = OnUnload;

  147.         DbgPrint("驱动程序已经启动\n");

  148.         DbgPrint("修改SSDT表...\n");

  149.         //修改 ZwOpenProcess 函数地址
  150.         OldZwOpenProcess =(ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess));
  151.         (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)) = NewZwOpenProcess;

  152.         DbgPrint("驱动程序加载完毕.\n");

  153.         return STATUS_SUCCESS;
  154. }
复制代码
安装驱动的源代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <process.h>

  5. #define BUF_SIZE 4096

  6. int main(int argc,char* argv[])
  7. {
  8.         char path[BUF_SIZE];
  9.         char base[BUF_SIZE];
  10.         char sername[BUF_SIZE];
  11.         char disname[BUF_SIZE];
  12.         memset(path,0,BUF_SIZE);
  13.         memset(base,0,BUF_SIZE);
  14.         memset(sername,0,BUF_SIZE);
  15.         memset(disname,0,BUF_SIZE);
  16.         
  17.         SC_HANDLE rh = NULL;
  18.         SC_HANDLE sh = NULL;
  19.         if (argc == 1)
  20.         {
  21.                 printf("use: install/start/uninstall\n");
  22.                 exit(0);
  23.         }
  24.         
  25.         ::GetModuleFileName(0,base,BUF_SIZE);
  26.         int p = strlen(base);
  27.         while(base[p] != '\\'){p--;}
  28.         strncpy(path,base,p+1);
  29.         memset(base,0,BUF_SIZE);
  30.         sprintf(base,"%sInstall.ini",path);
  31.         memset(path,0,BUF_SIZE);
  32.         ::GetPrivateProfileString("Config","Path","",path,BUF_SIZE,base);
  33.         ::GetPrivateProfileString("Config","ServiceName","",sername,BUF_SIZE,base);
  34.         ::GetPrivateProfileString("Config","DisplayName","",disname,BUF_SIZE,base);

  35.         printf("[*]Service Name:%s\n",sername);
  36.         printf("[*]Display Name:%s\n",disname);
  37.         printf("[*]Driver  Path:%s\n",path);
  38.         
  39.         
  40.         sh = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
  41.         
  42.         if (!sh){
  43.                 printf("[-]Error OpenSCManger.\n");
  44.                 exit(0);
  45.         }
  46.         
  47.         
  48.         if (argc == 2 && !strcmp(argv[1],"install"))
  49.         {
  50.                 if (!strcmp(path,""))
  51.                 {
  52.                         printf("[-]error read Install.ini\n");
  53.                         exit(0);
  54.                 }
  55.                 
  56.                 rh = CreateService(sh,sername,disname,
  57.                         SERVICE_ALL_ACCESS,
  58.                         SERVICE_KERNEL_DRIVER,
  59.                         //{
  60.                         //SERVICE_SYSTEM_START,
  61.                         SERVICE_DEMAND_START,
  62.                         //}
  63.                         SERVICE_ERROR_NORMAL,
  64.                         path,
  65.                         NULL,NULL,NULL,NULL,NULL);

  66.                 if (!rh){
  67.                         printf("[-]error CreateService.\n");
  68.                         exit(0);
  69.                 }

  70.                 printf("[-]Install Service Complete...\n");
  71.         }else if (argc == 2 && !strcmp(argv[1],"start"))
  72.         {

  73.                 rh = OpenService(sh,sername,SERVICE_ALL_ACCESS);

  74.                 if (!rh){
  75.                         printf("error OpenService.\n");
  76.                         exit(0);
  77.                 }

  78.                 StartService(rh,NULL,NULL);

  79.                 printf("[-]Start Service Complete...\n");

  80.         }else if (argc == 2 && !strcmp(argv[1],"uninstall"))
  81.         {
  82.                 rh = OpenService(sh,sername,SERVICE_ALL_ACCESS);

  83.                 if (!rh){
  84.                         printf("error OpenService.\n");
  85.                         exit(0);
  86.                 }

  87.                 SERVICE_STATUS ss;
  88.                 ControlService(rh,SERVICE_CONTROL_STOP,&ss);

  89.                 printf("[-]Stop Service Complete...\n");

  90.                 DeleteService(rh);

  91.                 printf("[-]Delete Service Complete...\n"); 
  92.         }

  93.         CloseServiceHandle(rh);
  94.         CloseServiceHandle(sh);

  95.         return 1;
  96. }
复制代码
调用驱动的应用程序代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <winioctl.h>

  5. #define IOCTL_HELLO_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

  6. int main(int argc,char* argv[])
  7. {
  8.         long pid = 0;
  9.         char ret[4096];
  10.         DWORD ReBytes = 0;
  11.         HANDLE hDevice=CreateFile("\\\\.\\ProtectProcess",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  12.         if(hDevice==INVALID_HANDLE_VALUE)
  13.         {
  14.                 if (2 == GetLastError())
  15.                 {
  16.                         printf("驱动程序未注册\n");
  17.                 }else
  18.                         printf("CreateFile() GetLastError reports %d\n",GetLastError());
  19.                 return FALSE;
  20.         }

  21.         memset(ret,0,4096);
  22.         printf("控制台版进程保护器\n");
  23.         printf("请输入需要保护的进程PID:");
  24.         scanf("%ld",&pid);
  25.         DeviceIoControl(hDevice,IOCTL_HELLO_CONTROL,&pid,sizeof(long),ret,4096,&ReBytes,NULL);

  26.         printf("Return Value:%s\n",ret);

  27.         CloseHandle(hDevice);
  28.         system("pause");
  29.         return 1;
  30. }

你可能感兴趣的:(Hook SSDT NtOpenProcess的完整代码)