⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 load.c

📁 驱动层Hook系统内核调用的
💻 C
📖 第 1 页 / 共 2 页
字号:

int get_device_from_file_name(char *file_name,char *device_name)
{
  char letter[3],volume[128];
  letter[0]=file_name[0];
  letter[1]=':';
  letter[2]=0x00;

  DWORD ret=QueryDosDevice(letter,volume,sizeof(volume));
  if (ret) sprintf(device_name,"%s%s\0",volume,&file_name[2]);
  else device_name[0]=0x00;

  return ret;
}



int main(int argc,char **argv)
{
  /*
   this version uses ZwQueryInformationThread in kernel driver to determine
   process that owns specific thread, unfortunately ntoskrnl.exe exports 
   ZwQueryInformationThread in XP and higher, but the implementation is also 
   available in W2k, so we will do a little hack here and from user mode 
   ntdll.dll we retrieve an index to SDT and send it to kernel driver to call
   ZwQueryInformationThread using this index
   we could hardcode the index for W2k but this way it is more elegant as we 
   don't need to care about service pack differences
   this is quite simple solution but it works only if this function is not 
   hooked in ntdll.dll, if the function is hooked (and index is rewritten)
   this hack fails, however, in this case we should load and map ntdll.dll
   from disk to get raw unhooked image and find our function address in export 
   table and retrieve the index from the image then, this is not implemented 
   in this version, we assume clear (not hooked) environment
  */
  ULONG SDT_index_ZwQIT=0;
  HMODULE ntdll=GetModuleHandle("ntdll.dll");
  PVOID ZwQIT=GetProcAddress(ntdll,"ZwQueryInformationThread");
  if (ZwQIT) SDT_index_ZwQIT=*((PULONG)((UCHAR *)ZwQIT+1));

  printf("SDT_index_ZwQIT = 0x%.8X\n",SDT_index_ZwQIT);
  if (SDT_index_ZwQIT>0x0200) SDT_index_ZwQIT=0;
  if (!SDT_index_ZwQIT)
  {
    printf("error: unable to retrieve valid SDT index for ZwQueryInformationThread\n");
    return 0;
  }

  printf("Opening service manager ...\n");
  HANDLE scm=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
  
  if(scm)
  {
    printf("Creating service ...\n");

    HANDLE svc=CreateService(scm,argv[1],argv[2],SERVICE_START | DELETE | SERVICE_STOP,SERVICE_KERNEL_DRIVER,
                             SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,argv[3],NULL,NULL,NULL,NULL,NULL);

    if(!svc)
    {
      printf("Creating failed, trying to open service ...\n");
      svc=OpenService(scm,argv[1],SERVICE_START | DELETE | SERVICE_STOP);
    }

    if(svc)
    {
      printf("Starting service\n");

      StartService(svc,0,NULL);

      printf("Creating communication device ...\n");

      /*
       for MSTS we need to use Global namespace to access our device
      */
      char dev_name[256];
      if ((GetVersion()&0xFF)>=5) sprintf(dev_name,"\\\\.\\Global\\%s\0",argv[1]);
      else sprintf(dev_name,"\\\\.\\%s\0",argv[1]);

      HANDLE dev=CreateFile(dev_name,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);

      if (dev==INVALID_HANDLE_VALUE) dev=0;
      if (dev)
      {
        printf("Starting notify thread\n");
        work=1;
        DWORD tid;
        HANDLE thread=CreateThread(NULL,0,notify_thread,dev_name,0,&tid);
        if (thread==INVALID_HANDLE_VALUE) thread=0;
        notify_event=CreateEvent(NULL,TRUE,FALSE,NULL);

        if (thread && notify_event)
        {
          CloseHandle(thread);

          printf("Press Enter to send IOCTL_HOOK_START\n");
          getchar();

          DRVCOMM_REQUEST_BUFFER buf_req;
          DRVCOMM_RESPONSE_BUFFER buf_res;
          DWORD bytes=0,ret;

          buf_req.parameters.init.SDT_index_ZwQueryInformationThread=SDT_index_ZwQIT;

          /*
           send command to our driver, no input buffer is used here
           output buffer contains status value only
          */
          memset(&buf_res,0,sizeof(buf_res));
          ret=DeviceIoControl(dev,IOCTL_HOOK_START,&buf_req,sizeof(buf_req),&buf_res,sizeof(buf_res),&bytes,NULL);
          printf("DeviceIoControl returned code 0x%.8X, status 0x%.8X and %d bytes\n",ret,buf_res.status,bytes);

          if (buf_res.status)
          {
            /*
             this is a loop for driver rules managment
            */
            printf("\nenter commands to protect/disable protection of processes\n"
                   "to enable protection for process write 'e PID'\n"
                   "to disable protection for process write 'd PID'\n"
                   "to answer notify check write 'p 0/1' - '0' for deny and '1' for permit\n"
                   "to (un)protect file write 'f 0/1' - '0' for unprotect and '1' for protect\n"
                   "current process id = %d\n"
                   "write 'x 0' for end\n",GetCurrentProcessId());

            while (work)
            {
              bytes=0;
              char ch_type;
              int obj_id=0;
              scanf("%c %d",&ch_type,&obj_id);
              getchar();

              int enable;
              ULONG code;
              char name_buf[1024],dev_buf[1024];

              switch (ch_type)
              {
                case 'd':
                case 'e':
                  enable=ch_type=='e';
                  code=IOCTL_PROTECT_PROCESS;
                  buf_req.parameters.protect_process.pid=obj_id;
                  buf_req.parameters.protect_process.enable=enable;
                  ret=DeviceIoControl(dev,code,&buf_req,sizeof(buf_req),&buf_res,sizeof(buf_res),&bytes,NULL);
                  printf("DeviceIoControl returned code 0x%.8X, status 0x%.8X and %d bytes\n",ret,buf_res.status,bytes);
                  break;

                case 'f':
                  enable=obj_id;
                  printf("enter filename: ");
                  //we're not making any kind of buffer overflow checks here
                  //in real world apps you should always control the size of user input
                  scanf("%s",name_buf);
                  getchar();
                  if (get_device_from_file_name(name_buf,dev_buf))
                  {
                    code=IOCTL_PROTECT_FILE;
                    swprintf(buf_req.parameters.protect_file.name,L"%S\0",dev_buf);
                    printf("sending protect request on %S\n",buf_req.parameters.protect_file.name);

                    buf_req.parameters.protect_file.enable=enable;
                    ret=DeviceIoControl(dev,code,&buf_req,sizeof(buf_req),&buf_res,sizeof(buf_res),&bytes,NULL);
                    printf("DeviceIoControl returned code 0x%.8X, status 0x%.8X and %d bytes\n",ret,buf_res.status,bytes);
                  } else printf("error: invalid filename\n");
                  break;

                case 'p':
                  notify_data=!obj_id;          //we set protect TRUE or FALSE -> protect = !permit
                  PulseEvent(notify_event);
                  break;

                case 'x':
                  work=0;
                  break;

                default:
                  printf("unknown command type %c\n",ch_type);
              }
            }

            bytes=0;
            printf("Press Enter to send IOCTL_HOOK_STOP\n");
            getchar();

            ret=DeviceIoControl(dev,IOCTL_HOOK_STOP,NULL,0,&buf_res,sizeof(buf_res),&bytes,NULL);
            printf("DeviceIoControl returned code 0x%.8X, status 0x%.8X and %d bytes\n",ret,buf_res.status,bytes);

            //cancel possible waiting
            PulseEvent(notify_event);
          }

          printf("Press Enter to send close device handle\n");
          getchar();
          CloseHandle(dev);
        } else printf("error: unable to create notify thread\n");

        if (notify_event) CloseHandle(notify_event);

      } else printf("error: unable to create communication device\n");

      printf("Press Enter to stop and delete service \n");
      getchar();

      SERVICE_STATUS status;
      ControlService(svc,SERVICE_CONTROL_STOP,&status);

      DeleteService(svc);
      CloseServiceHandle(svc);
    } else printf("error: unable to create/open service\n");

    CloseServiceHandle(scm);
  } else printf("error: unable to open manager\n");
  
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -