微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法使用STOP_PENDING停止内核驱动程序

如何解决无法使用STOP_PENDING停止内核驱动程序

我有一个内核驱动程序,该驱动程序枚举并关闭特定文件夹中存在的文件的所有句柄(“文件”类型),this是有关如何开始这一目标的参考代码。内核代码工作得很好,但是我有一个小问题,尤其是在停止驱动程序方面。然后,当执行 STOP_PENDING 下面的用户模式代码时,便会发生所有事情,而我无法关闭用户模式程序。当我不执行内核代码关闭句柄)时,驱动程序可以停止并成功删除

PS:用户模式代码无法打开目标文件夹的任何句柄。

关于这种奇怪行为的原因有一些想法吗?

为了在此论坛上更好地理解,我将仅发布相关代码usermode / kernel模式。

用户模式:

function UninstallService(sMachine,sService: string): Boolean;
var
  schm,schs: SC_Handle;
  ss: TServiceStatus;
  dwChkP: dword;
begin
  Result := False;
  schm := OpenSCManagerW(PWideChar(sMachine),nil,SC_MANAGER_CONNECT);
  if schm > 0 then
  begin
    schs := OpenServiceW(schm,PWideChar(sService),_DELETE or SERVICE_STOP or SERVICE_QUERY_STATUS);
    if schs > 0 then
    begin
      if (QueryServiceStatus(schs,ss)) then
      begin
        while (SERVICE_STOPPED <> ss.dwCurrentState) do
        begin
          ControlService(schs,SERVICE_CONTROL_STOP,ss);
          dwChkP := ss.dwCheckPoint;
          Sleep(ss.dwWaitHint);
          if (not QueryServiceStatus(schs,ss)) then
            Break;
          if (ss.dwCheckPoint < dwChkP) then
            Break;
        end;
      end;
      Result := DeleteService(schs);
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);

    schm := OpenSCManagerW(PWideChar(sMachine),SC_MANAGER_CONNECT);
    if schm > 0 then
    begin
      schs := OpenServiceW(schm,_DELETE or SERVICE_STOP or SERVICE_QUERY_STATUS);
      if schs = 0 then
      begin
        if GetLastError = ERROR_SERVICE_DOES_NOT_EXIST then
        begin
          Writeln('Service not exists');
          Result := True;
        end;
      end
      else
      begin
        CloseServiceHandle(schs);
      end;
      CloseServiceHandle(schm);
    end;
  end;
end;

内核代码

NTSTATUS DrvProcCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.information = 0;

    IoCompleteRequest(Irp,IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}

NTSTATUS DrvProcclose(IN PDEVICE_OBJECT DeviceObject,IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}

#define NT_DEVICE_NAME L"\\Device\\MyDrv"
#define DOS_DEVICE_NAME L"\\??\\MyDrv"

void DrvProcUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING deviceLinkUnicodeString;
    NTSTATUS status;

    RtlInitUnicodeString(&deviceLinkUnicodeString,DOS_DEVICE_NAME);

    status = IoDeleteSymbolicLink(&deviceLinkUnicodeString);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoDeleteSymbolicLink() error - 0x%X \n",status);
        return;
    }

    IoDeleteDevice(DriverObject->DeviceObject);

    DbgPrint("Goodbye from driver \n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
    UNICODE_STRING deviceNameUnicodeString;
    UNICODE_STRING deviceLinkUnicodeString;
    PDEVICE_OBJECT deviceObject = NULL;
    NTSTATUS ntStatus = STATUS_SUCCESS;

    RtlInitUnicodeString(&deviceNameUnicodeString,NT_DEVICE_NAME);

    ntStatus = IoCreateDevice(DriverObject,&deviceNameUnicodeString,FILE_DEVICE_UNKNowN,FILE_DEVICE_SECURE_OPEN,FALSE,&deviceObject);

    if (!NT_SUCCESS(ntStatus))
    {
        DbgPrint("IoCreateDevice() error - 0x%X \n",ntStatus);
        return ntStatus;
    }

    RtlInitUnicodeString(&deviceLinkUnicodeString,DOS_DEVICE_NAME);

    ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString,&deviceNameUnicodeString);

    if (!NT_SUCCESS(ntStatus))
    {
        DbgPrint("IoCreateSymbolicLink() error - 0x%X \n",ntStatus);

        if (NULL != deviceObject)
        {
            IoDeleteDevice(deviceObject);
        }

        return ntStatus;
    }

    DriverObject->MajorFunction[IRP_MJ_CREATE] = DrvProcCreate;
    DriverObject->DriverUnload = DrvProcUnload;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = DrvProcclose;

    DbgPrint("Hello from driver \n");

    return ntStatus;
}

编辑:

在下面的第一条评论之后,ControlService返回:

1061 - ERROR_SERVICE_CANNOT_ACCEPT_CTRL ,但在文档中:

除了SERVICE_CONTROL_STOP和SERVICE_CONTROL_INTERROGATE之外,驾驶员不接受其他控制代码


编辑2:

我尝试使用PC Hunter ARK(著名的中文反rootkit)进行卸载,并且成功停止了我的驱动程序。 PC Hunter的实现是用来卸载 .sys 模块的,类似于this。为什么有人知道,为什么Win32 api(ring3-usermode)无法正常工作?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。