Немного об устройстве wow64. Подгружаем свою dll в каждый x86 процесс на x64 ос

unitedkingdom

Интересующийся
PREMIUM USER
ЮБИЛЕЙНАЯ ЛЕНТА

unitedkingdom

Интересующийся
PREMIUM USER
ЮБИЛЕЙНАЯ ЛЕНТА
Регистрация
21 Июн 2018
Сообщения
243
Реакции
166
Репутация
0
Речь пойдёт об устройстве wow64 в винде. Для неосведомлённых: wow64 - это подсистема x64 винды для запуска x86 приложений. Всё далее описанное относится к x64 винде.
Для начала, смотрим разницу syscall'ov между x86 и x64 приложениями:
x64:


x86:


По fs:[c0h] прыжок в cs:33 для перехода в x64


Т.е. сисколл из x86 приложения в итоге заканчивается переходом в x64, сисколлом и возвращением обратно. Это означает, что можно спокойно выполнять x64 код в контексте приложения x86. Открывать велосипед не буду - подробно разбирал этот механизм rewolf, создав данный проект:

Пожалуйста Авторизуйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Я хотел бы рассказать про то, что происходит при запуске x86 приложения. А при запуске x86 приложения первым делом инициализируется процесс функцией ntdll!LdrpInitializeProcess, которая в свою очередь уходит в ntdll!Wow64LdrpInitialize:


Данная функция уходит в wow64!ProcessInit, а та в wow64!Wow64pLoadLogDll
Эта функция подгружает C:\Windows\System32\wow64log.dll




После этого произойдёт попытка получить адреса функций: Wow64LogSystemService, Wow64LogMessageArgList, Wow64LogTerminate, Wow64LogInitialize, если все нашлись ,то передача управления на Wow64LogInitialize




Т.к. я ни разу не замечал wow64log.dll в system32, то логично предположить, что её там просто напросто нет и предназначена эта тема была скорее всего для отладки. Нам же это даёт возможность выполнять свой код при старте каждого x86 процесса, правда с серьёзными ограничениями в виде отсутствия возможности использовать апи как привычно ибо мы находимся в контексте x86 приложения. Большого кода как пример эксплуатации данной возможности я не писал, вот пример длл (проект приложен внизу статьи):
C++:
#include <Windows.h>
#include <winternl.h>

typedef NTSTATUS(NTAPI *T_NtDelayExecution)(
IN BOOLEAN Alertable,
IN PLARGE_INTEGER DelayInterval);

EXTERN_C __declspec(dllexport) void WINAPI Wow64LogSystemService() {}
EXTERN_C __declspec(dllexport) void WINAPI Wow64LogMessageArgList() {}
EXTERN_C __declspec(dllexport) void WINAPI Wow64LogTerminate() {}

EXTERN_C __declspec(dllexport) void WINAPI Wow64LogInitialize()
{
T_NtDelayExecution NtDelayExecution = (T_NtDelayExecution)0x7ffe2fe80a10;
LARGE_INTEGER lTime;
lTime.QuadPart = 5000 * -10000;
NtDelayExecution(FALSE, &lTime);
}

BOOL WINAPI _DllMainCRTStartup(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
return TRUE;
}
После дропа данной длл с именем wow64log.dll в system32, я мог наблюдать таймаут на запуск каждого нового x86 процесса длительностью в 5 секунд.
Утилита для получения адреса функции в архиве, для неё как раз была использована wow64ext. Здесь не путать адрес от GetProcAddress x64 процесса с адресом от этой утилиты, т.к. x64 ntdll маппится в x86 процесс по другому адресу.
Пример предназначен как POC использования, поэтому динамического получения адресов здесь не было, это можно написать на основе исходов wow64ext.
 
  • Нравится
Реакции: ATR
Сверху