Скажи, я могу использовать Wow64DisableWow64FsRedirection API для отключения перенаправления файловой системы, но есть ли способ узнать, перенаправляется ли поток в данный момент? Другими словами, есть ли API как GetWow64FsRedirection
?
Не существует API-функции, которая сообщает об этом состоянии. Вы должны помнить, что вы отключили перенаправление.
Извините, забыл опубликовать продолжение. Как следует из принятого ответа, нет API, чтобы обнаружить это. Жаль, потому что информация хранится прямо там, в недокументированном разделе TEB
структура. (Смотрите мои комментарии в коде.)
Код ниже получит его.
Я должен предвосхитить его, сказав, что он был получен путем изменения вышеупомянутого API. Так что это очень недокументированный материал, который, вероятно, сломается в будущих версиях ОС. Так что не забудьте поставить версию безопасности перед использованием. Это должно быть хорошо для всех выпущенных версий 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=%d\n", resWow64FsOn);
void* pOldV;
if(::Wow64DisableWow64FsRedirection(&pOldV))
{
resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%d\n", resWow64FsOn);
::Wow64RevertWow64FsRedirection(pOldV);
resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%d\n", resWow64FsOn);
}
else
{
_tprintf(L"ERROR: (%d) API Failed\n", ::GetLastError());
}
Другой подход заключается в проверке существования wow32.dll
в каталоге Windows System32 (обычно C:\Windows\System32
).
В 64-битных системах этот файл должен находиться в SysWOW64
каталог, таким образом, если перенаправление файлов включено, оно будет найдено.
Точно так же можно проверить на отсутствие wow64.dll
, который находится в каталоге System32 на 64-битных системах, и если он не найден, перенаправление включено.
псевдокод для этого будет:
bool IsWow64FileSystemRedirectionEnabled()
{
if (!Is64BitOS()) return false;
if (FileExists(GetSystem32Directory() + "\\wow32.dll")) return true;
return false;
}
Куда: