共用方式為


模仿

某些檔案系統可能會認為,為原始呼叫端執行作業是很有用的。 例如,網路檔案系統可能需要在開啟檔案時擷取呼叫端的安全性資訊,以便使用適當的認證來執行後續作業。 毫無疑問,在許多其他特殊情況下,這種類型的功能在檔案系統內以及特定應用程式中都很有用。

模擬所需的關鍵例程包括:

  • PsImpersonateClientSeImpersonateClientEx--起始模擬。 除非指定特定執行緒,否則模擬會在目前執行緒的上下文中進行。

  • PsRevertToSelf--終止目前執行緒內容內的擬似身份。

  • PsReferencePrimaryToken-- 保留指定程序的主要(程序)權杖的參考。 此函式可用來取得系統上任何程序的權杖(Token)。

  • PsDereferencePrimaryToken--釋放對先前引用的主要權杖的引用。

  • SeCreateClientSecurityFromSubjectContext--傳回一個用於模擬的有用用戶端安全性內容,從主旨內容中獲取(例如,在 IRP_MJ_CREATE 處理期間提供給 FSD)。

  • SeCreateClientSecurity--根據系統上現有執行緒的安全性認證來建立用戶端安全性內容。

  • ImpersonateSecurityContext--模擬核心安全服務 ksecdd.sys內的安全內容。

  • RevertSecurityContext--終止核心安全性服務 ksecdd.sys內的模擬。

模擬很容易實現。 下列程式碼範例示範基本模擬:

NTSTATUS PerformSpecialTask(IN PFSD_CONTEXT Context)
{
  BOOLEAN CopyOnOpen;
  BOOLEAN EffectiveOnly;
  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  NTSTATUS Status;
  PACCESS_TOKEN oldToken;

  //
  // We need to perform a task in the system process context
  //
  if (NULL == Context->SystemProcess) {

    return STATUS_NO_TOKEN;

  }

  //
  // Save the existing token, if any (otherwise NULL)
  //
  oldToken = PsReferenceImpersonationToken(PsGetCurrentThread(),
                                           &CopyOnOpen,
                                           &EffectiveOnly,
                                           &ImpersonationLevel);

  Status = PsImpersonateClient( PsGetCurrentThread(),
                                Context->SystemProcess,
                                TRUE,
                                TRUE,
                                SecurityImpersonation);
  if (!NT_SUCCESS(Status)) {

    if (oldToken)
        PsDereferenceImpersonationToken(oldToken);
    return Status;

  }

  //
  // Perform task - whatever it is
  //


  //
  // Restore to previous impersonation level
  //
  if (oldToken) {
    Status = PsImpersonateClient(PsGetCurrentThread(),
                                 oldToken,
                                 CopyOnOpen,
                                 EffectiveOnly,
                                 ImpersonationLevel);

    if (!NT_SUCCESS(Status)) {
      //
      // This is bad - we can't restore, we can't leave it this way 
      //
      PsRevertToSelf();
    }
    PsDereferenceImpersonationToken(oldToken);
  } else {
    PsRevertToSelf();
  }

  return Status;
}

檔案系統開發人員可以使用此模擬程式碼的許多變體,但這提供了該技術的基本說明。