关闭Windows 文件保护的方法

http://www.bitsum.com/aboutwfp.asp#Hack_Method_5

[ Back to Bitsum Technologies ]

Last Revision: 01/01/06

Work in progress! Under construction, etc..


Disclaimer: DO NOT TRY ANY OF THESE METHODS UNLESS YOU KNOW WHAT YOU ARE DOING. THE AUTHOR OF THIS DOCUMENT MAKES NO WARRANTIES, EXPRESSED OR IMPLIED. THE AUTHOR OF THIS DOCUMENT CAN NOT BE HELD LIABLE FOR DAMAGES RESULTING FROM USE OR MIS-USE OF THESE TECHNIQUES. USE AT YOUR OWN RISK. THIS DOCUMENT IS INTENDED FOR ADVANCED PROGRAMMERS ONLY. DO NOT ATTEMPT IF YOU DO NOT WISH TO LOSE ANY OR ALL DATA ON THE COMPUTER. THIS DOCUMENT MAY CONTAIN ERRORS. IF YOU DO NOT AGREE TO THESE TERMS, DO NOT READ FURTHER AND DO NOT USE THESE TECHNIQUES.

IF YOU USE THIS ARTICLE IN ONE OF YOUR OWN, PLEASE LINK BACK TO IT AS A REFERENCE.


Hacking Windows File Protection

Jeremy Collake
Bitsum Technologies
http://www.bitsum.com .
jeremy@bitsum.com

Useful tools:

WfpReplace - Tool to replace WFP protected files. (x32 and x64) [C++ source included]
WfpAdmin - Tool to disable WFP on specific folders. (x32 only)
MoveLater - Console app to replace in-use files.
PEChksum - Console app to correct PE image checksums.

 

Quick links:

Hack Method 1: Disable WFP for specific folders until the computer is next rebooted via manual handle manipulation
Hack Method 2: Disable WFP completely until the computer is next rebooted via undocumented SFC API
Hack Method 3: Disable WFP on a specific file for 1 minute via undocumented SFC API
Hack Method 4: Disable WFP permanently via patches and undocumented registry value
Hack Method 5: Disable WFP permanently on specific files via patching the protected file list

 

Hacking Windows File Protection

Windows File Protection (WFP) is a mechanism that protects system files from being modified or deleted. Introduced in Windows 2000, Windows File Protection was a leap forward in operating system stability since it protected the core modules from being corrupted or updated except by service packs or hotfixes sent from Microsoft.

A big problem prior to Windows 2000 was 'DLL Hell'. Applications would often update system modules with their own versions, regardless if other applications already installed were depending on a different version of that same module. Although Microsoft recommended that application programmers place modules into the program's folder instead of the system folder, few programmers did. WFP solved DLL Hell, along with many other issues.

In order to protect the integrity of the system, Microsoft did not document a way to disable WFP. If they had, programmers would surely begin to circumvent it and have their application installers overwrite system modules with their own versions. Booting to Safe Mode was the only way Microsoft provided for replacing a protected file. In theory, this was a good idea. However, programmers and power users sometimes desire the power to replace or delete protected modules without the cumbersome process of booting to safe mode and back.

Enter the hacks.

In Windows 2000, a hidden registry value to fully disable WFP existed. Unfortunately, this didn't last long after I discovered and posted it to NTBugTraq. Microsoft soon tweaked their code so that the hidden registry value was neutralized (curiously, it wasn't completely removed from the code). I then created patches to re-enable this undocumented value. Appendix A describes the history of the discovery of the undocumented registry value and creation of the patches to re-enable it.

Since that time, many other techniques to disable or circumvent Windows File Protection have been discovered.

How the System File Checker monitors files for changes

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.

The contents of SFC.DLL and SFC_OS.DLL have changed between Windows 2000 and Windows XP. In Windows XP, SFC_OS.DLL contains all the core code and SFC.DLL is merely a proxy to it. The exports of SFC.DLL are forwarded on to SFC_OS.DLL. The SFCFILES.DLL module is simply a data holder that contains a list of all files protected by WFP.

At startup the winlogon service invokes the unnamed export ordinal 1 of SFC_OS.DLL, SfcInitProt. This API launches a new free thread called the 'SFC Watcher Thread'. This thread creates a series of directory change notification events, one for each folder that contains a protected file. The WaitForMultipleObjects API is then called within loop to wait for any of these events to be signalled. Upon event signaling, the modified file(s) are determined and replaced with copies found in the cache folder, if one exists there. If it doesn't, the user is prompted to insert the Windows installation CD so that the file can be replaced from the copy found on it.

Therefore, SFC actually allows for files to be replaced or modified, then overwrites them. A few second delay is incorporated so that time is given for write operations to 'settle down' before the affected file(s) are restored.

Knowing how SFC works means that one can easily disable it by terminating the watcher thread or by closing the directory change notification event handles. This leads us to methods 1 and 2:

The core of Windows File Protection
SFC.DLLWFP executable content. In XP only a proxy to SFC_OS.DLL.
SFC_OS.DLLWFP executable content.
SFCFILES.DLLContains list of protected files. Exports SfcGetFiles API.
SFC.EXESystem File Checker utility. Utility to scan WFP protected files for changes and replace altered versions.

Hack Method 1: Disable WFP for specific folders until the computer is next rebooted via manual handle manipulation

The first technique to disable WFP is to close 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 ntdll.NtDuplicateHandle (or kernel32.DuplicateHandle). This method is used by WfpAdmin.

Hack Method 2: Disable WFP completely until the computer is next rebooted via undocumented SFC API

The second technique is to terminate the SFC Watcher Thread that continually waits for and responds to the directory change notification events to be signalled. 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 kernel32.CreateRemoteThread and WFP will be disabled until the winlogon process restarts (computer is rebooted).

Ordinal 2:
DWORD WINAPI SfcTerminateWatcherThread();

The return value is 0 if success, or 1 if an error occurred .

Hack Method 3: Disable WFP on a specific file for 1 minute via undocumented SFC API

The SFC_OS.DLL module exports another very useful undocumented, unnamed API at oridinal 5: SfcFileException. This handy API will register a temporary SFC exception for specific file, allowing the file to be updated. The period the exception is in place is currently one minute.

Ordinal 5:
DWORD WINAPI SfcFileException(DWORD dwUnknown0, PWCHAR pwszFile, DWORD dwUnknown1);

dwUnknown0Unknown. Set to 0
pwszFileFilename
dwUnknown1Unknown. Set to -1

The return value is 0 if success, or 1 if an error occurred (usually that the file is not protected by WFP).

An example call to this API is:
SetSfcFileException(0, L"c://windows//notepad.exe",-1);

Hack Method 4: Disable WFP permanently via patches and undocumented registry value

Prior to Windows 2000 SP1 there was an undocumented registry value that would fully disable WFP. This is the famous 0xffffff9d value I discovered while reverse engineering SFC.DLL in Windows2000. Unfortunately, soon after its discovery Microsoft disabled it. Fortunately, the core code to disable WFP was left in SFC.DLL (later moved to SFC_OS.DLL). Therefore, a simple patch to SFC.DLL or SFC_OS.DLL will re-enable this value. I've created patches for 2K and XP and have generalized the patching procedure so the patch may be applied to all current and (hopefully) future versions of the SFC module without having to worry about a specific patch address.

General patch procedure:

For Windows 2000, the patch is applied to SFC.DLL.
For Windows XP and 2003, the patch is applied to SFC_OS.DLL.

Copy the target file to a temporary one.

Search for the bytes '83 F8 9D 75 07 8B C6'.
Replace the '8B C6' with '90 90'.

You must correct the checksum of the image by using our PEChkSum utility. It can be obtained here.

Now set the temporary file to replace the original at boot-time by using our MoveLatr utility. It can be obtained here.

Set the SFCDisable value described below and then reboot the computer to complete the process.

Undocumented SFCDisable value:

Key: HKEY_LOCAL_MACHINE/Software/Policies/Microsoft/Windows NT/Windows File Protection
Value name: SFCDisable
Value: 0xFFFFFF9D

Hack Method 5: Disable WFP permanently for specific files via patching the protected file list

More simple than patching executable code is simply patching the list of files contained in SFCFILES.DLL. First, copy SFCFILES.DLL to a temporary file. Using a hex editor (i.e. UltraEdit), search for files to disable protection on inside the temporary file. Once found, replacing the first character of the file name with 0 (that is: value 0 NOT ascii '0' character). After completing the modifications, correct the checksum using our PEChkSum utility and set the temporary file to replace the original at boot-time using our MoveLatr utility. Reboot the computer to finish the process.

-Jeremy Collake
jeremy@bitsum.com

Like this article? Please feed me by donating to jeremy@bitsum.com via paypal ;).

The End


 


The following are original publications preserved for historical reasons, misc. technical details, or other useless stuff.
Stop reading here.

 


Appendix A: Original publication of undocumented registry setting to fully disable WFP
(no longer works without binary patches)



NTBugTraq Posting:
 

W2k undocumented registry setting fully disables Windows File Protection

From: Jeremy Collake (collake@CHARTER.NET)
Date: Sat Jun 24 2000 - 05:16:46 CDT

  • 6:13am 6/24
     

    Summary: Undocumented registry setting allows for
       Windows File Protection (aka System File Checker)
       to be fully disabled.
     

    HowTo: Set the SFCDisable value (see Q222473) to
      0xffffff9d.
     

    Ok, after spending 6 hours in the guts of sfc.dll, sfcfiles.dll,
    and winlogon.exe I have *finally* discovered how to permanently
    disable windows file protection. The more I dug into the internals
    of SFC, the more I began to think that it would not be as easy as
    I first thought it would be - and indeed Microsoft does not want it
    to be easy. Windows File Protection, while annoying, does provide
    a good degree of system stability and even some level of virus/trojan
    protection by preventing system files from being modified without
    at least notifying the user. Therefore, I was *very* shocked when
    I was looking through a disassembly of sfc.dll and came to the code
    that checks the value of the SfcDisable in the WinLogon key.
    I see in the code of ordinal 2 (which is the initialization function
    that winlogon calls), sticking out like a sore thumb, this:
     

    76986A89 push 1
    76986A8B cmp eax, ebx
    76986A8D pop esi
    76986A8E jz loc_76986B97
    76986A94 cmp eax, esi
    76986A96 jz loc_76986B7A
    76986A9C cmp eax, 2
    76986A9F jz loc_76986B69
    76986AA5 cmp eax, 3
    76986AA8 jz short loc_76986AE0
    76986AAA cmp eax, 4
    76986AAD jz short loc_76986ACF
    76986AAF cmp eax, 0FFFFFF9Dh
    76986AB2 push ebx
    76986AB3 jz loc_76986B86
    76986AB9 push offset byte_76981898
    76986ABE push edi
    76986ABF call sub_7698877D
    76986AC4 mov dword_769901D4, ebx
    76986ACA jmp loc_76986B97
     

    Ok, values 0, 1, 2, 3, and 4 are documented at
    http://support.microsoft.com/support/kb/articles/Q222/4/73.ASP , but
    what the heck is this 0ffffff9dh value that it accepts?! As you can
    see, any value other than 0,1,2,3,4 and 0ffffff9dh are assumed to be
    zero, which is the default of SFC enabled with popups enabled. So,
    without further delay, I went and plugged 0ffffff9dh into the SfcDisable
    value to see what was up. Rebooted. I'll be darned, Microsoft provided
    a very,very simple way to fully disable WFP!
     

    When booting with this value in the SFCDisable value in the WinLogon
    key (HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Winlogon), an
    event is written to the system log, ID 64032 from Windows File
    Protection, with the description:
    "Windows File Protection is not active on this system. ".
     

    All attempts to replace/delete protected system files succeeded,
    just as if I were in safe mode :). I rebooted a few more times and
    verified that it is the one value (other than 4=popus disabled) that
    is not reset to 0 after the first boot.
     

    Needless to say, this is not what Microsoft intended.
     

    Well, it's now 6am, hopefully I haven't mucked this up too much in
    my delerium.
     

    Jeremy Collake
    collake@charter.net
    http://www.collakesoftware.com



Appendix B: Original publication of binary patches to SFC.DLL or SFC_OS.DLL
 

 

Binary Patches:

If you would like to re-enable the undocumented value to disable Windows File Protection, you may apply the appropriate patch and then replace the DLL in the 2k/XP recovery console (boot to CD).  Be sure to set the checksum in the PE header by using Bitsum Technology's SetCSUM utility after patching.

How to find the patch offset yourself for current and hopefully future version of SFC.DLL or SFC_OS.DLL:

Search for the hex byte sequence: '83 F8 9D 75 07 8B C6' and replace the '8B C6' with '90 90'. If more than one occurance of this sequence is found, do not patch unless you know what you are doing. Email me at jeremy@bitsum.com for more aid. Please do not email me with requests for instructions on how to actually apply the patches listed here. They are intentionally kept technical to prevent layman modification of windows system files which could result in an unbootable system, or worse.

This patch changes the instruction 'mov eax,esi' to two 'nop's. At this location of execution when the undocumented registry value is given, eax holds 0ffffff9d and esi is 0. Therefore, this patch prevents eax from being nullified before the switch on the registry value held in eax that follows.


Windows2000 SP2:

file:            SFC.DLL
virtual offset:  76986C11
physical offset: 6211
original:        8BC6
new:             9090

Windows 2000 SP4:

file:            SFC.DLL
virtual offset:  76986CDB
physical offset: 62DB
original:        8BC6
new:             9090


WindowsXP:

file:            SFC_OS.DLL
virtual offset:  76C6EEB8
physical offset: 0E2B8
original:        8BC6
new:             9090

WindowsXP SP1:

file:            SFC_OS.DLL
virtual offset:  76C6EFBB
physical offset: 0E3BB
original:        8BC6
new:             9090
 


 

*************


.586
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc

include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.lib

include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib

include /masm32/macros/macros.asm
include /masm32/macros/ucmacros.asm

SfcFileExceptionDef    typedef proto :dword,:dword,:dword
lpSfcFileException        typedef ptr SfcFileExceptionDef

.data
    WSTR szFile,"C:/windows/Explorer.exe"
.data?
    SfcFileException    lpSfcFileException    ?
 .code
Main proc
        invoke LoadLibrary,SADD('SFC_OS.DLL')
        invoke GetProcAddress, eax, 5
        mov SfcFileException, eax
        invoke SfcFileException, 0, offset szFile, -1
        .if eax
                invoke MessageBox,NULL,SADD('Err'),SADD('Err'),MB_OK
        .else
                invoke MessageBox,NULL,SADD('OK'),SADD('OK'),MB_OK
        .endif
        ret
Main endp

end Main
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值