Как стать автором
Обновить
24.87

Системное программирование *

Обеспечение работы прикладного ПО

Сначала показывать
Порог рейтинга
Уровень сложности

Консольное приложение readpe

Время на прочтение2 мин
Количество просмотров5.8K
В посте речь пойдет о консольной утилите ReadPE собственной разработки, которая парсит исполняемые файлы формата Portable Executable.

Отвечая на возможный вопрос: «Почему потребовался свой велосипед, если уже есть dumpbin?» скажу, что меня перестали удовлетворять многие известные утилиты подобного класса из-за их неспособности работать с хитровыдуманными и вручную созданными файлами. Взятые файлы входящие в известный набор Corkami и поданные на вход dumpbin, идущая в поставке с Visual Studio или pedump Мэтта Питрека в большинстве случаев откажутся работать с подобным файлом. Это связано с тем, что очень часто при написании подобных утилит опираются исключительно на официальное описание этого формата предоставляемого Microsoft. Несмотря на то, что сам формат достаточно простой, он тем не менее обладает весьма большим количеством подводных камней и лучшим руководством по этому формату является листинг кода из системного загрузчика в IDA Pro.

Читать дальше →

Хуки — это просто (часть 2)

Время на прочтение4 мин
Количество просмотров20K
image

Некоторое время назад я писал вводную статью о хуках (что это, зачем нужно, Hello world). Статья задумывалась простой, минималистичной и, вроде бы, такой и получилась. Единственный упрёк, который я услышал в комментариях — «Зачем же брать библиотеку Microsoft Detours, которая для коммерческого использования стоит 10 000$ ?». Замечание справедливое. В этой статье я приведу тот же пример с использованием другой библиотеки ценой примерно в 20 раз меньше (что уже вполне себе в рамках разумного) — madCodeHook.

Для лучшего понимания данной статьи рекомендуется сначала прочитать первую часть.
Читать дальше →

Сборщик мусора на С++

Время на прочтение12 мин
Количество просмотров60K
Привет, Хабр! Эту статью я задумал довольно давно. Речь в ней пойдет о простейшем копирующем сборщике мусора на С++. У него довольно много ограничений (часть не мешает, часть можно обойти, если задаться целью написать какую-то серьезную библиотеку, а для кое-чего неплохо было бы заиметь зачаточную поддержку от языка), зато и кода в нем чуть больше 100 строк. Заинтересовавшихся прошу под кат. Там минимум ООП, простейшие шаблоны и жуткие магические ритуалы с указателями.
Читать дальше →

MMU в картинках (часть 1)

Время на прочтение11 мин
Количество просмотров80K
Хочу поговорить об устройстве управления памятью (Memory Management Unit, MMU). Как вы, разумеется, знаете, основной функцией MMU является аппаратная поддержка виртуальной памяти. Словарь по кибернетике под редакцией академика Глушкова говорит нам, что виртуальная память — это воображаемая память, выделяемая операционной системой для размещения пользовательской программы, ее рабочих полей и информационных массивов.

У систем с виртуальной памятью четыре основных свойства:
  1. Пользовательские процессы изолированы друг от друга и, умирая, не тянут за собой всю систему
  2. Пользовательские процессы изолированы от физической памяти, то есть знать не знают, сколько у вас на самом деле оперативки и по каким адресам она находится.
  3. Операционная система гораздо сложнее, чем в системах без виртуальной памяти
  4. Никогда нельзя знать заранее, сколько времени займет выполнение следующей команды процессора

Выгода от всех вышеперечисленных пунктов очевидна: миллионы криворуких прикладных программистов, тысячи разработчиков операционных систем и несчетное число эмбеддеров благодарны виртуальной памяти за то, что все они до сих пор при деле.

К сожалению, по какой-то причине все вышеперечисленные товарищи недостаточно почтительно относятся к MMU, а их знакомство с виртуальной памятью обычно начинается и заканчивается изучением страничной организации памяти и буфера ассоциативной трансляции (Translation Lookaside Buffer, TLB). Самое интересное при этом остается за кадром.
Читать дальше →

Проблема 10 миллионов соединений

Время на прочтение1 мин
Количество просмотров26K
Несколько дней назад Роберт Грэм начал работу над серией статей C10M и планирует закончить работу в июле этого года.

Сегодня уже доступны следующие главы:
Читать дальше →

Модификация UEFI BIOS, часть вторая: полезные модификации

Время на прочтение7 мин
Количество просмотров148K
В этой статье я постараюсь рассказать о наиболее популярных и полезных модификациях UEFI BIOS, условиях их применения и способах поиска. Кроме этого, на описанной в первой части утилите UEFITool свет еще не сошелся клином, поэтому будут упомянуты и другие программы, используемые для модификации UEFI BIOS'ов различных производителей.
Если тема вам интересна — добро пожаловать под кат.
Ко второй части

Модификация UEFI BIOS, часть первая: знакомство с UEFITool

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

Как запустить программу без операционной системы: часть 5. Обращение к BIOS из ОС

Время на прочтение15 мин
Количество просмотров53K

В самой первой части нашей серии «Как запустить программу без операционной системы» мы остановились на том, что загрузили ядро с помощью GRUB’а и распечатали на экран классический “Hello World!”. Теперь мы покажем, как можно использовать прерывания BIOS’а в ядре ОС. А для начала — рассмотрим, что же такое прерывания BIOS’а, для чего они используются, и почему возникают проблемы с их вызовом.
Читать дальше →

Динамическое расширение ядра Linux — добавляем функцию «удалить в корзину»

Время на прочтение4 мин
Количество просмотров20K
Многим пользователям Linux, особенно тем, кто по тем или иным причинам перешёл на эту ОС с Windows, не хватает возможности удаления файлов «в корзину». Кроме того, наверняка, каждый, кто пользовался Linux'ом и по ошибке удалял какой-либо файл, испытывал смешанные чувства от отсутствия простой возможности восстановить утраченные данные.

В продолжение предшествующего материала, посвящённого перехвату функций ядра Linux, представляю способ использования разработанного ранее фреймворка для создания модуля ядра Linux, реализующего возможность удаления файлов «в корзину» (just for fun).

Читать далее

Как вынудить процесс использовать новый адрес DNS-сервера из обновлённого resolv.conf без перезапуска самого процесса

Время на прочтение4 мин
Количество просмотров13K
Я работаю системным администратором Unix. Однажды к нам в отдел эксплуатации сервисов упал тикет от программиста с выдержой из лога application-сервера в заголовке: "pgbouncer cannot connect to server". Посмотрев логи pgbouncer'ов, я увидел, что периодически возникают lookup fail'ы при обращении к нашим DNS. Было установленно, что это связано не с работой наших DNS-серверов, а с ненадёжностью самого протокола UDP: иногда возникают потери пакетов по разным причинам.
image
В результате, было решено установить на каждом сервере с pgbouncer'ами по кэширующему BIND. И тут возникла интересная проблема: pgbouncer не перечитывал по сигналу HUP файл /etc/resolv.conf и продолжал обращаться к старым DNS-серверам. А перезагружать баунсеры категорически нельзя: есть проблемные проекты, которые очень болезненно относятся к разрывом сессий с базой.

В данной статье я расскажу как можно pgbouncer или любую другую программу, использующую библиотечный вызов getaddrinfo(), заставить перечитать resolv.conf и начать использовать новый DNS-сервер совершенно безболезненно для клиентов (без даунтайма).
Читать дальше →

Перехват функций ядра Linux с использованием исключений (kprobes своими руками)

Время на прочтение8 мин
Количество просмотров15K
Перехват функций ядра является базовым методом, позволяющим переопределять (дополнять) различные его механизмы. Исходя из того, что за исключением небольших архитектурно-зависимых частей, ядро Linux почти полностью написано на языке C, можно утверждать, что для осуществления встраивания в большинство из компонентов ядра, достаточно иметь возможность перехвата соответствующих функций ЯВУ, реализующих ту или иную логику.

Данная статья является практическим обобщением представленных ранее статей:
  1. Управляемый PageFault в ядре Linux
  2. Кошерный способ модификации защищённых от записи областей ядра Linux

Далее будет рассмотрено каким образом использование данных материалов может быть применимо в обеспечении возможности перехвата функций ядра Linux.
Читать далее

Улучшение степени сжатия применяемого в UPX

Время на прочтение5 мин
Количество просмотров11K
От переводчика:

Под «капотом» следует перевод небольшого, но крайне полезного текстового файла "%UPX_SOURCE%\doc\filter.txt". В приведенном пути под UPX_SOURCE подразумевается файловый путь до исходных кодов к UPX версии 3.91.

Документ описывает достаточно важный аспект работы UPX называемый «фильтрацией» и при анализе упакованных с помощью UPX файлов крайне важно понимать как это работает. Все что описано про UPX также применимо и к другим упаковщикам.

Основная цель перевода это попытка помочь тем программистам кто пишет статические распаковщики исполняемых файлов. Другими словами эта информация будет полезной практикующим reverse-engineer-ам. Под статичеческим распаковщиком понимаю программу которая поданный на вход упакованный или запротекченный исполняемый файл анализирует и создает на выходе файл, как будто бы тот создан каким-либо компилятором. Особенностью такого типа распаковщиков в том что он работает исключительно на знании структуры защиты или упаковки файла, т.е. без применения «сброса дампа», «востановления импорта» и др. типов «читерства».

Понимание процесса фильтрации помогает при изучении упакованных файлов к примеру с помощью UPX, RLPack и др. В упакованных файла можно встретить код, где делаются некоторые «магические действиями» с маш. инструкциями переходов байты 0xE8, 0xE9 и др. Этой «магией» как раз и является «фильтрация». Она направлена на улучшение степени сжатия исполняемого файла.

Также знание о том как работает фильтрация может сохранить время специалиста в весьма сложных ситуациях. Бывает так, что получить кусок кода с фильтрацией за разумный срок вовсе невозможно, к примеру при работе с полиморфиками или с файлами где применяется виртуализация кода. Тогда знание о том как работает фильтрации позволит решить задачу по написанию кода дефильтрации без имения точного оригинального куска кода.

Почитать про фильтрацию в UPX

Кошерный способ модификации защищённых от записи областей ядра Linux

Время на прочтение4 мин
Количество просмотров11K
Те, кто хоть однажды сталкивался с необходимостью поменять что-то в ядре на лету не понаслышке знают, что данный вопрос требует детальной проработки, ведь страницы памяти ядра, хранящие код и некоторые данные, помечены как «read-only» и защищены от записи!

Для x86 известным решением является временное отключение страничной защиты посредством сброса бита WP регистра CR0. Но следует применять это с осторожностью, ведь страничная защита является основой для многих механизмов ядра. Кроме того, необходимо учитывать особенности работы на SMP-системах, когда возможно возникновение разных неприятных ситуаций.

Читать далее

Ближайшие события

Экспоненциальный алгоритм сильно замедляет Windows XP

Время на прочтение2 мин
Количество просмотров83K
Разработчик отдела Windows Update Даг Нил (Doug Neal) объяснил, почему в последнее время многие пользователи Windows XP испытывают проблемы с производительностью после установки свежих обновлений.

Как показало изучение логов с «заторможенных» машин, проблема заключается в неэффективном методе, которым модуль Windows Update Agent обрабатывает длинные списки предшествующих апдейтов. Время обработки списков возрастает экспоненциально с каждым новым апдейтом. Другими словами, обработка нового обновления занимает вдвое больше времени, чем предыдущего.

За историю Windows XP было выпущено огромное количество патчей, так что при обработке списка из 40+ старых апдейтов процесс svchost.exe начинает потреблять много ресурсов CPU, и это заметно отражается на общей производительности системы.
Читать дальше →

Простая маскировка модуля ядра Linux с применением DKOM

Время на прочтение5 мин
Количество просмотров11K
Как известно, задача сокрытия модуля ядра от вездесущих «глаз» пользователя может иметь множество приложений. В данной статье рассматривается применение DKOM (Direct Kernel Object Manipulation) — одной из техник, позволяющий осуществить сокрытие информации посредством модицикации внутренних структур ядра.

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

Читать далее

Управляемый PageFault в ядре Linux

Время на прочтение7 мин
Количество просмотров14K
Обработка исключений занимает важное место в процессе функционирования программных систем. Действительно, обеспечение своевременной и правильной реакции на нештатные события является одной из ключевых задач, выполняемых операционной системой и, в особенности, её ядром. Будучи современным, ядро Linux предоставляет возможность управления процессом обработки исключений, однако ввиду ограниченности его интерфейса, данный механизм не является распространённым среди разработчиков модулей ядра.

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

Читать далее

Стражи ночи

Время на прочтение9 мин
Количество просмотров82K
Будучи высококвалифицированным исследователем, я потратил немало времени на продвижение науки вперёд. Но я родился на Юге и искренне убеждён, что прогресс — это выдумка, и что нужно готовиться к Судному дню, к жатве того, что мы посеяли и к появлению быстрых зомби, медленных зомби, и даже вежливых зомби, которые обращаются к вам «сэр» или «мадам», но в итоге пытаются съесть ваш мозг дабы заполучить ваши навыки. Когда нагрянет революция, нужно быть готовым; поэтому в моменты тишины и покоя, когда я не произвожу очередной прорыв в науке, я размышляю над тем, что же я буду делать, когда прогноз погоды изменится на «РЕКИ КРОВИ ЦЕЛЫЙ ДЕНЬ ДО СКОНЧАНИЯ ВРЕМЁН».

В основном я думаю о тех, кто будет прикрывать мою спину, поскольку шансы на выживание в постапокалиптическом мире напрямую зависят от размера и качества того сброда, который вы будете называть своей командой. Очевидно, мне понадобятся: слесарь (чтобы двери вскрывать), эксперт‐подрывник (если уж у слесаря закончатся идеи) и конечно же тот парень, что отловит, выдрессирует и затем будет швырять змей в моих врагов (потому что в мире умершей надежды бросок змеёй — это разумный способ урегулирования разногласий). В сией антиутопии они помогут мне прослыть воинствующим философом.

Но! Но… Самым важным членом моей банды будет системный программист, ибо в гоббсовском кошмаре невероятных масштабов умеющему отладить драйвер устройства или распредёленную систему человеку можно доверять; системный программист видел ужасы Вселенной и понимает безысходность бытия. Системный программист писал драйверы для устройств, прошивку которых создавал то ли пьяный ребёнок, то ли трезвый карась. Системный программист отлавливал проблему с сетью через восемь машин, три часовых пояса и с дружеским визитом в Омск, откуда ее перенаправили в левое переднее копыто той лошади, что избавила Трою от перенаселения.1 Системный программист читал исходники ядра для лучшего понимания процессов мироздания и видел комментарий «И ЭТО РАБОТАЕТ ЛОЛ» в коде планировщика, и не смеялся он, но плакал; и отправил он патч ядра для восстановления баланса Силы и устранения инверсии приоритетов, что приводила к зависанию MySQL. Системный программист знает, что делать, когда общество падёт, потому что он уже живет в мире, где царит беззаконие.
Читать дальше →

Изучаем netfilter: пишем свой match-модуль на базе xt_string для поиска нескольких шаблонов

Время на прочтение11 мин
Количество просмотров9.8K

Введение


Недавно заметил, что на хабре мало информации по разработке модулей ядра. Всё что я нашёл:


Всегда удивляло то, что люди, более-менее знающие C, боятся и избегают даже читать ядерный код, как будто он на 60% состоит из ассемблера (который на самом деле тоже не такой уж сложный). Собственно я планирую написать серию статей, посвящённую разработке или доработке существующих модулей netfilter и iptables.

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

Что будем делать


Как сказано в названии статьи — мы напишем простой модуль iptables на базе xt_string. Xt_string — это модуль netfilter, умеет искать последовательность байт в пакете. Однако ему, на мой взгляд, не хватает способности осуществлять поиск нескольких последовательностей байт в заданном порядке. Ну, а так как лицензия GPL, то что мешает ему эту возможность придать?
И таки придаём!

Предотвращаем участие в dns amplification attack или опыт написания ядерного кода

Время на прочтение6 мин
Количество просмотров14K
Введение

В этой статье я хочу рассказать о достаточно очевидном, как мне кажется, способе фильтрации dns amplification attack, и о небольшом модуле, который был написан для реализации идеи.

О том, что такое dns amplification attack, писалось уже не раз, например здесь; многие с этим сталкивались, многие боролись, кто-то более успешно, кто-то менее. Атака строится на отправке DNS запроса к какому либо DNS серверу с подставленным ip адресом источника, равным ip адресу жертвы. Ответ от DNS сервера практически всегда больше, чем запрос, особенно учитывая, что атакующим обычно выполняется ANY запрос. AAAA записи — уже не редкость, SPF и другая информация в TXT записях, все это позволяет достаточно легко получить усиление в 5 и даже более раз. Для атакующего это выглядит очень заманчиво, можно устроить хороший dos, даже не имея большого ботнета. Можно очень долго рассуждать, почему возможен спуфинг ip адресов в Интернете, но реалии таковы, что он все еще возможен, поэтому на сегодняшний день задача затруднить использование своих DNS серверов в проведении подобных атак представляется весьма актуальной. Замечу также, что в данной атаке возможно использовать как авторитативные dns сервера, так и публичные резольверы; предлагаемое решение тоже может использоваться в обоих случаях.
Читать дальше →

Особенности встраивания в ключевые механизмы ядра Linux с использованием LSM

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

Среди способов встраивания в ядро Linux стоит отметить способ, основанный на использовании фреймворка Linux Security Modules (далее, LSM), предназначенного для интеграции различных моделей безопасности, служащих целью расширения базовой дискреционной модели безопасности Linux (DAC).
Читать дальше →

Вклад авторов