Windows File Protection (WFP) is a sub-system included in Microsoft Windows operating systems of the Windows 2000 and Windows XP.
It aims to prevent programs from replacing critical Windows system files.
The executable portion of WFP is called the System File Checker (SFC). It exists throughout SFC.DLL, SFC_OS.DLL, SFCFILES.DLL, and SFC.EXE:
- SFC.DLL: WFP executable content. In XP only a proxy to SFC_OS.DLL.
- SFC_OS.DLL: WFP executable content.
- SFCFILES.DLL: Contains list of protected files. Exports SfcGetFiles API.
- SFC.EXE: System File Checker utility. Utility to scan WFP protected files for changes and replace altered versions.
Bypassing the protection
It is possible to disable the WFP by terminating the watcher thread or by closing the directory change notification event handles.
Disable WFP for specific folders until the computer is next rebooted via manual handle manipulation
This technique consists in closing the directory change notification handles by enumerating the handles that winlogon has opened, determining which ones correspond to the folder(s) we wish to deprotect by querying and comparing the handle names, then closing those handles via NtDuplicateHandle (or DuplicateHandle). This method is used by WfpAdmin.
Disable WFP completely until the computer is next rebooted via undocumented SFC API
The technique consists in terminating the SFC Watcher Thread that continually waits for and responds to the directory change notification events to be signaled. Doing this manually isn't very practical since it is diffucult to be sure the right thread has been located. Fortunately, the SFC_OS.DLL exposes a nice unnamed export at ordinal 2: SfcTerminateWatcherThread. This API accepts no parameters and does exactly as its name implies. However, there is one caveat to using this function: It must be invoked in the process that created the SFC Watcher Thread: winlogon. To accomplish this, virtual memory needs to be allocated in the winlogon process space and a thread procedure that invokes SfcTerminateWatcherThread copied into that memory. The thread procedure should then be invoked using CreateRemoteThread and WFP will be disabled until the winlogon process restarts (computer is rebooted).
DWORD WINAPI SfcTerminateWatcherThread();
The return value is 0 if success, or 1 if an error occurred .