И вот я послал в Уxt4 Dev List настолько плохой патч, что мне посоветовали прочитать это
Просто кусок кода, который определяет является ли число степенью двойки.
if ((blocksize & (blocksize - 1)) != 0) {
fprintf(stderr,
"%s: blocksize %lu not a power-of-two value\n",
progname, blocksize);
return EINVAL;
}
]]>
Несмотря на то, что я отдалился от дел команды «Ufologists», я остаюсь ее большим болельщиком, и потому безмерно рад новости, которой хочу поделиться. В самом событии участия я не принимал (даже как наблюдатель), потому процитирую официальные новости университета.
Команда ТТИ ЮФУ «UFOlogists» заняла 5 место из 80возможных в отборочных соревнованиях IFSF CTF!
В преддверии Дня компьютерщика были проведены отборочные соревнования по информационной безопасности IFSF CTF.
На протяжении 36-ти часов в режиме онлайн команда Таганрогского технологического института Южного федерального университета «UFOlogists» решала задания по криптографическому анализу, администрированию сетей, реверс-иженерингу исполняемых файлов и поиску уязвимостей веб-приложений. В упорной борьбе с более чем 80-ю командами из разных уголков света наша команда заняла 5-е место, тем самым обеспечив себе приглашение в Тунис для проведения финальной части соревнований.
Так же в финал попали ещё три команды из России («More Smoked Leet Chicken» СпбГУ ИТМО, «MiT» Челябинского Государственного Университет в г.Миасс и «rdot.org» ), две команды из Франции («Big-Daddy», «Zenk-Security»), Нидерландов («Eindbazen») и столь известная в CTF-ных кругах команда из США «PPP» Carnegie Mellon University.
Стоит отметить, что IFSF CTF — это первые заграничные соревнования по информационной безопасности столь крупного масштаба, в которых команда «UFOlogists» была приглашена на очную часть в финал.
От себя скажу, что это самое значимое достижения движения CTF в ТТИ ЮФУ. Поздравляю ребят от всей души. Желаю победы в финале!
]]>Уважаемые коллеги,
1 декабря я буду защищать свой труд на тему «Разработка метода, алгоритмов и программ для автоматического поиска уязвимостей в ПО без исходного кода». Многое из того, о чем я писал в этом блоге, вошло в диссертацию. Идеи, задумки, алгоритмы и код, обросли обзорами, выводами и прочими формально нужными вещами и получилась диссертация.
У меня есть просьба к всем тем, кто работает в той же области знаний, что и я, либо в областях смежных. Если до 1 декабря (но чем раньше, тем лучше) у вас есть пол часа свободного времени и желание ознакомиться с моей работой (или желание помочь мне), то прочтите мой автореферат, который находится здесь и напишите свое мнение о нем. Мнения, помогут мне, если они будут в одной из следующих форм:
Ну и разумеется буду рад услышать любое мнение о моей работе (так же через любой из доступных видов связи).
Мой адрес: artem.blagodarenko(c)gmail.com
С уважением, Артем Васильевич Благодаренко
]]>Так уж получилось, что я по большей части «фаззю для того что бы фаззить». Спортивный интерес. Однако, для того что бы отделить обычные сбои от сбоев, которые могут привести к уязвимости безопасности, полезно представлять текущее положение в деле выявления возможных уязвимостей. Поэтому я написал небольшой обзор. На полноту он не претендует, но для «погружения в тему», думаю, сойдет.
Сбой в работе тестируемой программы не всегда является уязвимостью безопасности. В общем случае программный сбой относится к качеству ПО. Сбой становится уязвимостью, когда он дает одну из следующих возможностей:
Вопрос автоматической классификации сбоев по рискам безопасности интересует многих исследователей [1,2,3]. Главный вопрос, который приходится решать при подобной автоматической классификации: могут ли данные, приведшие к сбою, быть изменены посредством пользовательского ввода. К примеру, предположим, что сбой произошел на следующей инструкции: call [eax]. Исключение 0xc0000005 — STATUS_ACCESS_VIOLATION. Произошла попытка обращения к неверному участку памяти. В случае если значение регистра eax равно NULL и логика программы не дает возможность изменить содержимое данного регистра, максимальное последствие к которому может привести сбой – отказ обслуживания. Другое дело, если значение регистра можно изменить (например, в результате переполнения). В этом случае это уже потенциальная возможность передачи управления на заданный адрес.
Наиболее распространенный вид сбоев – необработанное программное или аппаратное исключение. В таблице ниже приведены виды исключений и риски безопасности при данном виде сбоя[2] .
| Исключение | Возможна ли эксплуатация | Комментарий |
| Нарушение прав доступа для операции записи | Практически всегда | Попытка записи в область памяти не разрешенную для записи |
| Нарушение прав доступа для операции чтения на указателе команды (нарушение прав доступа на EIP) | Практически всегда | Есть возможность установить EIP на заданный участок памяти |
| Нарушение прав доступа для операции чтения | Возможна | В случае если исключение происходит при копировании с префиксом rep при большом ecx или, если читаемое значение позже используется как счетчик |
| Не возможна | При чтении по нулевому адресу или по неизменяемому адресу | |
| Деление на нуль | Не возможна | Если обработчик не подменен |
| Исключение C++ | Не возможна | Если обработчик не подменен |
Таким образом, при анализе сбоя на предмет возможности эксплуатации можно пользоваться схемой, изображенной на рисунке 1.
Рисунок 1 – Схема анализа сбоя на возможность эксплуатации[2]
Задача автоматического определения возможности влияния пользовательскими данными на данные, приводящие к сбою, успешно решается с помощью taint-анализа[3]. Суть метода заключается в анализе параметров инструкций и оценке их влияния друг на друга. В качестве параметров инструкции могут выступать следующие контейнеры:
Параметры, явные и неявные, разделяются на входные и выходные. Значение контейнеров входных параметров получается либо на предыдущих шагах программы, либо являются константами. Любые данные получаемые от пользователя (через поля ввода, из фалов, из сети) считаются не доверительными, контейнеры в которые они располагаются, помечаются. Далее, если помеченные контейнеры участвуют в операции и влияют на результат, то контейнер результата так же получает метку. Метка может быть отменена, если в контейнер будут помещены данные из непомеченного контейнера. Рассмотрим пример:
mov ebx, eax
add ecx, ebx
xor eax, eax
mov [ecx],9090h
Будем считать, что регистр eax получил свое значение из пользовательского ввода (например, через параметр функции), а значит он автоматически помечается. Оператор mov ebx, eax копирует значение регистра eax в ebx. После этой операции ebx так же следует пометить. Оператор xor eax, eax действует так же как mov eax, 0. В eax помещается значение, на которое априори не может повлиять пользовательский ввод. С этого момента регистр eax теряет метку. Однако ecx все еще отмечен и по этой причине команда mov [ecx], 9090h является уязвимым местом, она позволяет записать 9090h (две операции nop) в область памяти, которую можно задать через пользовательский ввод.
Taint-анализ используется во многих утилитах[1, 3, 5]. Для анализа дампов сбоев такой анализ используется в модуле !exploitable[ 1 ] для отладчика WinDbg компании Microsoft. Модуль позволяет выполнить следующие основные функции:
Другой модуль для того же отладчика vdt_trace[3] позволяет отследить поток данный и предоставляет данные необходимые для подготовки эксплоита.
Я вернулся с РусКрипто 2011. Ощущений море. Напишу здесь коротко именно о докладе. В целом — очень понравилось. Понравилось, что были люди, с которыми можно было поговорить по теме. Это счастливая случайность, наверное, потому что конференция в большей степени криптографическая.
По сравнению с предыдущими секциями, где фирмы и организации порой «кусали» друг друга, секция «Реверсинг. Анализ исполняемого кода и технологии защиты» выглядела как дружеская беседа. Доклад слушали, задавали вопросы. Было интересно. Потом была возможность пообщаться подробнее с остальными докладчиками секции Алексеем Чиликовым и Маньковом Евгением.
Выкладываю сюда презентацию с доклада. Позже она появиться и на сайте конференции, но думаю это произойдет не сразу. Снимали и видео. Не знаю, может и оно появится на сайте. Все что было на слайдах упоминалось так или иначе в этом блоге. Если нужно что-то пояснить, то отвечу на любые вопросы. Проверить правдивость сказанного в презентации можно на последней версии dataflow.
Спасибо кафедре БИТ ТТИ ЮФУ за возможность участвовать в конференции, организаторам РусКрипто 2011 за интересное событие, докладчикам секции за интересные доклады, посетившим секции за интерес и мнения.
]]>Буквально только что закончились отборочные РусКрипто CTF 2011 и я не могу не похвастаться Ufologists едут на финал! Ребята уступили лишь HackerDom ( им уступить не стыдно
) в стратегической борьбе «пости ответы меньше будешь выше». О правиле узнали лишь после того, как оказались на второй позиции, иначе бы не упустили своей позиции.
В финале оказались:
1) HackerDom (Уральский государственный университет им. А.М. Горького, г. Екатеринбург)
2) Ufologists (Технологический Институт Южного Федерального Университета в г. Таганроге, г. Таганрог)
3) [Censored] (Балтийский федеральный университет имени И. Канта, г. Калининград)
4) SiBears (Томский государственный университет, г. Томск)
5) Bushwhackers (Московский государственный университет имени М.В. Ломоносова, г. Москва)
Поздравляю команды и до встречи в финале!
Описание задания T4 в блоге Антона Речкова.
]]>Конференция РусКрипто’2011 пройдет с 30 марта по 2 апреля в Московской области в гостиничном комплексе «Солнечный Park Hotel & SPA 4*». Конференция посвящена компьютерной безопасности. Есть секции по общим вопросам, по криптографии, по безопасности интренета, по учебе, по академическим проектам и по реверсивной инженерии.
В последней секции с докладом буду выступать я. Тема моего доклада: «Выбор точки внедрения для фаззинга в памяти». Официальная аннотация:
В данной работе предлагается алгоритм выбора точки программы для тестирования методом черного ящика. На основе статического и динамического анализа собираются данные о связях функций. Анализ связей позволяет построить рейтинг потенциального покрытия кода при тестировании методом черного ящика, начиная с заданной точки.
Доклад планирую немного расширить относительно заданной темы. Расскажу о фаззинге в памяти, о том какие проблемы возникают. Расскажу о том, что я сделал, чтобы фаззить в памяти стало легче, ну и о выборе точки внедрения. Примеры.
В программе конференций насторожило количество докладов в моей секции ( всего 3! ). Возможно, остальные участвуют в конкурсе докладов и появятся позже? Знаю так же, что точно намечается интересный анализ сканеров SQL-инъекций от Андрея Петухова.
Так же в рамках конференции будут соревнования CTF. Кто будет участвовать в финале пока не известно, так как отборочные 18 марта в пятницу. В отборочных примут участие две команды с нашего университета: Ufologists и BitOn. Удачных флагов!
]]>MSR ( model specific register ) — регистры процессора специфичные для данного типа процессора.
Virtual Box — программное обеспечение для виртуализации.
Virtual Box 4.0.4 и более ранние версии игнорируют большинство регистров MSR. Хотя мог бы разрешать доступ к регистрам хостовой системы. Однако, процессоров много и каждый имеет свой собственный набор регистров MSR и потому проще запретить все, что не относится к стандартному набору, так безопаснее.
Иногда хочется запустить в виртуальной машине и отладить что-нибудь, что работает с MSR. При этом, например, известно какие регистры нужно использовать и насколько безопасно их использовать из виртуальной машины. Если бы нужно было бы использовать VMWare, то с мыслю этой пришлось бы попрощаться( если конечно не мил подход реверсить-патчить-реверсить-патчить). Но, к счастью, Virtual Box предоставляется с исходниками. Правда только Virtual Box OSE. Не беда, будем использовать его. А именно две версии: 3.2.8 ( стандартный для Ununtu 10.10 ) и 4.0.4 ( последняя версия на момент написание текста ). Сразу же предупрежу: НЕ ПЫТАЙТЕСЬ СОБРАТЬ VIRTUAL BOX НА WINDOWS. Я потратил на это неблагодарное дело 4 дня и не добился результатов. Попробовал в Linux — сразу же все получилось. На Windows пытался качать, устанавливать миллион зависимостей, пока не наткнулся на ветку форума, где в итоге было сказано «мы используем свои внутренние тулзы для сборки дистрибутивов для Windows. Мило …
Так вот, под Linux все просто. Делаем все по инструкции. Пробовал для i386 и x64. Продукт собирается и запускается.
Перейдем теперь непосредственно к тому, что патчить. Путем простых умозаключений стало понятно, что если что-то править то в файле src/VBox/VMM/VMMR0/HWVMXR0.cpp. Путь у него и имя говорящие. Номера регистров для вашего процессора можно найти в мануле от «Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2«. Для моего i3 я получил значения, общие для всего семейства i7
#define MSR_LASTBRANCH_TOS 0x1c9 #define MSR_LASTBRANCH_0_FROM_IP 0x680 #define MSR_LASTBRANCH_1_FROM_IP 0x681 #define MSR_LASTBRANCH_2_FROM_IP 0x682 #define MSR_LASTBRANCH_3_FROM_IP 0x683 #define MSR_LASTBRANCH_4_FROM_IP 0x684 #define MSR_LASTBRANCH_5_FROM_IP 0x685 #define MSR_LASTBRANCH_6_FROM_IP 0x686 #define MSR_LASTBRANCH_7_FROM_IP 0x687 #define MSR_LASTBRANCH_8_FROM_IP 0x688 #define MSR_LASTBRANCH_9_FROM_IP 0x689 #define MSR_LASTBRANCH_10_FROM_IP 0x68a #define MSR_LASTBRANCH_11_FROM_IP 0x68b #define MSR_LASTBRANCH_12_FROM_IP 0x68c #define MSR_LASTBRANCH_13_FROM_IP 0x68d #define MSR_LASTBRANCH_14_FROM_IP 0x68e #define MSR_LASTBRANCH_15_FROM_IP 0x68f #define MSR_LASTBRANCH_0_TO_IP 0x6c0 #define MSR_LASTBRANCH_1_TO_IP 0x6c1 #define MSR_LASTBRANCH_2_TO_IP 0x6c2 #define MSR_LASTBRANCH_3_TO_IP 0x6c3 #define MSR_LASTBRANCH_4_TO_IP 0x6c4 #define MSR_LASTBRANCH_5_TO_IP 0x6c5 #define MSR_LASTBRANCH_6_TO_IP 0x6c6 #define MSR_LASTBRANCH_7_TO_IP 0x6c7 #define MSR_LASTBRANCH_8_TO_IP 0x6c8 #define MSR_LASTBRANCH_9_TO_IP 0x6c9 #define MSR_LASTBRANCH_10_TO_IP 0x6ca #define MSR_LASTBRANCH_11_TO_IP 0x6cb #define MSR_LASTBRANCH_12_TO_IP 0x6cc #define MSR_LASTBRANCH_13_TO_IP 0x6cd #define MSR_LASTBRANCH_14_TO_IP 0x6ce #define MSR_LASTBRANCH_15_TO_IP 0x6cf
Вставить дефайны можно где-нибудь в обозначенном файле. Номера регистров есть. Теперь нужно дать указание Virtual Box «прокидывать» их в хост.
/* Nehalem family DEBUG MSRs */ vmxR0SetMSRPermission(pVCpu, MSR_IA32_DEBUGCTL, true, true); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_TOS, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_0_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_1_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_2_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_3_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_4_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_5_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_6_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_7_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_8_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_9_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_10_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_11_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_12_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_13_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_14_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_15_FROM_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_0_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_1_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_2_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_3_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_4_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_5_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_6_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_7_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_8_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_9_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_10_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_11_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_12_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_13_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_14_TO_IP, true, false); vmxR0SetMSRPermission(pVCpu, MSR_LASTBRANCH_15_TO_IP, true, false);
Параметры «true, false» означают доступ для чтения, если нужна запись, то добавляем «true, true». Вставляем их в группу подобных вызовов.
Теперь можно пересобрать, перезагрузить драйвера и все должно работать.
Что бы упросить задачу выкладываю патчи для virtual box 3.2.8 и virtual box 4.0.4. Качаем их в папку с исходниками и выполняем: patch -p1 < virtualbox-ose_3.2.8-dfsg-enable-MSR-i7.diff или patch -p1 < VirtualBox-4.0.4_OSE-enable-MSR-i7.diff.
]]>Цель: создание инструмента для изменения покрытия кода программы.
Ограничение: имеется только исполняемый код, исходных кодов нет.
Требования: простота, скорость, точность.
Что нам может предложить процессор
Процессоры Intel предоставляют специальные возможности для отладки и измерения эффективности приложений[Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A: System Programming Guide, Part 1 ]. Доступ к ним осуществляется через регистры DB0-DB7, а так же через ряд специфичных для модели процессора регистров (MSR). Следующие основные возможности предоставляются:
Исключение отладки (#DB) обрабатывает вектор прерывания int 1. Здесь отладчики уровня ядра размещают свой код, реализующий логику отладки. Для определения причины исключения используется регистр статуса отладки (DR6). Процессор генерирует исключение отладки во время исполнения инструкции при условии, что взведен флаг TF в регистре EFLAGS. Данное исключение является «исключением-ловушкой»(trap), потому что генерируется после того, как инструкция была исполнена. Процессор не генерирует исключение после инструкций, которые устанавливают флаг TF. К примеру, исключение не произойдет после инструкции POPF. Процессор очищает флаг TF перед тем, как вызывать обработчик int 1. В случае, если одновременно вызываются два прерывания (int 3 и int 1), то прерывание int 1 будет обрабатываться первым.
Особый интерес представляют специальные возможности процессора для отслеживания последних ветвей исполнения. На рисунке ниже дан пример дизассемблированного кода, представленного в виде линейных блоков ( ветвей ) и связей между ними.
Впервые возможность устанавливать точки останова на заданные ветви, прерывания, исключения, а так же при переходе от одной ветви к другой была введена в процессоры семейства P6. Данная возможность была улучшена в следующих процессорах: Pentium 4, Intel Xeon, Pentium M, Intel® CoreTM Solo, Intel® CoreTM Duo, Intel® CoreTM2 Duo, Intel® CoreTM i7, а так же Intel® AtomTM. Данные процессоры имеют схожий набор функционала по отслеживанию ветвей. Различаться могут размер стека для хранения данных о последних ветвях LBR, а так же набор аппаратно специфичных регистров, используемых для управления возможностями. Далее в тексте, будет дано общее описание возможностей процессоров вышеперечисленных семейств. Специфичные возможности и параметры будут представлены на примере процессора Intel Core i7.
MSR-регистр IA32_DEBUGCTL предоставляет собой битовое поле для управления расширенными возможностями отладки. Регистр имеет номер 01D9h и содержит следующие важные биты (для всех поддерживаемых процессоров):
В случае, если флаг LBR (bit 0) из регистра IA32_DEBUGCTL MSR установлен, процессор начинает автоматически записывать данные об исполненных ветвях, прерываниях и исключениях в стеке регистров MSR LBR. Когда процессор генерирует исключение отладки (#DB), он автоматически очищает флаг LBR до запуска обработчика исключения. Стек MSR-регистров при этом не очищается, что позволяет проводить анализ сохраненных значений. Если LBR сброшен, а TR установлен, то процессор продолжает заполнять LBR, потому что данный стек используется при генерации BTM. Прерывание #DB не очищает данный флаг автоматически.
Процессоры семейства i7 (ядро Nehalem) предоставляют 16 пар регистров MSR[Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3B: System Programming Guide, Part 2 ] для сохранения данных о последних исполненных ветвях кода. Формат данных в регистрах, содержащих значение о месте программы, откуда было передано управление, представлено в следующей таблице.
| Битовое поле | Битовое смещение | Доступ | Описание |
| Data | 47:0 | чтение | Адрес, откуда было передано управление |
| SIGN_Ext | 62:48 | чтение | Знаковое расширение данного регистра |
| MISPRED | 63 | чтение | Устанавливается, если переход бы предсказан |
Формат данных в регистрах, содержащих значение о месте программы, куда было передано управление, отличается от представленного выше отсутствием поля MISPPRED.
Текущее положение в стеке хранится в регистре MSR_LASTBRANCH_TOS. Номера специфичных для i7 регистров представлены в следующей таблице.
| Номер | Имя | Описание |
| 1C9h | MSR_LASTBRANCH_TOS | Указатель стека LBR |
| 680h | MSR_LASTBRANCH_0_FROM_IP | Часть стека LBR (первый элемент), содержащая адрес памяти, из которого был совершен переход |
| 6C0h | MSR_LASTBRANCH_0_TO_IP | Часть стека LBR (первый элемент), содержащая адрес памяти, на который был совершен переход |
Что с этим можно сделать
Наиболее точным способом зафиксировать каждую исполненную процессором инструкцию (а именно эта статистика, фактически, является оценкой покрытия кода) было бы трассировать каждый шаг исполнения процессора. Для этих целей в современных процессорах семейства PC используется флаг трассировки. Однако, применение данного способа связано с большими накладными расходами на обработку исключений на каждом шаге процессора, что приводит к невозможности использования его для оценки реальных приложений.
Существует возможность уменьшить накладные расходы путем инициирования исключения трассировки только в начале каждого линейного блока. Линейный блок, получивший управление, считается покрытым, так как в его пределах нет инструкций передачи управления и, следовательно, каждая его инструкция будет исполнена. Таким образом, данный подход не уменьшает точности оценки покрытия.
Для решения различных задач полезно знать не только адрес, куда был совершен переход при передаче управления, но и исходный адрес. Для этих целей удобно использовать стек MSR-регистров LBR. Значение на вершине этого стека будет содержать адрес перехода и исходный адрес.
Значения приведенных выше MSR-регистров доступны только из режима ядра. При реализации алгоритма оценки покрытия только в режиме ядра неизбежны следующие проблемы:
Данные проблемы, а так же возможность использования наработок для статического и динамического анализа программ пользовательского режима, обуславливают использование архитектуры системы, где имеются две главные части:
Отладчик пользовательского режима решает еще одну важную задачу – взвод флага TF для исследуемого потока. Флаг TF взводится отладчиком для потока сразу после его старта. Тот факт, что отладчик реализован в пользовательском режиме упрощает задачу выделения из всех потоков только те, что относятся к исследуемой программе.
После того как флаг TF установлен и инструкция исполнена, управление получает часть системы, расположенная в ядерном адресном пространстве. Здесь фиксируется информация о переходе. После этого необходимо установить флаг BTF, который сбрасывается перед передачей управления обработчику int 1.
После этого управление снова получает отладчик пользовательского режима. Здесь сохраняется информация о переходе, проводится необходимый анализ и взводится флаг TF. Общая схема работы систем представлена на рисунке ниже.
Обмен между подсистемой, расположенной в ядре, и подсистемой пользовательского режима происходит через стандартный механизм ioctl. Получение предыдущей ветви выполняется при обработке шага трассировки в пользовательском режиме. Это дает возможность получить данные для последнего перехода.
Что в итоге получилось
Реализованная утилита проста и наглядна. Называется она IKWYD-0.2.0 (исходные коды). Консольная программа принимает один аргумент — коммандная строка для запуска исселдуемой программы. Утилита сама подгружает драйвер при старте и выгружает при завершении работы. Скомпилированный проект, исходные коды и описание может быть загружено со страницы проекта.
Из известных минусов на данный момент: драйвер не правильно работает на многопроцессорных системах — требуется доработка. Утилита значительно притормаживает из-за того что флаг TF взводится в пользовательском режиме. Если кто-то знает, как это сделать в драйвере — обязательно расскажите мне об этом!
Буду рад услышать любой фидбэк.
]]>