如何判断WOW文件系统是否为线程打开

How to tell if WOW file system redirection is on for a thread?

本文关键字:是否 线程 文件系统 WOW 何判断 判断      更新时间:2023-10-16

说,我可以使用WOW64DisableWow64fsredirection API禁用文件系统重定向,但是是否有办法知道该线程当前是否正在重定向?换句话说,是否有像GetWow64FsRedirection这样的API?

没有报告此状态的API函数。期望您记住您禁用重定向。

对不起,忘了发布后续行动。正如公认的答案所暗示的那样,没有API可检测到这一点。太糟糕了,因为该信息在线程TEB结构的无证件部分中存储。(请参阅代码中的评论。)

下面的代码将检索它。

我必须通过说这是通过逆转上述API获得的。因此,这是一个高度无证件的东西,可能会在将来的OS版本中破坏。因此,请确保在使用版本保障措施之前。对于所有已发布的Windows版本,都应该可以,包括Windows 10 Build 17134:

enum YESNOERR{
    ERR = -1,
    NO = 0,
    YES = 1,
};
struct PROC_STATS{
    BOOL b32BitProcessOn64BitOS;
    DWORD dwOS_Major;
    DWORD dwOS_Minor;
    DWORD dwOS_Build;
    PROC_STATS()
    {
        BOOL (WINAPI *pfnIsWow64Process)(HANDLE, PBOOL);
        (FARPROC&)pfnIsWow64Process = ::GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
        BOOL bWow64 = FALSE;
        b32BitProcessOn64BitOS = pfnIsWow64Process && pfnIsWow64Process(::GetCurrentProcess(), &bWow64) && bWow64;
        LONG (WINAPI *pfnRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
        (FARPROC&)pfnRtlGetVersion = ::GetProcAddress(::GetModuleHandle(_T("ntdll.dll")), "RtlGetVersion");
        OSVERSIONINFOEX osvi = {0};
        osvi.dwOSVersionInfoSize = sizeof(osvi);
        pfnRtlGetVersion(&osvi);
        dwOS_Major = osvi.dwMajorVersion;
        dwOS_Minor = osvi.dwMinorVersion;
        dwOS_Build = osvi.dwBuildNumber;
    }
};
PROC_STATS procStats;

YESNOERR __cdecl GetWow64FsRedirection()
{
    //Checks if Wow64 file system redirection is on for the current thread
    YESNOERR res = ERR;
    __try
    {
        if(procStats.b32BitProcessOn64BitOS)
        {
            //Really easy pre-Win10 v.10.0.10041.0
            if(procStats.dwOS_Major < 10 ||
                (procStats.dwOS_Major == 10 && procStats.dwOS_Build <= 10041))
            {
                //Win XP, 7, 8.1 & earlier builds of Win10
                __asm
                {
                    mov     eax, fs:18h             ; TEB
                    mov     eax, [eax + 0F70h]
                    mov     eax, [eax + 14C0h]
                    xor     ecx, ecx
                    test    eax, eax                ; 0=Wow64FsRedir is on, 1=Off
                    setz    cl
                    mov     [res], ecx
                }
            }
            else
            {
                //Latest builds of Win10 have a separate WoW TEB block
                __asm
                {
                    mov     eax, fs:18h             ; TEB
                    mov     ecx, [eax + 0FDCh]      ; WowTebOffset
                    test    ecx, ecx
                    jns     lbl_no_offset           ; it must precede TEB
                    add     eax, ecx
lbl_no_offset:
                    cmp     eax, [eax + 18h]        ; pick version of the struct
                    jz      lbl_alt
                    mov     eax, [eax + 14C0h]
                    jmp     lbl_check
lbl_alt:
                    mov     eax, [eax + 0E30h]
lbl_check:
                    xor     ecx, ecx
                    test    eax, eax                ; 0=Wow64FsRedir is on, 1=Off
                    setz    cl
                    mov     [res], ecx
                }
            }
        }
        else
        {
            //It's off by default
            res = NO;
        }
    }
    __except(1)
    {
        //Oops, too far in the future -- this no longer works
        res = ERR;
    }
    return res;
}

这是您可以测试的方式:

resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
void* pOldV;
if(::Wow64DisableWow64FsRedirection(&pOldV))
{
    resWow64FsOn = GetWow64FsRedirection();
    _tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
    ::Wow64RevertWow64FsRedirection(pOldV);
    resWow64FsOn = GetWow64FsRedirection();
    _tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
}
else
{
    _tprintf(L"ERROR: (%d) API Failedn", ::GetLastError());
}

另一种方法是检查Windows System32目录中wow32.dll的存在(通常是C:WindowsSystem32)。在64位系统上,该文件应位于SysWOW64目录中,因此,如果启用了文件重定向,它将找到。同样,可以检查位于64位系统上的System32目录中的wow64.dll的不存在,如果找不到它,则启用了重定向。

伪代码为:

bool IsWow64FileSystemRedirectionEnabled()
{
    if (!Is64BitOS()) return false;
    if (FileExists(GetSystem32Directory() + "\wow32.dll")) return true;
    return false;
}

其中:

  • Is64BitOS可以如下所示实现
  • FileExists可以如下所示实现
  • GetSystem32Directory-可以如下所示实现