1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

The Kernel-Bridge Framework

Тема в разделе "WASM.PROJECTS", создана пользователем HoShiMin, 18 ноя 2018.

  1. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    > Ты делаешь данные нечитабельными

    Если заблокировать область памяти то во первых ловушки это всегда просто решали, а во вторых возникает проблема - когда второй поток начнёт выборку. Ты ведь тупо не разблокируешь память, это асинхрон. Поэтому область нужно переместить в памяти, технически это называется пересборка", морф либо в виде блока релокация - базовая техника виксов. Как ты это сделаешь через таблицы трансляции, на каждой выборке пошлёшь межпроцессорное прерывание что бы тормознуть cpu, да это какой то бред.
     
  2. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    В гипервизоре у каждого процессора свой собственный набор таблиц EPT, описывающих всю доступную процессору физ. память.
    Процессор меняет атрибуты страниц только у себя, поэтому ни с кем синхрониться не надо.
    --- Сообщение объединено, 3 авг 2020 ---
    Кстати, ещё момент, чисто эстетический.
    Чтобы подменить память, мне нужно в поле записать новый указатель.
    Код (C):
    1.  
    2. struct EPT_PTE
    3. {
    4.     ... Какие-то поля ...
    5.     uint64_t hostPhysAddr;
    6. };
    7.  
    8. EPT_PTE* pte = getEptPte(guestPhysAddr);
    9. pte->hostPhysAddr = newPagePhysAddr;
    10.  
    Красиво и просто.

    Ты же предлагаешь что-то пересобирать и релоцировать, когда то же самое я делаю буквально в одну инструкцию - в один mov.
     
    Последнее редактирование: 3 авг 2020
    TrashGen и q2e74 нравится это.
  3. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    Давай на примере. Есть область памяти. Что бы её скрыть нужно подменить все выборки к ней, те вначале обнаружить, затем подменить. Обычно делается так - находится первая выборка, область релоцируется, либо если это секция с релоками(pe-формат), то её можно пересобрать. Область блокирована, к ней происходит выборка, срабатывает триггер(если визор), либо ловушка(#GP), пересчитывается адресная дельта - управление получает релоцированная область либо морф буфер, в любом случае текущий адрес отображён на буфер модом кода. Далее управление отпускается и отрабатывает изменённый код.

    Но а как отработает этот механизм EPT и прочая харда ?
     
  4. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Он работает на лету. Ты делаешь страницу недоступной для выборки, которую хочешь поймать.
    Нужно поймать чтение - делаешь страницу нечитабельной. Надо поймать исполнение - делаешь неисполняемой.
    Когда процессор пытается получить доступ, которого у страницы нет - вылетает EPT Violation. Ты его ловишь и обрабатываешь, как тебе угодно.
     
  5. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    Хорошо и как как это практически реализовать ?

    Допустим нужно промониторить системный загрузчик. Ты весь нэйтив заблочишь. И что делать когда сработает ловушка ?

    Отобразишь на другой адрес и туда кинешь управление.. это рекурсивная проблема. Не говоря уже про тайминг.
     
  6. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Если нужно промониторить системный загрузчик, я возьму WinDbg.
    Чем и как? В обработчике гипервизора я по-прежнему могу обращаться к функциям NT (которые доступны на высоких IRQL), т.к. нахожусь в адресном пространстве системы.
    Соответственно, в обработчике ловушки я могу вызвать PsGetCurrentProcess(), узнать, откуда вызывают, из какого режима (юзермод\ядро), сделать всё необходимое для обработки.
    Но зачастую и этого не надо, т.к. чаще всего задача стоит "просто скрыть" или "просто подменить" для всех без разбора.

    Да, здесь ты меня подловил: если код, который исполняется в странице, читает сам себя, а на чтение у тебя стоит страница с нулями, ты уйдёшь в вечный цикл подмен.
    Однако, я решил это просто и элегантно: я дал пользователю возможность самому задавать страницы, которые будут видны, когда код читает сам себя и когда код пишет сам в себя.
    И всё, даже эта проблема решена.

    И по-прежнему, одним единственным mov'ом. И разумеется, это ультрабыстро: например, у меня за амортизированную константу, считай за O(1).
     
    q2e74 нравится это.
  7. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    > Да, здесь ты меня подловил:

    Ничего я не ловил это классика - перемещение и передача управления, при этом возникает рекурсивная проблема, буфер выполняется и к нему применяется то же решение что к исходному и так по цепочке.
     
  8. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    ...это знать надо
    [​IMG]

    Но, в любом случае, я и это решил простым и прямолинейным способом.
    А детали реализации можешь глянуть вот здесь.
     
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    По ссылке смотреть нечего там какие то архитектурные манипуляции на самом дне.

    > ...это знать надо

    Конечно. Для какой то модификации блока он перемещается, затем возникает та же задача с уже перемещённым блоком и каждый раз усложняется. Доходит даже до корреляции патчей. Нельзя тупо подменить данные, ты это сделать не смог какие бы сказки не рассказывал давно наработана по этой теме глубокая теория. И обкатана на практике а не в сферическом вакууме ради написать ;)
     
  10. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Но ведь... Ты можешь скачать готовые бинарники у меня с гитхаба и проверить всё сам. Все эти апишки проброшены в юзермодную библиотечку.
    Подключи User-Bridge.h и из неймспейса Hypervisor дёрни функцию KbVmmInterceptPage.

    Или посмотри в папке Kernel-Tests: там у меня юзермодная утилитка для тестов, вот готовый пример, который подменяет страничку с кодом.
    Всё, что я тебе рассказываю, уже готовое ready-to-use решение. Бери и пользуйся!
    --- Сообщение объединено, 3 авг 2020 ---
    Вспомнилась цитата из трека ГРОТа:
     
    Последнее редактирование: 3 авг 2020
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    > Подключи User-Bridge.h и из неймспейса Hypervisor дёрни функцию KbVmmInterceptPage.

    Всё дело в том, что это можно сделать более простым путём. Тем более в юзер. Теоретически может и интересно во всём этом копаться, но практически смысла не видно :)

    Бесчисленное количество задач/семплов решено через юзер визор и небыло никогда необходимости в км вирте и даже не нужен был виндебаг. Может если задача по ядру это всё как то поможет, но очень сомневаюсь. Там старые годные инструменты, никакая вирта там не нужна.
    --- Сообщение объединено, 4 авг 2020 ---
    > дёрни функцию KbVmmInterceptPage.

    И на асинхронной выборке будет синь. Ты сам выше писал что никакой синхрон не нужен, это значит что как только ты начал использовать ос апи твой код кривой и анстаб и вылетит на первом синхрон событии, даже атака не нужна ;)
     
  12. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    3.608
    Раньше их были тыщи, сейчас видимо уже миллионы семплов прошли через легендарный визор вирус блокады. Своего рода успех, раз этот инструмент так активно используется в антивирусной индустрии.
    --- Сообщение объединено, 4 авг 2020 ---
    Если кодец инжектится в существующий процесс и выполняется в контексте другого процесса, то ядерный визор будет эффективнее.
     
  13. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Откуда берётся всё, что берётся? Я выше написал, почему синхронизация не нужна.

    Давай ещё раз: потому что подмена памяти происходит для каждого процессора отдельно, и подмена на одном процессоре никак не влияет на остальные.
    По одному и тому же виртуальному адресу каждый логический процессор видит разную память с разными правами.

    Ты ведь даже не проверял, верно? А я устраивал нагрузочное тестирование, к одной и той же странице параллельно обращаясь из трёх десятков потоков на чтение, запись и исполнение с 16 логических процессоров одновременно.
    И на основе чего тогда ты делаешь выводы?

    В твоём визоре синхронизация необходима, т.к. у всех процессоров общая PTE на всех. В гипервизоре я для каждого процессора создаю его собственное адресное пространство - у каждого процессора своя EPT, её не с кем синхронизировать, т.к. доступ к ней имеет только процессор-владелец.
     
    q2e74 нравится это.
  14. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    HoShiMin,

    > Ты ведь даже не проверял, верно?

    А что проверять ?

    Говорил же, покажи пример - возьми простейшее приложение и крутни своим визором. Что бы был результат. Кому твои PTE нужны :D
     
  15. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.077
    разве визор и гипервизор это одно и тоже? Это же разные технологии как бы.
     
  16. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    644
    HoShiMin, запилите четвертую часть статьи в виде пошаговой инструкции, что вы делали. Повторим где-то на недельке, запишем, зальем на ютуб, разместите на гитхабе.
     
  17. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    3.608
    Ну нет, но да. То что Инде называет визором - это по сути наколеночный дби, то что Хошимин называет гипервизором - это по сути гипервизор. Проблема в том, что в голове Инде есть только одна задача - поиск оеп, и от этого он пытается любой софт натянуть на эту задачу.
     
    TrashGen нравится это.
  18. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Здесь одной статьёй не обойдётся.
    В третьей закончили на настроенном EPT, всё готово к запуску визора.
    Одна статья уйдёт на сам запуск (на настройку VMCS), другая - на написание обработчиков #VMEXIT'ов.
    Третья - уже скрытие памяти.

    А я взялся с нуля переписывать кб.
    Уже глаза мозолит заглавный CamelCase - переписываю уже на человеческом camelCase. Вычищаю легаси, добавляю больше плюсов, новые апишки, рефакторинг всего и вся...
    В общем, всё будет (и статьи тоже), но не сразу...
     
    q2e74 нравится это.
  19. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.985
    M0rg0t,

    > разве визор и гипервизор это одно и тоже?

    Одно и тоже, разница лишь в моде. Гипером называется тк понятие ввели вендоры. Сделай тоже в р0 это гипером не будет обычный визор, хоть и будет работать в точности как и хард вирта. Вообще визор это механизм трассировки по сути потока инструкций или выборки. Как не странно хв такое не умеет, это аналог механизма исключений в ином моде. Тоже самое элементарно реализуется на старых добрых ловушках.

    Внимание замылили сложностью хв, это предназначено исключительно для запуска ос в ос. Но многие пытаются натянуть сову на глобус без практических целей, нравится видимо ядро дебажить и прочие сложности.
     
    Последнее редактирование: 5 авг 2020
  20. HoShiMin

    HoShiMin Active Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    869
    Адрес:
    Россия, Нижний Новгород
    Откуда ты всё это берёшь? Что, гипервизор не умеет трассировать код? Тогда почитай главу "Monitor Trap Flag", что само по себе нужно для пошаговой трассировки гостя, а также, главу про перехват прерываний, что позволит ловить тебе гостевые int3 и Single Step.
    У кого это элементарно реализуется?
    Пропатчишь IDT - тебя съест PatchGuard. Пропатчишь PTE - начнётся нерешаемая гонка процессоров.
    Что ты собрался пересобирать? Ты даже не знаешь, кто, откуда и из какого контекста будет вызывать скрываемую страницу.
    Она может быть и в юзермоде, и в ядре, к ней могут обращаться из любого процесса, на любом IRQL, на чтение, запись и исполнение одновременно, сразу из разных процессоров.
    На эту страницу могут создавать отображения, в том числе, отображения на нижележащую физическую память напрямую (MmMapIoSpace).
    Во всех этих случаях подмена должна работать корректно.

    Где эти "старые годные" инструменты? Приведи хоть один пример. Не в виде бумажных концептов, которые невозможно осуществить на практике, а реальные готовые проекты.
    У меня - вот, на гитхабе. Не просто концепт, а готовое решение с юзермодным интерфейсом. Полторы тысячи строк логики, которые покрывают все описанные выше случаи. Причём, в общем виде: я не покрывал ни один из этих случаев специальным кейсом.
    И PatchGuard остаётся включённым - в системе не патчится ни одного байта.
    Есть что противопоставить?
     
    TrashGen и Rel нравится это.