Даже и не думайте пользоваться функцией Wow64DisableWow64FsRedirection!

Просто удивительно, насколько опасной может быть функция Wow64DisableWow64FsRedirection. Эта функция позволяет временно отключить перенаправление файловой системы в Wow64. Еще более удивительно, что лишь малая доля разработчиков соглашается менять свой код, даже после подробного объяснения, в чем, собственно, проблема.

В чем состоит опасность? Во-первых, при отключенном перенаправлении файловой системы не работает загрузка 32-х битных системных библиотек. Они, как правило, загружаются из system32 и только перенаправление ввода/вывода спасает ситуацию. Во-вторых, и это самое главное, разработчик очень редко полностью контролирует весь ввод-вывод на участке между Wow64DisableWow64FsRedirection и Wow64RevertWow64FsRedirection.

«Как это возможно?» - спросите вы, «ведь все три строчки кода – вот они, как на ладони». Очень просто. Вот неполный список случаев, когда может происходить неявная загрузка кода:

link /dump /exports c:\Windows\System32\kernel32.dll | findstr forwarded
          1    0          AcquireSRWLockExclusive (forwarded to NTDLL.RtlAcquireSRWLockExclusive)
          2    1          AcquireSRWLockShared (forwarded to NTDLL.RtlAcquireSRWLockShared)
         14    D          AddVectoredContinueHandler (forwarded to NTDLL.RtlAddVectoredContinueHandler)
         15    E          AddVectoredExceptionHandler (forwarded to NTDLL.RtlAddVectoredExceptionHandler)
         70   45          CancelThreadpoolIo (forwarded to NTDLL.TpCancelAsyncIoOperation)
         86   55          CloseThreadpool (forwarded to NTDLL.TpReleasePool)
         87   56          CloseThreadpoolCleanupGroup (forwarded to NTDLL.TpReleaseCleanupGroup)
         88   57          CloseThreadpoolCleanupGroupMembers (forwarded to NTDLL.TpReleaseCleanupGroupMembers)
         89   58          CloseThreadpoolIo (forwarded to NTDLL.TpReleaseIoCompletion)
         90   59          CloseThreadpoolTimer (forwarded to NTDLL.TpReleaseTimer)
         91   5A          CloseThreadpoolWait (forwarded to NTDLL.TpReleaseWait)
         92   5B          CloseThreadpoolWork (forwarded to NTDLL.TpReleaseWork)

Проблема еще и в том, что код, использующий Wow64DisableWow64FsRedirection, в общем-то, работает в большинстве случаев. Так что разработчик не видит проблемы до тех пор, пока код не будет запущен в незнакомом окружении на машине заказчика. Или пока не выйдет новая версия ОС, используемой библиотеки или клавиатурного шпиона, которая вдруг начала загружать код в том месте, где раньше ничего такого не происходило.

PS. А когда можно использовать Wow64DisableWow64FsRedirection? Единственный поддерживаемый сценарий – вызов CreateFile, обернутый в Wow64DisableWow64FsRedirection и Wow64RevertWow64FsRedirection.

comments powered by Disqus