Отправляет email-рассылки с помощью сервиса Sendsay

Хakep_daily

  Все выпуски  

Исследуем механизмы работы гипервизора Hyper-V *


PDA   подписка    wiki   bugtrack   статьи    видео   блог   форум   поиск    друзья   






Кодек MozJPEG 3.0: оптимизированная версия JPEG
2014-12-29 18:00 Denis Mirkov

В июле 2014 года Mozilla провела сравнительное тестирование форматов сжатия изображений и выяснила, что WebP и JPEG XR не обеспечивают особого преимущества перед хорошо оптимизированным кодеком JPEG, хотя тот разработан более 20 лет назад. Только HEVC (H.265) показал гораздо лучший результат, но это запатентованный кодек, который формально нельзя использовать в свободных продуктах.

В то же время Mozilla ведёт планомерную работу над кодеками нового поколения. Daala показывает хорошие результаты, но пока не готов для повсеместного использования. В краткосрочной перспективе Mozilla предлагает использовать модернизированный JPEG-кодек MozJPEG, который обеспечивает лучшее качество сжатия, при этом сохраняя полную совместимость со стандартом JPEG и со всеми браузерами. Недавно вышла третья его версия.

MozJPEG отличается тем, что умеет делать оптимизацию с прогрессивным сканированием — трюк, известный по инструменту jpegcrush/jpegrescan. Параметры прогрессивного сканирования влияют на степень сжатия. Возможно уменьшить размер файла, если правильно их подобрать.

Кроме того, MozJPEG использует технику из современных видеокодеков, которая называется треллис-квантование (trellis quantization). Этот алгоритм базируется на дискретно-косинусном преобразовании, он используется в видеокодеках Theora, Xvid, x264, утилите mencoder (опция -trellis).

Для сравнения, вот как выглядит одна и та же фотография, сжатая с помощью ImageMagick и с помощью MozJPEG.

ImageMagick (20,8 КБ), convert -quality 18

ImageMagick (20,8 КБ), convert -quality 18

MozJPEG (20,6 КБ), cjpeg -quant-table 2 -quality 29.4

MozJPEG (20,6 КБ), cjpeg -quant-table 2 -quality 29.4

Вдобавок ко всему, в MozJPEG исправлен известный баг JPEG с созданием мутного ореола вокруг текста.

Libjpeg 6b (6,2 КБ), cjpeg -sample 1x1 -quality 16

Libjpeg 6b (6,2 КБ), cjpeg -sample 1×1 -quality 16

MozJPEG (6 КБ), cjpeg -sample 1x1 -quality 35.5

MozJPEG (6 КБ), cjpeg -sample 1×1 -quality 35.5

MozJPEG бинарно совместим как с libjpeg-turbo, так и с классическим libjpeg, то есть его можно использовать как замену libjpeg.

Прочитать полностью на сайте: Кодек MozJPEG 3.0: оптимизированная версия JPEG



Chrome DevTools вне браузера
2014-12-29 19:45 Denis Mirkov

Кому-то нравятся средства разработки Chrome DevTools, но он по принципиальным соображениям не хочет пользоваться браузером Chrome. Теперь появилось решение проблемы: отдельное приложение Chrome DevTools App.

За это следует благодарить программиста Кеннета Охенберга (Kenneth Auchenberg). Он взял DevTools из репозитория и «упаковал» код в приложение, используя среду node-webkit. Более того, он ещё и сделал симпатичный дизайн заставки в «материальном» стиле с помощью компонентов AngularJS Material.

003

Правда, для работы приложения всё-таки нужен запущенный экземпляр Chrome с включенной функцией удалённой отладки (remote debugging). Сама программа в рабочем состоянии выглядит точно так же, как Chrome DevTools в браузере (видео).

004

В будущем Кеннет Охенберг собирается полностью отвязать DevTools от Chrome, чтобы он мог работать и с Firefox, и с другими браузерами.

Прочитать полностью на сайте: Chrome DevTools вне браузера



Суперкомпьютер из 412 приставок PlayStation 3
2014-12-29 22:45 Denis Mirkov

Кафедра физики в Массачусетском университете сейчас пользуется особенной популярностью у студентов. Среди них быстро распространилась новость, что доктор физических наук Гурав Кханна (Gaurav Khanna) собрал суперкомпьютер из 412 игровых приставок PlayStation 3. Среди студентов много геймеров, им хотелось посмотреть, как работает такое чудо техники.

Гурав Кханна занимает должность заместителя директора Центра научных вычислений и визуализации данных и занимается изучением чёрных дыр. Свой первый кластер он соорудил ещё в 2007 году из 16 игровых приставок для моделирования столкновений чёрных дыр.

Конкретный предмет исследований — распространение гравитационных волн, которые искажают ткань пространства-времени. Поскольку чёрные дыры невозможно наблюдать с помощью телескопов, то исследовать этот эффект помогают компьютерные симуляции.

В последнее время суперкомпьютеры всё чаще используются в научных экспериментах. Сам д-р Кханна называет их «третьим столпом» современной науки, наравне с теорией и экспериментом. «Наука становится дорогой, — говорит он. — У нас просто не хватает финансирования, как на уровне университета, так и на федеральном уровне. Суперкомпьютеры позволяют учёным компенсировать недостающие ресурсы». А использование игровых приставок делает экономию ещё более значительной.

Для настоящего суперкомпьютера нужно покупать множество дорогих комплектующих: процессоры, память и т.д., тогда как Sony продаёт приставку PlayStation по довольно низкой цене, возможно, даже ниже себестоимости, чтобы заработать на компьютерных играх. В отличие от других приставок, на PlayStation 3 можно установить другую операционную систему, что делает её привлекательной в глазах разработчиков и программистов (в PlayStation 4 такая функция отсутствует). Сейчас PS3 можно купить за $250-300.

003

Нынешний кластер начался с того, что компания Sony Computer Entertainment America пожертвовала четыре приставки PS3 для эксперимента. Университет выделил деньги на восемь штук, а д-р Кханна купил ещё четыре за свои деньги. На все 16 приставок он установил Linux и подключил кластер к интернету.

В 2009 году он опубликовал научную работу с описанием этого опыта. Автор показал, что такой суперкомпьютер на порядок превосходит по вычислительной мощности процессор обычного ПК. В том же году Гурав Кханна обнародовал первые результаты моделирования на «игровом» кластере.

Работа физика привлекла внимание государственных структур, и в 2010 году Научно-исследовательская лаборатория ВВС США построила собственный кластер из приставок PlayStation 3 для моделирования городского ландшафта по показаниям радаров. Лаборатория пожертвовала Гураву 176 приставок для дальнейших исследований, а в 2014 году — ещё 220 штук.

Кластер оборудован в охлаждающем контейнере, изначально предназначенном для перевозки молока.

Сейчас у конструктора идея сделать новый суперкомпьютер из современных графических карт, каждая из которых обладает вычислительной мощностью как 20 приставок PlayStation 3.

Прочитать полностью на сайте: Суперкомпьютер из 412 приставок PlayStation 3



Обзор лучших репозиториев Github за неделю
2014-12-30 08:00 Denis Mirkov

Продолжаем публиковать обзоры open source проектов, наиболее популярных на сайте Github за неделю.

1. Awesome Courses: список курсов по разным областям информатики, собранных с университетских страниц со всего интернета.

2. Openbay: исходный код веб-сайта The Pirate Bay, чтобы любой желающий мог поднять копию на своём сервере.

3. Front-end Job Interview Questions: список вопросов, которые часто задают на собеседованиях при приёме на работу фронтенд-разработчиков. Репозиторий полезен как для соискателей, так и для отделов HR.

4. Algorithms: реализация некоторых алгоритмов на Ruby. Полезен как дополнение к предыдущему репозиторию, потому что такие задачки тоже часто задают на собеседованиях.

5. Core: красивый форумный софт для современного веба, официальный сайт.

003

6. Lwan: экспериментальный масштабируемый высокопроизводительный веб-сервер, официальный сайт.

7. Atom Shell: кроссплатформенная оболочка для десктопных приложений.

8. uBlock: эффективный блокировщик рекламы для браузеров на движке Chromium. Потребляет меньше оперативной памяти и блокирует больше рекламы, чем AdBlock, AdBlock Plus и другие конкуренты.

9. H2O: оптимизированный веб-сервер с поддержкой HTTP/1.x и HTTP/2.

10. Awesome Android UI: модерируемый список библиотек Android UI/UX.

Прочитать полностью на сайте: Обзор лучших репозиториев Github за неделю



AdBlock Plus: причина утечек памяти в Firefox и Chrome
2014-12-30 09:30 Denis Mirkov

Блокировщик рекламы AdBlock Plus — самое популярное расширение для браузеров Firefox и Chrome. Теоретически, оно должно уменьшать расход оперативной памяти, останавливая загрузку рекламных баннеров. Но ирония в том, что в реальности AdBlock Plus увеличивает расход памяти. Более того, тесты показывают, что AdBlock Plus также увеличивает количество вычислительных ресурсов, которые тратятся на рендеринг сайта, то есть компьютер с блокировщиком рекламы потребляет больше энергии. На ноутбуке это означает сокращение времени работы от аккумулятора.

На первый взгляд, такие результаты тестирования могут показаться противоречивыми, ведь блокировщик рекламы скрывает от показа, например, флэш-анимацию, которая потребляет немало ресурсов процессора. Но реальность такова, что AdBlock Plus вырос в монстрообразное приложение, которое потребляет больше RAM, чем экономит.
003

По результатам тестирования, браузер на 64-битной операционной системе с установленным AdBlock Plus потребляет, в среднем, на 60-70 МБ больше оперативной памяти. Более того, для каждого фрейма наблюдается оверхед около 4 МБ. Это объясняется тем, что AdBlock Plus вставляет гигантский CSS, чтобы закрыть рекламу. На некоторых страницах есть множество встроенных фреймов, поэтому такая блокировка влетает в копеечку.

Например, на сайте TechCrunch, где грузятся социальные кнопки и множество постороннего контента, без AdBlock Plus потребление памяти составляет 194 МБ, а с включенным блокировщиком рекламы — 417 МБ.

В качестве экстремального примера можно протестировать эту страницу, на которой более 400 фреймов. Без AdBlock Plus она занимает в памяти 370 МБ, а с ним — 1960 МБ. Естественно, при таких характеристиках страница гораздо медленнее загружается в браузерах с AdBlock Plus.

См. также:
Вышел блокировщик рекламы µBlock для Firefoч
Ответ AdBlock Plus на обвинения в утечке памяти

Прочитать полностью на сайте: AdBlock Plus: причина утечек памяти в Firefox и Chrome



Microsoft разрабатывает новый браузер Spartan
2014-12-30 11:06 Denis Mirkov

По неофициальной информации, компания Microsoft работает над новым браузером вместо Internet Explorer. Браузер под кодовым названием “Spartan” будет представлен вместе с одним из билдов Windows 10.

Говорят, что новая разработка редмондской корпорации создаётся по образцу Firefox и Chrome, с новым дизайном вкладок (табов) и поддержкой расширений.

Несколько независимых источников сообщают, что браузер Spartan не является IE12, а станет заменой для него. Это будет легковесный, аскетичный браузер с минималистичным интерфейсом.

Один из источников — сотрудник Microsoft Томас Нигро (Thomas Nigro), который слышал о новом браузере и упомянул этот факт в своём твиттере. Тема обсуждалась в декабрьском подкасте LiveTile.

По имеющейся информации, Spartan по-прежнему будет использовать JavaScript-движок Chakra и движок рендеринга Microsoft Trident (а не WebKit). Судя по всему, сейчас в разработке находятся две версии Trident.

Если новый браузер всё-таки будет готов к моменту выпуска Windows 10, то в комплекте с этой ОС, вероятно, появится два браузера: Spartan и IE 11 (для обратной совместимости).

Возможно, дебют Spartan состоится 21 января на большой презентации Microsoft.

Прочитать полностью на сайте: Microsoft разрабатывает новый браузер Spartan



АНБ использует протокол Jabber для чатов
2014-12-30 12:40 Denis Mirkov

Немецкий журнал Der Spiegel опубликовал новую порцию секретных документов АНБ, полученных от Эдварда Сноудена. В документах речь идёт о сервисах IM и методах шифрования.

Среди прочего, упоминается, что само АНБ использует протокол XMPP (Jabber) для внутренних коммуникаций. Этот же протокол, по мнению спецслужб, используется хакерами и активистами, которые пытаются избежать слежки и надзора со стороны АНБ.

Перехват сообщений в чат-сервисах осуществляется в рамках программы Scarletfever, которая является частью большей инициативы Longhaul. Спецслужбы пытаются перехватить весь трафик и взломать шифры.

Зашифрованные сообщения привлекают особое внимание разведчиков. Ещё с тех времён, когда надёжное шифрование было доступно только государственным агентствам, считается, что зашифрованные послания — признак нелегальной активности или шпионажа.

003

В документах сказано, что «устойчивый перехват» трафика Skype начался в феврале 2011 года и продолжается «до настоящего времени» (сами документы двухлетней давности). Интересно, что начало прослушки совпадает с датой покупки сервиса Skype компанией Microsoft, хотя последняя всячески отрицает факт сотрудничества с разведкой.

В то же время АНБ признаёт неудачные попытки взломать некоторые коммуникационные протоколы. Проблемы возникли с расшифровкой почты от почтовых сервисов с поддержкой криптографии, таких как Zoho, а также с отслеживанием пользователей сети анонимайзеров Tor. Немало головной боли агентам добавляют люди, которые используют программу шифрования дисков Truecrypt, а для коммуникации прибегают к протоколу Off-the-Record (OTR).

004

АНБ называет «катастрофической» ситуацию, когда объект слежки комбинирует несколько средств для анонимизации. Например, чат CSpace и голосовые звонки по ZRTP через сеть Tor. В этом случае агенты «практически полностью теряют понимание о присутствии объекта», сказано в документе.

Вообще, в АНБ уделяют особое внимание криптографии. Например, на Рождество сотрудники играют в традиционную игру Kryptos Kristmas Kwiz, разгадывая криптографические головоломки. Победителям вручают подарки — кружки “Kryptos”.

В 2013 году бюджет АНБ превысил $10 млрд, в том числе бюджет криптографического подразделения Cryptanalysis and Exploitation Services (CES) составил $34,3 млн.

Прочитать полностью на сайте: АНБ использует протокол Jabber для чатов



Quake 1 на экране осциллографа
2014-12-30 14:10 Denis Mirkov

Финский инженер Пекка Вяанянен (Pekka Väänänen) поставил перед собой непростую и неординарную задачу: вывести действие игры Quake 1 на экран осциллографа в реальном режиме времени.

На первый взгляд, задача кажется неподъёмной: как можно отобразить игру на монохромном экране, который принимает аналоговый сигнал? Ведь осциллограф с электронно-лучевой трубкой предназначен для визуализации волн, то есть амплитудных и временных параметров электрического сигнала, подаваемого на вход прибора. Тем не менее, инженер сумел найти решение (видео).

Для подачи сигнала Пекка использовал аудиокабель от наушников, а осциллограф перевёл в режим X-Y. Затем он нашёл способ, как кодировать изображение в звуковом сигнале, чтобы осциллограф выводил на экране нужную картинку. Пришлось написать специальный конвертер. Кстати, подобный приём использовался в знаменитом демо Youscope от 2007 года, но там осциллограф показывает заранее подготовленное отрендеренное видео. Здесь же Quake кодируется в реальном времени.

003

Пропускной способности аудиотракта хватает на передачу примерно 1000 строк за раз. Главной проблемой стал обход встроенных звуковых фильтров. Обойти их всё-таки не удалось, так что пришлось адаптировать конвертер. Для генерации сигнала в реальном времени инженер использовал программы ASIO и PortAudio, а также движок рендеринга Darkplaces.

В принципе, с помощью такого способа можно даже играть в Quake, глядя на экран осциллографа. Хотя это не слишком удобно.

Прочитать полностью на сайте: Quake 1 на экране осциллографа



ФБР ищет «хороших» хакеров для сотрудничества
2014-12-30 15:50 Denis Mirkov

Федеральное бюро расследований объявило набор кандидатов на новую вакансию: «специальный киберагент» (Cyber Special Agent). Согласно описанию, представители этой профессии должны сражаться с глобальными киберугрозами, сотрудничать с международными правоохранительными органами и защищать критичную национальную инфраструктуру.

Требования к специальным киберагентам

  • Возраст от 23 до 36,5 лет
  • Высшее образование в признанном США колледже/университете
  • Минимум три года работы на полную ставку в сфере информационной безопасности, криминалистической экспертизы, программирования или «этического хакинга»
  • Возможность выполнять задания на всей территории, которая входит в юрисдикцию ФБР
  • Отличные физические кондиции и способность пройти строгий экзамен на физическую подготовку
  • Соответствие всем остальным требованиям, которые выдвигаются для специальных агентов


В качестве кандидатов рассматриваются только граждане США. Более подробное описание вакансии приведено на сайте USAJobs.

ФБР не называет количество специалистов, которых намерено принять в штат, но директор подразделения Роберт Андерсон (Robert Anderson) сказал, что вакансий много.

Специальным агентам обещают годовую зарплату от $59 340 до $76 578. Вакансии открыты до 20 января 2015 года.

Прочитать полностью на сайте: ФБР ищет «хороших» хакеров для сотрудничества



Исследуем механизмы работы гипервизора Hyper-V
2015-01-05 13:56 gerhart

Со времени публикации первой части статьи глобально в мире ничего не изменилось: Земля не наскочила на небесную ось, все так же растет популярность облачных сервисов, все так же в гипервизоре компании Microsoft не были обнаружены новые дыры, а исследователи не хотят тратить свое время на поиск багов в плохо документированной и мало изученной технологии. Поэтому я предлагаю тебе освежить память первой частью из предыдущего номера, пополнить запас своего бара и приступить к чтению, ведь сегодня мы сделаем драйвер, взаимодействующий с интерфейсом гипервизора и отслеживающий передаваемые гипервизором сообщения, а также изучим работу компонентов служб интеграции Data Exchange.

Обработка сообщений гипервизора

На dvd.xakep.ru мы выложили драйвер, написанный с помощью Visual Studio 2013. Он должен быть загружен в root ОС, например с помощью OSRLoader. Для отправки IOCTL-кодов используется простая программа SendIOCTL.exe. После отправки IOCTL-кода INTERRUPT_CODE драйвер начинает выполнять обработку данных, переданных гипервизором через нулевой слот SIM. К сожалению, переменная HvlpInterruptCallback, в которой содержится адрес массива с указателями обработчиков сообщений, ядром не экспортируется, поэтому для ее обнаружения необходимо проанализировать код экспортируемой ядром функции HvlRegisterInterruptCallback, содержащей необходимый нам адрес массива. Также, к сожалению, не получится просто вызвать HvlRegisterInterruptCallback для регистрации своего обработчика сообщений, так как в самом начале функции идет проверка значения переменной HvlpFlags. Если переменная равна 1 (а ей присваивается это значение на начальных этапах загрузки ядра), то функция прекращает выполнение, возвращает код ошибки 0xC00000BB (STATUS_NOT_SUPPORTED) и, соответственно, регистрация обработчика не происходит, поэтому для замены обработчиков придется написать свой вариант функции HvlpInterruptCallback. В драйвере hyperv4 необходимые действия выполняются функцией RegisterInterrupt:


int RegisterInterrupt()
{
UNICODE_STRING uniName;
PVOID pvHvlRegisterAddress = NULL;
PHYSICAL_ADDRESS pAdr = {0};
ULONG i,ProcessorCount;
// Получаем число активных ядер процессоров
ProcessorCount = KeQueryActiveProcessorCount(NULL);
// Выполняем поиск адреса экспортируемой функции HvlRegisterInterruptCallback
DbgLog("Active processor count",ProcessorCount);
RtlInitUnicodeString(&uniName,L"HvlRegisterInterruptCallback");
pvHvlRegisterAddress = MmGetSystemRoutineAddress(&uniName);
if (pvHvlRegisterAddress == NULL){
DbgPrintString("Cannot find HvlRegisterInterruptCallback!");
return 0;
}
DbgLog16("HvlRegisterInterruptCallback address ",pvHvlRegisterAddress);
// Выполняем поиск адреса переменной HvlpInterruptCallback, FindHvlpInterruptCallback((unsigned char *)pvHvlRegisterAddress);
// Производим замену оригинальных обработчиков на свои
ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchmWinHvOnInterrupt,(uintptr_t)pvHvlpInterruptCallbackOrig,WIN_HV_ON_INTERRUP_INDEX);
ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR0_INDEX);
ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR1_INDEX);
ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR2_INDEX);
ArchmHvlRegisterInterruptCallback((uintptr_t)&ArchXPartEnlightenedIsr,(uintptr_t)pvHvlpInterruptCallbackOrig,XPART_ENLIGHTENED_ISR3_INDEX);
// Так как значение SIMP для всех ядер разное, то необходимо получить физические адреса всех SIM

WARNING

Во время экспериментов, связанных с интенсивной работой виртуальных машин, лучше заменять один обработчик в массиве HvlpInterruptCallback, поскольку замена всех сразу приводит к нестабильной работе системы (по крайней мере, при большом потоке отладочных сообщений через KdPrint и WPP).


// сделать возможным доступ к содержимому страницы, смапировав ее с помощью Mm MapIoSpace, и сохранить полученные виртуальные адреса каждой страницы в массив для последующего использования
for (i = 0; i < ProcessorCount; i++)
{KeSetSystemAffinityThreadEx(1i64 <
Call Sitent!IoAllocateMdl vmbus!InstanceCloseChannel+0x22d (адрес возврата для функции, имя которой отсутствует в символах)
vmbus!InstanceDeviceControl+0x118
..................................
vmbkmcl!KmclpSynchronousIoControl+0xa7
vmbkmcl!KmclpClientOpenChannel+0x2a6
vmbkmcl!KmclpClientFindVmbusAnd
if (pvSIMP[uCurProcNum] != NULL){
phvMessage = (PHV_MESSAGE)pvSIMP[uCurProcNum];
} else{
DbgPrintString("pvSIMP is NULL");
return;
}
// Уведомление об отправке сообщения через 1-й слот SIM phvMessage1 = (PHV_MESSAGE)((PUINT8)pvSIMP[uCurProcNum]+ HV_MESSAGE_SIZE); // for SINT1
if (phvMessage1-\>Header.MessageType != 0){
DbgPrintString("SINT1 interrupt");
}
// В зависимости от типа сообщения вызываем процедуры обработчики
// Структуры для каждого типа сообщения описаны в TLFS
switch (phvMessage-\>Header.MessageType)
{
case HvMessageTypeX64IoPortIntercept:
PrintIoPortInterceptMessage(phvMessage);
break;
case HvMessageTypeNone:DbgPrintString("HvMessageTypeNone");
break;
case HvMessageTypeX64MsrIntercept:PrintMsrInterceptMessage(phvMessage);
break;
case HvMessageTypeX64CpuidIntercept:PrintCpuidInterceptMessage(phvMessage);
break;
case HvMessageTypeX64ExceptionIntercept:PrintExceptionInterceptMessage(phvMessage);
break;
default:
DbgLog("Unknown MessageType", phvMessage-\>
Header.MessageType);
break;
}
}

Функция получает номер активного логического процессора, адрес страницы SIM и считывает значение нулевого слота SIM. Сперва производится анализ типа сообщения phvMessage-\>Header.MessageType, поскольку тело сообщения для каждого типа разное. В DbgView можно увидеть следующую картину (см. рис. 3).

image3

Рис. 3. Вывод DbgView при обработке гипервизором обращений к MSR-регистрам

image4

Функция ParseVmbusMessage (рис. 4).

Функция получает номер активного логического процессора, адрес страницы SIM и считывает значение четвертого слота SIM. Для примера разобраны сообщения CHANNELMSG_OPENCHANNEL и CHANNELMSG_GPADL_HEADER, но в исходных кодах LIS можно увидеть формат всех типов сообщений и без труда дописать необходимые обработчики. Сообщения для шины VMBus обычно генерируются при включении/выключении виртуальной машины или же одного из компонентов Integration Services. Например, при включении компонента Data Exchange отладчик или DbgView покажет информацию, изображенную на рис. 5.

image5

Рис. 5. Отладочный вывод сообщений при включении компонента Data Exchange

Integration Services — Data Exchange

Далее рассмотрим, каким же образом происходит обмен данными между гостевой и root ОС на примере одного из компонентов служб интеграции — Data Exchange. Этот компонент позволяет root ОС считывать данные из определенной ветки реестра гостевой ОС. Для проверки в гостевой ОС создадим в ветке HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Virtual Machine\Guest ключ со значением KvPDataValue (см. рис. 6).

Рис. 6. Ключ KvPDataValue

Рис. 6. Ключ KvPDataValue

Для получения значения ключа в root ОС был использован следующий PowerShell-скрипт(см. рис. 7).

image7

Рис. 7. PowerShellскрипт для запроса значений реестра из гостевой ОС

Скрипт вернет значение ключа KvPDataKey (см. рис. 8). Скрипт получает весь доступный набор значений с помощью \$vm.GetRelated(«Msvm_KvpExchangeComponent»).GuestExchangeItems и только после этого выполняет разбор каждого полученного объекта на предмет поиска ключа KvPDataKey. Соответственно, скрипт будет работать только в том случае, если в свойствах из этой функции вызывается nt!IoAllocateMdl с размером выделяемого буфера 0xC000. Результат выполнения функции — сформированная структура MDL (см. рис. 11). Далее вызывается MmProbeAndLockPages, после завершения выполнения которой структура MDL дополняется элементами PFN (см. рис. 12). В данном примере была выделена непрерывная область физической памяти, хотя это условие выполняется необязательно. Далее вызывается vmbus!ChCreateGpadlFromNtmdl (вторым параметром передается адрес MDL), которая вызывает vmbus!ChpCreateGpaRanges, передавая ей в качестве первого параметра все тот же MDL. Далее выполняется копирование элементов PFN из структуры MDL в отдельный буфер (см. рис. 13), который станет телом сообщения CHANNELMSG_GPADL_HEADER, отправляемого гостевой ОС в root ОС посредством вызова vmbus!ChSendMessage. hv!HvPostMessage или в winhv!WinHvPostMessage можно увидеть сообщение (рис.14).

Рис. 8. Результат выполнения скрипта

Рис. 8. Результат выполнения скрипта

image11

Рис. 11. Значение структуры MDL

 

Рис. 12. PFN в MDLструктуре

Рис. 12. PFN в MDLструктуре

Рис. 13. Участок кода, отвечающий за копирование PFN в отдельный буфер

Рис. 13. Участок кода, отвечающий за копирование PFN в отдельный буфер

Рис. 14. Массив PFN, обрабатываемый гипервизором

Рис. 14. Массив PFN, обрабатываемый гипервизором

Первые 16 байт — это общий заголовок сообщения, где, например, 0xF0 — размер тела сообщения, внутри размещается VMBus-пакет, в заголовке которого указан тип пакета — 8 (CHANNELMSG_GPADL_HEADER), rangecount равен 1, из чего следует, что в один пакет вместились все данные, которые было необходимо передать. В случае большого объема данных драйвер гостевой ОС разделил бы их на части и отправил отдельными сообщениями. Далее root ОС шлет сообщение CHANNELMSG_OPENCHANNEL_RESULT, затем гостевая ОС шлет CHANNELMSG_OPENCHANNEL. После этого в root ОС отрабатывает Work Item (см. рис. 15).

Рис. 15. Вызов ChMapGpadlView

Рис. 15. Вызов ChMapGpadlView

В ходе его выполнения вызывается vmbusr!ChMapGpadlView->vmbusr!PkParseGpaRanges, которой, в свою очередь, передается указатель на часть сообщения, содержащую размер буфера 0xC000 и PFN, переданные в сообщении CHANNELMSG_GPADL_HEADER. Далее происходит вызов vmbusr!XPartLockChildPagesSynchronous-\>vmbusr!XPartLockChildPages, после чего выполняется функция из драйвера vid.sys (имя функции неизвестно, поскольку символы для драйвера отсутствуют), которой в качестве второго параметра передается блок PFN, отправленный ранее в сообщении из гостевой ОС (см. рис. 16).

Рис. 16. Обработка гостевых PFN драйвером vid.sys

Рис. 16. Обработка гостевых PFN драйвером vid.sys

Непосредственно после возврата из функции в [rsp+30h] находится указатель на вновь созданную структуру MDL (см.рис. 17).

Рис. 17. Структура MDL, возвращаемая драйвером vid.sys

Размер выделенного буфера также равен 0xC000. После этого root ОС шлет сообщение CHANNELMSG_OPENCHANNEL_RESULT. На этом процесс активации компонента Data Exchange завершается. Таким образом создается некий shared-буфер, видимый как гостевой, так и root ОС. Это можно проверить, выполнив запись произвольных данных в буфер в гостевой ОС, например с помощью команды:

WINDBG\>!ed 2d5bb000 aaaaaaaa
WINDBG\>!db 2d5bb000
#2d5bb000 aa aa aa aa 10 19 00

А в root ОС посмотреть содержимое страницы, соответствующей PFN, возвращенной функцией драйвера vid.sys:

WINDBG\>!db 1367bb000
#1367bb000 aa aa aa aa 10 19

Как видно, значения совпали, так что это действительно одна и та же физическая область памяти. Вспомним, что на предыдущих этапах мы определили, что при активации компонента Data Exchange создается порт типа HvPortTypeEvent с TargetSint = 5. Соответственно, все операции с этим портом в root ОС будет обрабатывать KiVmbusInterrupt1, из которой происходит вызов vmbusr!XPartEnlightenedIsr, а она, в свою очередь, вызывает KeInsertQueueDpc с параметром DPC (его значение показано на рис. 19).

Рис. 19. Значение DPC, которую ставит в очередь XPartEnlightenedIsr

Рис. 19. Значение DPC, которую ставит в очередь XPartEnlightenedIsr

Из vmbusr!ParentRingInterruptDpc через несколько вызовов будет выполнена vmbusr!PkGetReceiveBuffer.

WINDBG\>k
Child-SP RetAddr Call Site
fffff800`fcc1ea38 fffff800`6cdc440c
vmbusr!PkGetReceiveBuffer+0x2c
fffff800`fcc1ea40 fffff800`6cdc41a7
vmbusr!PipeTryReadSingle+0x3c
fffff800`fcc1eaa0 fffff800`6cdc4037
vmbusr!PipeProcessDeferredReadWrite+0xe7
fffff800`fcc1eaf0 fffff800`6c96535e
vmbusr!PipeEvtChannelSignalArrived+0x63
fffff800`fcc1eb30 fffff800`6cdc4e3d
vmbkmclr!KmclpVmbusManualIsr+0x16
fffff800`fcc1eb60 fffff800`fb2d31e0
vmbusr!ParentRingInterruptDpc+0x5d

Если просмотреть эту область памяти, то становятся видны параметры гостевой ОС.

WINDBG\> dc ffffd0016fe33000 L1000
…………………………………………………………………………………………………………………
ffffd001`6fe35b30 0065004e 00770074 0072006f
0041006b N.e.t.w.o.r.k.A.
ffffd001`6fe35b40 00640064 00650072 00730073
00500049 d.d.r.e.s.s.I.P.
ffffd001`6fe35b50 00340076 00000000 00000000 00000000
v.4.............
…………………………………………………………………………………………………………………
ffffd001`6fe35d20 00000000 00000000 00000000 00000000
................
ffffd001`6fe35d30 00300031 0030002e 0030002e 0033002e
1.0...0...0...3.
ffffd001`6fe35d40 00000000 00000000 00000000 00000000
................
WINDBG\>!pte ffffd001`6fe35b30
VA ffffd0016fe35b30
PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at
FFFFF6FB74005BF8
PTE at FFFFF6E800B7F1A8
contains 0000000000225863 contains 00000000003B7863 contains
000000010FB12863 contains 80000001367BD963
pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA-KWEV pfn
1367bd -G-DA--KW-V
pfn 1367bd — это PFN 3-й страницы из конвертированного MDL

Также этой же функции в rdx передается указатель, содержащий смещение относительно адреса начала общих с гостевой ОС страниц (в примере он равен 4448h), по которому необходимо произвести чтение:

vmbusr!PkGetReceiveBuffer+0x4e:
mov r8,r10 (в r10d был ранее загружено смещение из rdx)
add r8,qword ptr [rcx+20h] — в rcx+20 содержится указатель на одну из общих с гостевой ОС страницу
WINDBG\>!pte @r8
VA ffffd0016ff22448
PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at FFFFF6FB74005BF8
PTE at FFFFF6E800B7F910
contains 0000000000225863 contains 00000000003B7863 contains
000000010FB12863 contains 80000001367C0963
pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV pfn 10fb12 ---DA-KWEV pfn
1367c0 -G-DA--KW-V

Поставим точку останова на начало функции vmbusr!PkGetReceiveBuffer и выполним PowerShell-скрипт. Точка останова сработает, при этом будет видно, что функции передается структура (указатель в rcx) и в rcx+18 находится указатель на блок памяти:

WINDBG\>? poi(@rcx+18)
Evaluate expression: -52770386006016 = ffffd001`6fe33000
WINDBG\>!pte ffffd001`6fe33000
VA ffffd0016fe33000
PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB
7DBA0028 PDE at FFFFF6FB74005BF8
PTE at FFFFF6E800B7F198
contains 0000000000225863 contains
00000000003B7863 contains
000000010FB12863 contains
80000001367BB963
pfn 225 ---DA--KWEV pfn 3b7 ---DA--KWEV
pfn 10fb12 ---DA--KWEV pfn
1367bb -G-DA--KW-V
WINDBG\>r cr3
cr3=00000000001ab000
WINDBG\>!vtop 1ab000 ffffd 0016fe33000
Amd64VtoP: Virt ffffd001`6fe33000,
pagedir 1ab000
Amd64VtoP: PML4E 1abd00
Amd64VtoP: PDPE 225028
Amd64VtoP: PDE 3b7bf8
Amd64VtoP: PTE 00000001`0fb12198
Amd64VtoP: Mapped phys 00000001`367bb000
Virtual address ffffd0016fe33000 translates to
physical address
1367bb000

INFO

Информацию о технологии KvP можно найти в блогах MSDN:
goo.gl/R0U52l
goo.gl/UeZRK2

Если поставить точку останова на инструкцию add r8,qword ptr [rcx+20h], то через несколько итераций в r8 можно увидеть имя и значение ключа KvpDataKey:

WINDBG\>dc @r8
ffffd001`6ff21d10
....H...........
ffffd001`6ff21d20
....(........... ffffd001`6ff21d30

00020006 00000148 00000000 00000000
00000001 00000 a28 00000003 00050002
размер передаваемого блока
0a140000 00000000 00000515 00000103
…………….
ffffd001`6ff21d40 00000004 00000001 00000016 0000001a
…………….
ffffd001`6ff21d50 0076004b 00440050 00740061 004b0061
K.v.P.D.a.t.a.K.
ffffd001`6ff21d60 00790065 00000000 00000000 00000000
e.y………….
…………………………………………………….
……….
ffffd001`6ff21f50 0076004b 00440050 00740061 00560061
K.v.P.D.a.t.a.V.
ffffd001`6ff21f60 006c0061 00650075 00000000 00000000
a.l.u.e………
WINDBG\>!pte ffffd001`6ff21f50
VA ffffd0016ff21f50
PXE at FFFFF6FB7DBEDD00 PPE at FFFFF6FB7DBA0028 PDE at
FFFFF6FB74005BF8
PTE at FFFFF6E800B7F908
contains 0000000000225863 contains 00000000003B7863 contains
000000010FB12863 contains 80000001367BF963
pfn 225 —DA–KWEV pfn 3b7 —DA–KWEV pfn 10fb12 —DA-KWEV pfn
1367bf -G-DA–KW-V

Затем после завершения PkGetReceiveBuffer функция PipeTryReadSingle копирует данные из shared-буфера с помощью функции memmove.

При этом размер блока (в данном случае A28) указан непосредственно в самом блоке, но если будет задано число больше, чем 4000h, то копирование не будет произведено. Таким образом, видно, что обмен данными между root ОС и гостевой ОС использует общий буфер, а интерфейс гипервизора используется лишь для уведомления root ОС о том, что необходимо выполнить считывание данных из этого буфера. В принципе, ту же операцию можно было бы выполнить при помощи отправки нескольких сообщений, используя winhv!HvPostMessage, но это привело бы к значительному снижению производительности.

Использование интерфейса перехвата гипервизора

Настроим гипервизор таким образом, чтобы он отправлял уведомление root ОС в случае, если в одной из гостевой ОС выполняется инструкция cpuid с параметром 0x11114444. Для этого Hyper-V предоставляет интерфейс в виде гипервызова HvInstallIntercept. В драйвере hyperv4 реализована функция SetupIntercept, которая получает список идентификаторов всех активных гостевых ОС и вызывает для каждой WinHvInstallIntercept.

int SetupIntercept()
{
HV_INTERCEPT_DESCRIPTOR Descriptor;
HV_INTERCEPT_PARAMETERS Parameters = {0};
HV_STATUS hvStatus = 0;
HV_PARTITION_ID PartID = 0x0, NextPartID = 0;
// Если в качестве параметра инструкции в RAX-инструкции CPUID будет передано значение 0x11114444, то гипервизор выполнит перехват и отправит сообщение родительскому разделу для обработки результата
DbgPrintString("SetupInterception was called");
Parameters.CpuidIndex = 0x11114444;
Descriptor.Type = HvInterceptTypeX64Cpuid;
Descriptor.Parameters = Parameters;
hvStatus = WinHvGetPartitionId(&PartID);
do{
hvStatus = WinHvGetNextChildPartition(PartID,NextPartID,&NextPartID);
if (NextPartID != 0){
DbgLog("Child partition id", NextPartID);
hvStatus = WinHvInstallIntercept(NextPartID,
HV_INTERCEPT_ACCESS_MASK_EXECUTE, &Descriptor);
DbgLog("hvstatus of WinHvInstallIntercept = ",hvStatus);
} } while ((NextPartID != HV_PARTITION_ID_INVALID) &&
(hvStatus == 0));
return 0;}

Также изменим функцию PrintCpuidInterceptMessage таким образом, чтобы она в случае, если в гостевой ОС в регистре EAX (или RAX, если код, выполняющий инструкцию CPUID, выполняется в longmode) находится число 0x11114444, записывала в поле DefaultResultRdx структуры HV_X64_CPUID_INTERCEPT_MESSAGE, расположенную в нулевом слоте SIM, значение 0x12345678:

void PrintCpuidInterceptMessage(PHV_MESSAGE hvMessage)
{PHV_X64_CPUID_INTERCEPT_MESSAGE_phvCPUID = (PHV_X64_CPUID_NTERCEPT_MESSAGE)_hvMessage-\>Payload;
DbgLog(" phvCPUID-\>DefaultResultRax",phvCPUID-\>DefaultResultRax);
DbgLog(" phvCPUID-\>DefaultResultRbx",phvCPUID-\>DefaultResultRbx);
DbgLog(" phvCPUID-\>DefaultResultRcx",phvCPUID-\>DefaultResultRcx);
DbgLog(" phvCPUID-\>DefaultResultRdx",phvCPUID-\>DefaultResultRdx);
if (phvCPUID-\>Rax == 0x11114444){
phvCPUID-\>DefaultResultRdx =0x12345678;
DbgLog16(" phvCPUID-\>Header.Rip",phvCPUID-\>Header.Rip);
DbgPrintString(" Interception was handled");
}
}

Для проверки в гостевой ОС запустим тестовую утилиту, которая вызывает CPUID с Eax, равным 0x11114444. До установки перехвата утилита выведет результат, отображенный на рис. 20.

Рис. 20. Результат инструкции CPUID на обычной гостевой ОС

Рис. 20. Результат инструкции CPUID на обычной гостевой ОС

После активации перехвата результат будет следующим (см. рис. 21).

Рис. 21. Результат инструкции CPUID после установки перехвата

Рис. 21. Результат инструкции CPUID после установки перехвата

При этом в root ОС будет выведено сообщение (см. рис. 22).

Рис. 22. Отладочный вывод обработки сообщения гипервизора при установленном перехвате

Рис. 22. Отладочный вывод обработки сообщения гипервизора при установленном перехвате

Сразу стоит обратить внимание на то, что этот трюк пройдет только в том случае, если root ОС ранее не установила перехваты для заданных условий. В этом случае после того, как драйвер hyperv заменит значение, управление перейдет на оригинальную WinHvOnInterrupt, которая вызовет функцию обработки из драйвера vid.sys (эта функция является четвертым параметром функции winhvr!WinHvCreatePartition, вызываемой в root ОС при создании дочернего раздела при включении виртуальной машины), что может привести к изменению результата. В нашем случае такой обработчик, разумеется, установлен не был, гипервизор проанализировал данные в нулевом слоте SIM и исправил результат инструкции CPUID.

В заключение

Несмотря на то что после прочтения моего труда твой мозг наверняка встал в позу речного скорпиона (и если ты вообще досюда дочитал — респект тебе от всей нашей редакции)… так, я отвлекся. Эта статья получилась скорее обзорной, демонстрирующей работу некоторых функций и компонентов системы виртуализации Microsoft на примерах. Однако, надеюсь, эти примеры помогут лучше понять принципы работы этих компонентов и позволят более глубоко проанализировать безопасность, например VMBus, написав свой собственный фаззер.

Прочитать полностью на сайте: Исследуем механизмы работы гипервизора Hyper-V




© Copyright Gameland

В избранное