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

DOMINUS_EDEM

Местный житель
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
ЮБИЛЕЙНАЯ ЛЕНТА

DOMINUS_EDEM

Местный житель
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
ЮБИЛЕЙНАЯ ЛЕНТА
Регистрация
1 Июн 2018
Сообщения
1,099
Реакции
389
Репутация
1
Род занятий

Электронные кошельки, Пробив информации

Речь пойдёт об устройстве wow64 в винде. Для неосведомлённых: wow64 - это подсистема x64 винды для запуска x86 приложений. Всё далее описанное относится к x64 винде.
Для начала, смотрим разницу syscall'ov между x86 и x64 приложениями:
x64:
1.png

x86:
2.png

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

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

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

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

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

Т.к. я ни разу не замечал 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.
 
Сверху