Xtajit dll что это
Xtajit dll что это
Microsoft исправила проблему с потерей данных в Windows 10 October 2018 Update (версия 1809)
Компания Microsoft исправила проблему, которая приводила к потере данных на компьютере при обновлении до Windows 10 October 2018 Update. По итогам расследования разработчики обнаружили, что проблема затронула 0,01% всех установок Windows 10 (версия 1809) |
Microsoft исправила проблему с потерей данных
Обновленная версия Windows 10 October 2018 Update Build 17763.17 (KB4467228) уже поставляется участникам программы Windows Insider на канале «Поздний доступ» и Release Preview. Microsoft будет тщательно отслеживать обратную связь от тестировщиков и снова запустит обновление на стабильных каналах после завершения всех необходимых испытаний.
По итогам расследования Microsoft обнаружила, что проблема затронула 0,01% всех установок Windows 10 (версия 1809).
Проблема возникала только на устройствах с включенным перенаправлением известных папок и только, если при включенной функции, файлы оставались в директории по умолчанию.
Перенаправление известных папок позволяет пользователям перемещать классические папки Windows, такие как Рабочий стол, Документы, Изображения, Видеозаписи и т.д. в другое расположение. Некоторые пользователи и системные администраторы пользуются данной функцией с целью освобождения пространства на основном диске.
Данная функция встроена в операционную систему Windows. Просто кликните правой кнопкой мыши по любой папке, например по папке Документы, выберите Свойства, перейдите на вкладке «Расположение» и нажмите кнопку «Переместить. ». Там же вы можете восстановить настройки по умолчанию.
Мы полностью исследовали данные проблемы и разработали решения, которые позволят предотвратить потерю данных во всех трех обозначенных сценариях, чтобы «оригинальная» папка вместе со всем содержимым сохранилась. |
Отметим, что сообщения о потере данных поступали в приложение «Отзывы» от инсайдеров за несколько месяцев до релиза Windows 10 версии 1809. Похоже, что данные отчеты остались незамеченными, потому что не получили достаточного количества голосов или комментариев.
Сегодня Microsoft запустила новые функции для отзывов и обратной связи, которые позволяют классифицировать уровень воздействия и опасность обнаруженной проблемы.
WOW64 Implementation Details
The WOW64 emulator runs in user mode. It provides an interface between the 32-bit version of Ntdll.dll and the kernel of the processor, and it intercepts kernel calls. The WOW64 emulator consists of the following DLLs:
These DLLs, along with the 64-bit version of Ntdll.dll, are the only 64-bit binaries that can be loaded into a 32-bit process. On Windows 10 on ARM, CHPE (Compiled Hybrid Portable Executable) binaries may also be loaded into an x86 32-bit process.
At startup, Wow64.dll loads the x86 version of Ntdll.dll (or the CHPE version, if enabled) and runs its initialization code, which loads all necessary 32-bit DLLs. Almost all 32-bit DLLs are unmodified copies of 32-bit Windows binaries, though some are loaded as CHPE for performance reasons. Some of these DLLs are written to behave differently on WOW64 than they do on 32-bit Windows, usually because they share memory with 64-bit system components. All user-mode address space above the 32-bit limit is reserved by the system. For more information, see Performance and Memory Consumption under WOW64.
Instead of using the x86 system-service call sequence, 32-bit binaries that make system calls are rebuilt to use a custom calling sequence. This calling sequence is inexpensive for WOW64 to intercept because it remains entirely in user mode. When the custom calling sequence is detected, the WOW64 CPU transitions back to native 64-bit mode and calls into Wow64.dll. Thunking is done in user mode to reduce the impact on the 64-bit kernel and to reduce the risk of a bug in the thunk that might cause a kernel-mode crash, data corruption, or a security hole. The thunks extract arguments from the 32-bit stack, extend them to 64 bits, then make the native system call.
Environment Variables
When a 32-bit process is created by a 64-bit process, or when a 64-bit process is created by a 32-bit process, WOW64 sets the environment variables for the created process as shown in the following table.
Process | Environment variables |
---|---|
64-bit process | PROCESSOR_ARCHITECTURE=AMD64 or PROCESSOR_ARCHITECTURE=IA64 or PROCESSOR_ARCHITECTURE=ARM64 ProgramFiles=%ProgramFiles% ProgramW6432=%ProgramFiles% CommonProgramFiles=%CommonProgramFiles% CommonProgramW6432=%CommonProgramFiles% Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: The ProgramW6432 and CommonProgramW6432 environment variables were added starting with Windows 7 and Windows Server 2008 R2. |
32-bit process | PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=%PROCESSOR_ARCHITECTURE% ProgramFiles=%ProgramFiles(x86)% ProgramW6432=%ProgramFiles% CommonProgramFiles=%CommonProgramFiles(x86)% CommonProgramW6432=%CommonProgramFiles% |
Global Hooks
The SetWindowsHookEx function can be used to inject a DLL into another process if the following conditions are met:
Be aware that the WH_MOUSE, WH_KEYBOARD, WH_JOURNAL*, WH_SHELL, and low-level hooks can be called on the thread that installed the hook rather than the thread processing the hook. For these hooks, it is possible that both the 32-bit and 64-bit hooks will be called if a 32-bit hook is ahead of a 64-bit hook in the hook chain. For more information, see Using Hooks.
Сведения о реализации WOW64
Эмулятор WOW64 работает в пользовательском режиме. Он предоставляет интерфейс между 32-разрядной версией Ntdll.dll и ядром процессора и перехватывает вызовы ядра. Эмулятор WOW64 состоит из следующих библиотек DLL:
Эти библиотеки DLL, а также 64-разрядная версия Ntdll.dll являются единственными 64-разрядными двоичными файлами, которые можно загрузить в 32-разрядный процесс. в Windows 10 на ARM двоичные файлы чпе (скомпилированные гибридные переносимые исполняемые файлы) также могут быть загружены в 32-разрядный процесс x86.
При запуске Wow64.dll загружает версию x86 Ntdll.dll (или версию ЧПЕ, если она включена) и выполняет свой код инициализации, который загружает все необходимые 32-разрядные библиотеки DLL. почти все 32-разрядные библиотеки dll являются немодифицированными копиями 32-разрядных Windows двоичных файлов, хотя некоторые из них загружаются как чпе по соображениям производительности. некоторые из этих библиотек dll ведут себя по-разному на основе WOW64, чем в 32-разрядных Windows. обычно это обусловлено тем, что они совместно используют память с 64-разрядными компонентами системы. Все адресное пространство пользовательского режима свыше 32-разрядного предела резервируется системой. Дополнительные сведения см. в разделе Использование производительности и памяти в эмуляторе WOW64.
Вместо использования последовательности вызовов системной службы x86, 32-разрядных двоичных файлов, которые делают системные вызовы, перестраиваются для использования пользовательской последовательности вызова. Эта последовательность вызова недорога для перехвата WOW64, так как она полностью находится в пользовательском режиме. При обнаружении пользовательской последовательности вызовов ЦП WOW64 возвращается в собственный 64-разрядный режим и вызывается в Wow64.dll. Преобразователь выполняется в пользовательском режиме, чтобы снизить воздействие на 64-разрядное ядро и снизить риск ошибки в преобразователе, которая может привести к сбою в режиме ядра, повреждению данных или бреши в безопасности. Преобразователи извлекают аргументы из 32-битного стека, расширяют их до 64 бит, а затем выполняют собственный системный вызов.
Переменные среды
При создании 32-разрядного процесса с помощью 64-разрядного процесса или при создании 64-bit процесса в 32-разрядном процессе WOW64 устанавливает переменные среды для созданного процесса, как показано в следующей таблице.
Процесс | Переменные среды |
---|---|
64-разрядный процесс | _Архитектура процессора = amd64 или _ архитектура процессора = ia64 или _ архитектура процессора = ARM64 ProgramFiles =% ProgramFiles% ProgramW6432 =% ProgramFiles% CommonProgramFiles =% CommonProgramFiles% CommonProgramW6432 =% CommonProgramFiles% Windows server 2008, Windows Vista, Windows Server 2003 и Windows XP: переменные среды ProgramW6432 и CommonProgramW6432 были добавлены начиная с Windows 7 и Windows Server 2008 R2. |
32-разрядный процесс | _Архитектура процессора = x86 ПРОЦЕССОР _ ARCHITEW6432 =% _ архитектура процессора% ProgramFiles =% ProgramFiles (x86)% ProgramW6432 =% ProgramFiles% CommonProgramFiles =% CommonProgramFiles (x86)% CommonProgramW6432 =% CommonProgramFiles% |
Глобальные перехватчики
Функцию сетвиндовшукекс можно использовать для внедрения библиотеки DLL в другой процесс при соблюдении следующих условий.
Имейте в виду, что в потоке, в котором установлен обработчик, а не поток, обрабатывающий обработчик, может быть вызвана _ мышь, что, в том, что для входа в систему, т _. е. _ Журнал * _, _ _. Для этих обработчиков возможно, что будут вызываться как 32-разрядные, так и 64-разрядные обработчики, если 32-разрядный обработчик впереди в цепочке прерываний до 64-разрядного обработчика. Дополнительные сведения см. в разделе Использование перехватчиков.
WoW64 internals
. re-discovering Heaven’s Gate on ARM
MSDN offers brief article on WoW64 implementation details. We can find that WoW64 consists of (ignoring IA-64):
Besides Nt* system call translation, the wow64.dll provides the core emulation infrastructure.
If you have previous experience with reversing WoW64 on x64, you can notice that it shares plenty of common code with WoW64 subsystem on ARM64. Especially if you peeked into WoW64 of recent x64 Windows, you may have noticed that it actually contains strings such as SysArm32 and that some functions check against IMAGE_FILE_MACHINE_ARMNT (0x1C4) machine type:
Those similarities can help anyone who is fluent in x86/x64, but not that much in ARM. Also, HexRays decompiler produce much better output for x86/x64 than for ARM32/ARM64.
Initially, my purpose with this blogpost was to get you familiar with how WoW64 works for ARM32 programs on ARM64. But because WoW64 itself changed a lot with Windows 10, and because WoW64 shares some similarities between x64 and ARM64, I decided to briefly get you through how WoW64 works in general.
Table of contents
Terms
Througout this article I’ll be using some terms I’d like to explain beforehand:
Kernel
This section shows some points of interest in the ntoskrnl.exe regarding to the WoW64 initialization. If you’re interested only in the user-mode part of the WoW64, you can skip this part to the Initialization of the WoW64 process.
Kernel (initialization)
Initalization of WoW64 begins with the initialization of the kernel:
nt!PspSystemDlls appears to be array of pointers to some structure, which holds some NTDLL-related data. The order of these NTDLLs corresponds with this enum (included in the PDB):
Now, let’s look how such structure looks like:
The nt!PspLocateSystemDll function intializes fields of this structure. The layout of this structure isn’t unfortunatelly in the PDB, but you can find a reconstructed version in the appendix.
x64 | ARM64 |
---|---|
(0) LdrInitializeThunk | (0) LdrInitializeThunk |
(1) RtlUserThreadStart | (1) RtlUserThreadStart |
(2) KiUserExceptionDispatcher | (2) KiUserExceptionDispatcher |
(3) KiUserApcDispatcher | (3) KiUserApcDispatcher |
(4) KiUserCallbackDispatcher | (4) KiUserCallbackDispatcher |
— | (5) KiUserCallbackDispatcherReturn |
(5) KiRaiseUserExceptionDispatcher | (6) KiRaiseUserExceptionDispatcher |
(6) RtlpExecuteUmsThread | — |
(7) RtlpUmsThreadYield | — |
(8) RtlpUmsExecuteYieldThreadEnd | — |
(9) ExpInterlockedPopEntrySListEnd | (7) ExpInterlockedPopEntrySListEnd |
(10) ExpInterlockedPopEntrySListFault | (8) ExpInterlockedPopEntrySListFault |
(11) ExpInterlockedPopEntrySListResume | (9) ExpInterlockedPopEntrySListResume |
(12) LdrSystemDllInitBlock | (10) LdrSystemDllInitBlock |
(13) RtlpFreezeTimeBias | (11) RtlpFreezeTimeBias |
(14) KiUserInvertedFunctionTable | (12) KiUserInvertedFunctionTable |
(15) WerReportExceptionWorker | (13) WerReportExceptionWorker |
(16) RtlCallEnclaveReturn | — |
(17) RtlEnclaveCallDispatch | — |
(18) RtlEnclaveCallDispatchReturn | — |
On the other hand, all NtdllWow*Exports contain the same set of function names:
Those addresses are actually targets of the pointers in the NtdllWow*Exports structure. Also, those functions combined with PsWow*SharedInformation might give you hint that they’re related to this enum (included in the PDB):
Notice how the order of the SharedNtdll32BaseAddress corellates with the empty field in the previous screenshot (highlighted). The set of WoW64 NTDLL functions is same on both x64 and ARM64.
(The C representation of this data can be found in the appendix.)
Kernel (create process)
Initialization of the WoW64 process
The fun part begins!
NOTE: Initialization of the wow64.dll is same on both x64 and ARM64. Eventual differences will be mentioned.
Wow64DetectMachineTypeInternal determines the machine type of the executed process and returns it. Wow64SelectSystem32PathInternal selects the “emulated” System32 directory based on that machine type, e.g. SysWOW64 for x86 processes or SysArm32 for ARM32 processes.
Finally, the RunCpuSimulation function is called. This function just calls BTCpuSimulate from the binary-translator DLL, which contains the actual emulation loop that never returns.
wow64!ProcessInit
If any of these functions wouldn’t be exported, the DLL would be immediately unloaded.
If we’d drop custom wow64log.dll (which would export functions mentioned above) into the %SystemRoot%\System32 directory, it would actually get loaded into every WoW64 process. This way we could drop a custom logging DLL, or even inject every WoW64 process with native DLL!
For more details, you can check my injdrv project which implements injection of native DLLs into WoW64 processes, or check this post by Walied Assar.
wow64!ServiceTables
(More detailed definition of this structure is in the appendix.)
ServiceTables array is populated as follows:
These two symbols mentioned above are the only symbols that wow64.dll requires wow64win.dll to export.
Let’s have a look at sdwhnt32 service table:
The job of these wh* functions is to correctly convert any arguments and return values from the 32-bit version to the native, 64-bit version. Keep in mind that that it not only includes conversion of integers and pointers, but also content of the structures. Interesting note might be that each of the wh* functions has only one argument, which is pointer to an array of 32-bit values. This array contains the parameters passed to the 32-bit system call.
The ntdll.dll and win32u.dll are obvious and they represent the same thing as their native counterparts. The service tables used by kernel32.dll and user32.dll contain functions for transformation of particular csrss.exe calls into their 64-bit version.
wow64!Wow64SystemServiceEx
The system call number isn’t just an index, but also contains index of a system table which needs to be selected (this is also true for ntoskrnl.exe ):
wow64!ProcessInit (cont.)
We can see that there is no wow64cpu.dll on ARM64. Instead, there is xtajit.dll used for x86 emulation and wowarmhw.dll used for ARM32 emulation.
wow64.dll then loads one of the selected DLL and tries to find there following exported functions:
BTCpuProcessInit (!) | BTCpuProcessTerm |
BTCpuThreadInit | BTCpuThreadTerm |
BTCpuSimulate (!) | BTCpuResetFloatingPoint |
BTCpuResetToConsistentState | BTCpuNotifyDllLoad |
BTCpuNotifyDllUnload | BTCpuPrepareForDebuggerAttach |
BTCpuNotifyBeforeFork | BTCpuNotifyAfterFork |
BTCpuNotifyAffinityChange | BTCpuSuspendLocalThread |
BTCpuIsProcessorFeaturePresent | BTCpuGetBopCode (!) |
BTCpuGetContext | BTCpuSetContext |
BTCpuTurboThunkControl | BTCpuNotifyMemoryAlloc |
BTCpuNotifyMemoryFree | BTCpuNotifyMemoryProtect |
BTCpuFlushInstructionCache2 | BTCpuNotifyMapViewOfSection |
BTCpuNotifyUnmapViewOfSection | BTCpuUpdateProcessorInformation |
BTCpuNotifyReadFile | BTCpuCfgDispatchControl |
BTCpuUseChpeFile | BTCpuOptimizeChpeImportThunks |
BTCpuNotifyProcessExecuteFlagsChange | BTCpuProcessDebugEvent |
BTCpuFlushInstructionCacheHeavy |
wow64!ThreadInit
ThreadInit does some little thread-specific initialization, such as:
x86 on x64
Entering 32-bit mode
RunSimulatedCode runs in a loop and performs transitions into 32-bit mode either via:
NOTE: Explanation of segmentation and “why does it work just by changing a segment register” is beyond scope of this article. If you’d like to know more about “long mode” and segmentation, you can start here.
You can see the simplest form of switching into the 32-bit mode. Also, at the beginning you can see that TurboThunkDispatch address is moved into the r15 register. This register stays untouched during the whole RunSimulatedCode function.
Leaving 32-bit mode
The Wow64SystemServiceCall is just a simple jump to the Wow64Transition :
If you remember, the Wow64Transition value is resolved by the wow64cpu!BTCpuGetBopCode function:
It selects either KiFastSystemCall or KiFastSystemCall2 based on the CpupSystemCallFast value.
The KiFastSystemCall2 looks like this (used when CpupSystemCallFast == 0 ):
Clearly, the KiFastSystemCall is faster, so why it’s not used used every time?
It turns out, CpupSystemCallFast is set to 1 in the wow64cpu!BTCpuProcessInit function if the process is not executed with the ProhibitDynamicCode mitigation policy and if NtProtectVirtualMemory(&KiFastSystemCall, PAGE_READ_EXECUTE) succeeds.
This is because KiFastSystemCall is in a non-executable read-only section ( W64SVC ) while KiFastSystemCall2 is in read-executable section ( WOW64SVC ).
But the actual reason why is KiFastSystemCall in non-executable section by default and needs to be set as executable manually is, honestly, unknown to me. My guess would be that it has something to do with relocations, because the address in the jmp 33h:$+9 instruction must be somehow resolved by the loader. But maybe I’m wrong. Let me know if you know the answer!
Turbo thunks
I hope you didn’t forget about the TurboThunkDispatch address hanging in the r15 register. This value is used as a jump-table:
There are 32 items in the jump-table.
CpupReturnFromSimulatedCode is the first code that is always executed in the 64-bit mode when 32-bit to 64-bit transition occurs. Let’s recapitulate the code:
You might be confused now, because few sections above we’ve defined the service number like this:
…therefore, after right-shifting this value by 16 bits we should get always 0, right?
It turns out, on x64, the WOW64_SYSTEM_SERVICE might be defined like this:
Let’s examine few WoW64 system calls:
Let’s finally explain “turbo thunks” in proper way.
The notation of Thunk* labels is as follows:
Let’s take the NtWaitForSingleObject and its turbo thunk Thunk3ArgSpNSpNSpReloadState as an example:
When we cross-check this information with its function prototype, it makes sense:
Disabling Turbo thunks
On Windows x64, the Turbo thunk optimization can be actually disabled!
The function prototype might look like this:
NOTE: This function prototype has been reconstructed with the help of the wow64!Wow64CallFunction64Nop function code, which just logs the parameters.
wow64cpu!BTCpuTurboThunkControl then checks the input parameter.
This means 2 things:
With all this in mind, we can achieve disabling Turbo thunks by this call:
What it might be good for? I can think of 3 possible use-cases:
x86 on ARM64
The x86 emulation on Windows ARM64 consists also of other “XTA” components:
With a simple Python script, we can mass-rename all functions referenced in this array:
I’d like to thank Milan Boháček for providing me this script.
Windows\SyCHPE32 & Windows\SysWOW64
One thing you can observe on ARM64 is that it contains two folders used for x86 emulation. The difference between them is that SyCHPE32 contains small subset of DLLs that are frequently used by applications, while contents of the SysWOW64 folder is quite identical with the content of this folder on Windows x64.
The CHPE DLLs are not pure-x86 DLLs and not even pure-ARM64 DLLs. They are “compiled-hybrid-PE”s. What does it mean? Let’s see:
We can see it contains regular x86 function prologue, immediately followed by x86 function epilogue and then jump somewhere, where it looks like that there’s just garbage. That “garbage” is actually ARM64 code of that function.
NOTE: Again, if you’re feeling adventurous, you can patch FileHeader.Machine field in the PE header to IMAGE_FILE_MACHINE_ARM64 (0xAA64) and open this file in IDA. You will see a whole lot of correctly resolved ARM64 functions. Again, I’d like to thank to Milan Boháček for this tip.
If your question is “how are these images generated?”, I would answer that I don’t know, but my bet would be on some internal version of Microsoft’s C++ compiler toolchain. This idea appears to be supported by various occurences of the CHPE keyword in the ChakraCore codebase.
ARM32 on ARM64
The loop inside of the wowarmhw!BTCpuSimulate is fairly simple compared to wow64cpu.dll loop:
nt!KiEnter32BitMode / SVC 0xFFFF
Let’s peek for a moment into the kernel to see how is this SVC instruction handled:
nt!KiExit32BitMode / UND #0xF8
Let’s look at the NtMapViewOfSection system call in the SysArm32\ntdll.dll :
Let’s peek into the kernel again:
NOTE: It can be noticed that Windows uses UND instruction for several purposes. Common example might also be UND #0xFE which is used as a breakpoint instruction (equivalent of __debugbreak() / int3 )
- Как надевать блесну на спиннинг
- Как испаряется ртуть в воде