MmMapLockedPagesSpecifyCache + CoW

Тема в разделе "WASM.BEGINNERS", создана пользователем HoShiMin, 6 янв 2019.

  1. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Добрый день форумчанам.
    На повестке совершенно дурацкий вопрос - нужно заставить сработать Copy-on-Write при записи в отображение CoW-памяти.

    К примеру, ставим хук на одну из системных функций (например, SetLastError в kernel32) в чужом процессе.
    Процесс накрыт каллбэками, сделать VirtualProtectEx/WriteProcessMemory мы не можем.
    У памяти только RX-права - делаем Writeable-отображение.

    Пробуем из драйвера (проверки и обработку ошибок для простоты опустим):
    Код (C):
    1.  
    2. NTSTATUS WriteProcessMemory(PEPROCESS Process, PVOID BaseAddress, PVOID Buffer, SIZE_T Size)
    3. {
    4.     PMDL Mdl = IoAllocateMdl(BaseAddress, Size, NULL, NULL, FALSE);
    5.     MmProbeAndLockProcessPages(Mdl, Process, KernelMode, IoReadAccess); // IoReadAccess, т.к. у памяти нет W-прав
    6.     PVOID Mapping = MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmNonCached, NULL, FALSE, NormalPagePriority);
    7.     MmProtectMdlSystemAddress(Mdl, PAGE_WRITECOPY); // Или PAGE_READWRITE, одинаково плохо
    8.  
    9.     RtlCopyMemory(Mapping, Buffer, Size);
    10.  
    11.     MmUnmapLockedPages(Mapping, Mdl);
    12.     MmUnlockPages(Mdl);
    13.     IoFreeMdl(Mdl);
    14. }
    15.  
    Copy-on-Write не срабатывает и мы перезаписываем общую для всех процессов память.
    Как можно затриггерить CoW, чтобы страница подгрузилась в целевой процесс?

    [РЕШЕНО]
    Вручную затриггерил CoW.
    В PTE есть поле AVL, винда хранит в нём бит Writeable и бит CopyOnWrite.
    Взводим оба этих бита, выполняем запись в страницу, винда подгружает страницу в целевой процесс (чей cr3 загружен в данный момент).
    После процедуры CoW будет взведён бит Dirty, т.к. выполнялась запись в страницу.

    Готовое решение для всех режимов (x86, x86+PAE и x64 для всех размеров страниц):
    https://github.com/HoShiMin/Kernel-Bridge/blob/master/Kernel-Bridge/API/PteUtils.cpp
     
    Последнее редактирование: 13 янв 2019
  2. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    и на акой выньке ты так изощряешься ? :)
     
  3. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    На десятке 1809 х64. А что?
     
  4. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    любопытства ради спросил.. впрочем, мне непонятно на аких основаниях ты хочешь получить cow, если у тебя нет прав на запись???
     
  5. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    А как иначе записать что-то в RX-память, которая, к тому же, ещё и общая между всеми процессами?
    Вот и ищу способ как-то триггернуть CoW, а дальше работать с уже локальной копией.

    И, желательно, способ без новых апи, появившихся лишь в Win 8.1 и 10 (т.е., ZwProtectVirtualMemory юзать нельзя, в более ранних выньках он не экспортируется)
     
    Последнее редактирование: 6 янв 2019
  6. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    если в ядре нет ошибок иль скрытых дверок, то (по идее) таких пируэтов допускать оно не должно, ибо явное нарушение секуры. тут остаётся только ядро отдебажить и пропатчить :)
     
  7. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Ну блин, засада там, откуда не ждали...
     
  8. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    с другой стороны == если ты имеешь права на чтение заданных адресов, выдели память явно и запиши в неё нужные тебе данные. зачем тебе именно коровка нужна???
     
  9. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Ну смотри: хочу записать трамплин в начало какой-нибудь системной функции.
    Пока CoW не сработал, странички этих библиотек во всех процессах смотрят на одну и ту же физическую память.
    Если я ставлю трамплин, записывая его во Writebale-маппинг этой памяти, трамплин ставится во все процессы, т.к. я меняю общую память.
    А мне надо сначала подгрузить эту страничку в процесс, а потом уже создавать её Writeable-отображение.
    А само отображение нужно, т.к. у памяти только RX-права, а ZwProtectVirtualMemory не экспортируется.
     
  10. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
  11. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    А почему не экспортируется гора других полезных функций, доступных в ntdll?
    Видимо, решили, что эта функция не нужна для разработки "индустриальных" драйверов.
    И впрямь, для каких целей может понадобиться эта функция, кроме хакерских? Я не могу придумать ни одного сценария использования этой функции в широком продакшне.
    А чем меньше у программиста хакерского инструментария - тем меньше вероятность, что он наломает дров и синих экранов.
    Их логику можно понять: кривые драйвера, а ругают винду - пользователи-то не знают технических деталей. Они лишь видят, что винда падает в синий экран. А для MS это репутационные потери.
    На их месте я бы сделал то же самое - закрыл всё, что можно закрыть.

    И, кстати, по этой же причине они и ввели PatchGuard и разом избавились от зоопарка невалидных дров, перехватывающих всё подряд.
     
  12. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
  13. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
  14. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    им по-большей части всегда было фиолетово на репутацию == пипл хавает, бабло приливает :)
    --- Сообщение объединено, 7 янв 2019 ---
    отобрази, куда надо, и выставь rwx.
     
  15. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    А для чего тогда все заморочки с WHQL и тестами HLK? Контроль качества ядерных компонентов у них на высоте.
    --- Сообщение объединено, 7 янв 2019 ---
    Так сделал же, посмотри в шапку) В этом и проблема, что мой RWX-маппинг не триггерит CoW, и мы меняем общую память)
     
  16. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    открывай процесс и копируй в его память то, что тебе нужно. Ты же можешь в драйвере листать процессы итд
    ядро писалось и полировалось долго.. но в сущности ринг0 остаётся ринг0 и защиту от дурака там не сделаешь.
     
  17. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    А сделать это мы не можем, потому что у памяти RX-права, а чтобы получить W, надо или Writeable-маппинг (а он не триггерит CoW), или дёрнуть ZwProtectVirtualMemory, а она не экспортируется, и сразу начинаются костыли с парсингом таблицы экспортов и прочие радости (плюс, она может быть перехвачена)
     
  18. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    HoShiMin, тогда остаётся патчить ядерные функи и всё будет übermacht :)
    если ты про аверки, они любые костыли отловить смогут, ибо (так сказать) развиваются :)
     
  19. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.422
    Адрес:
    Россия, Нижний Новгород
    Чтобы стало убермахт, придётся пройти все круги ада и обойти патчгуард)
    А банальная защита от инжектов - перехватили NtProtectVirtualMemory и запрещаем менять права у своей X-памяти
     
  20. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.077
    а искомая задача в чём заключается? можь ты пошёл слишком сложной тропинкой..