Vmem процесс что это
Процесс Vmmem — что это?
Приветствую друзья! Сегодня мы поговорим про один процесс, который вы можете заметить в диспетчере задач… название его — Vmmem. Постараемся выяснить — зачем он нужен? Это может быть процесс вполне легальной программы, но это может быть и вирус.. поэтому давайте разбираться))
Описание
Процесс Vmmem — это оперативная память, которая выделена для использования виртуальной машиной (Hyper-V).
Простыми словами — виртуальная машина, это в некотором смысле виртуальный компьютер, который имеет свой процессор, свою оперативку. Сколько виртуальная машина (или несколько) потребляет памяти — столько примерно и будет кушать оперативы процесс Vmmem.
Разбираемся
Чтобы отключить процесс Vmmem, попробуйте следующее:
Можно также ограничить ресурсы Vmmem путем создания файла %UserProfile%\.wslconfig, внутри которого прописать:
[wsl2]
memory=6GB # Ограничиваем память для WSL2 VM.
processors=5 # Ограничиваем количество процессов для WSL2 VM.
Вот пример сколько процесс может потреблять оперативки (это еще далеко немного):
Картина может быть и такой, здесь уже намного больше используется:
Заключение
Удачи и добра, до новых встреч друзья!
Добавить комментарий Отменить ответ
Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.
Процесс «Система и сжатая память» в Windows 10
Функция сжатия оперативной памяти в Windows 10 предназначена для ускорения работы (отзывчивости) системы за счет хранения части страниц в оперативной памяти в сжатом виде. Тем самым достигается уменьшение количества обращений на чтение и запись страниц памяти из медленного (по сравнению с RAM) файла подкачки на жестком диске. Нужные данные извлекаются из более быстрой оперативной памяти быстрее, даже с учетом того, что на их сжатие/декомпрессию тратятся дополнительные ресурсы процессора.
Особенности технологии «Сжатой памяти» в Windows 10
Изначально поток, отвечающий за работу подсистемы сжатой памяти, находилась внутри процесса System, что не очень удобно с точки зрения диагностики. В Windows 10 1511 этот функционал был выделен в отдельный процесс — Система и сжатая память (System and compressed memory).
В Windows 10 Anniversary edition (1607) появился отдельный процесс Сжатая память (Memory Compression), скрытый от диспетчера задач. Получить информацию об этом процессе можно с помощью PowerShell командлета Get-Process:
Также информацию об использовании сжатой памяти системой можно получить с помощью диспетчера задач. Перейдите на вкладку Производительность (Performance), выберите раздел Память (Memory). Текущее значение использования сжатой памяти отображается в значении параметра Использование (сжатая). В моем примере используется 3 Гб памяти, из которой в сжатом виде хранится 230 Мб. Чтобы понять, какой объем данных получилось упаковать в сжатый блок, нужно навести мышкой на график Структура памяти:
Используется сжатой памяти (230 Мб). В сжатой памяти хранится примерно 1012 Мб данных, освобождая для системы 782 Мб памяти.
Как вы видите, уровень компрессии достигает почти 400%, так что экономия довольно большая.
В большинстве случаев, если компьютер работает нормально и на нем установлен достаточный объём оперативной памяти, процесс «Сжатой памяти» работает отлично и не требует никакого вмешательства.
Процесс «Система и сжатая память» сильно грузит компьютер
Но иногда случается, когда процесс «Система и сжатая память» начинает довольно сильно грузить процессор или жесткий диск компьютера (вплоть до 100%, это видно в диспетчере задач), или же занимаеть в памяти слишком много места. Компьютер, при этом, естественно, начинает сильно тормозить и подвисать.
Что делать в этом случае?
Я приведу 2 совета, которые должны помочь исправить проблему с высокой загрузкой системы процессом «Сжатая память».
Если указанные манипуляции не помогли, можно попробовать отключить сжатую память.
Как отключить сжатую память в Windows 10
Если вы хотите проверить стабильность работы Windows 10 без использования функции «сжатой памяти», можно временно отключать эту функцию. Для этого, откройте консоль PowerShell с правами администратора. Проверим, включена ли сейчас опция «Сжатой памяти»:
Строка MemoryCompression : True указывает на то, что сжатая память включена.
Отключим сжатую память:
И перезагрузим компьютер
После загрузки проверьте, как ведет себя система. Если производительность улучшилась, можно оставить ОС в режиме с отключенным режимом сжатой памяти.
Чтобы включить MemoryCompression, выполните команду:
Заключение
Технология «Сжатой памяти» в Windows 10, как правило работает довольно эффективно и не требует никаких вмешательств. В том случае, если она вызывает проблемы на вашем компьютере, скорее всего у вас имеются некоторые проблемы с настройками системы, оборудованием или драйверами. В случае необходимости, функцию сжатия памяти можно совсем отключить.
В некоторых случаях пользователям для исправления проблемы со сжатой памятью рекомендуют:
В некоторых случаях эти советы помогают избавится от чрезмерной нагрузки на компьютер со стороны процесса «Сжатая память», но при этом отключаются базовые подсистемы оптимизации производительности Windows, что может негативно сказаться на других аспектах производительности системы.
Организация виртуальной памяти
Привет, Хабрахабр!
В предыдущей статье я рассказал про vfork() и пообещал рассказать о реализации вызова fork() как с поддержкой MMU, так и без неё (последняя, само собой, со значительными ограничениями). Но прежде, чем перейти к подробностям, будет логичнее начать с устройства виртуальной памяти.
Конечно, многие слышали про MMU, страничные таблицы и TLB. К сожалению, материалы на эту тему обычно рассматривают аппаратную сторону этого механизма, упоминая механизмы ОС только в общих чертах. Я же хочу разобрать конкретную программную реализацию в проекте Embox. Это лишь один из возможных подходов, и он достаточно лёгок для понимания. Кроме того, это не музейный экспонат, и при желании можно залезть “под капот” ОС и попробовать что-нибудь поменять.
Введение
Любая программная система имеет логическую модель памяти. Самая простая из них — совпадающая с физической, когда все программы имеют прямой доступ ко всему адресному пространству.
При таком подходе программы имеют доступ ко всему адресному пространству, не только могут “мешать” друг другу, но и способны привести к сбою работы всей системы — для этого достаточно, например, затереть кусок памяти, в котором располагается код ОС. Кроме того, иногда физической памяти может просто не хватить для того, чтобы все нужные процессы могли работать одновременно. Виртуальная память — один из механизмов, позволяющих решить эти проблемы. В данной статье рассматривается работа с этим механизмом со стороны операционной системы на примере ОС Embox. Все функции и типы данных, упомянутые в статье, вы можете найти в исходном коде нашего проекта.
Будет приведён ряд листингов, и некоторые из них слишком громоздки для размещения в статье в оригинальном виде, поэтому по возможности они будут сокращены и адаптированы. Также в тексте будут возникать отсылки к функциям и структурам, не имеющим прямого отношения к тематике статьи. Для них будет дано краткое описание, а более полную информацию о реализации можно найти на вики проекта.
Общие идеи
Аппаратная поддержка
Обращение к памяти хорошо описанно в этой хабростатье. Происходит оно следующим образом:
Процессор подаёт на вход MMU виртуальный адрес
Если MMU выключено или если виртуальный адрес попал в нетранслируемую область, то физический адрес просто приравнивается к виртуальному
Если MMU включено и виртуальный адрес попал в транслируемую область, производится трансляция адреса, то есть замена номера виртуальной страницы на номер соответствующей ей физической страницы (смещение внутри страницы одинаковое):
Если запись с нужным номером виртуальной страницы есть в TLB [Translation Lookaside Buffer], то номер физической страницы берётся из нее же
Если нужной записи в TLB нет, то приходится искать ее в таблицах страниц, которые операционная система размещает в нетранслируемой области ОЗУ (чтобы не было промаха TLB при обработке предыдущего промаха). Поиск может быть реализован как аппаратно, так и программно — через обработчик исключения, называемого страничной ошибкой (page fault). Найденная запись добавляется в TLB, после чего команда, вызвавшая промах TLB, выполняется снова.
Таким образом, при обращении программы к тому или иному участку памяти трансляция адресов производится аппаратно. Программная часть работы с MMU — формирование таблиц страниц и работа с ними, распределение участков памяти, установка тех или иных флагов для страниц, а также обработка page fault, ошибки, которая происходит при отсутствии страницы в отображении.
В тексте статьи в основном будет рассматриваться трёхуровневая модель памяти, но это не является принципиальным ограничением: для получения модели с бóльшим количеством уровней можно действовать аналогичным образом, а особенности работы с меньшим количеством уровней (как, например, в архитектуре x86 — там всего два уровня) будут рассмотрены отдельно.
Программная поддержка
Виртуальный адрес
Page Global Directory (далее — PGD) — таблица (здесь и далее — то же самое, что директория) самого высокого уровня, каждая запись в ней — ссылка на Page Middle Directory (PMD), записи которой, в свою очередь, ссылаются на таблицу Page Table Entry (PTE). Записи в PTE ссылаются на реальные физические адреса, а также хранят флаги состояния страницы.
То есть, при трёхуровневой иерархии памяти виртуальный адрес будет выглядеть так:
Значения полей PGD, PMD и PTE — это индексы в соответствующих таблицах (то есть сдвиги от начала этих таблиц), а offset — это смещение адреса от начала страницы.
В зависимости от архитектуры и режима страничной адресации, количество битов, выделяемых для каждого из полей, может отличаться. Кроме того, сама страничная иерархия может иметь число уровней, отличное от трёх: например, на x86 нет PMD.
Для обеспечения переносимости мы задали границы этих полей с помощью констант: MMU_PGD_SHIFT, MMU_PMD_SHIFT, MMU_PTE_SHIFT, которые в приведённой выше схеме равны 24, 18 и 12 соответственно их определение дано в заголовочном файле src/include/hal/mmu.h. В дальнейшем будет рассматриваться именно этот пример.
На основании сдвигов PGD, PMD и PTE вычисляются соответствующие маски адресов.
Эти макросы даны в том же заголовочном файле.
Для работы с виртуальной таблицами виртуальной памяти в некоторой области памяти хранятся указатели на все PGD. При этом каждая задача хранит в себе контекст struct mmu_context, который, по сути, является индексом в этой таблице. Таким образом, к каждой задаче относится одна таблица PGD, которую можно определить с помощью mmu_get_root(ctx).
Страницы и работа с ними
Размер страницы
В реальных (то есть не в учебных) системах используются страницы от 512 байт до 64 килобайт. Чаще всего размер страницы определяется архитектурой и является фиксированным для всей системы, например — 4 KiB.
С одной стороны, при меньшем размере страницы память меньше фрагментируется. Ведь наименьшая единица виртуальной памяти, которая может быть выделена процессу — это одна страница, а программам очень редко требуется целое число страниц. А значит, в последней странице, которую запросил процесс, скорее всего останется неиспользуемая память, которая, тем не менее, будет выделена, а значит — использована неэффективно.
С другой стороны, чем меньше размер страницы, тем больше размер страничных таблиц. Более того, при отгрузке на HDD и при чтении страниц с HDD быстрее получится записать несколько больших страниц, чем много маленьких такого же суммарного размера.
В дальнейшем речь пойдёт о страницах обычного размера.
Устройство Page Table Entry
В реализации проекта Embox тип mmu_pte_t — это указатель.
Каждая запись PTE должна ссылаться на некоторую физическую страницу, а каждая физическая страница должна быть адресована какой-то записью PTE. Таким образом, в mmu_pte_t незанятыми остаются MMU_PTE_SHIFT бит, которые можно использовать для сохранения состояния страницы. Конкретный адрес бита, отвечающего за тот или иной флаг, как и набор флагов в целом, зависит от архитектуры.
Можно установить сразу несколько флагов:
Здесь vmem_page_flags_t — 32-битное значение, и соответствующие флаги берутся из первых MMU_PTE_SHIFT бит.
Трансляция виртуального адреса в физический
Как уже писалось выше, при обращении к памяти трансляция адресов производится аппаратно, однако, явный доступ к физическим адресам может быть полезен в ряде случаев. Принцип поиска нужного участка памяти, конечно, такой же, как и в MMU.
Для того, чтобы получить из виртуального адреса физический, необходимо пройти по цепочке таблиц PGD, PMD и PTE. Функция vmem_translate() и производит эти шаги.
Сначала проверяется, есть ли в PGD указатель на директорию PMD. Если это так, то вычисляется адрес PMD, а затем аналогичным образом находится PTE. После выделения физического адреса страницы из PTE необходимо добавить смещение, и после этого будет получен искомый физический адрес.
Пояснения к коду функции.
mmu_paddr_t — это физический адрес страницы, назначение mmu_ctx_t уже обсуждалось выше в разделе “Виртуальный адрес”.
С помощью функции vmem_get_idx_from_vaddr() находятся сдвиги в таблицах PGD, PMD и PTE.
Работа с Page Table Entry
Для работы с записей в таблице страниц, а так же с самими таблицами, есть ряд функций:
Эти функции возвращают 1, если у соответствующей структуры установлен бит MMU_PAGE_PRESENT
Page Fault
Page fault — это исключение, возникающее при обращении к странице, которая не загружена в физическую память — или потому, что она была вытеснена, или потому, что не была выделена.
В операционных системах общего назначения при обработке этого исключения происходит поиск нужной странице на внешнем носителе (жёстком диске, к примеру).
Выталкивание страниц во внешнюю память и их чтение в случае page fault не реализовано. С одной стороны, это лишает возможности использовать больше физической памяти, чем имеется на самом деле, а с другой — не является актуальной проблемой для встраиваемых систем. Нет никаких ограничений, делающих невозможной реализацию данного механизма, и при желании читатель может попробовать себя в этом деле 🙂
Выделение памяти
Для виртуальных страниц и для физических страниц, которые могут быть использованы при работе с виртуальной памятью, статически резервируется некоторое место в оперативной памяти. Тогда при выделении новых страниц и директорий они будут браться именно из этого места.
Исключением является набор указателей на PGD для каждого процесса (MMU-контексты процессов): этот массив хранится отдельно и используется при создании и разрушении процесса.
Выделение страниц
Итак, выделить физическую страницу можно с помощью vmem_alloc_page
Функция page_alloc() ищет участок памяти из N незанятых страниц и возвращает физический адрес начала этого участка, помечая его как занятый. В приведённом коде virt_page_allocator ссылается на участок памяти, резервированной для выделения физических страниц, а 1 — количество необходимых страниц.
Выделение таблиц
Тип таблицы (PGD, PMD, PTE) не имеет значения при аллокации. Более того, выделение таблиц производится также с помощью функции page_alloc(), только с другим аллокатором (virt_table_allocator).
Участки памяти (Memory Area)
После добавления страниц в соответствующие таблицы нужно уметь сопоставлять участки памяти с процессами, к которым они относятся. У нас в системе процесс представлен структурой task, содержащей всю необходимую информацию для работы ОС с процессом. Все физически доступные участки адресного пространства процесса записываются в специальный репозиторий: task_mmap. Он представляет из себя список дескрипторов этих участков (регионов), которые могут быть отображены на виртуальную память, если включена соответствующая поддержка.
brk — это самый большой из всех физических адресов репозитория, данное значение необходимо для ряда системных вызовов, которые не будут рассматриваться в данной статье.
ctx — это контекст задачи, использование которого обсуждалось в разделе “Виртуальный адрес”.
struct dlist_head — это указатель на начало двусвязного списка, организация которого аналогична организации Linux Linked List.
За каждый выделенный участок памяти отвечает структура marea
Поля данной структуры имеют говорящие имена: адреса начала и конца данного участка памяти, флаги региона памяти. Поле mmap_link нужно для поддержания двусвязного списка, о котором говорилось выше.
Отображение виртуальных участков памяти на физические (Mapping)
Ранее уже рассказывалось о том, как происходит выделение физических страниц, какие данные о виртуальной памяти относятся к задаче, и теперь всё готово для того, чтобы говорить о непосредственном отображении виртуальных участков памяти на физические.
Отображение виртуальных участков памяти на физическую память подразумевает внесение соответствующих изменений в иерархию страничных директорий.
Подразумевается, что некоторый участок физической памяти уже выделен. Для того, чтобы выделить соответствующие виртуальные страницы и привязать их к физическим, используется функция vmem_map_region()
В качестве параметров передаётся контекст задачи, адрес начала физического участка памяти, а также адрес начала виртуального участка. Переменная flags содержит флаги, которые будут установлены у соответствующих записей в PTE.
Основную работу на себя берёт do_map_region(). Она возвращает 0 при удачном выполнении и код ошибки — в ином случае. Если во время маппирования произошла ошибка, то часть страниц, которые успели выделиться, нужно откатить сделанные изменения с помощью функции vmem_unmap_region(), которая будет рассмотрена позднее.
Рассмотрим функцию do_map_region() подробнее.
Макросы GET_PTE и GET_PMD нужны для лучшей читаемости кода. Они делают следующее: если в таблице памяти нужный нам указатель не ссылается на существующую запись, нужно выделить её, если нет — то просто перейти по указателю к следующей записи.
В самом начале необходимо проверить, выровнены ли под размер страницы размер региона, физический и виртуальный адреса. После этого определяется PGD, соответствующая указанному контексту, и извлекаются сдвиги из виртуального адреса (более подробно это уже обсуждалось выше).
Затем последовательно перебираются виртуальные адреса, и в соответствующих записях PTE к ним привязывается нужный физический адрес. Если в таблицах отсутствуют какие-то записи, то они будут автоматически сгенерированы при вызове вышеупомянутых макросов GET_PTE и GET_PMD.
Освобождение виртуального участка памяти (Unmapping)
После того, как участок виртуальной памяти был отображён на физическую, рано или поздно её придётся освободить: либо в случае ошибки, либо в случае завершения работы процесса.
Изменения, которые при этом необходимо внести в структуру страничной иерархии памяти, производятся с помощью функции vmem_unmap_region().
Все параметры функции, кроме последнего, должны быть уже знакомы. free_pages отвечает за то, должны ли быть удалены страничные записи из таблиц.
try_free_pte, try_free_pmd, try_free_pgd — это вспомогательные функции. При удалении очередной страницы может выясниться, что директория, её содержащая, могла стать пустой, а значит, её нужно удалить из памяти.
нужны как раз для случая двухуровневой иерархии памяти.
Заключение
Конечно, данной статьи не достаточно, чтобы с нуля организовать работу с MMU, но, я надеюсь, она хоть немного поможет погрузиться в OSDev тем, кому он кажется слишком сложным.
Разбор Memory Forensics с OtterCTF и знакомство с фреймворком Volatility
Недавно закончился OtterCTF (для интересующихся — ссылка на ctftime), который в этом году меня, как человека, достаточно плотно связанного с железом откровенно порадовал — была отдельная категория Memory Forensics, которая, по сути, представляла из себя анализ дампа оперативной памяти. Именно ее я хочу разобрать в этом посте, всем кому интересно — добро пожаловать под кат.
Введение
Возможно, на Хабре уже были статьи, описывающие работу с Volatility, но, к сожалению, я их не нашел. Если не прав — киньте в меня ссылкой в комментариях. Эта статья преследует две цели — показать, насколько бессмысленны все попытки администратора защитить систему, в случае если у атакующего есть дамп оперативной памяти и познакомить читателей с самым прекрасным, на мой взгляд, инструментом. Ну и, конечно же, обменяться опытом. Достаточно воды, приступим!
Знакомство с инструментом
Из-за питона инструмент кроссплатформенный, поэтому проблем с запуском под какой-то популярной ОС, на которой есть питон возникнуть не должно. Фреймворк поддерживает огромное количество профилей (в понимании Volatility — системы, с которых был снят дамп): от популярных Windows-Linux-MacOs до «напрямую» списанных dd-дампов и дампов виртуальных машин (как QEMU, так и VirtualBox). По-моему, очень неплохой наборчик.
Мощь этого инструмента действительно потрясает — я наткнулся на него в момент отлаживания своего ядра для ARM’a и он прекрасно анализировал то, что я давал ему на вход
Как бонус — поддержка почти любого адресного пространства, которое можно себе вообразить.
Кажется, пиара получилось чуть больше, чем планировалось изначально. Давайте попробуем заняться самим анализом.
Базовая информация и поверхностный анализ
Для тех, кто хочет проделывать все манипуляции по ходу статьи — ссылка на Mega с образом или можно с помощью wget:
В нашем случае выхлоп будет примерно следующим:
Итак, мы получили почти исчерпывающую информацию о нашем дампе — предположительно, с какой ОС он был сделан (отсортировано в порядке вероятности), локальную дату и время на момент снятия дампа, адресацию и еще много чего. Итак, мы поняли, что перед нами дамп Windows 7 Service Pack 1 x64. Можно копать вглубь!
What’s the password
Так как это своеобразный райтап, то я буду давать формулировку задачи и потом описывать, как ее решить с помощью волатилити.
Первая задача — достать пароль пользователя
Прекрасно! Мы, предположительно, получили имя пользователя и, заодно, убедились, что нужные нам SYSTEM и SAM уже подгружены в память. Теперь просто достаем хеши и идем перебирать:
И сразу же получаем пароль пользователя:
General Info
Задача — достать IP-адрес и имя компьютера
Теперь, когда мы знаем, кто мы, надо бы понять, где мы. То есть хорошо бы узнать наш IP-адрес и имя машины. В случае с IP-адресом все просто — смотрим на список подключений на момент дампа с помощью netscan :
IP 192.168.202.131 найден. Конечно, это IP в локальной сети, но, к сожалению, из дампа больше не вытащишь — для того, чтобы достать внешний IP нужно побольше, чем просто дамп. Теперь достанем имя компа. Для этого просто прочитаем ветку SYSTEM реестра:
Play Time
Пользователь любит играть в старые видеоигры. Требуется найти название его любимой игры и IP-адрес ее сервера
Name game
Мы знаем, что пользователь залогинен в канал Lunar-3. Но какое имя аккаунта?
Так как пользователь залогинен в этот канал, то имя должно быть просто в виде plain-text в дампе. Делаем strings и получаем флаг:
Silly Rick
Наш пользователь всегда забывает свой пароль, поэтому он использует менеджер паролей и просто копирует нужный пароль, когда нужно войти. Может быть, вам удастся что-то узнать?
Hide and Seek
Причина тормозов компьютера в вирусе, который уже давно сидит в системе. Может быть, вы сможете его найти? Будьте осторожны, у вас только три попытки, чтобы сдать этот флаг!
Ну что же, если у нас три попытки, то будем осторожны, как нам и посоветовали =)
Для начала, получим список всех процессов с помощью pslist :
Ага! Есть подозрительные строчки
Как мы видим, процесс с PID’ом 3820 порождает процесс с PID’ом 3720. Повод проанализировать обоих. Для начала получим список dll-библиотек, которые используют процессы:
Так. Exe в папке с торрентами? Как-то странно. Еще и ntdll.dll тоже не внушает доверия. Попробуем получить список dll, которые использует процесс 3720:
Вау. А вот это совсем ненормально. Значит, первое предположение, что это именно тот троянчик, который мы ищем. Сдампим процесс с помощью memdump и проанализируем его любым декомпилятором:
Bit by Bit и Graphics is for the weak
Найдите адрес биткойн-кошелька злоумышленника, который заразил компьютер вирусом!
Recovery
Вымогатель зашифровал файлы. Помогите пользователю восстановить к ним доступ!
Немного пролистав, находим и ее:
Ну уже кое-что новое, теперь мы знаем, что длина пароля 15 символов. Попробуем вытащить его из дампа процесса и сразу же оценим, насколько все плохо:`
Неплохо. Можно, конечно, посидеть поперебирать ручками, но это как-то слишком. Применим немного черной магии!
Команда выглядит страшно, но стоит немного в нее вглядется и она становится кристально очевидной. Если это не так — опять-таки пинайте в комментариях, разберу по кирпичикам. А тем временем, мы сократили количество с миллиона до каких-то жалких трех тысяч. Посмотрим, что это за строки:
Итак, судя по этому выводу ключ где-то наверху предыдущего вывода. Первых строк, похожих на ключ не так много и тут действительно придется воспользоваться древним заклинанием BruteForce
Вместо заключения
Спасибо, что дочитали мою статью до конца. Если есть какие-то косяки или недочеты — просьба писать в комментарии, постараюсь все исправить. Это не все задачи, которые были связаны с этим образом. Я продолжаю решать эту серию и по мере своего продвижения буду добавлять новые решения. Надеюсь, каждый вынес для себя что-то новое. Так же, если все будет окей, то через некоторое время я смогу запустить у себя чекер флагов для этих задач и любопытные смогут порешать сами, а потом, если что-то не получится — глянуть на мои решения. Всем добра :3