共用方式為


稽核 Visual C++ 執行階段版本的使用情況

Microsoft Visual C++ Redistributable 與 Visual Studio C++ 執行環境(統稱「VC Runtime」)是許多應用程式的關鍵元件。 在你的網路中,機器可能仍在執行安裝並使用已不支援版本的 VC 執行時的應用程式。 你可以使用 NTFS 檔案稽核來識別此類使用,作為替換為使用支援版本 VC 執行環境的應用程式的步驟。 本文將引導您如何設定 NTFS 檔案稽核,提供故障排除技巧,並強調定期稽核的好處。

如需不再支援之 VC 執行階段版本的詳細資訊,請參閱 Microsoft Visual C++ 最新支援的可再發行套件下載。

啟用NTFS檔案稽核以判斷 VC 執行時間使用量

本文提供手動啟用 NTFS 檔案稽核及審查稽核事件的步驟,以判斷哪些應用程式呼叫了不支援的 VC 執行時版本。 由於應用程式可以使用多個檔案,本文也說明如何使用 PowerShell 和 cmdlets 來更新審計權限。 如需如何設定檔案審核策略的詳細資訊,請參閱 在檔案或資料夾上套用基本審核策略。

在系統上手動啟用物件存取稽核

在啟用檔案層級稽核前,必須先啟用物件存取:

  1. 選擇 Windows+R 以開啟 Run 對話框。 接著進入 並選擇 Enter 以開啟 本地群組政策編輯器。
  2. 前往 電腦配置>Windows 設定>安全設定>進階稽核政策設定>系統稽核政策>物件存取
  3. 按兩下 稽核檔案系統。 在 [稽核文件系統屬性] 對話框中,選取 [[設定下列稽核事件][成功][確定]。
  4. 關閉本地群組原則編輯器。

或者,你也可以用來 啟用物件存取:

  1. 使用 列出命令列中的目前設定。
  2. 使用 啟用物件存取。

在檔案上手動啟用稽核

若要監視存取 VC 執行時間檔案的進程,請在 VC 執行時間檔案上啟用稽核:

  1. 以滑鼠右鍵按下您要稽核的檔案,選取 [屬性] ,然後選取 [安全性] 索引卷標。如需尋找已安裝 VC 執行時間檔案的詳細資訊,請參閱 VC 執行時間安裝的位置。
  2. 選取 [進階]。
  3. 在 進階安全設定 對話框中,選擇 「稽核 」標籤,然後選擇 繼續。
  4. 若要新增稽核規則,請選取 [[新增]。 在稽核條目對話框中,選擇一個主體,然後輸入你想新增的使用者或群組名稱,例如 (Everyone)。 然後選擇確定。
  5. 在 類型中,確保選擇 成功 。
  6. 選擇 顯示進階權限清除全部瀏覽資料夾/執行檔案確認。
  7. 請注意,稽核記錄中新增的一列與你所選的相符。 選取 [確定] 。
  8. 在 屬性 對話框中,選擇 確定。

現在已為檔案啟用稽核規則。

手動檢閱稽核記錄

NTFS 檔案稽核會產生事件 4663:這個事件表示某程序嘗試存取包含稽核權限的物件的每一個檔案。

  1. 選擇 Windows+R 以開啟 Run 對話框。 接著輸入 eventvwr.msc,並選擇 Enter 開啟 事件檢視器
  2. 事件檢視器中,透過展開Windows 日誌,進入安全性日誌下的安全性記錄。 結果窗格會列出安全性事件。
  3. 在 [動作] 窗格中選擇 [篩選目前記錄...] 來尋找稽核事件。 若要將事件範圍縮小到事件 ID 4663(檔案系統類別的審核成功率),請在包含/排除事件 ID 的文字框中輸入 4663。

關於檔案存取稽核事件 4663 的範例,請參見 4663(S):嘗試存取物件。

使用 PowerShell 稽核 VC 運行時間使用量

要使用 PowerShell 更新檔案稽核權限,請依照以下步驟操作:

  1. 定義適用於檔案 的檔案系統稽核規則 。
  2. 使用 取得檔案的安全性描述元。
  3. 將稽核規則 套用至安全性描述元。
  4. 使用 在源檔上套用更新的安全性描述元。
  5. 使用 檢視檔案存取稽核事件 4663 記錄。

PowerShell:審核已不支援的 VC 執行階段檔案

下列 PowerShell 程式代碼可讓您稽核不再支援的已安裝的 VC 執行時間檔案。

function Get-AuditRuleForFile {
    $auditRuleArguments =   'Everyone'              <# identity #>,
                            'ExecuteFile, Traverse' <# fileSystemRights #>,
                            'Success'               <# flags #>
    $auditRule = New-Object System.Security.AccessControl.FileSystemAuditRule($auditRuleArguments)

    return $auditRule
}

function Set-FileAuditRule {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$file,
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.Security.AccessControl.FileSystemAuditRule]$auditRule
    )

    $existingAcl = Get-Acl -Path $file
    $existingAcl.AddAuditRule($auditRule) | Out-Null
    Set-Acl -Path $file -AclObject $existingAcl
}

$newAuditRule = Get-AuditRuleForFile

# Visual Studio Redistributable for 2005 (VC++ 8.0) and 2008 (VC++ 9.0)
Get-ChildItem "$ENV:SystemRoot\WinSxS\Fusion" -filter '*.dll' -ErrorAction SilentlyContinue -Recurse |
Where-Object FullName -IMatch 'microsoft\.vc[89]0' |
ForEach-Object {
    Set-FileAuditRule $_.FullName $newAuditRule
}

# Visual Studio Redistributable for 2010 (VC++ 10.0), 2012 (VC++ 11.0) and 2013 (VC++ 12.0)
$languageCodes = 'chs|cht|deu|enu|esn|fra|ita|jpn|kor|rus'
$versions = '(1[012]0)'
$regex = "^((atl|msvc[pr]|vcamp|vccorlib|vcomp)$versions|mfc$versions(u|$languageCodes)?|mfcm$versions(u)?)\.dll$"
Get-ChildItem "$ENV:SystemRoot\SysWOW64","$ENV:SystemRoot\System32" -filter '*.dll' |
Where-Object Name -imatch $regex |
ForEach-Object {
    Set-FileAuditRule $_.FullName $newAuditRule
}

PowerShell:檢視檔案稽核事件

PowerShell 提供 取得各種事件日誌的事件記錄,如以下 PowerShell 程式碼所示,列出過去 24 小時內所有檔案存取稽核事件 4663 紀錄:

function Get-AuditEntries {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.DateTime]$oldestTime
    )
    Get-WinEvent -FilterHashtable @{LogName='Security';Id=4663;StartTime=(Get-Date $oldestTime)} |
    ForEach-Object {
        $record = [ordered]@{}
        $record['TimeCreated'] = $_.TimeCreated
        $accessName = ($_.Message |
            Select-String -Pattern "Accesses:[\t\s]+(?<Accesses>.+)").Matches.Groups[1]
        ([xml]$_.ToXML()).Event.EventData.ChildNodes |
        ForEach-Object -Begin {
            $record[$accessName.Name]=$accessName.Value.Trim()
        } -Process {
            $record[$_.Name] = $_.'#text'
        }
        [PSCustomObject]$record
    } |
    Where-Object { $_.ObjectName -imatch '\.dll$'}
}

Get-AuditEntries -oldestTime (Get-Date).AddHours(-24)
TimeCreated : 11/20/2024 5:00:11 AM
Accesses : Execute/Traverse
SubjectUserSid : \*\*\*\*\*
SubjectUserName : \*\*\*\*\*
SubjectDomainName : WORKGROUP
SubjectLogonId : \*\*\*\*\*
ObjectServer : Security
ObjectType : File
ObjectName : C:\\Windows\\WinSxS\\amd64\_microsoft.vc90.crt\_1fc8b3b9a1e18e3b\_9.0.30729.9635\_none\_08e2c157a83ed5da\\msvcr90.dll
HandleId : 0x93c
AccessList : %%4421
AccessMask : 0x20
ProcessId : 0x24d4
ProcessName : C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe
ResourceAttributes : S:AI

稽核 VC 運行時間使用量之後的後續步驟

在確定哪些程序使用 VC 執行時檔案,或哪些應用程式安裝了 Visual C++ Redistributable 後,請卸載這些應用程式或升級到不依賴不支援的 VC 執行時的新版本。

有些 Microsoft 應用程式需要舊版的 VC 執行環境。 欲了解更多資訊,請參閱 Visual C++ 可再發佈函式庫與執行時函式庫常見問題集。

Visual C++ 運行時安裝位置

下表列出各版本 VC 執行環境的安裝地點。

Visual Studio 版本 安裝地點
Visual Studio 2013 (VC++ 12.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2012 (VC++ 11.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2010 (VC++ 10.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2008 (VC++ 9.0) %SystemRoot%\\WinSxS\\Fusion
Visual Studio 2005(VC++ 8.0) %SystemRoot%\\WinSxS\\Fusion